Elektroda.pl
Elektroda.pl
X

Wyszukiwarki naszych partnerów

Kategoria: Kamery IP / Alarmy / Automatyka Bram
Montersi
Kategoria: Akumulatorki / Baterie / Ładowarki

[STM32][DMA][USART] Kompletacja ramek

kozak_sc 20 Sie 2010 12:54
  • #1 20 Sie 2010 12:54
    kozak_sc
    Poziom 23  

    Witam
    Skonfigurowałem UART-a w STM32 do współpracy z DMA i teraz mam pytanko czy jest jakiś łatwy sposób na generację przerwania nie po skompletowaniu określonej liczby znaków tylko po nadejściu konkretnego znaku (znacznik końca ramki) ??

  • #2 20 Sie 2010 13:49
    michalko12
    Specjalista - Mikrokontrolery

    Niestety nie ma takiej możliwości. UART zbierający dane przez DMA ma niewiele przypadków racji bytu, co innego przy nadawaniu. Lepszym rozwiązaniem jest UART z FIFO. Albo musisz zrezygnować z DMA na RX albo co jakiś czas sprawdzać co UART odebrał.

  • #3 20 Sie 2010 13:54
    nsvinc
    Poziom 34  

    Nie ma takiej możliwości. DMA w STM32 nie ma funkcji przerzutu do tokena.
    Takie coś ma np. DMA zaimplementowany w PIC32.

    Na twój problem stosuje się specyficzne obejście, tzw. szukacz :] (nie wiem
    czy jest to nazwane profesjonalnie, ale wiadomo ocb)

    Sytuacja:
    1) DMA jest skonfigurowany w circular mode, i przerzuca w kółko n danych
    do bufora o rozmiarze n. Wskaznik na pamięć ustawiasz na zerowy
    element bufora, z inkrementacją. Wskaznik na peryferium ustawiasz na UARTx->DR, bez inkrementacji.

    2) Tworzysz zmienną, inicjalizujesz zerem. Nazwijmy ją ple

    3) W main posuwasz ple do przodu aż do momentu gdy osiągnie ona
    DMAx->CNDTR-wielkosc bufora (pamietaj o minus!). Robisz to np.
    forem. Break-asz fora gdy znajdziesz interesujący cię token.

    4) ple w tym przypadku jest twoim szukaczem. Nie możesz nigdy zgubić
    jego najaktualniejszej wartości, nawet po opuszczeniu powyzej opisanego
    fora. Pamiętaj również o tym, że szukacza musisz odpowiednio zawijać na
    skraju bufora!

    Kodu niestety nie mogę udostępnić, bo jest komercyjny, a
    nie mam w tej chwili czasu przerabiać go do przykładu.

    ->michalko12
    Własnie DMA jest niezbędny podczas praktycznie dowolnego RX-a. TX sam
    decyduje o częstotliwości wysyłki znaków, no bo TY nadajesz, a KTOŚ odbiera -
    nie musisz dostosowywać w większości przypadków prędkości TX do odbiornika.
    Pamiętaj, że to RX jest krytyczny, bo KTOŚ nadaje, a TY masz zdążyć odebrać
    dane!
    Zbuduj interfejs przetwarzający w obie mańki 1M znaków z parserem,
    formaterem danych i obsługą pobocznych peryferiów BEZ DMA - wtedy Ci uwierzę...

  • #4 20 Sie 2010 14:46
    michalko12
    Specjalista - Mikrokontrolery

    nsvinc napisał:

    ->michalko12
    Własnie DMA jest niezbędny podczas praktycznie dowolnego RX-a. TX sam
    decyduje o częstotliwości wysyłki znaków, no bo TY nadajesz, a KTOŚ odbiera -
    nie musisz dostosowywać w większości przypadków prędkości TX do odbiornika.
    Pamiętaj, że to RX jest krytyczny, bo KTOŚ nadaje, a TY masz zdążyć odebrać dane!


    Cytat:
    UART zbierający dane przez DMA ma niewiele przypadków racji bytu, co innego przy nadawaniu.


    "Ma niewiele" a nie "wcale nie ma". W przypadku TXa jest tak samo, co ci po DMA przy pełnym RSie. Mówię tylko o przypadku STM32 gdzie te peryferia sa takie jakie są.


    nsvinc napisał:
    Zbuduj interfejs przetwarzający w obie mańki 1M znaków z parserem,
    formaterem danych i obsługą pobocznych peryferiów BEZ DMA - wtedy Ci uwierzę...


    Dlatego napisałem że lepszym rozwiązaniem jest FIFO i nie mówię że DMA jest be, bo nie jest, tylko nie we wszystkich przypadkach używanie DMA jest wygodne.

  • #5 20 Sie 2010 14:55
    nsvinc
    Poziom 34  

    Oczywiście że FIFO. Ale w przypadku STM32 do tego FIFO dane wklada DMA.
    Tak jest w moim przykładzie.

    Czym jest "pełny RS"? A w STM32 jest jaki? Połowiczny?
    Przecież i tak masz wyprowadzone CTS i RTS, ktore raczej świadczą
    o "pełności" tego RSa.

    Co Ci po kontroli przepływu (chyba o to chodzilo z "pełnością"), skoro np.
    jeśli w danym momencie rdzen robi coś raczej istotnego (scheduler OSa,
    przerwanie...) a malutkie np. 128bajtowe FIFO jest pełne, to CTS idzie w dół - nie ma transmisji...

    Po co, skoro DMA może przerzucić zawartość FIFO do jakiegoś bardzo
    dużego bufora roboczego, a transmisja może iść dalej niezależnie od
    zajętości rdzenia?

    fakt, problem rozwiązuje potężne fifo o wielkości potrzebnego bufora roboczego,
    ale jaka jest opłacalność jego implementacji? Łatwiej użyć DMA i osiągnąć
    ekwiwalentny efekt.

  • #6 23 Sie 2010 08:40
    kozak_sc
    Poziom 23  

    W moim przypadku to akurat faktycznie DMA na odbiorze nie ma sensu bo otrzymuje kilkanaście ramek na sekundę (po kilkanaście znaków) więc szukanie cały czas w buforze końca ramki wyjdzie mi tak samo jak odbieranie znaku w przerwaniu sprawdzanie czy nie koniec i ładowanie do bufora. DMA chciałem dać dlatego żeby nie musieć się martwić odbiorem na kilku uartach a "mielić" ramki dopiero jak będą kompletne, niestety Cortex M3 tego nie wspiera a przesiadka tylko z tego powodu na PIC32 nie wchodzi w grę :P Dzięki koledzy za odpowiedź.

  • #7 19 Lip 2013 15:52
    Svavo
    Poziom 23  

    A właśnie, że jest sposób na efektywne wykorzystanie DMA przy odbiorze, nawet dla zmiennej długości ramek. Wystarczy ustawić przerwanie od stanu IDLE dla kanału szeregowego U(S)ART, które generowane jest po zakończeniu transmisji. W tym momencie wszystkie dane są już w zdefiniowanym w DMA obszarze pamięci.

  • #8 19 Lip 2013 19:13
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Podobają mi się te rzeczy o których czytam tutaj (; Do tej pory myślałem że DMA raczej nie ma sensu przy odbiorze danych których długość jest nieznana/zmienna, a tu proszę... Wychodzi na to, że przy zastosowaniu standardowych mechanizmów RTOSa (programowe timery) + ewentualne przerwanie od IDLE można mieć samo odbieranie "gratis".

    4\/3!!

  • #9 19 Lip 2013 19:55
    BlueDraco
    Specjalista - Mikrokontrolery

    Tylko ile to kosztuje w oprogramowaniu... Coś dużo się tego robi.

  • #10 19 Lip 2013 20:08
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Nie uważasz przecież chyba, że da się zrobić wydajny i szybki kod realizujący kilka skomplikowanych funkcji przy użyciu 10-ciu linijek kodu, no nie?

    Poza tym wg mnie taka idea ("nadganianie" DMA w buforze cyklicznym) nie kosztuje nic więcej kodu niż normalna obsługa przerwania, za to ile mniej czasu...

    4\/3!!

  • #11 19 Lip 2013 20:45
    nsvinc
    Poziom 34  

    Tą ideę praktykuję od lat w m.in. różnego rodzaju interfejsach/translatorach, i jeszcze mnie to nie zawiodło. Różnica w ilości kodu - praktycznie żadna.
    Poza tym nie trzeba wcale mieć timerów ani zadnego supervisora, jeśli masz gwarancję, że dane przetworzysz szybciej, niz przychodzą. A parser i obróbka może się mielić najzwyklej w pętli głównej.

  • #12 19 Lip 2013 21:15
    Freddie Chopin
    Specjalista - Mikrokontrolery

    nsvinc napisał:
    Poza tym nie trzeba wcale mieć timerów ani zadnego supervisora, jeśli masz gwarancję, że dane przetworzysz szybciej, niz przychodzą. A parser i obróbka może się mielić najzwyklej w pętli głównej.

    Ja tutaj patrzę od razu pod kątem podpięcia takiego odbioru pod strumienie (czyli FILE, scanf() itd.), które z racji swojej asynchroniczności generalnie potrzebują "czegoś" co by od czasu do czasu odczytywało dane i budziło wątki które na te dane czekają, więc jak znalazł timer programowy lub przerwanie.

    4\/3!!

  • #13 20 Lip 2013 12:15
    Svavo
    Poziom 23  

    Obsługa UART'a przez DMA czy (tylko) przerwania to najniższa warstwa stosu - to co zrobimy z danymi dalej zależy już od konkretnego przypadku. Przerwania i FIFO (o odpowiednim rozmiarze) znacząco odciążają CPU ale korzystając z DMA zostają tylko przerwania przy zakończeniu nadawania/odbioru. Poza przypadkiem, kiedy trzeba analizować każdy nadchodzący bajt, widzę same zalety korzystania z DMA.

  • #14 20 Lip 2013 15:30
    nsvinc
    Poziom 34  

    To działa tylko jeśli nadający wysyła kiedykolwiek to 'idle'. Komputer na życzenie nie potrafi - nie przejdzie [dane][idle][dane][idle] jeśli w kompie mam zapchaną kolejkę wyjściową. Wtedy pozostaje softem gonić index zapisu DMA.

    Dla strumieni transmisja synchroniczna często odpada ze względu na długi RTTI. Ale to też zależy od tego, co transportuje protokół. Ja często jestem zmuszony do transmisji izochronicznej, i nie ma czasu na ACK. A implementacja protokołu obsługującego ACK window to w 99% przypadków przerost formy nad treścią.
    Opracowałem dla siebie wzorzec protokołu multipleksowanego, gdzie po symbolu startu ramki wiadomo, czy ramka niesie dane izochroniczne, czy transakcję pytanie-odpowiedź. I implementuję to w praktycznie każde urządzenie ;]

    A kiedy nie trzeba analizować każdego nadchodzącego bajtu? - praktycznie zawsze trzeba, jeśli DMA nie potrafi rozpoznać narzuconych symboli (jak w PIC32). Poza tym - każdy szanujący się protokół dokleja CRC na koniec ramki, więc trzeba mielić każdy bajt chociażby po to, żeby karmić obliczarkę CRC.
    Korzystanie z DMA ma same zalety niezależnie od tego, co dalej robimy z danymi - w którymś topicu przytoczyłem obliczenia, które uwidaczniają różnicę w obciążeniu procesora.

  • #15 22 Lip 2013 09:26
    Svavo
    Poziom 23  

    nsvinc napisał:
    To działa tylko jeśli nadający wysyła kiedykolwiek to 'idle'. Komputer na życzenie nie potrafi - nie przejdzie [dane][idle][dane][idle] jeśli w kompie mam zapchaną kolejkę wyjściową. Wtedy pozostaje softem gonić index zapisu DMA.(...)

    IDLE określa stan "mark" (=1) na magistrali i nie ma potrzeby tego "znaku" wysyłać. Oznacza to po prostu brak danych na magistrali. Dzięki temu można odróżnić stan IDLE od DISCONNECTED.

  • #16 22 Lip 2013 09:31
    nsvinc
    Poziom 34  

    Jeśli magistrala jest przeciążona to nie występuje na niej 'brak danych'. Idle to jest 10 sampli jedynek pod rząd i faktycznie występuje jesli magistrala jest w danym momencie bezczynna - ale nie występuje, jak jest przeciążona.
    To o czym mówisz ma sens tylko przy transmisji synchronicznej, gdzie nadawca wysyla kompletna ramke i czeka na ACK od odbiorcy.
    Jeśli nadawca tłucze strumien zapychając całą dostępną przepustowość - nie ma szans...

  • #17 22 Lip 2013 09:38
    Svavo
    Poziom 23  

    nsvinc napisał:
    Jeśli magistrala jest przeciążona to nie występuje na niej 'brak danych'. Idle to jest 10 sampli jedynek pod rząd i faktycznie występuje jesli magistrala jest w danym momencie bezczynna - ale nie występuje, jak jest przeciążona.
    To o czym mówisz ma sens tylko przy transmisji synchronicznej, gdzie nadawca wysyla kompletna ramke i czeka na ACK od odbiorcy.
    Jeśli nadawca tłucze strumien zapychając całą dostępną przepustowość - nie ma szans...

    Jeśli magistrala jest przeciążona to siłą rzeczy nie występuje stan IDLE. W znanych mi protokołach opartych na łączu RS232/485 urządzenia zawsze pracują jako master<->slave, dlatego tu problem przeciążenia magistrali nie występuje.

  • #18 22 Lip 2013 14:30
    asier
    Poziom 10  

    Manual o IDLE mówi:

    Cytat:
    An Idle character is interpreted as an entire frame of “1”s followed by the start bit of the next
    frame which contains data (The number of “1” ‘s will include the number of stop bits).

    Czy ktoś może sprawdzał praktycznie kiedy faktycznie pojawia się flaga IDLE? Ja z powyższej informacji wnioskuję, że ta flaga ustawia się dopiero wtedy, gdy nadejdzie nowy znak poprzedzony odpowiednio długą ciszą na linii, czyli nie da się wykryć przerwy zanim nie nadejdzie kolejna ramka.

  • #19 22 Lip 2013 14:34
    Svavo
    Poziom 23  

    asier napisał:
    Manual o IDLE mówi:
    Cytat:
    An Idle character is interpreted as an entire frame of “1”s followed by the start bit of the next
    frame which contains data (The number of “1” ‘s will include the number of stop bits).

    Czy ktoś może sprawdzał praktycznie kiedy faktycznie pojawia się flaga IDLE? Ja z powyższej informacji wnioskuję, że ta flaga ustawia się dopiero wtedy, gdy nadejdzie nowy znak poprzedzony odpowiednio długą ciszą na linii, czyli nie da się wykryć przerwy zanim nie nadejdzie kolejna ramka.

    Jest dokładnie tak jak napisali w manualu, czyli flaga pojawia się po 10-ciu kolejnych bitach =1. W praktyce oznacza to odebranie całej paczki danych.

  • #20 22 Lip 2013 14:42
    asier
    Poziom 10  

    Svavo napisał:
    Jest dokładnie tak jak napisali w manualu, czyli flaga pojawia się po 10-ciu kolejnych bitach =1. W praktyce oznacza to odebranie całej paczki danych.

    To może uściślę pytanie. Czy w sytuacji, gdy skończył się pakiet danych i nie ma już następnych, dostanę przerwanie od IDLE po 10-ciu bitach ciszy od ostatniego znaku, czy też przerwanie pojawi się dopiero wtedy gdy w przyszłości rozpocznie się nowy pakiet danych?

  • #22 22 Lip 2013 15:07
    asier
    Poziom 10  

    Svavo napisał:
    Odpowiedź A

    Dzięki! Ta informacja pomoże mi w przyszłości w przeróbce pewnego projektu.

  • #23 02 Lut 2017 14:51
    mongoł2000
    Poziom 18  

    Wiem , że stary temat, ale czemu koledzy nie używają mechanizmu wyszukiwania znaku w transmisji, która jest sprzętowa....opis w DS dotyczy Modbus, ale działa w normalnym trybie USART.
    Wpisuje się w miejsce rejestru ADD znacznik np. końca linii - 0x0D, a potem uruchamiamy przerwanie od Character Match.
    Druga możliwość to przerwanie po np.100 bitach na magistrali w bezczynności.

  • #24 02 Lut 2017 15:36
    kozak_sc
    Poziom 23  

    To zależy na którym procku. Na STM32F1 nie ma takiej możliwości. Z tego co widzę character match jest w STM32L4

  • #25 02 Lut 2017 16:33
    Piotrus_999
    Poziom 39  

    O F1 to trzeba zapominać przy cenach nowszych rodzin

  • #26 03 Lut 2017 07:48
    kozak_sc
    Poziom 23  

    Cenach jak cenach. Ostatnio bardzo chętnie do projektów dajemy procki L1 ze względu na to że mają poprawionych bardzo dużo błędów w krzemie w stosunku do F1. W F103 na przykład procek idzie do faulta gdy do pamięci na FSMC chcą się odwołać jednocześnie CORE i DMA - porażka.

  • #27 03 Lut 2017 10:14
    Piotrus_999
    Poziom 39  

    Serii X1 nie lubię bo to najstarsze i najbardziej zabugowione. To już lepiej x0 albo X3. Ostatnio do nisko budżetowych moje ulubione to f3 jak bez sieci i USB

  • #28 14 Lut 2017 20:01
    ufock
    Poziom 8  

    kozak_sc napisał:
    Na STM32F1 nie ma takiej możliwości.

    Reference manual twierdzi inaczej. ;)

  • #29 14 Lut 2017 22:11
    Freddie Chopin
    Specjalista - Mikrokontrolery

    ufock napisał:
    Reference manual twierdzi inaczej.

    Prosimy więc o stosowny cytat wraz ze wskazaniem źródła.

  • #30 14 Lut 2017 22:28
    Piotrus_999
    Poziom 39  

    Freddie Chopin napisał:
    Prosimy więc o stosowny cytat wraz ze wskazaniem źródła.
    Pewnie o LIN przeczytał a tam jest "delimiter character". I tak to zrozumiał.