2017-03-20 5 views
0

저는 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의 값으로 유지되는지 확인합니다. 레지스터 (주소 계산에 사용)는 선점 전과 동일하지 않습니다.
각각의 로컬 변수가 데이터 메모리에서 잘못 가져 오기 때문에 상황이 달라질 수 있습니다.
스택 오버 플로우 문제가있는 경우 어떻게 디버깅 할 수 있습니까?

+0

가장 빠른 방법은 작업 스택 크기를 늘리고 문제가 없어지는지 확인하는 것입니다. 이 값이 너무 작은 경우 시스템 스택 크기를 늘려보십시오. 어떤 툴체인을 사용하고 있습니까? 또한 malloc이 태스크 루프 안에 있지 않다고 가정합니다. –

+0

FreeRTOS 힙 크기에 거의 모든 RAM을 할당했으며 xPortGetMinimumEverFreeHeapSize()는 약 50MB의 여유 공간을 반환합니다. 나는 각각의 작업을 스택 크기의 두 배 더 할당했다. 각 작업에 대해 uxTaskGetStackHighWaterMark는 스택 오버플로가 발생하지 않음을 나타내는 값을 반환합니다. 내가 확인하지 않은 유일한 작업은 LWiP 스레드이지만 문제가 있다고 생각하지 않습니다. gcc-arm-none-eabi-5_4-2016q3을 사용하고 있습니다. 작업 루프 안에 있지만 루프는 다음과 같이 시작합니다. xQueueReceive() 시간당 한 번 차단 해제됩니다. 물론 메모리가 해제됩니다. –

+0

그러면 스택 오버 플로우 문제가 발생하지 않습니다. 레지스터 저장 및 복원은 xPortPendSVHandler에서 자동으로 저장됩니다. 여기에서 디버깅 할 수 있지만 모든 컨텍스트 전환을 위해 여기에 와서 작업을 복원 할 때 잡기가 까다로울 수 있습니다. –

답변

1

Cortex-M의 대부분의 문제는 잘못된 인터럽트 우선 순위 할당과 스택 오버플로가 발생하므로 이후 버전의 FreeRTOS에서는이 두 가지 오류에 대해 많은 트랩을 사용하여 문제가 발생하면 즉시 알려줍니다. 다음과 같은 일반적인 오류를 잡아낼 수있는 능력 :

configASSERT()이 정의되어 있습니까? 그리고 어떤 버전의 FreeRTOS를 사용하고 있습니까? 버전이 나올수록 configassert()가 도움이 될 것입니다.

configCHECK_FOR_STACK_OVERFLOW을 2로 설정하고 스택 오버플로 후크를 정의 했습니까?

+0

configASSERT는 다음과 같이 정의됩니다. #define configASSERT (x) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for (;;);} 버전은 8.2.3입니다. 예, 스택 오버플로 후크 및 malloc 실패 후크를 사용합니다. 그 (것)들에게서 아무 문제도보고되지 않았다. –

+0

다른 작업이이 작업 스택에 스탬프 처리 중일 수 있습니까? –

0

문제의 원인을 찾았습니다. blockingFunction() 안에 명시 적으로 채워진 버퍼가있었습니다. 버퍼가 너무 작아서 작업의 TCB를 덮어 썼습니다.

관련 문제