Pytanie:
Czy można przerwać proces kopiowania struktury przez przerwanie w osadzonym C?
Stani
2018-09-06 14:27:06 UTC
view on stackexchange narkive permalink

Wewnątrz sterownika mam funkcję kopiowania danych z wewnętrznej struktury do struktury z aplikacji.

Czy ten proces może zostać przerwany przez wyzwalacz przerwania mikrokontrolera?

  uint16_t getRawData (struct Data * Data_external)
{
  if (Data_external == NULL)
  {
    return ERR_PARA;
  }
  jeszcze
  {
    * Data_external = Data_internal;// proces kopiowania.Czy można to przerwać?
  }
  return ERR_NONE;
}
 
Tak naprawdę nie ma „procesu kopiowania”, będą instrukcje kopiujące bajty dookoła i jeśli nie są one atomowe, można je przerwać, zależy to od architektury, kompilatora, ustawień i wyrównania
W C nie ma gwarancji, że proces kopiowania struktury nie zostanie przerwany.Jednak przerwanie ma zwykle powrócić do punktu w kodzie, w którym proces kopiowania może się zakończyć.Więc prawdopodobnie nie ma to znaczenia, chyba że kod przerwania zależy od niego z jakiegoś powodu (mało prawdopodobne w większości przypadków). Jeśli jednak te struktury są częścią pary sterowników przerwań górnych / dolnych, może to być problem, jeśli górny poziomjest w trakcie usuwania lub dodawania „porcji” do bufora, gdy ma miejsce przerwanie, które musi również poradzić sobie z „porcjami” w tym samym buforze.
@jonk: Proszę nie odpowiadać na pytanie w komentarzach, ponieważ omija to normalny proces sprawdzania odpowiedzi, jak [omówione w meta] (https://meta.stackexchange.com/questions/117251)
@DaveTweed Wtedy ty i ta strona *** stracicie *** moje komentarze.Nie piszę odpowiedzi, chyba że mam czas na pisanie pełniejszych.To mój jedyny sposób działania i nie zmienię tego.Jeśli czuję, że mam wystarczająco dużo czasu na „właściwą odpowiedź”, zgodnie z moją definicją, będę kontynuował jak poprzednio.Ale pracuję bardzo ciężko nad kilkoma różnymi aktywnymi projektami i NIE mam czasu na mój zwykły poziom kontekstu odpowiedzi i treści.Więc albo piszę krótkie komentarze jako komentarze, albo strona traci dostęp do mojego czasu.Twoja decyzja.Mój czas jest podany na moich warunkach lub wcale.
@jonk: Nie ma nic złego w pisaniu krótkiej odpowiedzi, o ile jest ona kompletna i samodzielna, tak jak Twój komentarz.Twoje zaangażowanie w rozwlekłe odpowiedzi zależy wyłącznie od Ciebie.Witryna ma zasady i procesy, a ja po prostu staram się poprowadzić Cię we właściwym kierunku.Ostatecznie wszystko zależy od Ciebie - mogłeś mieć 9 głosów za (+90 rep) na swoją odpowiedź ...
@DaveTweed Dzięki za ponaglenie.Punkty są przeważnie nieistotne.Myślę, że kiedy dotarłem do „zredukowanych reklam” w wysokości 200 pkt, nie przejmowałem się resztą (ani nie korzystałem z niej). Nie sądzę, że zasługuję na wysokie liczby, które mam teraz.Jestem tylko hobbystą, na litość boską.I bardzo się martwię, że ludzie mogą pomylić ten numer reputacji jako znaczący dla nich więcej niż powinien.Wolałbym, aby moje słowa zawsze były „podejrzane” i zasługiwały na krytykę, a nie traktowane jako jakiś rodzaj ewangelii.Gdybym mógł zmniejszyć liczbę moich powtórzeń, zrobiłbym to.
@jonk Jeśli naprawdę chcesz, aby ludzie mogli „podejrzewać” Twoje odpowiedzi, pozwól im prawidłowo głosować na nie.W (mało prawdopodobnym!) Przypadku, gdy opublikujesz coś złego jako komentarz, użytkownicy nie będą mogli zagłosować przeciw.Może to być szczególnie problem, jeśli ludzie głosują za komentarzem, który początkowo wydaje się poprawny (znowu nie, żebym kwestionował jakość twoich komentarzy / odpowiedzi :))
@mbrig Możesz mnie źle zrozumieć.Decyduję się * tylko * pisać *** odpowiedzi *** jako takie i z dołączonym moim imieniem i nazwiskiem, jeśli zawierają pełny kontekst i treść lub w innym przypadku, gdy myślę, że mogę zapewnić * nietypowe * lub * unikalne * podejście.Są one również zawsze badane w tym sensie, że nie opublikuję odpowiedzi, zanim * dwukrotnie * sprawdzę siebie, znajdując odniesienia i materiały pomocnicze, które są zgodne z moim stanowiskiem, a także które mogę zacytować, gdy zapytam.Nie tylko piszę.Piszę, następnie badam, sprawdzam i weryfikuję.Następnie opublikuj.W przeciwnym razie nie pojawia się jako odpowiedź ode mnie.
@mbrig Wreszcie mój numer przedstawiciela nie * ma znaczenia. * To, co piszę, może być.Ale to osobny problem.Chciałbym tylko móc wyczyścić lub pozbyć się mojego numeru rep.Cieszę się, że niektórzy ludzie uznali moją odpowiedź (lub dwie) za pomocną.Ale ludzie mają naturalną tendencję do wyobrażania sobie czegoś innego, biorąc pod uwagę mój numer rep, a ja chciałbym, żeby tego nie robili.To wszystko.Twoja sugestia nie dotyczy *** żadnych *** moich obaw.
@jonk: Możesz rozpocząć pytanie bounty i nagrodzić kogoś z 29 tys. reputacji za pozbycie się go;)
@Rev1.0 Mógłbym to zrobić, gdyby nie wymagało to również zbytniego zastanowienia się nad wymyśleniem problemu / pytania, które jest tego warte, i być może nie omieszkam również usunąć problemu, który wskazuję, ale zamiast tego po prostu przekazać gokogoś innego (co nie rozwiązuje moich obaw). Jednak dobry twórczy pokaz.;)
@jonk: Hehe, zwariujmy więc;) 1. Utwórz drugie konto 2. Napisz świetne pytanie + nagrodę za pomocą pierwszego konta 3. Odpowiedz na pytanie zamieszczając świetną odpowiedź na 2. koncie 4. Usuń drugie konto -> Wynik: Napisałeś dobre pytanie,dobra odpowiedź i nawet straciłeś reputację, robiąc to ... wszystko, czego kiedykolwiek chciałeś;)
@Rev1.0 (1) Mam przeczucie, że naruszałoby to jakąś interpretację zasad i skutkowałoby zbanowaniem.(2) Nadal chciałbym, aby ludzie wiedzieli, kim jestem, a zmienianie kont w znacznym stopniu komplikuje lub pokonuje ten cel.(3) Ktoś (nawet jeśli to ja) nadal kończy z tymi punktami rep.(4) Uwielbiam kreatywne myślenie!Dzięki.
Siedem odpowiedzi:
filo
2018-09-06 16:30:30 UTC
view on stackexchange narkive permalink

