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 */
}

每一个人任务的剩余空间就可以打印出来了

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