文章目录[隐藏]
FreeRTOS移值
提示:以下是本篇文章正文内容,下面案例可供参考
一、什么是FreeRTOS?
FreeRTOS的名字,可以分为两部分:Free和RTOS,Free就是免费的、自由的、不受约束的意思,RTOS全称是Real Time Operating System,中文名就是实时操作系统。可以看出FreeROTS就是一个免费的RTOS类系统。这里要注意,RTOS不是指某一个确定的系统,而是指一类系统。比如UCOS,FreeRTOS,RTX,RT-Thread等这些都是RTOS类操作系统。
二、FreeRTOS的特点
FreeRTOS是一个可裁剪的小型RTOS系统,其特点包括:
● FreeRTOS的内核支持抢占式,合作式和时间片调度。
● SafeRTOS衍生自FreeRTOS,SafeRTOS在代码完整性上相比FreeRTOS更胜一筹。
● 提供了一个用于低功耗的Tickless模式。
● 系统的组件在创建时可以选择动态或者静态的RAM,比如任务、消息队列、信号量、 软件定时器等等。
● 已经在超过30种架构的芯片上进行了移植。 ● FreeRTOS-MPU支持Corex-M系列中的MPU单元,如STM32F103。
● FreeRTOS系统简单、小巧、易用,通常情况下内核占用4k-9k字节的空间。
● 高可移植性,代码主要C语言编写。
● 支持实时任务和协程(co-routines也有称为合作式、协同程序,本教程均成为协程)。
● 任务与任务、任务与中断之间可以使用任务通知、消息队列、二值信号量、数值型信 号量、递归互斥信号量和互斥信号量进行通信和同步。
● 创新的事件组(或者事件标志)。
● 具有优先级继承特性的互斥信号量。
● 高效的软件定时器。
● 强大的跟踪执行功能。
● 堆栈溢出检测功能。
● 任务数量不限。
● 任务优先级不限。
进入正题FreeRTOS移值
三、FreeRTOS移值
下面是基于固件库模板来进行FreeRTOS移值
3.1、添加FreeRTOS源码
首先我们在固件库模板中创建以下几个文件夹
创建FreeRTOS文件夹以后就可以将FreeRTOS的源码添加到这个文件夹中 (如下图所示)HARDWARE 用来存放我们后面用到的外设代码 SYSTEM用来存放系统文件下面会介绍到
portable文件夹,我们只需要留下keil、MemMang和RVDS这三个文件夹,其他的都可以删除掉,完成以后如图
3.2、打开固件库project下的工程文件在分组中添加文件
添加分组后将下列c文件分别导入相应的文件夹下面
添加c文件 ,点击下面按键进行快捷添加方式
3.3、文件路径添加
点击魔术棒 选择c/c++ 进行相应c文件头文件的路径添加
以上就完成了FreeRTOS的简单移值和环境配置
四、FreeRTOS第一个实验
下面我们将移值好的FreeRTOS进行简单的多任务程序
工程中用到的 usart sys delay 相关文件都放在SYSTEM文件夹中的 我会将完整的文件放在下面。
/*----------------------------------------------------------------------
*第一个FreeRTOS实验
*Date:2022-2-12
*Author:小殷同学
*---------------------------------------------------------------------*/
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "FreeRTOS.h"
#include "task.h"
//任务优先级
#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);
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
delay_init(); //延时函数初始化
uart_init(115200); //初始化串口
LED_Init(); //初始化LED
//创建开始任务
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(); //开启任务调度
}
//开始任务任务函数
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);
vTaskDelete(StartTask_Handler); //删除开始任务
taskEXIT_CRITICAL(); //退出临界区
}
//LED0任务函数
void led0_task(void *pvParameters)
{
while(1)
{
LED0=~LED0;
vTaskDelay(500);
printf("led1 is running\r\n");
}
}
//LED1任务函数
void led1_task(void *pvParameters)
{
while(1)
{
LED1=0;
vTaskDelay(200);
LED1=1;
vTaskDelay(800);
printf("led2 is running\r\n");
}
}
代码中具体的相关参数就不介绍了 基础的大家可以去B站学习
由于stm32f103c8t6只有一颗板载LED 我们通过串口打印形式
注意
上面进行多任务创建我们是通过动态形式创建 与静态创建有点区别
动态创建时我们将下面这句宏定义 为0 当使用静态创建时为1
configSUPPORT_STATIC_ALLOCATION 1 设置为1 时如果使用动态创建方式会出现下面这个错误进行相应修改就好了
相关资料链接
链接:https://pan.baidu.com/s/1EXxSt6QEd1lCaXnlDryv-g
提取码:8ac6
–来自百度网盘超级会员V4的分享
版权声明:本文为CSDN博主「奋斗的小殷」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/boybs/article/details/122900212
暂无评论