多任务程序
1.1 RTOS的统一接口¶
在cmsis_os2.c
文件中由一个osThreadNew()
函数,用于统一各种操作系统的任务接口,我们学习FreeRTOS所以优先使用FreeRTOS原生代码函数。
1.2 FreeRTOS默认任务¶
在使用STM32CubeMX配置完FreeRTOS以后,会有一个默认任务生成,可以在Core\Src\freertos.c
文件中找到:
C
void MX_FREERTOS_Init(void) {
...
/* creation of defaultTask */
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
/* USER CODE BEGIN RTOS_THREADS */
...
}
找到osThreadNew()
函数的第一个参数,即StartDefaultTask()
函数,并替换默认函数内容,我们就有第一个循环任务:
C
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument) {
/* USER CODE BEGIN StartDefaultTask */
/* Infinite loop */
for (;;) {
rtBuzzer_ON_Time();
// osDelay(1);
}
/* USER CODE END StartDefaultTask */
}
Danger
Bsp_Loop()
是一个蜂鸣器加LED的死循环函数。
此外,我们应知道,默认任务封装在MX_FREERTOS_Init()
函数中(RTOS初始化函数),在main.c
文件中约 126 行可以找到这个函数。
1.3 创建一个原生FreeRTOS任务¶
首先了解FreeRTOS的任务创建函数xTaskCreate()
,然后参考默认任务osThreadNew()
的传入参数。
C
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, // 函数指针, 任务函数
const char * const pcName, // 任务的名字
const configSTACK_DEPTH_TYPE usStackDepth, // 栈大小,单位为word,10表示40字节
void * const pvParameters, // 调用任务函数时传入的参数
UBaseType_t uxPriority, // 优先级
TaskHandle_t * const pxCreatedTask ); // 任务句柄, 以后使用它来操作这个任务
关于默认任务的参数设置,找到osThreadNew()
的第三参数&defaultTask_attributes
的定义位置:
C
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
.name = "defaultTask",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
接下来创建,我们的第一个原生任务:
① 任务函数,位置在freertos.c
文件的最下方,函数类型参数参考void StartDefaultTask(void *argument)
,注意看注释找任务函数定义位置。
C
/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
void MyTask(void *argument)
{
rtMotor_Test();
}
/* USER CODE END Application */
② 声明任务函数,在C语言学习时我们就知道的知识点,位置紧挨着void StartDefaultTask(void *argument);
。
C
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
void MyTask(void *argument);
/* USER CODE END FunctionPrototypes */
③ 创建任务,位置在MX_FREERTOS_Init()
函数中,根据注释找位置创建我们自己的任务。
C
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
xTaskCreate(MyTask, "RbTask_1", 124, NULL, osPriorityNormal, NULL);
/* USER CODE END RTOS_THREADS */