FreeRTOS学习笔记一:移植FreeRTOS与使用规范

时间:2021-02-25 05:20:28

对于一个单片机工作者而言,在写习惯了单流水式的程序后,习惯了写状态机,标志位等后,肯定会想在单片机中跑系统,减轻工作量,个人认为FreeRTOS是首选,原因肯简单:开源;只有开源才会有越来越多的企业和个人去用。

一:
不管哪种单片机,在跑系统前提下都是基于硬件驱动程序已经是完好的状态下运行,所以跑系统之前
做的第一件事情就是移植好单片机的硬件驱动程序,有外围显示器件或者其他的器件的,同样得移植为
当前单片机可以完美驱动的状态,相信程序眼眼里都是不容瑕疵,追求完美的。

二:
在写好硬件驱动程序后,就是对系统进行移植,在官网下载最新的源码移植,初学者当然可以用别人移植好的工程,但是要告诉你,freertos系统更新特别快,所以以后最好自己移植,相信自己移植的才会最放心啊。严格按照整理出来的内容,移植相应的文件到工程当中
(参考正点原子的STM32移植的使用手册进行移植,当然对于其他类型的芯片,也是一样的移植方法)

三:使用Free_rtos:
1)main.c中包含头文件

include “FreeRTOS.h”

include “task.h”

2)定义声明任务相关单元
/优先级最低的是开始任务,是放在main函数里面的/
//任务优先级

define START_TASK_PRIO 1

//任务堆栈大小

define START_STK_SIZE 128

//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数声明
void start_task(void *pvParameters);

/下面就定义我们工程中要用到的函数/
//任务优先级

define LED0_TASK_PRIO 2

//任务堆栈大小

define LED0_STK_SIZE 50

//任务句柄
TaskHandle_t LED0Task_Handler;
//任务函数声明
void led0_task(void *pvParameters);

//任务优先级

define LED1_TASK_PRIO 3

//任务堆栈大小

define LED1_STK_SIZE 50

//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);

//任务优先级

define FLOAT_TASK_PRIO 4

//任务堆栈大小

define FLOAT_STK_SIZE 128

//任务句柄
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);
}
}