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



Teraz jest 19 kwi 2024, o 22:45


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 8 ] 
Autor Wiadomość
PostNapisane: 12 wrz 2017, o 08:25 
Offline
Nowy

Dołączył(a): 27 lut 2014
Posty: 3
Pomógł: 0

Witam.
Chciałbym prosić o pomoc odnośnie języka C w uP. Sprawa rozchodzi się o dostęp dwóch obiektów tej samej struktury do jednej funkcji która posiada zmienne typu static. Dokładnie jak poradzić sobie z tym, że opisywana funkcja jest wykorzystywana na przemian w dwóch przerwaniach, przez co nie do końca wiem co się dzieje ze zmiennymi kiedy podczas wykonywania tej funkcji program zostanie przerwany przez inne przerwanie i wskoczy do początku opisywanej funkcji a po skończeniu program wraca do ukończenia wcześniejszego przerwania. Przepraszam, że tak to pogmatwanie brzmi.
Nie jestem tego pewny ale domyślam się, że w chwili przerwania wykonywanej funkcji wartości zmiennych zostają wrzucone na stos i tam zapamiętane a gdy program wraca to wcześniejszego miejsca wartości zmiennych są przywracane. ?. Niestety tak to chyba nie działa i program się wywala.
Jeżeli sytuacja jest nie zrozumiana to mogę postarać się wrzucić program, lecz kodu jest dość sporo. Aby jeszcze bardziej przybliżyć problem, nadmienię że przerwania są od odbioru Uart'a parametry transmisji (115200, 8o1), Fcpu 32Mhz i jest to program który ma zaimplementowane na jednym procesorze dwa modbus slave przez co dla obydwu jest zaimplementowany ten sam kod, w większości przypadków w funkcjach są zmienne umieszczone w strukturze przez co tam problemów nie ma. Nie chcę tworzyć dwa razy tych samych funkcji bo to bez sensu dlatego myślałem nad takim tworem jak alokacja funkcji w pamięci lecz nic na ten temat w sieci nie znalazłem. Rozwiązanie polegało by na przekazaniu adresu zaalokowanej funkcji do wskaźnika funkcji w strukturze. Chętnie usłyszę inne rozwiązania które zburzą pomysł alokacji.
Z góry dziękuje za pomoc,
Pozdrawiam



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 wrz 2017, o 09:11 
Offline
Użytkownik

Dołączył(a): 25 lip 2013
Posty: 2561
Pomógł: 126

Za mało szczegółów. Nawet modelu procka nie podałeś. Wrzuć cały kod poza tymi, które pochodzą z książek Mirka



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 wrz 2017, o 15:30 
Offline
Użytkownik

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

Witam,

Jeśli chodzi o przechowywanie zmiennych na stosie - nie dotyczy to zmiennych static i globalnych. W ogólnym przypadku funkcja będzie reetrant jedynie wtedy, gdy nie korzysta w ogóle ze zmiennych static lub globalnych, inaczej jest to proszenie się o kłopoty. Można to rozwiązać na kilka sposobów, np. zastosować coś w rodzaju mutexa, ale to już niestety zależy od konkretnej implementacji.
Dopisane: poruszyłeś przy okazji w sumie ciekawy problem, nad którym się kiedyś też zastanawiałem, ale nie znalazłem rozwiązania: jak "zaalokować" 2 kopie tej samej funkcji w kodzie? Może ktoś mądrzejszy na to odpowie?

Pozdrawiam, QuadMan.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 12 wrz 2017, o 18:19 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

QuadMan napisał(a):
Może ktoś mądrzejszy na to odpowie?

Nie wiem, czy w tej sytuacji odpowiadać :)
Na wszelki wypadek zaznaczę, że wcale nie uważam się za mądrzejszego :)

marpol1992 napisał(a):
Sprawa rozchodzi się o dostęp dwóch obiektów tej samej struktury do jednej funkcji która posiada zmienne typu static. Dokładnie jak poradzić sobie z tym, że opisywana funkcja jest wykorzystywana na przemian w dwóch przerwaniach

Nie jestem pewien, czy dobrze rozumiem o co chodzi (przydałby się chociaż fragment kodu), ale jeśli funkcja nie jest reentrant ze względu na to, że wykorzystuje zmienne statyczne, które zachowują wartość pomiędzy wywołaniami funkcji, można to rozwiązać mniej więcej w taki sposób:

  • zamiast

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


  • można

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


