今天是2024.9.28,学习freerots的第一天。用到的是stm32f407zgt6开发板。参考正点原子的视频和文档。
纯个人向总结和理解,欢迎交流和指正。
一.初识freerots(实时操作系统)
引入freertos的目的
今天第一天学习freertos,明白了为什么需要用到freertos。其实在目的就是为了解决调度问题,传统的裸机开发中,代码只能一句一句跑。但是引入了操作系统之后,可以使得代码能够并发执行。(个人理解)(这里的并发的意思的话,学过操作系统的朋友因该知道,不是同意时刻运行,而是在同一个时段,一个时间片一个时间片地交替运行)
(我看的是正点原子的视频,视频里面由一个特别贴切的例子。比如说玩游戏的时候对象打电话过来,按照传统的无操作系统的开发逻辑,必须是先把游戏打完才能回消息。而引入os之后,便可以并发,打游戏的时候切出去回消息,回完消息再回来打游戏,就是这么个意思)。
至于这么多操作系统为什么要用freertos呢,最重要的原因当然是他免费啦
freertos支持的三种调度模式
抢占式:针对优先级不同的任务
时间片:针对优先级相同的任务
协程式:当前任务一直执行,高优先级不会抢占地优先级,实时性差,逐渐被淘汰
任务以及任务的优先级
任务优先级
任何时间点只有一个任务运行,运行哪个任务是由Freertos来进行调度的。调度器会重复的开启,关闭某一个任务。任务1运行的优先级在创建任务时配置,优先级高的优先抢占cpu资源。但是在中断面前,所有优先级任务都是小弟,中断是最高优先级! (毕竟前者是由软件触发中断直接由硬件触发)。
任务状态
任务状态是指任务当前处于运行,就绪,阻塞还是挂起的状态。
任务控制块
每一个任务都有任务控制块,任务控制块存储的是关于任务的一些特征信息。
比如说任务堆栈栈顶,状态表,事件表,优先级,任务名字之类的。在创建任务的时候,freertos就会给每个任务的分配一个任务控制块。
任务堆栈
简而言之,他的作用就是任务恢复的时候需要知道上次运行到哪里了,从而接着上次运行的地方继续运行。
二.任务相关接口函数
原理和对freertos的基本理解了解完之后就要开始应用了。最首先的就是任务的创建,删除,恢复,挂起之类的。
1.任务的创建和删除
(1)创建方法
这里第三个关于使用MPU的就先不介绍哈,因为原子老师没讲。
动态创建
任务的任务控制块以及任务的栈空间所需要的内存,均由FREERTOS从FREERtos管理的堆中分配。申请的空间是由FREERTOS管理的。
任务创建传入参数和返回值
然后看看动态创建函数需要传入的参数吧
静态创建
任务的任务控制块以及任务的栈空间所需的内存,需用户分配提供。这两者因该就是这么个区别吧
所以实现的时候主要的区别就是,静态创建任务的时候,需要自己写申请空闲任务和申请定时器任务的函数,并且在创建任务的时候需要自己定义一个堆栈空间(也就是自己定义一个数组)。
申请空闲任务和定时器任务
//获取空闲任务的任务堆栈和任务控制块内存
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
{
*ppxIdleTaskTCBBuffer = &IdleTaskTCB;
*ppxIdleTaskStackBuffer = IdleTaskStack;
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
//获取定时器服务任务的任务堆栈和任务控制块内存
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize)
{
*ppxTimerTaskTCBBuffer=&TimerTaskTCB;
*ppxTimerTaskStackBuffer=TimerTaskStack;
*pulTimerTaskStackSize=configTIMER_TASK_STACK_DEPTH;
}
其实就是自己定义以下关于空闲任务和定时器任务的堆栈数组,任务控制块,还有堆栈大小。
创建静态任务
创建静态任务的函数在传入参数和返回值上和动态创建有些区别,静态创建的时候需要自己定义一个堆栈数组和一个任务控制块传入(用户分配内存),动态创建不需要,动态创建时reeRTOS会自己帮你分配好。另外一个区别就是静态创建时不需要传入句柄,静态创建函数的返回值就是这个任务的句柄!
(2)删除方法
动态任务和静态任务的删除都一样,调用删除函数传入句柄就可以了。
2.任务的挂起和恢复
(1)挂起的方法
要挂起任务时直接调用这个函数就可以了,传入需要挂起的函数的句柄;
(2)恢复的方法
恢复由两个函数,一个是在任务中恢复,另一个是咋在中断中恢复。两者都是传入任务句柄就可以了。
任务中恢复
这个十分简单,在任务中直接调用挂起函数
中断中恢复
中断中恢复比较重要的点:
1.如果要在freertos中使用中断,那么中断优先级分组需要设置为组4。并且中断的中断优先级不能大于freertos允许的任务优先级的最大值(范围5-15之间)。
2.中断函数中需要判断是否需要切换上下文。如果恢复的任务的事件优先级高于被中断打断的事件的事件优先级,则恢复函数返回pdTRUE,需要切换上下文。如果恢复的任务的任务优先级低于被中断打断的事件的事件优先级,则回复函数返回pdFALSE,不需要切换上下文。
个人认为关于任务创建删除挂起恢复应该就是这么些东西了,如有错误请指正。