一、freeRTOS任务挂起和恢复
在FreeRTOS中,可以通过挂起和恢复任务来控制任务的执行。任务挂起指暂停一个任务的执行,任务恢复则是使一个被挂起的任务继续执行。
FreeRTOS提供了vTaskSuspend()函数来挂起一个任务,该函数接受一个参数,即要挂起的任务的句柄。例如,如果要挂起名为task_handle的任务,则可以使用以下代码:
vTaskSuspend(task_handle);
类似地,FreeRTOS也提供了vTaskResume()函数来恢复一个被挂起的任务,该函数也接受一个参数,即要恢复的任务的句柄。例如,如果要恢复名为task_handle的任务,则可以使用以下代码:
vTaskResume(task_handle);
需要注意的是,当一个任务被挂起后,它将不再被调度器执行,直到被恢复为止。在任务挂起期间,该任务所占用的CPU处理时间将被释放,以便其他任务能够获得更多的CPU时间。因此,在实际应用中,可以通过挂起一些低优先级的任务来让高优先级的任务优先执行,以提高系统的响应速度。
二、以下是一个简单的示例,演示如何在FreeRTOS中挂起和恢复任务:
实现功能:通过按键控制挂起正在执行的任务。
工程配置及代码分析
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_PIN_9 == GPIO_Pin)
{
if(HAL_GPIO_ReadPin(GPIOI, GPIO_PIN_9)==GPIO_PIN_SET)
{
//HAL_Delay(10);
if(HAL_GPIO_ReadPin(GPIOI, GPIO_PIN_9)==GPIO_PIN_SET)
printf("key3 is down");
KeyStatus = KEY_DOWN;
}
else
{
// HAL_Delay(10);
if(HAL_GPIO_ReadPin(GPIOI, GPIO_PIN_9)==GPIO_PIN_RESET)
printf("key3 is up");
KeyStatus = KEY_UP;
}
}
}
先写一下中断回调函数,读取管脚状态,加一个延时滤波,如果是按下将状态值存入key_down,
抬起将状态值存入key_up。
任务函数的编写:
void led_test(void const * argument)
{
/* USER CODE BEGIN led_test */
/* Infinite loop */
for(;;)
{
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_8, GPIO_PIN_RESET);
osDelay(500);
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_8, GPIO_PIN_SET);
osDelay(500);
}
/* USER CODE END led_test */
}
led任务,间隔0.5m闪烁。
void key_test(void const * argument)
{
/* USER CODE BEGIN key_test */
KeyStatus = KEY_RESET;
/* Infinite loop */
for(;;)
{
if(KeyStatus == KEY_DOWN){
vTaskSuspend(ledtestHandle);
KeyStatus = KEY_RESET;
}
if(KeyStatus == KEY_UP){
vTaskResume(ledtestHandle);
KeyStatus = KEY_RESET;
}
osDelay(10);
}
按键任务,按键按下,挂起led任务,按键抬起,恢复led任务。
‘实现结果:按键一直按下时,led任务被挂起,保留最后一次工作状态,按键松开,led任务被恢复,接着闪烁。