freertos任务栈溢出检测方案&任务状态信息打印
·
CHECK_FOR_STACK_OVERFLOW:提供三个选项(Disable/Operation1/Operation2)选择方案:选择Operation1模式进行栈溢出检测

在RTOS里面改
/* USER CODE BEGIN 4 */
void vApplicationStackOverflowHook(xTaskHandle xTask, signed char *pcTaskName)
{
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook function is
called if a stack overflow is detected. */
printf("%s is stack OverFlow\r\n",pcTaskName);
}
/* USER CODE END 4 */
/* USER CODE BEGIN Header_UsarT1_Task */
void vStackOverFlowTest(void)
{
uint8_t u8testBuff[128];
int16_t i;
(void)u8testBuff;
for(i=360;i>=0;i--)
{
u8testBuff[i]=0x88;
}
}
/**
* @brief Function implementing the UsarT1Task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_UsarT1_Task */
void UsarT1_Task(void *argument)
{
/* USER CODE BEGIN UsarT1_Task */
/* Infinite loop */
for(;;)
{
//HAL_Delay(2000);
vStackOverFlowTest();
osDelay(2);
}
/* USER CODE END UsarT1_Task */
}
上面这种其实不好用了解就好,像我的代码根本就不打印,直接宕机了。接下来再介绍一种方法
获取任务状态的方案

打印重新定向

int fputc(int ch, FILE *f)
{
/* 1. 先进来就翻转灯⿔⿔如果灯不闪,说昿 printf 没链到这个函敿 */
//HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_14);
/* 2. 限时等待,别让任务卡歿 */
uint32_t tick = HAL_GetTick();
while (!(USART1->SR & USART_SR_TXE))
{
if (HAL_GetTick() - tick > 10) // 10 ms 等不到就放弃
{
//HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_15); // 再闪丿次灯做超时提礿
return ch; // 直接返回,别让任务死
}
}
USART1->DR = ch;// 把数据写进发送寄存器,开始发逿
return ch;// 返回发鿁的字符
}
按键部分之前的文章里面有

typedef enum{
KEY_DOWN,
KEY_UP,
KEY_RESET
}teKey1PA6Status;

/* USER CODE BEGIN 2 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
/* lastTick 只会在第丿次进中断时设丿 0,以后每次中断都记住上一次有效按键的时刻 */
static uint32_t lastTick[2] = {0}; // 0:按下 1:松开
/* 1. 先判断是不是我们关心的引脚(PA6_ */
if (GPIO_Pin == KEY1PA6_Pin)
{
int evt = HAL_GPIO_ReadPin(KEY1PA6_GPIO_Port, KEY1PA6_Pin); // 0=按下 1=松开
uint32_t now = HAL_GetTick();
uint32_t *pLast = &lastTick[evt]; // 用不同计时器
/* 2. “同丿事件 20 ms 内重复认为是抖动,直接无觿 */
if (now - *pLast < 20)
return;
/* 3. 到现在已绿>20 ms了,把这次记录为新的有效时刻 */
*pLast = now;
/* 4. 现在可以安全地认为是丿次真正的按下或松弿 */
if (evt == GPIO_PIN_RESET) // 低电广 ↿ 按下
{
Key1PA6Status = KEY_DOWN;
printf("key_down\r\n");
}
else // 高电广 ↿ 松开
{
Key1PA6Status = KEY_UP;
printf("key_up\r\n");
}
}
}
/* USER CODE END 2 */
freertos里面

/* USER CODE END Header_KEY1PA6_Task */
uint8_t u8TaskIistBuff[400];//用于接收任务状态的信息
void KEY1PA6_Task(void *argument)
{
/* USER CODE BEGIN KEY1PA6_Task */
Key1PA6Status = KEY_RESET;//初始怿
/* Infinite loop */
for(;;)
{
if(Key1PA6Status == KEY_DOWN)//按下怿
{
memset(u8TaskIistBuff,0,400);
vTaskList((char*)u8TaskIistBuff);//用vTaskList把任务状态的信息写u8TaskIistBuff
printf("Name State Prionity Stack Num\r\n");
printf("**********************************************\r\n");
printf("%s",u8TaskIistBuff);
printf("**********************************************\r\n");
Key1PA6Status = KEY_RESET;
}
if(Key1PA6Status == KEY_UP)//弹起怿
{
Key1PA6Status = KEY_RESET;
}
osDelay(10);
}
/* USER CODE END KEY1PA6_Task */
}
每一个人任务的剩余空间就可以打印出来了
更多推荐



所有评论(0)