Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 15 lis 2024, o 06:43


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 8 ] 
Autor Wiadomość
PostNapisane: 30 kwi 2015, o 20:25 
Offline
Użytkownik

Dołączył(a): 26 lut 2014
Posty: 227
Lokalizacja: LDZ
Pomógł: 22

Witam.

Chciałbym się podzielić z Wami biblioteką mojego autorstwa służącą do obsługi USART w AVR. Celem było napisanie jak najbardziej uniwersalnej oraz nieblokującej obsługi USART.
Funkcjonalność biblioteki:
  • Pełna niezależność od rejestrów procesora(naoglądałem się Mirka poradników o callbackach ;)) - ta przyjemność pozostaje po stronie użytkownika.
  • Obsługa buforów cyklicznych z obsługą przepełnienia - po jednym dla nadawania i odbierania danych.
  • Nieblokujące funkcje wysyłania i odbierania - transmisja z i do bufora odbywa się w przerwaniach.
Poniżej kod biblioteki:
usart.h
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

usart.c
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

I oczywiście przykładowe wykorzystanie biblioteki. Tutaj proste echo odebranych danych wersja dla Atmegi2560:
main.h
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

main.c
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Proszę o niekopiowanie kodu w innych miejscach bez mojej zgody. Kod udostępniam do użytku niekomercyjnego.
Myślę, że komentarze w plikach wystarczą za wyjaśnienie sposobu użytkowania tej biblioteki. Wszelka konstruktywna krytyka mile widziana.
EDYTA1:
Zmiany w bibliotece:
  • Bufory definiowane przez użytkownika, wskaźniki na nie należy przekazywać do funkcji biblioteki. Dzięki temu można zunifikować bufor jeśli transmitujemy w trybie half duplex.
  • Dodano callback do funkcji odbierania wywoływany po pierwszym pojawieniu się danych w buforze.
  • Dodano flagę wysyłania tak by nie było możliwe kilkukrotne uruchamianie wysyłania.
EDYTA2:
Kolejne zmiany i poprawki.
  • Dodano możliwość skorzystania z makr zamiast systemu callback-ów co zmniejsza kod wynikowy.
  • Usunąłem błąd w procedurze odbierania danych polegający na błędnym wykrywaniu przepełnienia bufora. Chyba nikt nie przejrzał kodu bo aż raziło ;)



Ostatnio edytowano 9 maja 2015, o 18:47 przez ryba84, łącznie edytowano 5 razy

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 kwi 2015, o 20:51 
Offline
Użytkownik

Dołączył(a): 26 lut 2014
Posty: 227
Lokalizacja: LDZ
Pomógł: 22

Nie tak ostro bo w piórka obrosnę ;). Masz rację powinienem sprawdzać czy mam podpięty callback bo program pójdzie w maliny, ale chciałem kilkadziesiąt bajtów zaoszczędzić (chyba, że masz pomysł jakich flag optymalizacji użyć aby GCC samo usuwało zbędny kod). Z drugiej strony jeśli użytkownik nie zarejestruje funkcji to i tak mu nie będzie działać to co chce. Sprawdzam tylko czy ktoś chce obsługiwać przepełnienie bufora. Reszta ma być bo inaczej nie działa ;). Tak trzeba się wysilić aby użyć tej biblioteki (inicjalizacja), ale dzięki takiemu podejściu jak się przesiądę na jakiś inny procek (ARM?PIC?) to nadal można korzystać z tego kodu (chyba :?: ). Za to dorobienie do tego obsługi RS485 w trybie half duplex jest banalnie proste, bo wystarczy wachlować dodatkowym pinem podczas uruchamiania i wyłączania trybu nadawania. Kombinowałem z napisaniem jakiejś prostej funkcji inicjalizacji pod AVR z callbackiem pod rejestry użyszkodnika, ale to moim zdaniem strata czasu. Równie dobrze może być tak jak jest, a po niewielkich przeróbkach (które za jakiś czas wrzucę) możemy korzystać z kilku USART-ów na raz z oddzielnymi buforami dla każdego z nich.



Ostatnio edytowano 30 kwi 2015, o 21:14 przez ryba84, łącznie edytowano 2 razy

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 kwi 2015, o 21:12 
Offline
Użytkownik

Dołączył(a): 26 lut 2014
Posty: 227
Lokalizacja: LDZ
Pomógł: 22

To by było ciekawe czy działa pod PIC. Jak jest możliwość pomijania zbędnego kodu w GCC to z chęcią z niej skorzystam. Albo może jakiś warning/błąd podczas kompilacji, że nie zarejestrowałem funkcji. Ja dopiero raczkuję w C i tylko w wolnym czasie, więc jak są jakieś sugestie to z chęcią ich posłucham(przeczytam :) ).



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 kwi 2015, o 21:20 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 30 gru 2012
Posty: 188
Lokalizacja: Świnice Warckie woj. łódzkie
Pomógł: 12

jeśli chodzi o flagi to
W konfiguracji projektu C/C++ Build -> Settings -> AVR Compiler -> Optimization zaznaczone opcje -ffunction-sections oraz -fdata-sections
ewentualnie w starszej wersji avr plugin dopisać w Other Optimization Flags
Kod:
-ffunction-sections -fdata-sections

