2016-08-05 8 views
0

stm32 + rtos를 사용하여 spi flash를 기반으로 파일 시스템을 구현하고 있습니다. freertos의 경우 heap_1 구현을 채택했습니다. 이것은 내가 어떻게 내 일을 창조하는지입니다.Freertos + STM32 - malloc을 통한 스레드 메모리 오버플로

osThreadDef(Task_Embedded, Task_VATEmbedded, osPriorityNormal, 0, 2500); 
    VATEmbeddedTaskHandle = osThreadCreate(osThread(Task_Embedded), NULL); 

이 스레드에 10000 바이트의 메모리가 할당되었습니다.

및이 스레드 플래시에 데이터를 쓰려고했습니다. 처음 몇 권에서는 성공적으로 작동했습니다. 하지만 여하튼 나는 더 많은 글쓰기를 시도 할 때 충돌이 일어난다.

VATAPI_RESULT STM32SPIWriteSector(void *writebuf, uint8_t* SectorAddr, uint32_t buff_size){ 



    if(STM32SPIEraseSector(SectorAddr) == VAT_SUCCESS){ 
     DBGSTR("ERASE SECTOR - 0x%2x %2x %2x", SectorAddr[0], SectorAddr[1], SectorAddr[2]); 
    }else return VAT_UNKNOWN; 
    if(STM32SPIProgram_multiPage(writebuf, SectorAddr, buff_size) == VAT_SUCCESS){ 
     DBGSTR("WRTIE SECTOR SUCCESSFUL"); 
     return VAT_SUCCESS; 
    }else return VAT_UNKNOWN; 

    return VAT_UNKNOWN; 

} 

.

VATAPI_RESULT STM32SPIProgram_multiPage(uint8_t *writebuf, uint8_t *writeAddr, uint32_t buff_size){ 
    VATAPI_RESULT nres; 
    uint8_t tmpaddr[3] = {writeAddr[0], writeAddr[1], writeAddr[2]}; 
    uint8_t* sectorBuf = malloc(4096 * sizeof(uint8_t)); 
    uint8_t* pagebuf = malloc(255* sizeof(uint8_t)); 
    memset(&sectorBuf[0],0,4096); 
    memset(&pagebuf[0],0,255); 
    uint32_t i = 0, tmp_convert1, times = 0; 


    if(buff_size < Page_bufferSize) 
     times = 1; 
    else{ 
     times = buff_size/(Page_bufferSize-1); 
     if((times%(Page_bufferSize-1))!=0) 
      times++; 
    } 

    /* Note : According to winbond flash feature, the last bytes of every 256 bytes should be 0, so we need to plus one byte on every 256 bytes*/ 
    i = 0; 
    while(i < times){ 
     memset(&pagebuf[0], 0, Page_bufferSize - 1); 
     memcpy(&pagebuf[0], &writebuf[i*255], Page_bufferSize - 1); 
     memcpy(&sectorBuf[i*Page_bufferSize], &pagebuf[0], Page_bufferSize - 1); 
     sectorBuf[((i+1)*Page_bufferSize)-1] = 0; 
     i++; 
    } 

    i = 0; 
    while(i < times){ 
     if((nres=STM32SPIPageProgram(&sectorBuf[Page_bufferSize*i], &tmpaddr[0], Page_bufferSize)) != VAT_SUCCESS){ 
      DBGSTR("STM32SPIProgram_allData write data fail on %d times!",i); 
      free(sectorBuf); 
      free(pagebuf); 
      return nres; 
     } 
     tmp_convert1 = (tmpaddr[0]<<16 | tmpaddr[1]<<8 | tmpaddr[2]) + Page_bufferSize; 
     tmpaddr[0] = (tmp_convert1&0xFF0000) >> 16; 
     tmpaddr[1] = (tmp_convert1&0xFF00) >>8; 
     tmpaddr[2] = 0x00; 
     i++; 
    } 
    free(sectorBuf); 
    free(pagebuf); 
    return nres; 
} 

나는 디버거를 열고 난 혼란 임 내가 "malloc에"후 메모리를 무료로했다는 것을 무엇인지, 기능 "STM32SPIProgram_multiPage"의 "sectorbuf"를 malloc으로 할당 할 때 충돌처럼 보인다. 누구나 그것에 대해 생각해 봤어?

팔 - 없음 - EABI 크기 "RTOS.elf"독서하는 dec 진수 파일 이름
77,564 988 100,756 179,308 2bc6c RTOS.elf

+0

오. 전에 "sectorBuf"와 "pagebuf"를 전역 변수로 넣으면 모든 함수가 잘 작동합니다. 하지만 너무 많은 RAM을 소비합니다. 왜 이제는 동적 메모리를 대신 사용했는지. – Pawan

+0

그래서 문제는 동적 메모리를 사용하여 발생합니다 생각합니다. – Pawan

+1

malloc (heap_1.c 및 관련 힙 크기는 malloc과 완전히 독립적입니다)에 의해 힙 관리를위한 메모리를 할당 했습니까? – Garf365

답변

0

BSS
텍스트 데이터 the man

메모리 관리

[...]

