1、問(wèn)題:
在移植、使用安富萊的FreeRTOS堆棧溢出檢測(cè)例程的過(guò)程中,出現(xiàn)如下情況
串口數(shù)據(jù)并沒(méi)有打印完成,直接進(jìn)入了硬件報(bào)錯(cuò)。同時(shí)在仿真過(guò)程中,溢出檢測(cè)的vApplicationStackOverflowHook也沒(méi)有進(jìn)入。
2、解決方案:
通過(guò)修改vTaskDelay(1);改成vTaskDelay(10);之后,串口數(shù)據(jù)會(huì)全部打印,并且進(jìn)入vApplicationStackOverflowHook。
/*
*********************************************************************************************************
* 函 數(shù) 名: StackOverflowTest
* 功能說(shuō)明: 任務(wù)棧溢出測(cè)試
* 形 參: 無(wú)
* 返 回 值: 無(wú)
*********************************************************************************************************
*/
static void StackOverflowTest(void)
{
int16_t i;
uint8_t buf[2048];
(void)buf; /* 防止警告 */
/*
1. 為了能夠模擬任務(wù)棧溢出,并觸發(fā)任務(wù)棧溢出函數(shù),這里強(qiáng)烈建議使用數(shù)組的時(shí)候逆著賦值。
因?yàn)閷?duì)于M3和M4內(nèi)核的MCU,堆棧生長(zhǎng)方向是向下生長(zhǎng)的滿棧。即高地址是buf[2047], 低地址
是buf[0]。如果任務(wù)棧溢出了,也是從高地址buf[2047]到buf[0]的某個(gè)地址開(kāi)始溢出。
因此,如果用戶直接修改的是buf[0]開(kāi)始的數(shù)據(jù)且這些溢出部分的數(shù)據(jù)比較重要,會(huì)直接導(dǎo)致
進(jìn)入到硬件異常。
2. 棧溢出檢測(cè)是在任務(wù)切換的時(shí)候執(zhí)行的,我們這里加個(gè)延遲函數(shù),防止修改了重要的數(shù)據(jù)導(dǎo)致直接
進(jìn)入硬件異常。
3. 任務(wù)vTaskTaskUserIF的??臻g大小是2048字節(jié),在此任務(wù)的入口已經(jīng)申請(qǐng)了??臻g大小
------uint8_t ucKeyCode;
------uint8_t pcWriteBuffer[500];
這里再申請(qǐng)如下這么大的??臻g
-------int16_t i;
-------uint8_t buf[2048];
必定溢出。
*/
for(i = 2047; i >= 0; i--)
{
buf[i] = 0x55;
vTaskDelay(10);
}
}
修改之后的結(jié)果:
3、原因分析
在一開(kāi)始的串口打印過(guò)程中,因?yàn)檠訒r(shí)不夠,沒(méi)有將所有的數(shù)據(jù)打印出來(lái),同時(shí),因?yàn)檠訒r(shí)時(shí)間太少,導(dǎo)致在進(jìn)入空閑線程之后,串口數(shù)據(jù)未打印未完成,并且產(chǎn)生溢出中斷,導(dǎo)致直接進(jìn)入硬件報(bào)錯(cuò)。