następnie w AVR C Linker -> General -> Other Arguments dopisać
Kod:
-Wl,--gc-sections


i jeśli dobrze pamiętam to Eclipse Gadget ma tez opcję z dodaniem tych parametrów do projektu

_________________
ATMEL-ICE+ATXmega256A3BU oraz dużo samozaparcia



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 kwi 2015, o 21:49 
Offline
Użytkownik

Dołączył(a): 26 lut 2014
Posty: 227
Lokalizacja: LDZ
Pomógł: 22

Mam to ustawione i to się odnosi tylko do nieużywanych funkcji. Tutaj problemem jest część kodu znajdująca się w funkcji. Pomijając sprawdzanie czy funkcje zostały zarejestrowane zyskujemy 12 bajtów w tym konkretnym przykładzie (program ma 898bajtów bez sprawdzania i 910 bajtów z, co dla Atmegi2560 akurat ma kolosalne znaczenie :) ). Brak rejestracji funkcji może wprowadzać w błąd (ciągłe resetowanie się procka) i w konsekwencji szukanie błędu nie tam gdzie trzeba. W pierwszym poście poprawiłem to dla innych. Ja albo sobie dorobię makra do wyłączania zbędnych sekcji, albo może znajdą się flagi wywalające zbędny kod. Tylko to nie takie proste, bo kompilator nie kompiluje od razu całego projektu tylko pliki po kolei, więc kompilując usart.c nie wie jeszcze czy użyszkodnik będzie rejestrował callbacki w głównym programie. Trafiłem kiedyś na flagi możliwe do użycia tylko jak wszystko kompilowało się z jednej linii polecenia, ale nie działają z najnowszym toolchain Atmela (albo ja nie umiem ich użyć).

EDYTA:
Są dwie opcje kompilacji:
  • -fwhole-program - tego nie umiem w ogóle zmusić do działania - trzeba przekazywać wszystkie pliki źródłowe na raz do kompilatora
  • -flto - pod Eclipse tworzy większy kod (1416 bajtów), ale z linii komend daje 894 bajty (system linux):
    Kod:
    avr-gcc -Wall -I"/home/ryba/Programowanie/avr/usart_lib" -Os -fpack-struct -fshort-enums -ffunction-sections -fdata-sections -ffreestanding -fno-tree-scev-cprop -mcall-prologues -flto -std=gnu99 -funsigned-char -funsigned-bitfields -mmcu=atmega2560 -DF_CPU=16000000UL -MD -MP -MT -MF"usart_lib.d" "../usart.c" "../main.c" -mmcu=atmega2560 -Wl,--relax -Wl,--gc-sections -Wl,-Map=usart_lib.map -o usart_lib.elf
    żeby nie było tak różowo to i w Eclipse i z linii komend wali warningiem:
    Kod:
    In function '__vector_25':
    ../main.c:74:1: warning: '_vector_25' appears to be a misspelled signal handler [enabled by default]
     ISR(USART0_RX_vect) {
     ^
    In function '__vector_27':
    ../main.c:78:1: warning: '_vector_27' appears to be a misspelled signal handler [enabled by default]
     ISR(USART0_TX_vect) {
    co nie zmienia faktu, że program działa.
Pierwsza opcja może być wydajniejsza gdyż wszystkie funkcje w plikach traktuje jako statyczne pozwalając na bardziej agresywną optymalizację, ale ja nie umiem jej zmusić do działania.

EDYTA2:
Działa też -fwhole-program nawet w Eclipse. Tylko żeby działało musiałem dać na górze main.c
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
co nie jest zbyt ładną praktyką. Daje to kod wielkości 816 bajtów (ok. 10% mniejszy)!!! Według dokumentacji GCC nie wolno łączyć obu optymalizacji.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 maja 2015, o 19:20 
Offline
Użytkownik

Dołączył(a): 13 lut 2015
Posty: 99
Pomógł: 6

Dosyć ciekawe podejście z callbackami.

_________________
AVR-UART-lib
AVR-FAST-ENCODER
RFM7x-lib



Ostatnio edytowano 7 paź 2017, o 20:36 przez jnk0le, łącznie edytowano 5 razy

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 maja 2015, o 19:02 
Offline
Użytkownik

Dołączył(a): 26 lut 2014
Posty: 227
Lokalizacja: LDZ
Pomógł: 22

Dzięki za podpowiedzi. Myślałem o rozwiązaniu z makrami, i może dorobię takie do wykorzystania w bibliotece. Na razie naniosłem kolejne poprawki w kodzie usuwając poważny błąd przy wykrywaniu przepełnienia bufora odbioru (funkcja, która powinna być wywoływana przy przepełnieniu była wywoływana przy każdym odebraniu danych).
A tak z innej beczki czy dopuszczalne jest definiowanie makr w pliku*.c?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 10 maja 2015, o 10:57 
Offline
Użytkownik

Dołączył(a): 13 lut 2015
Posty: 99
Pomógł: 6

Tak, ale tylko do użytku wewnątrz tegoż pliku.

_________________
AVR-UART-lib
AVR-FAST-ENCODER
RFM7x-lib



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 8 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 0 gości


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO