对于一个单片机工作者而言,在写习惯了单流水式的程序后,习惯了写状态机,标志位等后,肯定会想在单片机中跑系统,减轻工作量,个人认为FreeRTOS是首选,原因肯简单:开源;只有开源才会有越来越多的企业和个人去用。
一:
不管哪种单片机,在跑系统前提下都是基于硬件驱动程序已经是完好的状态下运行,所以跑系统之前
做的第一件事情就是移植好单片机的硬件驱动程序,有外围显示器件或者其他的器件的,同样得移植为
当前单片机可以完美驱动的状态,相信程序眼眼里都是不容瑕疵,追求完美的。
二:
在写好硬件驱动程序后,就是对系统进行移植,在官网下载最新的源码移植,初学者当然可以用别人移植好的工程,但是要告诉你,freertos系统更新特别快,所以以后最好自己移植,相信自己移植的才会最放心啊。严格按照整理出来的内容,移植相应的文件到工程当中
(参考正点原子的STM32移植的使用手册进行移植,当然对于其他类型的芯片,也是一样的移植方法)
三:使用Free_rtos:
1)main.c中包含头文件
2)定义声明任务相关单元
/优先级最低的是开始任务,是放在main函数里面的/
//任务优先级
//任务堆栈大小
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数声明
void start_task(void *pvParameters);
/下面就定义我们工程中要用到的函数/
//任务优先级
//任务堆栈大小
//任务句柄
TaskHandle_t LED0Task_Handler;
//任务函数声明
void led0_task(void *pvParameters);
//任务优先级
//任务堆栈大小
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);
//任务优先级
//任务堆栈大小
//任务句柄
TaskHandle_t FLOATTask_Handler;
//任务函数
void float_task(void *pvParameters);
3)mian函数编写
和不带系统编程一样
a:开始定义main函数中可能用到的变量,数组…;
b:初始化用的到硬件驱动,这也是和没有移植OS的一样,不同之处在于对系统时钟的管理,delay.c sys.c 等文件进行修改;
c:创建开始任务
//创建开始任务
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();
4)开始任务函数的编写
/开始任务任务函数
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); //进入临界区
//创建LED0任务
xTaskCreate((TaskFunction_t )led0_task,
(const char* )"led0_task",
(uint16_t )LED0_STK_SIZE,
(void* )NULL,
(UBaseType_t )LED0_TASK_PRIO,
(TaskHandle_t* )&LED0Task_Handler);
//创建LED1任务
xTaskCreate((TaskFunction_t )led1_task,
(const char* )"led1_task",
(uint16_t )LED1_STK_SIZE,
(void* )NULL,
(UBaseType_t )LED1_TASK_PRIO,
(TaskHandle_t* )&LED1Task_Handler);
//浮点测试任务
xTaskCreate((TaskFunction_t )float_task,
(const char* )"float_task",
(uint16_t )FLOAT_STK_SIZE,
(void* )NULL,
(UBaseType_t )FLOAT_TASK_PRIO,
(TaskHandle_t* )&FLOATTask_Handler);
vTaskDelete(StartTask_Handler); //删除开始任务
taskEXIT_CRITICAL(); //退出临界区
}
5)子任务函数的编写
//LED0任务函数
void led0_task(void *pvParameters)
{
while(1)
{
LED0=~LED0;
vTaskDelay(500);
}
}
//LED1任务函数
void led1_task(void *pvParameters)
{
while(1)
{
LED1=0;
vTaskDelay(200);
LED1=1;
vTaskDelay(800);
}
}
//浮点测试任务
void float_task(void *pvParameters)
{
static float float_num=0.00;
while(1)
{
float_num+=0.01f;
printf(“float_num的值为: %.4f\r\n”,float_num);
vTaskDelay(1000);
}
}