W ten sposób każda funkcja wywołująca ma swój komplet zmiennych statycznych, więc jeśli funkcja wywoływana zostaje przerwana i ponownie wywołana przez inny wątek, operuje po prostu na innych danych.

Oczywiście wszystko zależy od implementacji i powodu, dla którego funkcja jest non-reentrant (przyczyny mogą być różne). Trzeba też uważać na inne rzeczy - zmienne globalne, zwracanie wskaźników do zmiennych statycznych wewnątrz funkcji, funkcje wywoływane wewnątrz funkcji reentrant również muszą takie być...
Trochę można o tym poczytać np. tutaj



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 13 wrz 2017, o 06:54 
Offline
Nowy

Dołączył(a): 27 lut 2014
Posty: 3
Pomógł: 0

Dziękuje za podpowiedzi ostatecznie spróbuje skorzystać z rady "andrews".
Korzystam z uP PIC24FJ1024GA606. W przerwaniach od transmisji wykorzystuję tą samą funkcje, aby jakoś wywołania nie kolidowały ze sobą ustawione są różne priorytety mimo to nie koniecznie załatwia to sprawę. Umieszczam obiecany kod, jest to tylko część wysyłająca dane ale koncepcja odbioru jest podobna:

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


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


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


Mimo wszystko, czysto technicznie może ktoś wie jak zaalokować funkcję tak aby były w pamięci dwie kopie tej samej funkcji ? ;)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 13 wrz 2017, o 12:40 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

marpol1992 napisał(a):
Mimo wszystko, czysto technicznie może ktoś wie jak zaalokować funkcję tak aby były w pamięci dwie kopie tej samej funkcji ?


Samo skopiowanie i uruchomienie funkcji nie jest pewnie aż tak trudne, jak myślisz. Należałoby raczej zadać pytanie: Jaką taka funkcja ma szansę, by działać prawidłowo?

Przypuśćmy na przykład, że wewnątrz takiej kopiowanej funkcji masz wywołanie innej funkcji, tak jak jest w przedstawionym przez Ciebie kodzie. Podczas kompilacji kompilator może użyć do wywołania tej funkcji instrukcji RCALL. Jest to tzw. wywołanie relatywne, a operandem tej instrukcji jest wartość (stała, obliczona w trakcie budowania programu) będąca różnicą pomiędzy adresem tej instrukcji (ściśle zależnym od adresu wykonywanej aktualnie funkcji), a adresem wywoływanej funkcji. Jeśli teraz skopiujesz funkcję pod inny adres, to adres odniesienia się zmieni i wywołanie relatywne przekieruje program pod jakiś przypadkowy, błędny adres.

Nie znam się za bardzo na mikrokontrolerach, których temat dotyczy, więc nie będę się wdawał w szczegóły działania kompilatora, ale pewnie znalazłoby się jeszcze kilka innych powodów zmniejszających szansę powodzenia takiej techniki.

Nie twierdzę, że się nie da w ogóle, ale zapewne musi być spełnionych kilka warunków, niekoniecznie zależnych od programisty, aby taka operacja się powiodła, dlatego osobiście raczej tego sposobu bym nie polecał (nie tylko w tym konkretnym przypadku).



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 13 wrz 2017, o 17:06 
Offline
Użytkownik

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

Witam,

andrews napisał(a):
QuadMan napisał(a):
Może ktoś mądrzejszy na to odpowie?

Nie wiem, czy w tej sytuacji odpowiadać :)
Na wszelki wypadek zaznaczę, że wcale nie uważam się za mądrzejszego :)


szczerze, to właśnie Kol andrews miałem na myśli, no ale przecież nie mogłem Go tak po prostu "wywołać do tablicy" ;-).

Kolego andrews dzięki za, jak zwykle zresztą, "kawał" konkretnej i skondensowanej wiedzy. Twoje posty to zawsze perełki i skarbnica wiedzy. A ten pomysł z wywołaniem funkcji "noreetrant()" genialny w swej prostocie. Jeszcze raz dzięki!

Pozdrawiam serdecznie, QuadMan.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 14 wrz 2017, o 08:37 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

Nie wiem, czym sobie zasłużyłem na takie pochwały, niemniej dziękuję bardzo. :)
Prosiłbym jednak, żeby nie przesadzać, bo na tym forum jest wielu mądrzejszych ode mnie i mogą się poczuć urażeni.

________________________
AVR-GCC - dane w pamięci FLASH



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

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 1 gość


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