RTOS 객체는 동적으로 표준 C 라이브러리의 malloc()와() 무료 기능을 때때로 목적을 위해 이용 될 수 있지만 ...

그들은 항상 사용할 수 없습니다를 생성하는 경우 임베디드 시스템에서 그들은 귀중한 코드 공간 인 을 스레드로부터 안전하지 않으며 결정적이지 않습니다 (함수를 실행하는 데 걸리는 시간은 호출에 따라 다릅니다) ... 대체 메모리 할당 구현이 필요하지 않습니다. 하나의 임베디드/리얼 타임 시스템은 매우 다른 RAM 및 타이밍 요구 사항을 가질 수 있으므로 단일 RAM 할당 알고리즘 만 응용 프로그램의 하위 집합에 적합합니다.

이 문제를 해결하기 위해 FreeRTOS는 휴대용 계층에 메모리 할당 API를 유지합니다. 포터블 레이어는 코어 RTOS 기능을 구현하는 소스 파일 외부에 있으므로 개발중인 실시간 시스템에 적합한 애플리케이션 특정 구현을 제공 할 수 있습니다. RTOS 커널이 malloc()을 호출하는 대신 RAM을 필요로 할 때 pvPortMalloc()을 대신 호출합니다. RAM이 해제 될 때 free()를 호출하는 대신 RTOS 커널은 vPortFree()를 호출합니다.

[...]

(강조 광산.)

그래서 의미는 직접 malloc를 사용하는 경우, FreeRTOS 시스템에 의해 소비 힙을 처리 할 수 ​​없다는 것이다 기능. 간단한 malloc 래퍼 인 heap_3 관리를 선택하는 경우와 동일합니다.

당신이 선택한 메모리 관리에는 자유로운 기능이 없습니다.

heap_1.c는

이 모두의 간단한 구현입니다. 일단 할당되면 메모리를 해제 할 수 없습니다 (). 그럼에도 불구하고 heap_1.c는 많은 수의 임베디드 응용 프로그램에 적합합니다. 이는 작고 깊게 임베디드 된 많은 응용 프로그램이 시스템 부팅시 필요한 모든 작업, 대기열, 세마포어 등을 작성한 다음 응용 프로그램이 다시 꺼지거나 재부팅 될 때까지 이러한 모든 객체를 프로그램 수명 동안 사용하기 때문입니다). 아무것도 삭제되지 않습니다. 구현은 단순히 RAM을 요청할 때 단일 배열을 작은 블록으로 세분합니다. 배열의 총 크기 (힙의 전체 크기)는 configTOTAL_HEAP_SIZE에 의해 설정됩니다.이 크기는 FreeRTOSConfig.h에 정의되어 있습니다. configAPPLICATION_ALLOCATED_HEAP FreeRTOSConfig.h 구성 상수는 힙을 메모리의 특정 주소에 배치 할 수 있도록 제공됩니다.

xPortGetFreeHeapSize() API 함수는 할당되지 않은 총 힙 공간을 반환하므로 configTOTAL_HEAP_SIZE 설정을 최적화 할 수 있습니다.

heap_1 구현 : 응용 프로그램 (실제로 FreeRTOS 사용 도착하는 응용 프로그램의 대부분을 커버) 작업, 큐, 세마포어, 뮤텍스 등을 삭제하지 않을 경우

를 사용할 수 있습니다. 항상 결정적입니다 (항상 실행 시간이 동일합니다). 메모리 조각화가 발생할 수 없습니다. 정적으로 할당 된 배열에서 매우 간단하고 할당 된 메모리입니다. 따라서 실제 동적 메모리 할당을 허용하지 않는 응용 프로그램에서 사용하기에 적합한 경우가 많습니다.

. (강조 광산)

사이드 참고 : 체크 malloc 반환 값 != NULL 항상 있습니다.

+0

내가 선택한 메모리 관리 (heap_1.c)에 여유 용량이 없다는 것은 무엇을 의미합니까? 내가 malloc을 호출하면 그럴 수 있습니다. 나는 그 기억 영역을 자유롭게 할 수 없다? – Pawan

+0

아니요.'heap_1' 메모리 관리를 사용하려면'malloc'이 아니라'pvPortMalloc()'을 사용해야합니다. 'heap_1' 함수를 올바르게 사용하면 힙 할당 메모리를 해제 할 수 없습니다. – LPs

+0

FreeRTOS에는 동적 할당 메모리의 추상화가 있으며 5 가지 구현을 제공합니다. 첫 번째 (heap_1)은 malloc 만 허가하지만 free를 호출하면 아무 것도하지 않습니다 (한 번만 작업 메모리를 할당하고 결코 해제하지 않는 많은 임베디드 프로젝트에서 유용합니다). heap_2는 조금 더 복잡하고 여유 메모리는 있지만 메모리 관리는 좋지 않습니다. heap_3은 malloc에 ​​대한 래퍼이며 무료입니다. heap_4 및 heap_5는 여유 메모리를 위해보다 복잡한 메모리 관리 기능을 제공합니다. 귀하의 경우에는 마지막 2 개 중 하나를 선택하고'pvPortMalloc'과'pvPortFree'를 사용해야합니다. – Garf365