FreeRTOS STM32工程模板创建
仅在这一节做细节的演示,后续工程大家自行摸索,可以按照仓库的工程进行学习。
1. CubeMx生成工程
文档看到这里,应该都基本会CubeMx的操作了,所以一些细节上的东西不再展示,只提示一些注意的点,如果不清楚的可以返回去看基础例程的教程, CubeMx工程生成。
首先进入CubeMX, 设置好System Core, 注意system timebase Source选择一个定时器, 因为systick会被FreeRTOS使用了。推荐低优先级的TIM作为时基, 留出高优先级TIM可以用在其他地方, 这里使用TIM11.
2. 熟悉API
由于我们的目的是快速学习,然后上手做项目,所以太底层的东西我们先不讲,我们先学会使用API怎么用,首先打开工程,进入cmsis_os2.h
, 图片和代码文档中不好放,所以我们在视频中作详细的讲解。
cmsis_os2.h
中的内容,无非就是以下内容,更加详细的可以去查cmsis_os2.h的手册:
- 定义Kernel和Thread的state, 定义优先级;
- 定义一些内核初始化和启动等函数;
- 定义Thread Management Functions, 例如方便的创建线程, 获取线程信息等;
- 信号量, 队列等管理;
- 其他的flag等等;
总之大家可以自行的摸索一下,后续我们将会使用这些API进行项目的开发。
3. 打开工程,创建任务
首先在freertos.c
中添加两个任务句柄,仿照默认的defaultTaskHandle
来写。
我们平常写的时候记得时刻注意按照框架写,这也是工作时项目开发的必要的,让后人能够看懂。当然,我跟你们一样,对于CubeMX初始化的代码,这么多BEGIN END,我也看麻了,人都麻了,然后我还要遵循他。。。。。。
这里创建了一个LED闪烁的任务,以及一个串口打印log的任务:
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
.name = "defaultTask",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityLow,
};
/* Definitions for LED_Task */
osThreadId_t LED_TaskHandle;
const osThreadAttr_t LED_Task_attributes = {
.name = "LED_Task",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityLow1,
};
/* Definitions for Log_Task */
osThreadId_t Log_TaskHandle;
const osThreadAttr_t Log_Task_attributes = {
.name = "Log_Task",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityLow1,
};
然后在MX_FREERTOS_Init
函数中,按照defaultTask创建新的Task,LED的任务就设定500ms为间隙来闪烁;LOG的任务就设定500ms的间隙来发送串口信息。
/* Create the thread(s) */
/* creation of defaultTask */
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
/* creation of LED_Task */
LED_TaskHandle = osThreadNew(LedTaskFunc, NULL, &LED_Task_attributes);
/* creation of Log_Task */
Log_TaskHandle = osThreadNew(LogTaskFunc, NULL, &Log_Task_attributes);
/* USER CODE END RTOS_THREADS */
函数的内容很简单,如下:
void LedTaskFunc(void *argument)
{
for(;;)
{
HAL_GPIO_TogglePin(LED_T_GPIO_Port, LED_T_Pin);
osDelay(500);
}
}
void LogTaskFunc(void *argument)
{
for(;;)
{
printf("this is log task\r\n");
osDelay(500);
}
}
按照仓库的代码设置配置好,然后烧录到开发板我们来测试,可以看到一边在闪灯,一边在发送串口信息,这样我们初步就对RTOS有一个了解啦!是不是上手很简单呢?
4. 课后作业
- 完成FreeRTOS工程的创建;
- 先熟悉Task的创建,自行创建一些任务试试吧!
其他的队列或者任务之间通信等等操作,各种组件我们后续再讲。