-
11. Data: 2018-09-13 09:05:02
Temat: Re: Biblioteka standardowa time.h i mikrokontrolery
Od: Atlantis <m...@w...pl>
Z ciekawości zobaczę też chyba jak ten projekt zachowa się po
przeniesieniu na jakąś "większą" płytkę Nucleo albo Discovery. Tylko
muszę znaleźć na to chwilę czasu. ;)
-
12. Data: 2018-09-13 09:14:42
Temat: Re: Biblioteka standardowa time.h i mikrokontrolery
Od: Jacek Radzikowski <j...@s...die.die.die.piranet.org>
On 09/13/18 03:03, Atlantis wrote:
> On 13.09.2018 08:37, Jacek Radzikowski wrote:
>
>> To mocno śmierdzi pisaniem po stosie, i problem wcale nie musi być w
>> twoim kodzie. Uprość maksymalnie program testowy, nie używaj LCD ani
>> innych wodotrysków, tylko pisz na konsolę szeregową. Jeśli w dalszym
>> ciągu będą problemy, to błąd najprawdopodobniej siedzi gdzieś w obsłudze
>> RTC. Jeśli nie, to dodawaj po kolejne elementy i patrz kiedy zacznie
>> wariować. Wtedy możesz zacząć szukać w którym komponencie jest problem.
>
> Płytka prototypowa na której działa ten przykład jest dość skromna - to
> fakt. Flash jest w chwili obecnej prawie całkowicie zapchany, jednak
> pamięci RAM pozostało jeszcze całkiem sporo. Wątpię, żeby mogło dojść do
> napisania stosu. Biblioteka LCD działała prawidłowo na AVR, a po
> przeportowaniu na STM32 program z nią również działa poprawnie, pod
> warunkiem zastąpienia wbudowanego RTC osobną zmienną przechowującą
> timestampa.
>
> Jedyne co mi jeszcze przychodzi do głowy, to próba odczytywania RTC z
> parametrem RTC_FORMAT_BCD, a następnie konwertowania do postaci binarnej
> za pomocą zestawu własnych funkcji.
>
> W każdym razie sposób w jaki pobieram dane z RTC i wypełniam nimi
> strukturę struct tm wygląda w porzadku?
Ilość dostępnej pamięci nie ma żadnego znaczenia. Wystarczy zaalokować o
1 bajt za mało na dane i struktury w pamięci zaczynają na siebie
nachodzić. Nawet jeśli ponad nimi będzie jeszcze kilka MB nieużywanej
pamięci.
To że biblioteka działa na jednej platformie że oznacza że będzie
działać na innej. Dlatego do debugowania zawsze powinno się używać jak
najprostszego kodu testowego, z minimalną ilością zależności od
dodatkowych komponentów.
Poza tym że nie pochwaliłeś się jak inicjalizujesz hrtc, to na pierwszy
rzut oka nie ma do czego się przyczepić.
Jacek.
-
13. Data: 2018-09-13 11:18:40
Temat: Re: Biblioteka standardowa time.h i mikrokontrolery
Od: "Grzegorz Niemirowski" <g...@p...onet.pl>
Atlantis <m...@w...pl> napisał(a):
> struct tm dstTime;
Nie inicjalizujesz wszystkich pól tej struktury, np. tm_isdst. Wyzeruj ją:
przy deklaracji
struct tm dstTime = {0};
> Postanowiłem więc zrobić eksperyment i stworzyłem zmienną uint32_t _rtc,
> która była zwiększana o 1 w przerwaniu alarmu RTC. Podpiąłem ją do
> funkcji _gettimeofday i problem zniknął.
Przy okazji: zawsze używaj time_t bo nie masz gwarancji, że timestamp będzie
32-bitowy. To się może zmieniać w zależności od wersji kompilatora.
> Ktoś wie gdzie może leżeć przyczyna takiego zachowania? Co robię nie tak
> czytając RTC? Przykład u góry.
Moim zdaniem czytasz dobrze. Czemu nie wyświetlisz sobie poszczególnych pól
na LCD albo serialu? Im więcej danych diagnostycznych tym lepiej :)
--
Grzegorz Niemirowski
https://www.grzegorz.net/
-
14. Data: 2018-09-14 09:33:23
Temat: Re: Biblioteka standardowa time.h i mikrokontrolery
Od: Atlantis <m...@w...pl>
On 13.09.2018 11:18, Grzegorz Niemirowski wrote:
> Nie inicjalizujesz wszystkich pól tej struktury, np. tm_isdst. Wyzeruj
> ją: przy deklaracji
> struct tm dstTime = {0};
Spróbowałem nawet zerowania struktury za pomocą funkcji memset, ale to
chyba nie to.
Mam jeszcze jedną hipotezę - zauważyłem, że podczas ustawiania zegara na
początku pracy programu (kod wygenerowany przez STM32CubeMX) podawane są
również dodatkowe opcje (np. coś związanego ze zmianą czasu) a także
dzień tygodnia. W swojej funkcji synchronizującej czas pominąłem te
linijki. Po powrocie do domu zobaczę, jak będzie się zachowywał
uzupełniony kod.
Tak BTW przyszedł mi do głowy jeszcze jeden pomysł - z tego co pamiętam
w niektórych modelach PIC32 przed zmianą ustawień zegara konieczne było
odblokowanie tej możliwości poprze wpisanie odpowiedniej wartości do
jednego z rejestrów. Może coś takiego ma też miejsce przynajmniej w
niektórych STM32? W takiej sytuacji oczekiwałbym jednak, że autorzy HAL
wzięli to pod uwagę. Może jednak trzeba to zrobić osobno?
> Przy okazji: zawsze używaj time_t bo nie masz gwarancji, że timestamp
> będzie 32-bitowy. To się może zmieniać w zależności od wersji kompilatora.
Hmm... Przecież chyba właśnie na tym polega sens stosowania typów
zmiennych w formacie *int*_t? Rozumiem, gdybym użył typu unsigned long,
jednak uint32_t 32-bitową zmienną bez znaku? Czyżbym nie miał racji?
-
15. Data: 2018-09-14 11:00:04
Temat: Re: Biblioteka standardowa time.h i mikrokontrolery
Od: "Grzegorz Niemirowski" <g...@p...onet.pl>
Atlantis <m...@w...pl> napisał(a):
> Spróbowałem nawet zerowania struktury za pomocą funkcji memset, ale to
> chyba nie to.
W takim razie nie wiem. Niemniej ciągle się kłania monitorowanie wartości
RTC. To też jest odpowiedź na poniższe dwa Twoje akapity. Bez sprawdzenia
poprawności działania RTC nie ma
co się w ogóle zajmować time.h.
> Mam jeszcze jedną hipotezę - zauważyłem, że podczas ustawiania zegara na
> początku pracy programu (kod wygenerowany przez STM32CubeMX) podawane są
> również dodatkowe opcje (np. coś związanego ze zmianą czasu) a także
> dzień tygodnia. W swojej funkcji synchronizującej czas pominąłem te
> linijki. Po powrocie do domu zobaczę, jak będzie się zachowywał
> uzupełniony kod.
Zainicjuj zgodnie z samplami.
sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sTime.StoreOperation = RTC_STOREOPERATION_RESET;
Nie zostawiaj niezainicjowanych pól w strukturach.
> Tak BTW przyszedł mi do głowy jeszcze jeden pomysł - z tego co pamiętam
> w niektórych modelach PIC32 przed zmianą ustawień zegara konieczne było
> odblokowanie tej możliwości poprze wpisanie odpowiedniej wartości do
> jednego z rejestrów. Może coś takiego ma też miejsce przynajmniej w
> niektórych STM32? W takiej sytuacji oczekiwałbym jednak, że autorzy HAL
> wzięli to pod uwagę. Może jednak trzeba to zrobić osobno?
W STM32 też tak jest i to chyba we wszystkich. Autorzy HAL jak najbardziej o
to zadbali. Obejrzyj sobie kod funkcji ustawiających datę i czas. Jest tam
wykonywane odblokowywanie rejestrów.
>> Przy okazji: zawsze używaj time_t bo nie masz gwarancji, że timestamp
>> będzie 32-bitowy. To się może zmieniać w zależności od wersji
>> kompilatora.
> Hmm... Przecież chyba właśnie na tym polega sens stosowania typów
> zmiennych w formacie *int*_t? Rozumiem, gdybym użył typu unsigned long,
> jednak uint32_t 32-bitową zmienną bez znaku? Czyżbym nie miał racji?
Oczywiście jak najbardziej masz rację, że uint32_t to typ 32-bitowy bez
znaku i masz gwarancję, że zawsze tak będzie. Natomiast mnie chodziło o typ
time_t. Napisałem kiedyś takie coś:
struct tm * t = localtime((time_t *)&seconds);
a seconds było zadeklarowane jako uint32_t
I to działało poprawnie w GCC 5.4. Natomiast w GCC 7.2 przestało,
localtime() zaczęło zwracać bzdury. Dlaczego? Bo time_t zmieniono na
64-bitowy i localtime() pobierało za pomocą wskaźnika nie tylko zmienną
seconds ale także 4 bajty leżące obok w pamięci. Gdybym od razu zadeklarował
seconds jako time_t to nie byłoby problemu przy zmianie wersji GCC. uint32_t
to był nadal uint32_t, ale time_t zmieniono z uint32_t na uint64_t. Pewnie w
Twoim kodzie nie ma takiego problemu, ale pomyślałem, że warto wspomnieć.
--
Grzegorz Niemirowski
https://www.grzegorz.net/
-
16. Data: 2018-09-14 11:09:40
Temat: Re: Biblioteka standardowa time.h i mikrokontrolery
Od: Marek <f...@f...com>
On Fri, 14 Sep 2018 11:00:04 +0200, "Grzegorz Niemirowski"
<g...@p...onet.pl> wrote:
> time_t. Napisałem kiedyś takie coś:
> struct tm * t = localtime((time_t *)&seconds);
> a seconds było zadeklarowane jako uint32_t
> I to działało poprawnie w GCC 5.4. Natomiast w GCC 7.2 przestało,
Z tego co kojarzę time_t w (g)libc nigdy nie gwarantował typu 32uint
i było to "platform dependent".
--
Marek