Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

AVR - przerwanie NAKED od UART\a

17 Jan 2017 04:42 1395 16
Computer Controls
  • #1
    Anonymous
    Anonymous  
  • Computer Controls
  • #2
    dondu
    Moderator on vacation ...
    Dlaczego stos miałby się przepełnić poprawnie deklarując ISR?
    W jakim celu jest Ci to potrzebne?
    Innymi słowy, po co takie kombinowanie?

    A jeżeli już tak bardzo chcesz kombinować, to na początku funkcji przerwania odbioru danej przed wykonaniem sei wczytaj odczytaj UDR do jakiegoś rejestru lub pamięci.
  • #3
    Anonymous
    Anonymous  
  • #4
    tmf
    Moderator of Microcontroller designs
    @R-MIK Jeśli dasz NAKED i wstawkę w ASM, to ta wstawka może przecież zapisać i odczytać rejestr. A jaki to wiesz, bo sam go wybrałeś :) Możesz też użyć składni gcc do operacji w asemblerze, wtedy nie operujesz na rejestrach, tylko wskazujesz grupę, a kompilator sam sobie to tłumaczy na konkretne instrukcje. W tym przypadku IMHO lepiej po prostu wstawić goły asembler.
  • Computer Controls
  • #5
    BlueDraco
    MCUs specialist
    To nie zmierza w dobrym kierunku. Błąd w założeniach (nie wiemy, jakich), błędna koncepcja rozwiązania zapewne nieistniejącego problemu, próba dziwacznej implementacji. Nie tędy droga.
  • #6
    Anonymous
    Anonymous  
  • #7
    tmf
    Moderator of Microcontroller designs
    @R-MIK Po kolei. Pierwsze - po co ten naked? Co chcesz osiągnąć? Bo jeśli tylko odblokowanie przerwań, to przecież możesz dać sei w kodize normalnego przerwania, tyle, że przed skasowaniem stosownej flagi. Do czego tu chcesz użyć asemblera?
  • #8
    dondu
    Moderator on vacation ...
    R-MIK wrote:
    dondu wrote:
    Dlaczego stos miałby się przepełnić poprawnie deklarując ISR?

    Nie wiesz? Przecież napisałem, że flaga IRQ jest kasowana po odczycie rejestru a nie po wejściu w nie.

    Zanim odpowiesz czytaj proszę dokładnie co napisałem.

    R-MIK wrote:
    dondu wrote:

    W jakim celu jest Ci to potrzebne?

    To oczywiste, przerwania wielopoziomowe.

    Na to jest bardzo dobra odpowiedź:

    BlueDraco wrote:
    To nie zmierza w dobrym kierunku. Błąd w założeniach (nie wiemy, jakich), błędna koncepcja rozwiązania zapewne nieistniejącego problemu, próba dziwacznej implementacji. Nie tędy droga.
  • #9
    Anonymous
    Anonymous  
  • #10
    BlueDraco
    MCUs specialist
    Czyli błąd w założeniach projektu - źle wybrany mikrokontroler. Należy albo obsługiwać Onewire w sposób nie wymagający mikrosekundowej precyzji przerwań (czyli przez UART, których zapewne Ci zabrakło), albo zmienić mikrokontroler na taki, który da sobie z tym radę - AVR z większą liczbą UARTów lub dowolny z prawdziwym wielopoziomowym systemem przerwań, np. dowolny Cortex (TMF zaraz napisze, że Xmega też to potrafi).
    Robiąc to na ATmega w taki sposób prosisz się o kłopoty. Proteza z odblokowaniem przerwań w przerwaniach zwykle kończy się paskudnymi błędami synchronizacji.
  • #11
    Anonymous
    Anonymous  
  • #12
    BlueDraco
    MCUs specialist
    Ano do Slave to potrzeba przyzwoitego timera, a pewnie takich nie ma w ATmega. Z mniej przyzwoitym przydałby się wielopoziomowy system przerwań, a takiego też nie ma. Bez wielopoziomowego systemu przerwań pozostają dziurawe jak sito protezy. R-MIKu, nie idź tą drogą! Wiem, że i tak pójdziesz, boś uparty i do AVR przyklejony. ;)
    Kłopoty z odblokowywaniem przerwań są zawsze, czasem tylko się nie ujawnią, kiedy całość jest b. prosta. Np. w Twoim dekoderze DCC była z tym niezła jazda...
  • #13
    Anonymous
    Anonymous  
  • #14
    tmf
    Moderator of Microcontroller designs
    @R-MIK Obawiam się, że nie masz racji. Poczytaj ABI gcc, dowiesz się dlaczego np. R1 musi być zachowany na stosie. R0 i RAMPZ praktycznie też. Oczywiście jeśli zmienisz kod na własny, to można w pewnych przypadkach R0 i R1 odpuścić.
    Natomiast podstawowe pytanie - jakie ma znaczenie czy sei wykona się po 5, czy 20 taktach? Masz jakieś inne przerwania, które muszą być obsłużone z latencją <11 taktów? Bo jeśli nie to omawiany przykład to czysto akademicka dyskusja. Tym bardziej, że jak kojarzę resztę twojego kodu slave, to masz tam m.in. delay, które mocno się kłóci z przerwaniami.
    BTW, w kodzie sei możesz dać o jedną instrukcję przed odczytem UDR - zyskasz na tym na latencji. AVR gwarantuje, że wykona przyjnajmniej jedną instrukcję po sei. To nie ARM :)

    Dodano po 3 [minuty]:

    BlueDraco wrote:
    Ano do Slave to potrzeba przyzwoitego timera, a pewnie takich nie ma w ATmega. Z mniej przyzwoitym przydałby się wielopoziomowy system przerwań, a takiego też nie ma. Bez wielopoziomowego systemu przerwań pozostają dziurawe jak sito protezy. R-MIKu, nie idź tą drogą! Wiem, że i tak pójdziesz, boś uparty i do AVR przyklejony. ;)
    Kłopoty z odblokowywaniem przerwań są zawsze, czasem tylko się nie ujawnią, kiedy całość jest b. prosta. Np. w Twoim dekoderze DCC była z tym niezła jazda...


    Nie masz racji. Przecież takim timerem może być UART. Jedyna różnica, że nie można go sprzętowo wyzwolić, ale to załatwi prosty kod. Bez problemu można też wykorzystać timery z ATMegi. Wielopoziomowy system przerwań? Po co w tak trywialnym kodzie? Poza tym, wielopoziomowy system przerwań to prawie taki sam bajzel jak odblokowanie przerwania w przerwaniu, przecież to w praktyce to samo.
    IMHO autor widzi problemy, tam gdzie ich nie ma.
  • #15
    Anonymous
    Anonymous  
  • #16
    jnk0le
    Level 18  
    Jeśli chcesz włączać przerwania w przerwaniach uarta, powinieneś wyłączać źródło konkretnego przerwania (bity UDRIE, RXCIE).
    Samo odczytanie UDR i sei prowadzi do klasycznego race condition, a przerwania UDRIE inaczej nie będzie się dało zrobić.
  • #17
    Anonymous
    Anonymous