-
Data: 2018-09-13 00:07:56
Temat: Re: Biblioteka standardowa time.h i mikrokontrolery
Od: "Grzegorz Niemirowski" <g...@p...onet.pl> szukaj wiadomości tego autora
[ pokaż wszystkie nagłówki ]Atlantis <m...@w...pl> napisał(a):
> Czyli rozumiem, że inne ARM-y programuje się w podobny sposób,
> korzystając z tego samego kompilatora? Na przykład takie AT91SAM7* będą
> miały to rozwiązane w ten sam sposób, a różnice będą wynikały głównie z
> nieco innego zestawu peryferiów (np. brak SysTick) oraz innych bibliotek
> do ich obsługi?
Tak, zgadza się. W obrębie danego kompilatora wszystko będzie odbywało się
bardzo podobnie. Standardowe biblioteki C nie zajmują się peryferiami, nie
są aż tak niskopoziomowe i daje to pewną przenośność. Z resztą na
Windowsie/Linuksie Twój program też nie zajmuje się obsługą karty graficznej
czy pakietami TCP/IP. Od tego jest system operacyjny i sterowniki.
Kompilator interesuje przede wszystkim rdzeń mikrokontrolera, lista rozkazów
(np. Thumb2) czy dostępność FPU. Do tego opcje linkera, jak adresacja
RAM/Flash oraz dołączanie bibliotek. Nie ma znaczenia SysTick czy RTC.
Możesz zerknąć na pliki Makefile dla różnych ARMowych projektów i sprawdzić
jakie parametry są przekazywane do kompilatora.
> Tak z ciekawości. Jak to wyglądało w przypadku AVR-ów? W czasach, gdy
> uczyłem się tych mikrokontrolerów nigdy nie musiałem podpinać
> niskopoziomowych funkcji do obsługi biblioteki standardowej. Zamiast
> printf używałem zestawu snprintf + uart_puts, a operacje związane z
> czasem załatwiałem za pomocą zestawu własnych funkcji. Jestem jednak
> ciekaw na ile dałoby się to zrobić w teorii. Zwłaszcza, że przecież
> niektóre z wyższych modeli Atmegi i AtXmegi miały już dość sporo
> pamięci...
W AVR GCC jest taka funkcja:
FILE* fdevopen(int(*)(char, FILE *)put, int(*)(FILE *)get);
Służy ona do definiowania strumienia we/wy. Podajesz jej jako parametry
wskaźniki na funkcje do wysyłania i odbierania znaku. Parametry mogą być
NULami. I jest taki myk, że pierwsze wywołanie fdevopen(), które ma parametr
put niebędący NULem, powoduje zdefiniowanie strumienia stdout (standardowego
wyjścia). Jeśli więc masz funkcję uart_putc(), czyli dla pojedynczego znaku,
to możesz napisać:
int put(char c, FILE * file) {
uart_putc(c);
return 0;
}
I wywołać fdevopen():
fdevopen(&put, NULL);
Od tego momentu możesz używać printf() a wyniki jego działania będą szły na
port szeregowy. Albo np. na LCD jeśli zamiast uart_putc() użyjesz funkcji do
wyświetlania literki na wyświetlaczu. Możesz też zdefiniować drugi strumień
i odwoływać się do niego za pomocą fprintf() jeśli chcesz wysyłać teksty
metodą printfową zarówno na LCD jak i UART.
To wszystko jest opisane w dokumentacji AVR GCC, a dokładniej AVR libc
https://www.nongnu.org/avr-libc/user-manual/group__a
vr__stdio.html
Co do czasu, to AVR libc ma wewnętrzny licznik, który trzeba inkrementować
wywołując co sekundę funkcję system_tick(). A najpierw oczywiście
zainicjalizować wołając set_system_time(). Wtedy funkcja time() będzie mogła
zwrócić właściwy czas. Opis jest na stronie
https://www.nongnu.org/avr-libc/user-manual/group__a
vr__time.html Jak widać
obsługa czasu jest okrojona. Nie można np. ustawić strefy czasowej oraz
czasu letniego za pomocą zmiennej środowiskowej. Zamiast tego ustawia się
strefę funkcją set_zone() a czas letni jest załatwiany poprzez wskazanie
funkcją set_dst() funkcji, która obliczy przesunięcie czasu letniego na
podstawie podanego timestampa (przykładowo dzisiaj zwróci 3600 a w grudniu
0). Czyli jeśli wywołamy funkcję localtime(), to zostanie wzięty czas z
funkcji time(), dodane przesunięcie wynikające ze strefy czasowej (podane
jako parametr set_zone()) oraz dodane przesunięcie z funkcji wskazanej przez
set_dst(). A skąd wziąć funkcję do czasu letniego? W bibliotece
util/eu_dst.h jest taka funkcja dla Unii Europejskiej. Ale nie działa
poprawnie :) Bug+fix: https://savannah.nongnu.org/bugs/?44327
Czyli podsumowując, w AVR GCC zamiast syscalli wymyślili takie obejścia.
--
Grzegorz Niemirowski
https://www.grzegorz.net/
Następne wpisy z tego wątku
- 13.09.18 07:46 Atlantis
- 13.09.18 08:37 Jacek Radzikowski
- 13.09.18 09:03 Atlantis
- 13.09.18 09:05 Atlantis
- 13.09.18 09:14 Jacek Radzikowski
- 13.09.18 11:18 Grzegorz Niemirowski
- 14.09.18 09:33 Atlantis
- 14.09.18 11:00 Grzegorz Niemirowski
- 14.09.18 11:09 Marek
Najnowsze wątki z tej grupy
- DC blocker i buczące toroidy
- Problemy TSMC cd
- Detektor
- Może tutaj się uda: [NTG] Elewacja / dziurawa Churka
- Falownik jednofazowy a żarówka
- Agregat i "legalność" instalacji
- Uziom
- (Ponownie) odkryto, że ładowanie pulsacyjne robi dobrze
- driver led ?
- Długość wtyku zasilającego ?5.5mm
- Szukam przetwornicy 55-40V>8-8.2V 3-4A
- Kindle - pierwsze wrażenia
- Transformator TS90/16, uzwojenia połączone szeregowo na stałe, z asymetrycznym odczepem, napięcia 16V i 39V a prostowanie pełnookresowe
- regulacja prądu ?
- W jakim celu napięcia symetryczne?
Najnowsze wątki
- 2024-04-28 Elektryk przytarł podłogę
- 2024-04-27 Nowy, "szybki "komputer AsRock nie posiada modułu TPM
- 2024-04-27 Nowy, "szybki "komputer AsRock nie posiada modułu TPM
- 2024-04-27 Warszawa => Inżynier DevOps (projekt JP) <=
- 2024-04-27 Warszawa => Senior Account Manager (on-site) <=
- 2024-04-27 Wrocław => Dyrektor Sprzedaży (branża usług/produktów IT) <=
- 2024-04-27 Warszawa => Sales Representative for Outsourcing Services <=
- 2024-04-27 Chrzanów => Administrator i wdrożeniowiec Lotus Notes/Domino <=
- 2024-04-27 Ja pierdolę...
- 2024-04-27 Ryby i kawitacja
- 2024-04-27 Zabrze => Junior HelpDesk <=
- 2024-04-27 Katowice => Administrator IT - Wirtualizacja i Konteneryzacja <=
- 2024-04-27 Bażanowice => Inżynier Industrializacji - Elektronik <=
- 2024-04-27 Warszawa => Full Stack web developer (obszar .Net Core, Angular6+) <=
- 2024-04-27 Zadaszenie tarasu, a wymagany spadek