logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Xmega128A3 - uart na przerwaniach, biblioteka Atmela, echo na terminal.

dawid.barracuda 08 Kwi 2017 19:01 945 6
REKLAMA
  • #1 16400562
    dawid.barracuda
    Poziom 13  
    Cześć :)
    Postawiłem sobie za zadanie opanować i dobrze zrozumieć bibliotekę uart od Atmela. W poprzednim poście zastanawiałem się nad przerwaniem TXC, a teraz próbuję wykonać coś w rodzaju echa - mianowicie znaki, które wyślę z terminala do procka chcę wysłać na terminal w takiej samej kolejności + liczba informująca o ilości odebranych znaków. Popełniłem więc taki kod:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Zwracany łańcuch jest taki sam jak wysyłany + liczba odebranych znaków. Obawiam się jednak, że nie do końca robię to poprawnie. Może zajść przypadek, że nadejdzie dana/dane w trakcie wykonywania fragmentu warunku if(licznikOdebranychZnakow), gdyż operuję na przerwaniach. Pod koniec ifa zeruję ten licznik. Po zakończeniu wykonywania if'a i wyzerowaniu "licznikOdebranychZnakow" już nic więcej nie przychodzi, a dane wiszą mi w buforze odbiorczym, bo warunek wykonania bloku instrukcji if(licznikOdebranychZnakow) będzie niespełniony. Jak należy to dobrze rozwiązać, żebym zawsze wysłał wszystkie odebrane dane?

    Proszę uprzejmie o wskazówki i pozdrawiam.

    Dodano po 16 [minuty]:

    Co więcej, jak skasowałem fragment:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    to echa nie ma w ogóle, na terminal nic nie leci. Jak znowu wstawiłem ten fragment to zdarza się, że np. wysyłając łańcuch znaków: "abcdefghijklmnopqrstuvwxyz" do procesora, na terminal wróci: "zabcdefghijklmnopqrstuvwxy", czyli ostatnia literka zostaje przesunięta na początek.
    Jak należy to zorganizować, żeby nie było tego typu błędów?
  • REKLAMA
  • Pomocny post
    #2 16400682
    Konto nie istnieje
    Konto nie istnieje  
  • REKLAMA
  • Pomocny post
    #3 16400708
    tmf
    VIP Zasłużony dla elektroda
    @dawid.barracuda Pamiętaj o konieczności zapewnienia atomowości operacji na licznikOdebranychZnakow - zarówno podczas porównania tej zmiennej, jak i przypisania jej nowej wartości. Poza tym zamiast ją zerować na końcu odejmij od bieżącej wartości zmiennej, liczbę rzeczywiście wysłanych bajtów. Jeśli w międzyczasie coś zostanie odebrane, to wartość tej zmiennej zostanie zwiększona, a na końcu twojej funkcji po odjęciu liczby przesłanych bajtów zmienna ta będzie miała wartość różną od zera, w efekcie w kolejnym obiegu pętli nowoodebrane bajty zostaną wysłane. Oczywiście w twoich funkcjach musisz operować na "zamrożonej" wartości zmiennej licznikOdebranychZnakow - np. poprzez przypisanie jej wartości zmiennej lokalnej, którą dalej wykorzystujesz jako licznik.
  • REKLAMA
  • #4 16402096
    dawid.barracuda
    Poziom 13  
    I bufor kołowy właśnie jest wykorzystywany w bibliotece Atmela :)
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    @Piotrus_999 - uważasz, że powinienem napisać tutaj własne funkcje do obsługi uarta?
    Panie Tomku - rozumiem zamysł, poprawię kod :)

    Powiem może dokładniej co mam do zrobienia i dlaczego uparłem się na tę bibliotekę Atmela. Trochę mi nie wychodziło stąd wróciłem do początku żeby sobie ogarnąć funkcje tej biblioteki.
    Po pierwsze chcę mieć pewność, że jest to napisane porządnie. Po drugie, pracuję nad siecią urządzeń. Wszystkie mają RS232, a ja je chcę spiąć w sieć i wykorzystywać RS485 do komunikacji z komputerem. Chcę wykorzystać sobie do tego MODBUS, rejestry pasują do tego jak ulał. Stąd mikrokontroler pomiędzy PC i urządzeniem. Odpytywane one będą bez przerwy przez uC, a z PC co jakiś czas, np. co 2s będzie zapytanie o parametry i wysyłka aktualnej tablicy z wartościami.

    I w sumie pytanie sprowadza się do tego jak dobrze zorganizować komunikację. Mam urządzenie, wysyłam 20 komend do niego i dostaję 20 odpowiedzi. Jak poprawnie zrobić to tak, żeby wysłać te 20 komend, zaprzestać wysyłania na czas zbierania odpowiedzi, przyporządkować odpowiedzi do rejestrów (czyli zmiennych w tablicy), zatrzymać jedną kopię (na wypadek żądania wysyłki do PC), wysłać znowu zapytanie do urządzenia, zbierać dane w drugiej tablicy, potem nadpisać pierwszą i tak w kółko. Trzeba zrobić jakąś maszynę stanów logicznych korzystając z flag typu bool? Jesteście Koledzy dużo bardziej doświadczeni, a ja chcę to zrobić jak należy :)
  • Pomocny post
    #5 16402194
    Konto nie istnieje
    Konto nie istnieje  
  • REKLAMA
  • Pomocny post
    #6 16402249
    grko
    Poziom 33  
    @dawid.barracuda Na pewno nie powinieneś robić na siłę samemu. Potrzebujesz modułu, który implementuje algorytm FIFO aby w elegancki sposób obsłużyć UARTA. Warto się posłużyć implementacją, która już działa. Możesz pokusić się o własną implementację ale mimo wszystko wzorować się na czymś sprawdzonym. Taki moduł będziesz mógł sobie w przyszłości użyć w innych miejscach.

    Ten kod od atmela co wrzuciłeś jest słaby. Po pierwsze ze względu na nadużycie modyfikatora volatile. Po druge właśnie ze względu, że jest sam algorytm jest zaimplementowany w driverze.
  • #7 16402315
    dawid.barracuda
    Poziom 13  
    grko - skoro nie kod od Atmela to co proponujesz?
REKLAMA