Jak mogę używać malloc()
i free()
funkcjonować w PIC? Sprawdziłem stdlib.h
nagłówek i nie ma o nich wzmianki. Używam MCC18.
Czy ktoś musiał z nich skorzystać?
Potrzebuję ich, ponieważ przenoszę bibliotekę z systemu Windows XP do PIC. Przewodnik po przenoszeniu mówi
dostosować specyficzne funkcje systemu operacyjnego do moich PIC
Ale nie wiem, jak „przetłumaczyć” funkcje malloc()
i free()
.
Odpowiedzi:
W wielu aplikacjach trzeba będzie przydzielić pamięć, ale nie trzeba nic zwalniać, zachowując coś, co zostało po tym przydzielone. W takim systemie wystarczy użyć konsolidatora, aby zdefiniować tablicę przy użyciu całej dostępnej pamięci RAM, ustawić wskaźnik na początku tej tablicy, a następnie użyć ładnej, łatwej funkcji malloc:
Przyjemny i łatwy, a całkowity narzut wynoszący zaledwie dwa bajty dla dowolnej liczby przydziałów. Wywołanie free () na bloku spowoduje cofnięcie przydziału tego bloku i wszystkiego po nim.
Nieco bardziej skomplikowane wzorce alokacji można obsłużyć za pomocą dwóch wskaźników - jednego, który przydziela rzeczy z dołu pamięci przesuwając się w górę, a drugi z góry pamięci w dół. Możliwe jest również użycie kompaktującego śmietnika, jeśli dane w stercie są jednorodne i wiadomo, gdzie znajdują się wszystkie zewnętrzne odniesienia do niego.
źródło
malloc()
w mikrokontrolerach jest ogólnie uważany za „złą rzecz”. Ale jeśli jest to absolutnie potrzebne, będziesz chciał znaleźć wersję innej firmy.Jeśli masz szczęście, przenoszony kod może nie polegać na ponownym wykorzystaniu bloków pamięci. W takim przypadku możesz napisać prosty alokator, który zwraca wskaźnik do bufora pamięci RAM, a następnie przesuwa wskaźnik o żądany rozmiar bloku.
Z powodzeniem stosowałem to podejście już wcześniej przy przenoszeniu bibliotek PC na mikrokontrolery.
Poniżej skonfigurujesz alokator za pomocą
my_malloc_init()
i przydzielisz pamięć za pomocąmy_malloc()
.my_free()
ma na celu zaspokojenie zależności, ale tak naprawdę nic nie zrobi. Ostatecznie oczywiście zabraknie Ci miejsca.Aby to zadziałało, musisz zmierzyć najgorsze wymagania dotyczące pamięci w kodzie (zrób to na komputerze, jeśli to możliwe), a następnie odpowiednio skonfiguruj
HEAP_SIZE
. Przed wejściem do części biblioteki wymagającej pamięci dynamicznej zadzwońmy_malloc_init()
. Przed ponownym użyciem upewnij się, że nic nie wskazujeheap
.(uwaga: w prawdziwym świecie może być konieczne rozważenie wyrównania wskaźnika, tj. zaokrąglenia w górę
heap_ptr
o 2 lub 4 bajty)Inną opcją jest użycie prostszej struktury alokacji, niż
malloc()
zwykle, na przykład FreeList , chociaż może to nie pozwolić na alokację bloków o zmiennej wielkości.źródło
To nie jest odpowiedź na twoje pytanie, ale dynamiczne przydzielanie pamięci jest generalnie niezadowolone z powodu małych środowisk RAM i przy braku systemu operacyjnego (np. W świecie mikrokontrolerów) ... przestrzeń sterty dostępna w środowisku osadzonym jest zazwyczaj mierzone w setkach bajtów ...
Wdrożenie malloc i free jest zasadniczo utrzymaniem połączonej listy struktur „wolnych segmentów”, a jak można sobie wyobrazić, metadane związane z wolnymi segmentami nie są nieistotne w porównaniu z ilością zwykle dostępnej pamięci… czyli „narzutem” „zarządzania dynamiczną pulą pamięci zużywa znaczną ilość dostępnych zasobów.
źródło
Nie wiem, czy biblioteka standardowa C18 obsługuje
malloc
ifree
, ale Uwaga aplikacji Microchip AN914 pokazuje, jak możesz zaimplementować własną.W każdym razie Thomas i inni plakaty sugerują, że korzystanie z dynamicznej pamięci na PIC z bardzo małą pamięcią RAM jest obarczone niebezpieczeństwem. Możesz szybko zabraknąć ciągłego miejsca ze względu na brak bardziej zaawansowanych menedżerów pamięci wirtualnej , które dają pełne systemy operacyjne, co prowadzi do nieudanych alokacji i awarii. Co gorsza, może nie być deterministyczny i prawdopodobnie będzie utrudnieniem przy debugowaniu.
Jeśli to, co robisz, jest naprawdę dynamicznie określane w czasie wykonywania (rzadkie w przypadku większości osadzonych rzeczy) i musisz przydzielić przestrzeń tylko w kilku wyjątkowych sytuacjach, to mogę to zobaczyć
malloc
ifree
być do zaakceptowania.źródło
Jak duży jest twój PIC pod względem pamięci?
malloc jest bardzo nieefektywnym sposobem alokacji pamięci. Problem polega na tym, że pamięć może ulec fragmentacji przy częstych zwolnieniach i mallocach, a przy zaledwie kilku kilobajtach pamięci błędy alokacji są zbyt częste. Jest całkiem prawdopodobne, że jeśli używasz mniejszego układu lub wcześniejszego PIC18, nie ma wsparcia dla malloc, ponieważ Microchip albo postrzegał to jako bardzo trudne do wdrożenia (a może nawet niemożliwe w niektórych przypadkach) lub niewystarczająco użyte, aby mogło być Warto było. Nie wspominając o tym, ale jest również dość powolny, patrzysz na 1 cykl, aby użyć już dostępnego bufora statycznego i od 100 do 1000 cykli, aby wykonać malloc.
Jeśli chcesz przydzielić statycznie, twórz takie rzeczy, jak bufor dla funkcji sprintf (jeśli istnieje, około 128 bajtów), bufor dla karty SD (jeśli istnieje) i tak dalej, dopóki nie usuniesz potrzeby Malloc. Idealnie, używasz go tylko tam, gdzie go absolutnie potrzebujesz i nie możesz uciec od statycznego przydzielania, ale te sytuacje są zwykle rzadkie i może być znakiem, że powinieneś patrzeć na większe / mocniejsze mikrokontrolery.
A jeśli opracowujesz / przenosisz „system operacyjny” na PIC18 i jeśli obsługuje on mikrokontrolery, prawdopodobnie obsługuje on alokację statyczną. Na przykład SQLite3 obsługuje przydział statyczny - przydzielasz mu dużą tablicę buforów i używa go tam, gdzie to możliwe, nawet jeśli nie jest to dla mikrokontrolerów. Jeśli nie, to czy na pewno jest przeznaczony dla małego PIC18?
źródło
Jeśli rozważają
malloc()
ifree()
dla wbudowanego oprogramowania Proponuję spojrzeć na uC / OS-II iOSMemGet()
iOSMemPut()
. O ilemalloc()
pozwalają przeznaczyć dowolny blok pamięci,OSMem*()
daje stałej wielkości bloku z wstępnie przydzielone basenie. Uważam to podejście za właściwą równowagę między elastycznościąmalloc()
i odpornością statycznej alokacji.źródło
AFAIK, aby to zrobić poprawnie, naprawdę musisz patrzeć na urządzenie z jakimś rodzajem jednostki zarządzania pamięcią (MMU). Chociaż istnieją mechanizmy dynamicznej alokacji dla serii PIC18, to tak naprawdę nie będą tak solidne - a mówiąc o kimś, kto pracował nad oprogramowaniem układowym, które przesuwa granice serii PIC18, mogę powiedzieć, że nie dostaniesz spora aplikacja, jeśli wydasz cały narzut na menedżera pamięci.
Lepsze rozwiązanie: spróbuj zrozumieć, co robi i dlaczego potrzebuje dynamicznej alokacji. Sprawdź, czy nie można go ponownie uwzględnić, aby działał z alokacją statyczną. (Może się zdarzyć, że po prostu nie jest to możliwe - jeśli biblioteka / aplikacja jest zaprojektowana do robienia czegoś, co można dowolnie skalować, lub nie ma ograniczenia ilości danych wejściowych, które może zaakceptować.) Ale czasami, jeśli naprawdę myślisz jeśli chodzi o to, co próbujesz zrobić, może okazać się, że jest możliwe (a może nawet całkiem łatwe) użycie zamiast tego przypisania statycznego.
źródło