Tak.Prawie wszystko w MCU może zostać przerwane przez żądanie przerwania.Kiedy program obsługi przerwań zakończy działanie, poprzedni kod będzie kontynuowany, więc zwykle nie stanowi to problemu.

W specjalnym przypadku programy obsługi przerwań mogą zostać przerwane same przez przerwania o wyższych priorytetach (przerwania zagnieżdżone).

Jeśli seria instrukcji nie może zostać przerwana, musisz zaimplementować sekcję krytyczną (w zasadzie globalnie wyłącz przerwania, wykonaj zadanie, włącz ponownie).

Pamiętaj, że w zależności od architektury docelowego procesora pojedyncza linia C może zostać skompilowana do wielu instrukcji asemblera.Prosty i ++ w AVR jest kompilowany do wielu instrukcji, jeśli i to na przykład uint32_t .

Odnośnie twojego ostatniego akapitu, zakładam, że jest to prawdą tylko w systemach 16/8 bitowych, prawda?Wiem, że mówisz AVR ... tylko się upewniam.
memcpy struktury (jak w pytaniu) to również wiele instrukcji na 32-bitowym ARM.Inkrementacja uint64_t na 32-bitowym ARM również nie jest atomowa.Operacje bitowe są również odczytywane, modyfikowane i zapisywane (chyba że są używane pasma bitowe).
@HarrySvensson no - na dowolnej architekturze RMW, a większość uC jest typu Read - Modify - Write (większość procesorów RISC to RMW).Zatem i ++ wygeneruje w wielu przypadkach (z wyjątkiem sytuacji, gdy wartość jest po prostu przechowywana w rejestrze, co nie ma miejsca w tym przypadku) również trzy instrukcje na nowoczesnych 32/64 bitowych ARM uC.
Ach, doszło tutaj do lekkiego nieporozumienia.Myślałem o zadbaniu o przeniesienie podczas wykonywania przyrostów (przepełnienia) i oboje rozmawiacie o odzyskiwaniu z pamięci i odpisywaniu.- No cóż.
Ogólnie: wszystkie operacje na typach szerszych niż szerokość magistrali danych są „funky”.
Sam
2018-09-06 20:25:26 UTC
view on stackexchange narkive permalink

