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

KURS HOME ASSISTANT

Chcesz zautomatyzować swój dom bez skomplikowanego kodowania?
Zastanawiasz się nad wyborem sprzętu, oprogramowania i aplikacji?
Od czego zacząć przygodę z HA? Co będzie najlepsze na start?

Nasz kurs Home Assistant nauczy Cię krok po kroku, jak łatwo zautomatyzować swój dom i oszczędzić na rachunkach za prąd i ogrzewanie. Bez chmur, bez zbędnych abonamentów. Twoja przygoda z Home Assistant zaczyna się tutaj!

↓↓↓

    Szanujemy Twoją prywatność. Możesz wypisać się w dowolnym momencie.




    Teraz jest 14 lip 2025, o 19:30


    Strefa czasowa: UTC + 1





    Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 13 ] 
    Autor Wiadomość
    PostNapisane: 12 kwi 2016, o 22:04 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 17 sie 2013
    Posty: 48
    Pomógł: 2

    Witam,
    w programie używam bufor pierścieniowy do wysyłania znaków przez uart. Zastanawiam się czy da się wstrzymać wykonywanie przerwań podczas dodawania ramki danych do bufora, aby procedura przerwania nie próbowała dodać innych danych w trakcie. Oczywiście zaległe przerwania po dodaniu danych do bufora powinny się wykonać. Dodam że używam mikrokontrolera sam4s z rdzeniem cortex m4.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 12 kwi 2016, o 22:13 
    Offline
    Użytkownik

    Dołączył(a): 04 paź 2011
    Posty: 8615
    Pomógł: 338

    W bibliotekach jest taka funkcja
    void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority){..}


    przyjmuje ona wartość priorytetu oraz nr przerwania,ale zarówno systemowe jak i zewnętrze działają.
    możesz wiec sobie tak ustawić przerwania żęby np SysTick miał najniższy priorytet, niższy niż np USART
    dzieje się tak dlatego że uC obsługuje np 12 priorytetów wystarczy wiec SYSTick'owi przypisać 11 i SYSTick już żadnego przerwania nie wywłaszczy bo niby jak :).

    To się zwie Grupowanie i stanowi maskowanie linii zgłoszenia przerwania tylko w NVICu, ale pamiętaj wagi priorytetów nadal oznaczają to samo.

    _________________
    Zbuduj swój system [url=https://helion.pl/ksiazki/w-labiryncie-iot-budowanie-urzadzen-z-wykorzystaniem-ukladow-esp8266-i-esp32-andrzej-gromczynski,wlablo.htm#format/d]IOT[/url]



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 12 kwi 2016, o 22:35 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 17 sie 2013
    Posty: 48
    Pomógł: 2

    to rozumiem, ale przykładowo dodaję ramkę danych A która ma 20 bajtów. Robię to w pętli głównej, po dodaniu 10tego bajtu wykona się przerwanie zewnętrzne, które doda w tym momencie ramkę B która też ma 20 bajtów. W efekcie bufor będzie zawierał dane w następującej kolejności: 10 bajtów ramki A, całą ramkę B i 10 bajtów ramki A.

    ------------------------ [ Dodano po: 1 minucie ]

    A mi zależy aby dane się nie wymieszały



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 12 kwi 2016, o 22:50 
    Offline
    Użytkownik

    Dołączył(a): 26 lip 2012
    Posty: 291
    Lokalizacja: okolice Opola
    Pomógł: 20

    To wyłącz tylko przerwanie usartu na ten czas. Po co blokować niepotrzebnie inne w którym nie dotykasz bufora.

    _________________
    sig off ;(



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 13 kwi 2016, o 11:41 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 17 sie 2013
    Posty: 48
    Pomógł: 2

    Troszeczkę w nocy czytałem, więc mogłem coś źle zrozumieć :D

    Ale doczytałem się o takich makrach asemblerowych jak:

    __disable_irq()
    __enable_irq()

    i jeśli dobrze zrozumiałem to one ustawiają piorytet na wartość 0 aktualnie wykonywaną czynność.

    W takim razie jeśli będę miał taki kod:

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


    I jeśli w trakcie dodawania ramki A do bufora (czyli w trakcie wykonywania instrukcji z pomiędzy makr __disable_irq() __enable_irq() ) zostanie zgłoszone przerwanie zewnętrzne, to w dużym uproszczeniu w czasie będzie to wyglądać tak:
    Obrazek

    Czy dobrze myślę, czy jestem w błędzie?



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 13 kwi 2016, o 12:25 
    Offline
    Użytkownik

    Dołączył(a): 26 lip 2012
    Posty: 291
    Lokalizacja: okolice Opola
    Pomógł: 20

    Dokładnie tak działa. Tylko napisz po co wyłączać WSZYSTKIE przerwania, skoro możesz wyłączyć tylko to jedno konkretne od usartu. Reszta w której nie dotykasz twojego bufora może nadal chodzić.

    _________________
    sig off ;(



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 13 kwi 2016, o 14:38 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 17 sie 2013
    Posty: 48
    Pomógł: 2

    Wydaje mi się że wyłączenie przerwań tylko od usartu nie obroni mnie w takim przypadku przed wymieszaniem danych z ramek A i B. Dane się wymieszają w buforze, a usart wyśle wszystko w takiej kolejności w jakiej jest zapisane.

    Zapewne w momencie gdy w pętli głównej chce wykonywać operacje na buforze, pomogłoby zablokowanie przerwań które też modyfikują ten bufor.

    Tylko np. wyłączając przerwanie zewnętrzne w rejestrach peryferia PIO mogę zagubić część przerwań zewnętrznych.

    Obrazek

    Oczywiście z tym mogę się mylić, więc jeśli jest inaczej to nich ktoś mnie naprowadzi na dobry tok myślenia :) Na razie dopiero wchodzę w świat 32bitowych mikrokontrolerów.

    Więc tak jak pisałem w poprzednim poście makra __disable_irq() __enable_irq() zmieniają priorytet wykonywania się instrukcji pomiędzy tymi makrami na 0. Instrukcje stają się bardzo ważne a żadne przerwanie nie przerwie ich wykonywania. Ale też te przerwania nie zostaną zagubione, tylko zostaną odłożone na wykonanie się po makrze __enable_irq().

    Ze względu na to że USART nie tylko wysyła dane, ale również odbiera je. Muszę uważać z tymi makrami aby instrukcje pomiędzy nimi nie wykonywały się dłużej niż czas przyjścia jednego bajtu danych, ponieważ w przypadku przyjścia kilku bajtów z rzędu mogę nie nadążyć z ich odbiorem co spowoduje ich nadpisywanie.

    Jeśli piszę jakieś herezje to mnie poprawcie ;) Piszę po prostu tak jak ja to rozumiem. A dopiero się uczę, więc mogę się mylić.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 13 kwi 2016, o 16:19 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 11 mar 2014
    Posty: 1475
    Pomógł: 167

    Cytuj:
    Ze względu na to że USART nie tylko wysyła dane, ale również odbiera je. Muszę uważać z tymi makrami aby instrukcje pomiędzy nimi nie wykonywały się dłużej niż czas przyjścia jednego bajtu danych, ponieważ w przypadku przyjścia kilku bajtów z rzędu mogę nie nadążyć z ich odbiorem co spowoduje ich nadpisywanie.
    Mając prędkość 9600 bps, to jeden znak przychodzi rzadziej niż co 1 milisekundę (przy większej prędkości odpowiednio częściej, ale pewnie i tak nie używasz większej niż 115200 bps, więc a jest to tylko trochę więcej niż 10 razy szybszej). Więc przy szybkości działania procesora to jest wieczność (oczywiście jak masz poprawnie napisany kod).

    Nie do końca rozumiem. Czy masz jeden bufor na dane odbierane i nadawane?
    Kto i kiedy pisze do tego bufora oprócz programu głównego (jakie przerwanie)?

    --
    Pozdrawiam,
    Robert



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 13 kwi 2016, o 16:41 
    Offline
    Użytkownik

    Dołączył(a): 29 lip 2014
    Posty: 195
    Pomógł: 44

    Witam,

    Rozumiem, że jakieś przerwanie ( poza programem głównym ) pisze Ci dane do bufora nadawczego, który jest wysyłany w przerwaniu od UARTA, tak? Jeśli tak, to po prostu, na czas przepisywania tego bufora w wątku głównym, wyłącz to przerwanie, które może Ci ten bufor nadpisać. Po co w tym wypadku korzystać z __disable_IRQ(), które w tym wypadku jest metodą typu "Weź większy młotek!" ;-), daj spokój Twój procek to nie M0. Przy okazji, zdarzenia odbiorcze bęą dalej obsługiwane, choćbyś wieki te "parę" bajtów do bufora przepisywał ;-).Nota bene, sprawdź w CMSIS swojego procesora, co tak naprawdę robi to makro, bo podejrzewam, że po prostu: ASM volatile ("cpsid i"), czyli faktycznie wyłącza wszystkie przerwania, a nie "kombinuje" z BASEPRI ( co mógłby sugerować Twój poprzedni post ).

    Pozdrawiam, QuadMan.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 13 kwi 2016, o 16:55 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 17 sie 2013
    Posty: 48
    Pomógł: 2

    rskup napisał(a):
    Mając prędkość 9600 bps, to jeden znak przychodzi rzadziej niż co 1 milisekundę (przy większej prędkości odpowiednio częściej, ale pewnie i tak nie używasz większej niż 115200 bps


    Masz rację, akurat o tym napisałem trochę na wyrost. Korzystam z prędkości 115200 bps, taktuje mikrokontroler częstotliwością 50 MHz, więc naprawdę musiałbym poszaleć żeby zakłócić odbiór danych.

    rskup napisał(a):
    Nie do końca rozumiem. Czy masz jeden bufor na dane odbierane i nadawane?
    Kto i kiedy pisze do tego bufora oprócz programu głównego (jakie przerwanie)?


    mam osobne bufory do odbioru i do wysyłania danych. Dodawać dane do bufora nadawczego będę w pętli głównej i różnych przerwaniach. Jedno dodanie danych to cała ramka np 20 bajtów ( gdzie np pierwszy bajt to bajt staru, a ostatni czyli 20sty to CRC).

    Myślę że makra o których wcześniej pisałem powinny się sprawdzić. Po prostu na czas dodawania danych do bufora będę używać makra __disable_irq() __enable_irq()

    ------------------------ [ Dodano po: 15 minutach ]

    QuadMan napisał(a):
    .Nota bene, sprawdź w CMSIS swojego procesora, co tak naprawdę robi to makro, bo podejrzewam, że po prostu: ASM volatile ("cpsid i"), czyli faktycznie wyłącza wszystkie przerwania, a nie "kombinuje" z BASEPRI ( co mógłby sugerować Twój poprzedni post ).


    Niestety racja. Sprawdziłem i tak jest.
    ObrazekObrazek



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 13 kwi 2016, o 19:30 
    Offline
    Użytkownik

    Dołączył(a): 26 lip 2012
    Posty: 291
    Lokalizacja: okolice Opola
    Pomógł: 20

    Instrukcje enable i disavle irq sa częścią cmsis wiec de fakto czescie rdzenia a nie procesora wiec czy stm czy atmel czy nxp beda robily to samo.

    _________________
    sig off ;(



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 13 kwi 2016, o 20:25 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 11 mar 2014
    Posty: 1475
    Pomógł: 167

    Metoda pisania do tego samego bufora przez program główny oraz różne przerwania zawsze będzie powodowała problemy. Czy nie możesz mieć dodatkowych buforów dla przerwań i znaczników, które wykorzystuje procedura w programie głównym ładując odpowiednie dane do bufora nadawania?

    Możesz też jak masz stałą długość, to od razu zwiększać wskaźnik na tail-a o 20 bajtów a potem dopiero uzupełniać danymi. Ale wtedy musiałbyś zapewnić, że funkcje wysyłające nie zaczną wysyłać jak jeszcze nie wpisałeś danych (np. mieć dwa wskaźniki na koniec bufora, jeden dla funkcji zapisujących a drugi dla wysyłających - pierwszy zwiększać od razu a drugi po uzupełnieniu danych).

    --
    Pozdrawiam,
    Robert



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 13 kwi 2016, o 21:42 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 17 sie 2013
    Posty: 48
    Pomógł: 2

    O tej drugiej opcji już myślałem, to by była taka rezerwacja miejsca na dane. Można to zrobić z tym drugim wskaźnikiem albo jeśli bufor to przykładowo tablica typu uint16_t ( czasami tak robię, żeby przemycać jakieś dodatkowe dane, jestem świadomy że to marnotrawstwo pamięci) to można na nieużywanej części zmiennej ustawiać jakiś bit informujący funkcję wysyłającą że dane w mniej znaczącym bajcie są prawidłowe. W przypadku gdy funkcja wysyłająca (przerwanie) natrafiłaby na daną, która nie ma ustawionego tego bitu musiałaby włączyć jakiś timer, żeby za jakiś czas znowu została sprawdzona poprawność tej danej.

    Trochę ten bufor zrobi się skomplikowany, ale jeśli to zapewni poprawną kolejność wysyłania się danych to warto pokombinować :)



    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: 13 ] 

    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:  
    cron
    Sitemap
    Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
    phpBB SEO