安富莱电子 www.armfly.com
安富莱_STM32-V5开发板_FreeRTOS教程(V1.0)
实验目的:
* 1. 学习FreeRTOS的任务栈溢出检测方法一(模拟栈溢出)。
* 2. FreeRTOS的任务栈溢出检测方法一说明:
* a. FreeRTOSConfig.h文件中配置宏定义:
* #define configCHECK_FOR_STACK_OVERFLOW 1
* b. 在任务切换时检测任务栈指针是否过界了,如果过界了,在任务切换的时候会触发栈溢出钩子函数。
* void vApplicationStackOverflowHook( TaskHandle_t xTask,
* signed char *pcTaskName );
* 用户可以在钩子函数里面做一些处理。本实验是在钩子函数中打印出现栈溢出的任务。
* c. 这种方法不能保证所有的栈溢出都能检测到。比如任务在执行的过程中发送过栈溢出。任务切换前
* 栈指针又恢复到了正常水平,这种情况在任务切换的时候是检测不到的。又比如任务栈溢出后,把
* 这部分栈区的数据修改了,这部分栈区的数据不重要或者暂时没有用到还好,如果是重要数据被修
* 改将直接导致系统进入硬件异常。这种情况下,栈溢出检测功能也是检测不到的。
* d. 本实验就是简单的在任务vTaskUserIF中申请过大的栈空间,模拟出一种栈溢出的情况,溢出后触
* 发钩子函数,因为我们将溢出部分的数据修改了,进而造成进入硬件异常。
#define configCHECK_FOR_STACK_OVERFLOW 1
/*
*********************************************************************************************************
* 函 数 名: StackOverflowTest
* 功能说明: 任务栈溢出测试
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
static void StackOverflowTest(void)
{
int16_t i;
uint8_t buf[2048];
(void)buf; /* 防止警告 */
/*
1. 为了能够模拟任务栈溢出,并触发任务栈溢出函数,这里强烈建议使用数组的时候逆着赋值。
因为对于M3和M4内核的MCU,堆栈生长方向是向下生长的满栈。即高地址是buf[2047], 低地址
是buf[0]。如果任务栈溢出了,也是从高地址buf[2047]到buf[0]的某个地址开始溢出。
因此,如果用户直接修改的是buf[0]开始的数据且这些溢出部分的数据比较重要,会直接导致
进入到硬件异常。
2. 栈溢出检测是在任务切换的时候执行的,我们这里加个延迟函数,防止修改了重要的数据导致直接
进入硬件异常。
3. 任务vTaskTaskUserIF的栈空间大小是2048字节,在此任务的入口已经申请了栈空间大小
------uint8_t ucKeyCode;
------uint8_t pcWriteBuffer[500];
这里再申请如下这么大的栈空间
-------int16_t i;
-------uint8_t buf[2048];
必定溢出。
*/
for(i = 2047; i >= 0; i--)
{
buf[i] = 0x55;
vTaskDelay(1);
}
}
/*
*********************************************************************************************************
* 函 数 名: vApplicationStackOverflowHook
* 功能说明: 栈溢出的钩子函数
* 形 参: xTask 任务句柄
* pcTaskName 任务名
* 返 回 值: 无
*********************************************************************************************************
*/
void vApplicationStackOverflowHook( TaskHandle_t xTask, signed char *pcTaskName )
{
printf("任务:%s 发现栈溢出\r\n", pcTaskName);
}
实验目的:
* 1. 学习FreeRTOS的任务栈溢出检测方法二(模拟栈溢出)。
* 2. FreeRTOS的任务栈溢出检测方法二说明:
* a. FreeRTOSConfig.h文件中配置宏定义:
* #define configCHECK_FOR_STACK_OVERFLOW 2
* b. 在任务切换时检测任务栈指针是否过界了,如果过界了,在任务切换的时候会触发栈溢出钩子函数。
* void vApplicationStackOverflowHook( TaskHandle_t xTask,
* signed char *pcTaskName );
* 用户可以在钩子函数里面做一些处理。本实验是在钩子函数中打印出现栈溢出的任务。
* c. 任务创建的时候将任务栈所有数据初始化为0xa5,任务切换时进行任务栈检测的时候检测末尾
* 的16个字节是否都是0xa5,通过这种方式来检测任务栈是否溢出了。相比方法一,这种方法的速度
* 稍慢些,但是这样就有效的避免了方法一里面的部分情况。不过依然不能保证所有的栈溢出都能检测
* 到,比如任务栈末尾的16个字节没有用到,即没有被修改,但是任务栈已经溢出了,这种情况是检
* 测不到的。另外任务栈溢出后,任务栈末尾的16个字节没有修改,但是溢出部分的栈区的数据修改
* 了,这部分栈区的数据不重要或者暂时没有用到还好,如果是重要数据被修改将直接导致系统进入硬
* 件异常。这种情况下,栈溢出检测功能也是检测不到的。
* d. 本实验就是简单的在任务vTaskUserIF中申请过大的栈空间,模拟出一种栈溢出的情况,溢出后触
* 发钩子函数,因为我们将溢出部分的数据修改了,进而造成进入硬件异常。
#define configCHECK_FOR_STACK_OVERFLOW 2
函数内容和上面一样:
static void StackOverflowTest(void)
void vApplicationStackOverflowHook( TaskHandle_t xTask, signed char *pcTaskName )