Każda operacja, która nie jest atomowa, może zostać zakłócona przez przerwanie.Ten rodzaj programowania często bardzo różni się od większości innych programów i może być mylący dla osób, które nie studiowały projektowania procesorów lub architektury komputera.

Możesz pomyśleć sobie "To się nigdy nie wydarzy, ile czasu zajmie skopiowanie tego kodu i jakie jest prawdopodobieństwo przerwania?"Ale w przypadku większości wbudowanych aplikacji produkcyjnych stanie się tak, ponieważ produkt działa przez lata bez aktualizacji.

Innym problemem związanym z kopiami struktury, takimi jak ta, jest to, że kiedy się zdarzają, są niezwykle trudne do debugowania, ponieważ zdarzają się tylko wtedy, gdy przerwanie pojawia się we właściwym czasie (który może wynosić zaledwie jeden cykl).

Echelon
2018-09-06 18:39:19 UTC
view on stackexchange narkive permalink

Głównym celem przerwań jest to, że mogą (i zdarzają się) przez cały czas i są zaprojektowane tak, aby nie miały żadnego wpływu na każdy kod, który jest uruchamiany, gdy się pojawią. Wszystkie rejestry są zapisywane iw zależności od architektury procesora można zamienić zupełnie inny zestaw rejestrów, przerwanie robi swoje, a następnie oryginalne rejestry są przywracane i kod nadal działa normalnie.

Problemy mogą wystąpić, gdy procedura obsługi przerwań sama próbuje uzyskać dostęp do pamięci, do której uzyskuje dostęp działający, przerwany kod. Jeszcze bardziej subtelne błędy mogą wystąpić, gdy krytyczny czasowo proces I / O zostanie przerwany. Te problemy są powszechne w przypadku starszych, prostszych, mniej bezpiecznych architektur, w których może występować niewielka separacja między kodem trybu „użytkownik” i „nadzorca / jądro”.

Ten rodzaj problemu może być trudny do zidentyfikowania i często trudny do odtworzenia, ale raz zidentyfikowany jest często dość trywialny do naprawienia za pomocą programowania obronnego, muteksów / semaforów lub po prostu wyłączając przerwań w krytycznych sekcjach kodu.

Ogólna klasa problemów została dokładnie zbadana i nowoczesne wielordzeniowe procesory, a nawet wielozadaniowe systemy operacyjne nie byłyby możliwe, gdyby nie wypróbowano i przetestowano wielu rozwiązań.

Joshua
2018-09-07 04:32:01 UTC
view on stackexchange narkive permalink

Założę, że pytałeś o to z bardzo dobrego powodu.

  * Data_external = Data_internal;
 

Można podzielić (z wyjątkiem niektórych skrajnych przypadków, które prawdopodobnie nie będą miały tutaj miejsca).

Nie znam twojego procesora, ale nie widziałem jeszcze procesora, który nie byłby w stanie zrobić moralnego odpowiednika:

  cli ();/ * maskuj wszystkie przerwań * /
* Data_external = Data_internal;
sti ();/ * przywróć maskę przerwań * /
 

Teraz nie można go podzielić na żaden jednordzeniowy procesor, ponieważ nic nie może przerwać, gdy przerwania są wyłączone.To, czy jest to dobry pomysł, zależy od wielu rzeczy, których po prostu nie mam kwalifikacji.

Jeśli jesteś wielordzeniowy (i w końcu przypomniałem sobie, że na rynku jest wbudowany wielordzeniowy procesor), nie rób tego.To jest bezwartościowe.Musisz opracować odpowiednie blokowanie.

