eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.misc.elektronikaBiblioteka standardowa time.h i mikrokontrolery › Re: Biblioteka standardowa time.h i mikrokontrolery
  • 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/

Podziel się

Poleć ten post znajomemu poleć

Wydrukuj ten post drukuj


Następne wpisy z tego wątku

Najnowsze wątki z tej grupy


Najnowsze wątki

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: