저는 FreeRTOS를 STM32F407과 함께 사용하고 있습니다. 잘못된 컨텍스트 스위치 복원 문제가 있습니다. 코드는 다음과 내부 태스크 코드처럼 간다 :FreeRTOS 잘못된 컨텍스트 스위치 복원
char *ptr = pvPortMalloc(sizeof(char) * size);
memcpy(ptr, buf, size);
...
log("Before:");
logItoa((int)ptr);
blockingFunction(); // Here preemption will occur
log("After:");
logItoa((int)ptr);
blockingFunction()가 ptr
를 사용하지 않습니다.
STR R0, [R7, #24]
그래서 어드레스 (R7 + 24) 아래에있는 값을 확인 (^ 1) 데이터 메모리 및 볼 : I가
ptr
가리키는 주소가 명령어와 함께 저장되어, I 보시 디버깅 동적으로 할당 된 데이터의 주소가 성공적으로 저장됩니다.
컨텍스트 복원 후 변수
ptr
을 확인하고 새로 할당 된 데이터를 가리키고 있지 않음을 확인하여 주소 (^ 1) 아래의 값을 확인하고 값이 변경되지 않고 R7의 값으로 유지되는지 확인합니다. 레지스터 (주소 계산에 사용)는 선점 전과 동일하지 않습니다.
각각의 로컬 변수가 데이터 메모리에서 잘못 가져 오기 때문에 상황이 달라질 수 있습니다.
스택 오버 플로우 문제가있는 경우 어떻게 디버깅 할 수 있습니까?
가장 빠른 방법은 작업 스택 크기를 늘리고 문제가 없어지는지 확인하는 것입니다. 이 값이 너무 작은 경우 시스템 스택 크기를 늘려보십시오. 어떤 툴체인을 사용하고 있습니까? 또한 malloc이 태스크 루프 안에 있지 않다고 가정합니다. –
FreeRTOS 힙 크기에 거의 모든 RAM을 할당했으며 xPortGetMinimumEverFreeHeapSize()는 약 50MB의 여유 공간을 반환합니다. 나는 각각의 작업을 스택 크기의 두 배 더 할당했다. 각 작업에 대해 uxTaskGetStackHighWaterMark는 스택 오버플로가 발생하지 않음을 나타내는 값을 반환합니다. 내가 확인하지 않은 유일한 작업은 LWiP 스레드이지만 문제가 있다고 생각하지 않습니다. gcc-arm-none-eabi-5_4-2016q3을 사용하고 있습니다. 작업 루프 안에 있지만 루프는 다음과 같이 시작합니다. xQueueReceive() 시간당 한 번 차단 해제됩니다. 물론 메모리가 해제됩니다. –
그러면 스택 오버 플로우 문제가 발생하지 않습니다. 레지스터 저장 및 복원은 xPortPendSVHandler에서 자동으로 저장됩니다. 여기에서 디버깅 할 수 있지만 모든 컨텍스트 전환을 위해 여기에 와서 작업을 복원 할 때 잡기가 까다로울 수 있습니다. –