Co to jest CLI i STI?z google wydają się być instrukcjami x86?
@Sam: No tak, to są nazwy instrukcji w x86.Myślę, że mają te same nazwy w PDP-11, ponieważ jakiś kod, który tam powstał, miał takie same nazwy funkcji dla logicznego odpowiednika w trybie użytkownika (maskowanie sygnałów międzyprocesowych).Oto instrukcje dla Arduino: https://www.tldp.org/LDP/tlk/dd/interrupts.html
Zwykle wyłączasz przerwania, ale włączasz je ponownie tylko wtedy, gdy były faktycznie włączone.W przeciwnym razie twój kod ma efekt uboczny polegający na tym, że zawsze włącza przerwania, nawet jeśli były one wyłączone przed wywołaniem kodu.
Dmitry Grigoryev
2018-09-07 18:08:31 UTC
view on stackexchange narkive permalink

Przedstawiony przez Ciebie kod rzeczywiście może zostać przerwany.Jednak zanim zaczniesz tworzyć krytyczne sekcje w każdym miejscu, powinieneś sprawdzić kilka rzeczy:

  • Mówisz, że ta funkcja działa „wewnątrz sterownika”.Czy przerwania są już wyłączone, gdy wywoływana jest ta funkcja?A może jest wywoływany wewnątrz programu obsługi przerwań, który zapobiega wyzwalaniu innych przerwań?Jeśli tak, operacji w rzeczywistości nie można przerwać.

  • Czy dostęp do Data_internal jest kiedykolwiek uzyskiwany w ramach procedury obsługi przerwań?Jeśli nie, nic się nie stanie, nawet jeśli operację można przerwać.

studog
2018-09-07 23:49:40 UTC
view on stackexchange narkive permalink

[Za mało przedstawiciela, aby komentować]

Innym problemem związanym z tego rodzaju strukturą kopii jest to, że jest to płytka kopia.Zamiast tego możesz potrzebować dokładnej kopii.

Płytka kopia może prawdopodobnie, ale prawdopodobnie nie będzie atomowa, w zależności od architektury maszyny.Głęboka kopia prawie na pewno nie jest atomowa w żadnej architekturze.

Słuszna uwaga;ale głęboka kopia prawdopodobnie będzie atomowa, ponieważ prawie zawsze jest umieszczana na miejscu przez zamianę wskaźnika.Jednak w tym przypadku, gdyby była to głęboka kopia, na pewno nie będzie atomowa.
supercat
2018-09-07 23:51:55 UTC
view on stackexchange narkive permalink

Implementacja jakości odpowiednia dla systemów wbudowanych udokumentuje, jak volatile -kwalifikowane odczyty lub zapisy różnych typów będą wykonywane wystarczająco szczegółowo, aby wskazać, czy i jak mogą być „podzielone” przez przerwania , a także czy ulotne odczyty i zapisy są sekwencjonowane w odniesieniu do niekwalifikowanych odczytów i zapisów. Podczas gdy niektóre implementacje mogą zachowywać się tak, jakby wszystkie odczyty i zapisy były volatile -qualified, generalnie oczekuje się, że implementacje będą wolne do przetwarzania sekwencji niekwalifikowanych odczytów i zapisów w dowolny sposób, który byłby najbardziej wydajny, gdy istnieją brak interwencji volatile dostępów.

Odczytuje i zapisuje volatile -qualified integer type, które są 32-bitowe i mniejsze na typowym 32-bitowym mikrokontrolerze; przypisanie będzie składało się z atomowego odczytu, po którym nastąpi atomowy zapis. Jeśli chcesz mieć pewność, że 32-bitowa struktura jest kopiowana niepodzielnie, umieść ją w unii z uint32_t i przeczytaj lub napisz ten element, aby odczytać lub zapisać strukturę jako całość. Jakościowe implementacje, które są skonfigurowane tak, aby nadawały się do użytku w systemach wbudowanych, umożliwią stosowanie związków w taki sposób, bez względu na to, czy norma wymagałaby, aby implementacje, które nie są przeznaczone do takiego użytku, miałyby działać podobnie. Zauważ, że gcc i clang nie będą działały niezawodnie jako implementacje wysokiej jakości odpowiednie dla systemów wbudowanych, chyba że różne optymalizacje zostaną wyłączone.



To pytanie i odpowiedź zostało automatycznie przetłumaczone z języka angielskiego.Oryginalna treść jest dostępna na stackexchange, za co dziękujemy za licencję cc by-sa 4.0, w ramach której jest rozpowszechniana.
Loading...