2012-08-31 3 views
0

저는 프로그래밍 마이크로 컨트롤러를 처음 사용합니다. 나는 LPC1788로 2 주 동안 일 해왔다.LPC1788 마이크로 컨트롤러의 메모리 할당 문제

내가 최근에 한 가지 문제는 예상보다 훨씬 빨리 메모리가 부족하다는 것입니다. 나는 malloc 할 수있는 연속적인 메모리 블럭의 크기를 테스트함으로써 얼마나 많은 메모리가 사용 가능한지 테스트했다. 그 결과는 972 바이트이다. 할당은 주소 0x10000000 (이 보드에서 약 64kB가되어야하는 온칩 SRAM의 시작)에서 시작됩니다.

현재 작업하고있는 프로그램은 LCD를 사용하고 메시지를 인쇄 할 수있는 간단한 디버거 역할을합니다. 나는 새로운 메시지에 의해 끊임없이 "추가"될 하나의 문자열을 가지고 있으며, 전체 메시지가 LCD에 인쇄 될 것이다. 화면 아래의 메시지 길이가 수직 경계를 지나면 가장 적합한 메시지 (가장 가까운 메시지)가 삭제 될 때까지 삭제됩니다. 그러나 더 많은 메모리를 할당하기 전에 약 7 개의 추가 메시지 만 추가 할 수 있습니다. 필요한 경우 프로젝트의 main.c는 http://pastebin.com/bwUdpnD3

에서 호스팅됩니다. 이전에 threadX RTOS를 사용하여 여러 스레드를 만들고 실행하는 프로젝트에서 작업을 시작했습니다. 내가 그 프로그램에서 LCD의 사용을 포함 시키려고했을 때, 나는 거기에서도 매우 제한된 메모리를 발견했다. LCD는 SDRAM 기본 주소에서 시작하는 모든 픽셀 데이터를 저장하는 것으로 보이지만 사용중인 SRAM과 동일한 것인지 확실하지 않습니다.

필요한 것은 LCD를 사용할 수있는 동안 여러 스레드가 작동하거나 큰 문자열을 저장할 수 있도록 메모리를 할당하는 방법입니다. 한 가지 가능성은 버퍼 또는 다른 메모리 영역을 사용하는 것일 수 있지만, 어떻게해야하는지 잘 모르겠습니다. 어떤 도움을 주시면 감사하겠습니다.

tl; dr : LCD에 큰 문자열을 인쇄하려고 할 때 SRAM의 할당 가능한 메모리가 빠져 빠릅니다.

EDIT 1 : 변수 currMessage로 메모리 누수가 감지되었습니다. 나는 그것이 지금 고쳐 졌다고 생각한다 :

strcpy(&trimMessage[1], &currMessage[trimIndex+1]); 

// Frees up the memory allocated to currMessage from last iteration 
// before assigning new memory. 
free(currMessage); 
currMessage = malloc((msgSize - trimIndex) * sizeof(char)); 
for(int i=0; i < msgSize - trimIndex; i++) 
{ 
    currMessage[i] = trimMessage[i]; 
} 

편집 2 : 구현 된 메모리 누출 수정. 프로그램이 훨씬 잘 작동하고, 나는 매우 어리 석다.

+0

아마도 힙 조각화이거나 심지어 메모리 누수 일 수도 있습니다. 메모리 관리 전략에 대해 더 많이 생각해야합니다. –

답변

1

특히 제한된 메모리가있는 임베디드 환경에서 동적 메모리 할당을 사용할 때주의해야합니다. 아주 큰 구멍이 972 바이트가되도록 쉽게 메모리 공간을 조각 낼 수 있습니다.

힙에서 할당해야하는 경우 한 번 수행 한 다음 정적 버퍼와 거의 비슷하게 메모리에 고정시킵니다. 가능한 경우 정적 버퍼를 사용하고 할당을 모두 피하십시오. 동적 할당이 필요하면 고정 크기 블록을 유지하면 조각화에 도움이됩니다.

불행히도 조각화 문제를 극복하기 위해 약간의 엔지니어링 노력이 필요합니다. 그것은 노력할만한 가치가 있으며 시스템을 훨씬 강력하게 만듭니다.

SRAM 대 SDRAM의 경우 동일하지 않습니다. 나는 threadX에 익숙하지 않고 보드에 보드 지원 패키지 (BSP)가 있는지 여부를 알지 못하지만 일반적으로 SDRAM을 설정해야합니다. 즉, 부팅 코드는 메모리 컨트롤러를 초기화하고 타이밍을 설정 한 다음 해당 공간을 활성화해야합니다. 힙 구현에 따라 동적으로 추가하거나 더 많은 가능성이 있습니다. 힙 공간을 사용하여 컴파일해야합니다 (SDRAM 공간에서). 그런 다음 실제로 힙을 사용하기 전에 메모리를 구성하고 활성화하도록 설정해야합니다.

주의 할 점은 실제로 SRAM 공간에서 코드를 실행할 수 있으며 그 공간 중 일부는 프로세서 예외 테이블을 위해 예약 된 것입니다. 전체 공간을 사용할 수 없을 수도 있으며, 예를 들어 두 개의 서로 다른 주소 (0x00000000 및 0x10000000)를 통해 살아있을 수 있습니다. 나는 다른 ARM9 프로세서에서 이것이 일반적이라는 것을 알고있다. 처음에 0x00000000 공간에 매핑되는 플래시에서 부팅 한 다음 노래와 춤을 사용하여 부팅 프로그램을 SRAM에 복사하고 SRAM을 해당 공간에 매핑 할 수 있습니다. 이 시점에서 Linux와 같은 것으로 부팅 할 수 있습니다. 누가 0에서 작동하는 테이블을 업데이트 할 수있을 것으로 예상합니다.

BTW, 게시 한 코드에 메모리 누수가있는 것 같습니다. 즉, currentMessage 결코 해제되지 않습니다 ... 새 포인터로 덮어 씁니다. 그 블록들은 영원히 없어집니다.

+0

먼저 메모리 누수를 지적 해 주셔서 감사합니다. printMessage()에 대한 코드를 수정했는데 (변경된 내용이 원래 게시물로 편집 됨) 잘 정렬되어 있어도 프로그램은 여전히 ​​메모리가 부족한 것처럼 보입니다. 동적으로 한 번 할당하고 메모리에 매달릴 제안은 지금 당장 할 수있는 최선의 방법 같습니다. 아마도 currMessage에 대해 500 문자 배열을 만들고 그 안에있는 문자를 수정하면됩니다. 그래도 내가 다루고 싶은 다른 것, 즉 흠에 대해서는 약 400 바이트 밖에 남지 않습니다. – Tagc

+0

177 번 줄에 또 다른 메모리 누수가 있습니다. 비슷한 문제입니다. – jszakmeister

+0

좋은 지적. 내가 printMessage()에 있다고 생각했을 때 trimMessage()의 코드를 수정했다. (두 함수는 비슷하게 생겼다.) 둘 다 메모리 누수가 포함되어 있지만 어디에서든지 trimMessage()를 호출하지 않는 것을 보았습니다. 왜 거기에 수정이 적용되지 않았는지를 설명합니다. printMessage()에서 문제를 해결하는 데 문제가 있지만 작동 할 때 업데이트 할 것입니다. 타이. – Tagc

관련 문제