提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
提示:这里可以添加本文要记录的大概内容:
FreeRTOS是作者:Richard Barry在2002开发出来的轻量级嵌入式实时操作系统,具有轻量与简单等特点。与简单的裸机开发不同的是,FreeRTOS具有实时性的特点,且能最大的调度CPU资源,在一些实时性要求的高的场景应用十分广泛。深受广大嵌入工作者的青睐。
提示:以下是本篇文章正文内容,下面案例可供参考
一、FreeRTOS是什么?
FreeRTOS是一款轻量简单的嵌入式实时操作系统
二、使用步骤
1.下载STM32CubeMX并导入FreeRTOS
这是下载并配置STM32CubeMX的博客链接作者:老李的森林
在FreeRTOS 官网https://www.freertos.org/的主页点击“Download FreeRTOS”,即可进入到FreeRTOS 的下载页面
2.打开STM32CubeMX
选择你要开发的芯片的型号后,配置时钟方法这里就不多赘述了我选择的型号是STM32G431
在System core(系统核心)这里我们找到SYS,然后选择Timebase Source (时基源 ) 关于什么是时基源作者:我思维混乱
对于时基源,我的理解就是对程序的运行进行一个调度,比如在FreeRTOS中,我的程序都是这个程序执行一段时间,然后换另一个程序执行,而这个一段时间的长度,就是一个基准时间,来出发中断,这个中断触发与基准时间就是靠这个时基源
这里我选的是TIM8作为时基源,注意大家打开的之后可能是sysTick作为时基源,这里不建议用sysTick作为时基源,因为HAL库也是基于sysTick作为时基源。具体用了会发生什么问题,我不太清楚,但既然官方建议不使用sysTick作为时基源,咱们就换一个定时器。
配置FreeRTOS
我们左侧向下翻找到Middleware and Software Packs(中间件和软件包)
找到FREERTOS 右侧的选项是FreeRTOS的基础配置,这里我选择的Interface的版本为CMSIS_V1,其中CMSIS_V2是对CMSIS_V1的拓展,使其能支持包括所有Cortex-M内核的设备以及Corter-A5,A7,A9。
然后我们看下面的control parameters(控制参数)
看一下关键的配置MINMAL_STACK_SIZE(最小的栈的大小),
这是分配任务时给的内存大小
MAX_TASK_NAME_SIZE(最大任务名称大小)是对任务的命名
具体参数可以访问博客作者:嵌入式常工匠
按照他的默认就可以
然后右上角创建文件
vxTaskCreate()动态创建函数函数
我们学习FreeRTOS离不开创建任务以及删除任务,vxTaskCreate()这个函数是动态创建任务,
所谓动态创建任务是根据FreeRTOS自己自动分配内存,不用用户自己去向单片机申请内存。
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
const configSTACK_DEPTH_TYPE usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask )
这个是xTaskCreate的具体参数: xTaskCreate(Task1, "Task1", TASK1_STACK_SIZE, NULL, TASK1_PRIO, &Task1_Hander);
这是我创建的任务。第一个参数Task1 对应的是TaskFunction_t pxTaskCode,它的意思是要创建的函数名字,第二个参数"Task1"这个意思是函数的名字,大家可以根据这个函数执行的意思来命名,这个无所谓相当于注释,第三个参数TASK1_STACK_SIZE是创建栈的最大大小,这样xTaskCreate在申请内存时不会超过这个大小,第四个参数NULL是填函数的参数,这里我创建的任务没有入口参数所以填NULL,第五个参数,TASK1_PRIO是这个任务优先级,在FreeRTOS中是优先级的数字越大的,优先级越高这与STM32自己优先级相反,大家要注意。第六个参数是任务句柄,FreeRTOS根据这个句柄来执行一些功能比如删除任务的功能&Task1_Hander
这些变量大部分我都是通过define来声明的便于维护与修改
void Task1(void);
#define TASK1_STACK_SIZE 128
#define TASK1_PRIO 16
TaskHandle_t Task1_Hander;
xTaskCreateStatic()静态创建任务函数
所谓静态创建任务函数是,我们自己为任务开辟内存,因为单片机的RAM的资源是紧张的,我们在一些项目开发时会考虑RAM是否充足,但随着单片机的升级,单片机内存的容量也逐渐提升,所以我们在创建任务时一般也是使用动态创建任务vxTaskCreate()
,我们来简单说一下静态创建任务函数。
TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,
const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
const uint32_t ulStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
StackType_t * const puxStackBuffer,
StaticTask_t * const pxTaskBuffer )
这是静态创建任务函数的具体参数,我们看到前五个参数与动态创建任务函数的变量一致,这里我们就不过多介绍了。
这里还有注意静态创建任务函数的返回值是这个函数的句柄,我们来根据这个句柄来操作任务的状态。
这个函数的返回值为
None | 无法创建任务,因为puxStackBuffer或pxTaskBuffer为空 |
---|---|
Any other value | 如果是非空值,那么这个返回值一定是这个任务的权柄 |
我们可以先定义一个TaskHandle_t类型的参数,为了代码的可读性,这里我们的参数命名为TaskHandle_t Task1_Hander
StackType_t * const puxStackBuffer
这个参数的意思是创建堆的大小,也就是我们申请的RAM大小,
这里我创建的StackType_t TASK1_Stack[TASK1_STACK_SIZE];
这个大小与上面那个ulStackDepth
一致
这个值就是我TASK1_STACK_SIZE
的值。
StaticTask_t * const pxTaskBuffer
这个参数是一个TCB数据结构体这里我们先声明一个参数
StaticTask_t Task1_TCB;
Task1_Hander = xTaskCreateStatic(Task1, "Task1", TASK1_STACK_SIZE, NULL, osPriorityNormal4, TASK1_Stack, &Task1_TCB);
这就全部参数了
vTaskDelete();任务删除函数
这个函数的返回值为void ,参数也比较简单,就是要删除任务的句柄,就可以把任务删除
vTaskDelete(Task1_Hander);
像这样把Task1任务删除。
示例:
void Task4(void)
{
while (1)
{
if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == RESET)
{
vTaskDelete(Task1_Hander);//删除Task1
break;
}
vTaskDelay(10);
}
这个代码的意思就是我读取GOIOB_PIN_0为低电平时,删除任务Task1;
这个函数的产生为NULL就是删除任务本身,当然也可以填任务的权柄
实例:
vTaskDelete(NULL);
void Start_Task(void)
{
vTaskDelete(NULL);
//或者vTaskDelete(Start_Task_Hander);
}
这个代码的意思就是,当我创建start_Task任务时,就立刻删除这个Start_Task任务
这个函数就比较简单,在这里就不过多介绍了。
总结:
以上就是基于HAL库的FreeRTOS编程了,在这里我们介绍了比较基础创建任务函数,以及任务删除函数,这也是FreeRTOS比较重要的函数之一。