PIC에서 어떻게 사용 malloc()
하고 free()
기능합니까? stdlib.h
헤더를 확인했는데 언급이 없습니다. MCC18을 사용하고 있습니다.
아무도 그것들을 사용해야 했습니까?
Windows XP에서 PIC로 라이브러리를 이식하기 때문에 필요합니다. 포팅 가이드는
운영 체제의 특정 기능을 내 PIC 기능에 맞게 조정
그러나 malloc()
및 free()
함수 를 "번역"하는 방법을 모르겠습니다 .
PIC에서 어떻게 사용 malloc()
하고 free()
기능합니까? stdlib.h
헤더를 확인했는데 언급이 없습니다. MCC18을 사용하고 있습니다.
아무도 그것들을 사용해야 했습니까?
Windows XP에서 PIC로 라이브러리를 이식하기 때문에 필요합니다. 포팅 가이드는
운영 체제의 특정 기능을 내 PIC 기능에 맞게 조정
그러나 malloc()
및 free()
함수 를 "번역"하는 방법을 모르겠습니다 .
답변:
많은 응용 프로그램에서 메모리를 할당해야하지만 그 후에 할당 된 것을 유지하면서 아무것도 해제 할 필요가 없습니다. 이러한 시스템에서는 링커를 사용하여 사용 가능한 모든 RAM을 사용하여 배열을 정의하고 해당 배열의 시작에 대한 포인터를 설정 한 다음 멋진 malloc 함수를 사용하면됩니다.
char * next_alloc; void * malloc (int size) { char * this_alloc; this_alloc = next_alloc; if ((END_OF_ALLOC_SPACE-this_alloc) <size) 리턴 -1; next_alloc + = 크기; this_alloc을 반환; } 무효 무료 (void * ptr) { if (ptr) next_alloc = (char *) ptr; }
멋지고 쉬우 며, 할당 횟수에 따라 2 바이트의 총 오버 헤드가 발생합니다. 블록에서 free ()를 호출하면 해당 블록과 그 이후의 모든 항목이 할당 해제됩니다.
두 개의 포인터를 사용하여 약간 더 복잡한 할당 패턴을 처리 할 수 있습니다. 하나는 메모리의 맨 아래에서 위로 이동하고 다른 하나는 메모리에서 아래로 이동합니다. 힙의 데이터가 균일하고 외부 참조가 어디에 있는지 아는 경우 압축 가비지 수집기를 사용할 수도 있습니다.
malloc()
마이크로 컨트롤러에서 일반적으로 "나쁜 것"으로 간주됩니다. 그러나 절대적으로 필요한 경우 타사 버전을 찾고 싶을 것입니다.
운이 좋으면 이식하려는 코드가 메모리 블록 재사용에 의존하지 않을 수 있습니다. 이 경우 간단한 할당자를 작성하여 포인터를 RAM 버퍼로 반환 한 다음 요청 된 블록 크기만큼 포인터를 진행시킵니다.
PC 라이브러리를 마이크로 컨트롤러로 포팅하기 전에이 방법을 성공적으로 사용했습니다.
아래에서는로 할당자를 설정하고로 my_malloc_init()
메모리를 할당합니다 my_malloc()
. my_free()
의존성을 만족 시키지만 실제로는 아무것도하지 않습니다. 결국에는 공간이 부족할 것입니다.
이 작업을 수행하려면 코드의 최악의 메모리 요구 사항을 측정 한 다음 (가능한 경우 PC에서 수행) HEAP_SIZE
그에 따라 설정해야합니다 . 동적 메모리가 필요한 라이브러리 부분에 들어가기 전에를 호출하십시오 my_malloc_init()
. 재사용하기 전에 아직 아무것도 가리 키지 않도록하십시오 heap
.
uint8_t heap[HEAP_SIZE];
uint8_t *heap_ptr;
void my_malloc_init(void)
{
heap_ptr = heap;
}
void *my_malloc(size_t len)
{
uint8_t *p = heap_ptr;
heap_ptr += len;
if (heap_ptr >= heap + HEAP_SIZE)
return NULL;
else
return p;
}
void my_free(void)
{
// do nothing
}
(참고 : 실제로는 포인터 정렬을 고려해야합니다 (예 : heap_ptr
2 또는 4 바이트 반올림 ))
또 다른 옵션은 FreeListmalloc()
와 같이 일반적으로 제공되는 것보다 간단한 할당 구조를 사용하는 것인데 , 가변 크기 블록을 할당 할 수는 없습니다.
이것은 귀하의 질문에 대한 답이 아니지만 동적 메모리 할당은 일반적으로 작은 RAM 환경과 운영 체제가없는 경우 (예 : 마이크로 컨트롤러 세계에서) 쇠약합니다 ... 임베디드 환경에서 사용 가능한 힙 공간은 일반적으로 수백 바이트로 측정 ...
malloc과 free를 구현하는 것은 본질적으로 "free segment"구조의 링크 된 목록을 유지 관리하는 것입니다. 상상할 수 있듯이 free segment와 관련된 메타 데이터는 일반적으로 사용 가능한 메모리 양과 비교할 때 거의 중요하지 않습니다. "의 동적 메모리 풀 관리는 사용 가능한 많은 양의 리소스를 소비합니다.
C18 표준 라이브러리가 malloc
및을 지원 하는지 free
모르겠지만 Microchip 앱 노트 AN914 는 자신의 구현 방법을 보여줍니다.
어쨌든 토마스와 다른 포스터는 매우 작은 RAM 공간 으로 PIC에서 동적 메모리를 사용하는 것은 위험에 처해 있다고 제안했습니다 . 운영 체제가 제공하는 고급 가상 메모리 관리자가 없기 때문에 연속적인 공간이 빠르게 소진되어 할당 및 충돌이 발생할 수 있습니다 . 더 나쁜 것은 결정적이지 않을 수 있으며 디버그하기가 어려울 것입니다.
당신이하고있는 일이 런타임에 동적으로 결정되고 (대부분의 임베디드 일에는 드물게) 몇 가지 매우 특별한 경우 에만 공간을 할당 해야하는 경우 볼 수 malloc
있고 free
수용 가능합니다.
글쎄, 메모리면에서 PIC는 얼마나 큽니까?
malloc은 메모리를 할당 하는 매우 비효율적 인 방법입니다. 문제는 빈번한 여유 공간과 mallocs로 인해 메모리가 조각화 될 수 있고 단지 몇 킬로바이트의 메모리로 할당 실패가 너무 일반적이라는 것입니다. 더 작은 칩이나 이전 PIC18을 사용하는 경우 Microoc이 구현하기가 매우 어렵거나 (어쩌면 불가능할 수도 있음) 보았을 때 malloc을 지원하지 않을 가능성이 높습니다. 그만한 가치가 있습니다. 언급하지는 않지만 속도가 느립니다. 이미 사용 가능한 정적 버퍼를 사용하려면 1주기를, malloc을 수행하려면 100에서 1,000주기를 사용하십시오.
정적으로 할당하려면 malloc이 필요하지 않을 때까지 sprintf 함수용 버퍼 (있는 경우 약 128 바이트), SD 카드 용 버퍼 (있는 경우) 등을 작성하십시오. 이상적으로는 꼭 필요한 곳에만 사용하고 정적 할당을 피할 수는 없지만 이러한 상황은 일반적으로 드물고 더 크고 강력한 마이크로 컨트롤러를 살펴보아야한다는 신호일 수 있습니다.
그리고 PIC18에서 "운영 체제"를 개발 / 포팅하고 마이크로 컨트롤러를 지원하는 경우 정적 할당을 지원할 수 있습니다. 예를 들어, SQLite3는 정적 할당을 지원합니다. 큰 버퍼 배열을 할당하고 가능한 경우 마이크로 컨트롤러가 아닌 경우에도이를 사용합니다. 그렇지 않은 경우 작은 PIC18 용으로 설계 되었습니까?
AFAIK,이 작업을 올바르게 수행하려면 실제로 일종의 MMU (메모리 관리 장치)가있는 장치를보고 있어야합니다. PIC18 시리즈의 동적 할당 메커니즘은 존재하지만 실제로는 그다지 견고하지는 않을 것입니다. 그리고 PIC18 시리즈의 한계를 뛰어 넘는 펌웨어 작업을하는 사람 으로서는 말할 수 없습니다. 메모리 관리자에 모든 오버 헤드를 소비하는 경우 상당한 규모의 응용 프로그램.
더 나은 솔루션 : 수행중인 작업과 동적 할당이 필요한 이유를 이해하십시오. 정적 할당으로 작동하도록 리팩터링 할 수 없는지 확인하십시오. (라이브러리 / 응용 프로그램이 자유롭게 확장되거나 수용 할 수있는 입력량에 제한이없는 것을 수행하도록 설계된 경우에는 이것이 가능하지 않을 수도 있습니다.) 그러나 때로는 생각한다면 당신이하려는 일에 대해, 대신 정적 할당을 사용하는 것이 가능하고 (아마도 훨씬 쉽다는 것을) 알 수 있습니다.