FreeRtos是之前的一些聪明的工程师写的免费且开源的嵌入式实时操作系统代码,由于我们实际工作中不需要再去写rtos,我们只需要用就行了,所以博主这里只分享项目工程实战相关的内容,具体rtos源码,可以无需理会,除非你要自己写一个rtos。
另外rtos的移植的话,博主会放在最后一章,因为也没什么用(毕竟cubemx或者类似S32DS等软件已经可以一键生成带freertos的工程了)。
废话说完了,干货走起。
———————————————————————————————————————————
1.以rtos的形式开发时,首先是在main函数中进行相关外设的初始化,之后创建个start_task任务,start_task用于创建实际项目应用所需要的各个执行任务,创建完start任务之后,开始任务调度器的任务调度。
外设的初始化代码如下:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
delay_init(); //延时函数初始化
uart_init(115200); //初始化串口
LED_Init(); //初始化LED
LCD_Init(); //初始化LCD
POINT_COLOR = RED;
LCD_ShowString(30,10,200,16,16,"ATK STM32F103/F407");
LCD_ShowString(30,30,200,16,16,"FreeRTOS Examp 6-1");
LCD_ShowString(30,50,200,16,16,"Task Creat and Del");
LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");
LCD_ShowString(30,90,200,16,16,"2016/11/25");
2.创建任务:
之后main函数中要先创建开始任务,创建完成之后开始任务调度,代码如下:
//创建开始任务
xTaskCreate((TaskFunction_t )start_task, //任务函数
(const char* )"start_task", //任务名称
(uint16_t )START_STK_SIZE, //任务堆栈大小
(void* )NULL, //传递给任务函数的参数
(UBaseType_t )START_TASK_PRIO, //任务优先级
(TaskHandle_t* )&StartTask_Handler); //任务句柄
vTaskStartScheduler(); //开启任务调度
这个地方我们展开说一下创建任务的接口及所需变量定义:
创建任务接口:
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
const char * const pcName,
const uint16_t usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
①其中pxTaskCode为实际的任务接口名称,具体实现见下:
//开始任务任务函数
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); //进入临界区
//创建TASK1任务
xTaskCreate((TaskFunction_t )task1_task,
(const char* )"task1_task",
(uint16_t )TASK1_STK_SIZE,
(void* )NULL,
(UBaseType_t )TASK1_TASK_PRIO,
(TaskHandle_t* )&Task1Task_Handler);
//创建TASK2任务
xTaskCreate((TaskFunction_t )task2_task,
(const char* )"task2_task",
(uint16_t )TASK2_STK_SIZE,
(void* )NULL,
(UBaseType_t )TASK2_TASK_PRIO,
(TaskHandle_t* )&Task2Task_Handler);
vTaskDelete(StartTask_Handler); //删除开始任务
taskEXIT_CRITICAL(); //退出临界区
}
注意:start任务的主要功能为创建项目工程实际需要使用的具体任务,需要在创建完其他任务之后,删除掉start任务,所谓的“事了拂衣去,深藏功与名”
②pcName:即任务字符串名称,跟上一个任务名称保持一致即可;
③usStackDepth:即任务堆栈大小;
④pvParameters:传递给任务函数的参数,这里我们一般为NULL即可;
⑤uxPriority:任务优先级,注意freertos的任务优先级不同于中断优先级,freertos的任务优先级是值越大,优先级越高;
⑥pxCreatedTask:任务句柄,用来存放任务的相关信息;
任务相关参数的定义示例如下:
//任务优先级
#define START_TASK_PRIO 1
//任务堆栈大小
#define START_STK_SIZE 128
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);
3.删除任务:
vTaskDelete(StartTask_Handler); //删除开始任务
调用接口示例如上,vTaskDelate(NULL);时为删除当前任务;
3.集成示例:
之后我们创建task1和task2,在task1和task2的任务函数中的相关代码结构如下:
void task1_task(void *pvParameters)
{
//init code
while(1)
{
//action code
}
}
我们这里实现的task1和task2的任务逻辑为,task1按照1s为周期切换LCD屏幕区域的填充颜色,且在任务执行五次之后删除任务2;
task2的任务执行逻辑为按照1s为周期切换LCD屏幕的填充颜色;
实际效果见下:(后续会上传视频,视频正在审核中)
freertos的任务创建及删除演示视频