Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

AVR uCs - Dynamiczna alokacja pamięci na uC

mondo90 17 Aug 2015 21:03 1374 6
  • #1
    mondo90
    Level 13  
    Witam,

    ze względu na różne zadania które ma w różnym czasie realizować uC umieściłem zmienne związane z konkretnymi zadaniami w strukturach. Do tego zrobiłem to w taki sposób iż w każdej chwili mogę usunąć daną strukturę z pamięci mikrokontrolera (np. wtedy kiedy kończy się zadanie związane z obcecnie wykorzystywaną strukturą i zaczyna inne, które angażuje inną strukturę).



    Code: c
    Log in, to see the code
    Na pierwszy rzut oka wydaje się to świetny pomysł - nie ma marnowania pamięci, plus elegancka organizacja programu. Niestety kilka osób, poddało mój pomysł krytyce, twierdząc iż dynamiczna alokacja na uC jest krokiem w niekończące i niewyjaśnione problemy, których nie da się uniknąć. Jako alternatywę zaproponowano mi ustawienie wszystkich zmiennych z struktur jako globalne, lub używanie struktur *na sztywno*.
    Powiem szczerze, że mam dylemat. Poczytałem trochę na ten temat i autorzy książek, zawracają uwagę na ten temat aczkolwiek bez szczególnej paniki czy odradzania. Po drugie a tej chwili testuję takie rozwiązanie w przypadku jednej struktury na uC i wszytko działa ok.

    Czy ktoś ma doświadczenie z taką alokację na uC ? W finalnej wersji planowałem 3 struktury kasowane i tworzone na przemian, wedle zadania.

    Dzięki za pomoc.
  • Helpful post
    #4
    maciej_333
    Level 37  
    Moim zdaniem AVR to stanowczo za małe mikrokontrolery, by zarządzać w nich dynamicznie pamięcią. Już sama funkcja malloc zajmie całkiem sporo pamięci FLASH. Pamięci RAM też w większości AVR nie ma jakoś wyjątkowo wiele, by było czym zarządzać. Inna sprawa, że malloc/calloc/realloc i free mają zastosowanie do tablic, których rozmiary nie są znane w trakcie kompilacji. Tu robienie dynamicznie jednej struktury zwyczajnie nie ma sensu. Proponowałbym raczej kombinację unii i struktury razem. Powstałoby właściwie kilka struktur nałożonych na siebie. Ponadto przy tymczasowym tworzeniu struktury np. wewnątrz jakiejś funkcji, lepiej deklarować ją jako lokalną. To też oszczędności.

    Dynamiczne zarządzanie pamięcią nie niesie wielkich problemów, o ile jest poprawnie wykonane. Największe niebezpieczeństwo to wystąpienie przerwania w trakcie wykonywania funkcji malloc/calloc/realloc. Jeśli w tym przerwaniu wystąpi kolejne dynamiczne alokowanie pamięci to może być problem. Do tego trzeba sprawdzać, co zwracają podane tu funkcje. NULL oznacza, że przydzielenie pamięci nie było możliwe.

    Stosuję dynamiczną alokację pamięci w wielkim procesorze DSP TMS320C6678. Tworzę kilka bloków po 200 kB. Potem tworzę i kasuję kolejne, już mniejsze bloki. Działa to prawidłowo. Tylko, że w tym procesorze jest czym zarządzać.
  • Helpful post
    #5
    tmf
    Moderator of Microcontroller designs
    Dla dynamicznej alokacji pamięci ilość pamięci w systemie nie ma większego znaczenia. Nie ma granicy powyżej której ma ona sens, a poniżej już nie. Wszystko zależy od zastosowań. Tu kolega alokuje niewielkie ilości pamięci i być może ma to sens. IMHO dynamiczna alokacja pamięci jest demonizowana - jeśli wszystko robi się jak należy to jest to tak samo dobre na AVR jak i na PC. Oczywiście trzeba sobie zdawać sprawę z kilku rzeczy:
    - standardowe funkcje malloc/free/realloc/calloc nie są reentrant,
    - w specyficznej sytuacji może powstać problem z fragmentacją sterty,
    - trzeba mieć pewność, że alokacja zakończy się sukcesem, lub być przygotowanym na sytuację w której wystąpi problem.
    Każdy z tych problemów ma rozwiązanie - istnieją biblioteki z implementacją tych funkcji jako reentrant, są implementacje zapobiegające fragmentacji (która zresztą też zwykle jest niepotrzebnie demonizowana). Ostatni problem jest stosunkowo najprostszy - trzeba oszacować ile pamięci potrzebujemy i tak ustawić linker, aby odpowiednią ilość pamięci zarezerwować. Na MCU (niezależnie jakim) to najrozsądniejsze rozwiązanie, bo co niby aplikacja miałaby zrobić w przypadku niepowodzenia alokacji pamięci? Zwiesić się, czy zrestartować?:)
    Jeśli robisz jakieś listy, czy inne złożone typy danych o nieokreślonej wielkości/liczbie elementów to alokacja dynamiczna właściwie jest konieczna. Jeśli masz max 3 struktury o ograniczonej wielkości i jednocześnie wszystkie na raz mieszczą się w pamięci to zapewne ich alokacja statyczna jest równie dobra, a przy tym prostsza.
    BTW, nowe wersje gcc i C11 przewidują dynamiczne tablice o liczbie elementów ustalanych na etapie wykonywania programu, więc jakiś tam obszar wymagający do tej pory użycia alkokacji dynamicznej odpada.
  • #6
    mondo90
    Level 13  
    maciej_333 wrote:
    Moim zdaniem AVR to stanowczo za małe mikrokontrolery, by zarządzać w nich dynamicznie pamięcią

    Właśnie z tego względu dynamiczna alokacja może się okazać konieczna. Nie chcę przez to powiedzieć iż w moim wypadku tak jest bo oczywiście, że wykorzystanie statycznych struktur do tego akurat zadania pewnie wystarczy, jednak chcę przetestować dobrze to narzędzie by mieć je w zanadrzu gdy przyjdzie na nie czas :)

    maciej_333 wrote:
    Ponadto przy tymczasowym tworzeniu struktury np. wewnątrz jakiejś funkcji, lepiej deklarować ją jako lokalną

    Jest to jakieś rozwiąznie, ale ma pewną oczywistą wadę - jeśli wiele funkcji ma operować na tej strukturze to do każdej musisz przekazywać wskaźniki, to z kolei wymaga nieco innych definicji funkcji i to się ciągnie.... Jasne, da się zrobić ale ja jakoś wole to moje rozwiązanie ;)

    maciej_333, tmf dzięki za opinię i zwrócenie uwagi na najważniejsze problemy. Na razie testuję, wrócę za jakiś czas z aktualizacją. Na teraz mogę powiedzieć iż jak na razie, mając jedną statyczną strukturę, która ma 3 wskaźniki do dynamicznie alokowanych struktur wszytko działa prawidłowo ;)
  • #7
    Radek
    Level 13  
    Używając alokacji dynamicznej i tak musisz używać wskaźników na struktury.