STM32 CubeMX Freertos
STM32 CubeMX (Freertos任务:创建、删除、挂起、恢复)
- STM32 CubeMX Freertos
- 前言
- 一、STM32 CubeMX 配置
- 时钟树配置
- HAL时基选择TIM1(不要选择滴答定时器;滴答定时器留给OS系统做时基)
- 使能串口,用于用于检查实验现象
- 使用STM32 CubeMX 库,配置Freertos
- 创建任务
- 二、实验一:创建两个任务,LED闪烁
- 实验现象
- 使用 vTaskDelayUntil()绝对延时
- 三,实验二:删除LED1任务和自身任务
- 实验现象
- 四,实验三:任务的挂起和恢复
- 实验现象
- 总结
前言
学习使用Freertos第一步
FreeRTOS 任务管理,您需要掌握以下几个关键函数:
1. xTaskCreate()
:用于创建一个任务,需要指定任务函数、任务名称、任务栈大小和优先级等参数。
2. vTaskDelete()
:用于删除一个任务,可以由任务自身或其他任务调用。
3. vTaskDelay()
:用于使当前任务进入阻塞状态,延迟一段时间后再继续执行。
4. vTaskDelayUntil()
:类似于vTaskDelay(),但是可以实现周期性的延迟,使任务按照指定的时间间隔执行。
5. vTaskSuspend()和vTaskResume()
:用于暂停和恢复一个任务的执行,暂停后的任务将不会被调度执行。
6. xTaskResumeFromISR()
:在中断服务程序中恢复一个被挂起(暂停)的任务。
7. uxTaskPriorityGet()和vTaskPrioritySet()
:用于获取和设置任务的优先级。
8. uxTaskGetStackHighWaterMark()
:用于获取任务栈的剩余可用空间大小,可以用来检查任务是否使用了过多的栈空间。
一、STM32 CubeMX 配置
时钟树配置
HAL时基选择TIM1(不要选择滴答定时器;滴答定时器留给OS系统做时基)
使能串口,用于用于检查实验现象
使用STM32 CubeMX 库,配置Freertos
选择CMISS_V1接口就可以满足Freertos接口;且代码量比CMISS_V2小(CMISS_V2支持更多的RTOS接口,所以代码量比CMISS_V1多)
创建任务
二、实验一:创建两个任务,LED闪烁
代码如下(示例):
void LED1Task(void const * argument)
{
/* USER CODE BEGIN LED1Task */
/* Infinite loop */
for(;;)
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13,1);
printf("LED灭\r\n"); // printf输出字符串
osDelay(1000);
}
/* USER CODE END LED1Task */
}
/* USER CODE BEGIN Header_LED2Task */
/**
* @brief Function implementing the LED2 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_LED2Task */
void LED2Task(void const * argument)
{
/* USER CODE BEGIN LED2Task */
/* Infinite loop */
for(;;)
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13,0);
printf("LED亮\r\n"); // printf输出字符串
osDelay(2000);
}
/* USER CODE END LED2Task */
}
实验现象
使用 vTaskDelayUntil()绝对延时
使能 vTaskDelayUntil函数
void LED1Task(void const * argument)
{
/* USER CODE BEGIN LED1Task */
TickType_t xlaswketime;
xlaswketime = xTaskGetTickCount();//获取进入的时间
/* Infinite loop */
for(;;)
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13,1);
printf("LED灭\r\n"); // printf输出字符串
vTaskDelayUntil(&xlaswketime,1000);
}
/* USER CODE END LED1Task */
}
/* USER CODE BEGIN Header_LED2Task */
/**
* @brief Function implementing the LED2 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_LED2Task */
void LED2Task(void const * argument)
{
/* USER CODE BEGIN LED2Task */
TickType_t xlaswketime;
xlaswketime = xTaskGetTickCount();//获取进入的时间
/* Infinite loop */
for(;;)
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13,0);
printf("LED亮\r\n"); // printf输出字符串
vTaskDelayUntil(&xlaswketime,2000);
}
/* USER CODE END LED2Task */
}
#
三,实验二:删除LED1任务和自身任务
/* USER CODE END Header_LED1Task */
void LED1Task(void const * argument)
{
/* USER CODE BEGIN LED1Task */
TickType_t xlaswketime;
xlaswketime = xTaskGetTickCount();//获取进入的时间
/* Infinite loop */
for(;;)
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13,1);
vTaskDelayUntil(&xlaswketime,500);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13,0);
vTaskDelayUntil(&xlaswketime,500);
}
/* USER CODE END LED1Task */
}
/* USER CODE BEGIN Header_LED2Task */
/**
* @brief Function implementing the LED2 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_LED2Task */
void LED2Task(void const * argument)
{
/* USER CODE BEGIN LED2Task */
TickType_t xlaswketime;
xlaswketime = xTaskGetTickCount();//获取进入的时间
printf("5s后删除LED1任务,再5S删除自身任务\r\n"); // printf输出字符串
/* Infinite loop */
for(;;)
{
vTaskDelayUntil(&xlaswketime,5000);//5秒
vTaskDelete(LED1Handle);
printf("删除LED闪烁任务\r\n"); // printf输出字符串
vTaskDelayUntil(&xlaswketime,5000);//5秒
printf("删除自身任务\r\n"); // printf输出字符串
vTaskDelete(NULL);
printf("正常情况不会打印这段话\r\n"); // printf输出字符串
}
/* USER CODE END LED2Task */
}
实验现象
四,实验三:任务的挂起和恢复
void LED1Task(void const * argument)
{
/* USER CODE BEGIN LED1Task */
TickType_t xlaswketime;
xlaswketime = xTaskGetTickCount();//获取进入的时间
/* Infinite loop */
for(;;)
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13,1);
vTaskDelayUntil(&xlaswketime,500);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13,0);
vTaskDelayUntil(&xlaswketime,500);
}
/* USER CODE END LED1Task */
}
/* USER CODE BEGIN Header_LED2Task */
/**
* @brief Function implementing the LED2 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_LED2Task */
void LED2Task(void const * argument)
{
/* USER CODE BEGIN LED2Task */
TickType_t xlaswketime;
xlaswketime = xTaskGetTickCount();//获取进入的时间
printf("5s后暂停,再5S恢复\r\n"); // printf输出字符串
/* Infinite loop */
for(;;)
{
vTaskDelayUntil(&xlaswketime,5000);//5秒
vTaskSuspend(LED1Handle);
printf("暂停LED闪烁任务\r\n"); // printf输出字符串
vTaskDelayUntil(&xlaswketime,5000);//5秒
vTaskResume(LED1Handle);
printf("恢复LED闪烁任务\r\n"); // printf输出字符串
}
/* USER CODE END LED2Task */
}
实验现象
总结
学会 任务管理: 需要掌握并熟练任务的创建、删除、挂起、恢复和切换等操作,以及任务的优先级和调度机制。