【系统开发的了解】freeRTOS系统平台的使用

系列文章目录

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
TODO:写完再整理

文章目录

  • 系列文章目录
  • 前言
  • 一、实时操作系统RTOS的价值分析
    • 1.RTOS的市场
    • 2.前后台系统和实时系统的区别
    • 3.RTOS介绍
    • 4.RTOS操作系统类型
    • 5. RTOS的功能(这就是一个系统平台最基本的要求)
  • 二、FreeRTOS的文件移植步骤和文件架构
    • (1)demo文件夹
    • (2)license文件夹
    • (3)Source文件夹
    • 注意
  • 三、FreeRTOS配置与剪裁
  • 四、中断配置和临界代码段
    • 1.中断配置
    • 2.临界代码段的作用
  • 五、任务(相当于ROS的节点)
    • 0.任务与协程
    • 1.多任务的理解
    • 2.任务调度器的理解
    • 3.任务优先级与任务数量
    • 4.任务的状态
    • 5.任务创建\删除、挂起\恢复的API函数
    • 6.任务函数
    • 7.任务控制块
  • 六、FreeRTOS 列表和列表项的定义、初始化、插入、删除、遍历
    • 1.列表和列表项定义
    • 2.列表的初始化
    • 3.列表项初始化
    • 4.列表项插入
    • 5.列表项的删除
    • 6.列表的遍历
    • 7.列表项的插入和删除
  • 七、FreeRTOS内核控制函数
  • 八、FreeRTOS任务调度辅助API函数
  • 九、FreeRTOS 时间管理
  • 十、FreeRTOS 队列通讯(队列可以理解成“全局变量”与“话题数据”)
    • 0.通讯机制
    • 1.出队定义
    • 2.出队阻塞定义
    • 3.入队定义
    • 4.入队堵塞定义
    • 5.队列使用过程
    • 6.创建队列函数
    • 7.队列初始化函数
    • 8.向队列发送消息
    • 9.从队列里面读取消息
  • 十一、FreeRTOS信号量
    • 1.二值信号量(任务同步的应用场景)
    • 2.计数型信号量(资源访问的应用场景)
    • 3.互斥信号量
    • 4.递归互斥信号量
    • 技巧
  • 十二、FreeRTOS 软件定时器
    • 1.创建软件定时器
    • 2.复位软件定时器
    • 3.开启软件定时器
    • 4.停止软件定时器
  • 十三、FreeRTOS 事件标志组
    • 1.创建事件标志组
    • 2.设置事件位
    • 3.获取事件标志组值
    • 4.等待指定的事件位
  • 十四、FreeRTOS 任务通知
    • 1.发送任务函数
    • 2.获取任务通知
  • 十五、FreeRTOS 低功耗 Tickless 模式
  • 十六、FreeRTOS 空闲任务
  • 十七、FreeRTOS 内存管理
  • 注意
    • freertos的话题收发机制
  • 总结
  • 学习freertos的参考资料


前言

认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长!

本文先对freeRTOS系统平台的使用做个简单的介绍,具体内容后续再更,其他模块可以参考去我其他文章


提示:以下是本篇文章正文内容

一、实时操作系统RTOS的价值分析

1.RTOS的市场

近些年,MCU产品性价比不断提升,尤其是32位MCU,其运行主频已达百兆级甚至高达1GHz,功能越来越强,资源配置也越来越丰富,编程也越来越复杂,需要RTOS来配置管理基础资源和维护管理产品。RTOS可以应用到8位/16位/32位MCU产品上,但32位MCU产品将会是主流。MCU产品双核多核产品增多,产品功能的复杂度越来越高。而MCU与CPU产品不再是泾渭分明,异构集成将是一个新的产品发展特点。MCU产品将会沿着摩尔定律之路继续前行,会不断涌现出新的产品,RTOS的路越来越宽广。
.
.

2.前后台系统和实时系统的区别

一般嵌入式系统分为两种:前后台系统和实时系统

1.前后台系统
早期嵌入式开发没有嵌入式操作系统的概念 ,直接操作裸机,在裸机上写程序,比如用51单片机基本就没有操作系统的概念。通常把程序分为两部分:前台系统 和 后台系统。基本就没有操作系统的概念。中断服务程序用于处理系统的异步事件,也就是前台系统。前台是中断级(ISR),后台是任务级(tsak)
【系统开发的了解】freeRTOS系统平台的使用_第1张图片

2.RTOS 系统

操作系统一般可分为:通用操作系统(OS)和实时操作系统(RTOS)两大类。而实时操作系统(RTOS)根据其运行的处理器不同可以进一步分为:CPU RTOS和MCU RTOS两类。

Windows是面向消费者的,RTOS是面向开发者的;Windows有着统一的处理器,**在一台电脑上编译好的程序可以很方便地在另一台计算机上运行,RTOS使用的是不同架构的处理器或微控制器,不能跨处理器或硬件运行,需要进行相应地移植。**RTOS现阶段难以像Windows一样形成大一统的格局,差异化的应用需求仍然需要差异化的RTOS。

实时系统的任务切换机制
RTOS的内核负责管理所有的任务,内核决定了运行哪个任务,何时停止当前任务切换到其他任务,这个是内核的多任务管理能力。多任务管理给人的感觉就好像芯片有多个CPU,多任务管理实现了CPU资源的最大化利用,多任务管理有助于实现程序的模块化开发,能够实现复杂的实时应用。实时操作系统一般提供抢占式调度机制,重要的高优先级任务可以剥夺低优先级任务对CPU的使用权;同时,任务在等待使用资源时,RTOS可以将其CPU的使用权释放给其他就绪的任务,从而使得系统的总体响应速度更快。

【系统开发的了解】freeRTOS系统平台的使用_第2张图片

实现过程:系统先针对不同的任务(TASK)划分不同的优先级(每个任务都是一个死循环),还有MCU自带的一个中断服务程序(ISR),再根据任务调度器对每个任务进行调度,分配CPU资源,注意的是中断的优先级是最高的,能打断所有的任务。每个任务准备就绪好就可以通过任务调度器向CPU申请资源,RTOS系统运行的永远是最高优先级的准备就绪的任务

实时操作系统的两个误区
1、用了实时系统后,系统响应速度一定更快。不一定。因为实时操作系统本身引入了执行开销,所以对于小型应用来说,有RTOS的性能也许不如无操作系统的情况。实时操作系统的优势最能体现在中大型系统中,当任务间存在复杂的耦合和依赖关系,并且应用程序经常要长时间等待外部资源时。
2、用实时操作系统就可以保证实时性。不一定。相对来说,使用实时系统可以改善系统的实时性。但是实时操作系统只是作为工具存在的,如果需要提供实时性保障,还需要使用实时系统理论对任务的可调度性和响应时间进行分析,才可以得到科学、系统的响应性保障。

3.RTOS介绍

RTOS是一种系统软件,可以为应用程序(如机器人或者无人驾驶的导航应用)提供服务并管理微控制器硬件资源,这些硬件资源包括内存、外设和中断等。

实时操作系统的主要目的
给需要执行的各种任务分配处理时间。在实时操作系统中,我们可以把要实现的功能划分为多个任务,每个任务负责实现其中的一部分,每个任务都是一个很简单的程序,通常是一个死循环。

RTOS全称为:Real Time OS,就是实时操作系统,强调的是:实时性。实时操作系统(Real-time Operating System, RTOS)是针对有实时性要求的应用而设计的操作系统。
实时操作系统又分为硬实时和软实时。
1、硬实时要求在规定的时间内必须完成操作 ,硬实时系统不允许超时。
2、在软实时里面处理过程超时的后果就没有那么严格。

4.RTOS操作系统类型

RTOS操作系统类型:FreeRTOS,UCOS,RTX,RT-Thread,DJYOS等。
其中除了FreeRTOS(针对MCU的) RTEMS和RTLinux(针对CPU的)是免费的之外,其余RTOS都是需要商业授权的。uCos II和FreeRTOS是平时接触比较多的RTOS,相关资料比较多。而VxWorks是安全性公认最佳的,用于航空航天、轨道交通和卫星的应用。如果系统中需要使用复杂的文件、数据库、网络等功能,那么以Linux为基础的RTLinux是比较好的选择;但是如果系统对实时性和确定性的要求非常高,那么可以使用较为简单的RTOS(如 uCosII),再根据需要开发通信协议或者软件包。总体上来说,操作系统的复杂性是与应用软件的复杂性一致的。同时,功能上更复杂的RTOS对硬件系统资源的需求也会更高。
【系统开发的了解】freeRTOS系统平台的使用_第3张图片
Freertos和ucosI\ucosII的对比
从文件数量上,freertos的文件数量要比ucosI\ucosII小的多。但是ucos的中文学习资料比freertos丰富,上手容易,freertos的资料大都是英文的,但是开发也有官网支持文档。Freertos是免费的ucoss是收费的,所以大部分开发时,厂商哦都会选择freetros,其他的实时操作系统(RTOS)大都时基于freertos进行开发的

5. RTOS的功能(这就是一个系统平台最基本的要求)

一般的RTOS会提供以下全部或部分功能:
1、基于静态优先级(fixed-priority)的抢占式(preemptive)任务调度;
2、进程间通信(基于消息,消息邮箱,管道);【有利于分模块】
3、基于信号量(semaphore)的进程间同步;
4、任务的创建、暂停、删除;
5、资源访问控制(并发控制与防止互锁);
6、临界区(critical section)控制;
7、驱动程序的管理与接口;
8、MMU内存管理、内存动态申请与分配;
9、其他功能:如GUI用户界面和TCP/IP相关功能。
.
.

二、FreeRTOS的文件移植步骤和文件架构

FreeRTOS的源文件说明(记住每个文件夹功能)

(1)demo文件夹

FreeRTOS提供了很多芯片的例程,我们一直会参考这些例程,这些例程放在了改文件夹下

(2)license文件夹

关于我们用freeRTOS做产品的许可证说明

(3)Source文件夹

存放了freeRTOS的源代码
–include文件夹存放的时头文件(移植的时候需要);
–以.C后缀名结束的文件时FreeRTOS的源码文件,freeRTOS就是用C语言写的文件系统,freeRTOS系统就是一个纯软件系统;
–portable文件夹里面是freeRTOS系统软件和硬件连接的桥梁,不同编译器,不同MCU硬件,桥梁是不一样的(都是要移植对应的东西)
注意学了FreeRTOS就不用学习FreeRTOS plus了

注意

Freertos的部署是要依赖具体的芯片的,我们最好使用已经有移植成功案例的硬件芯片,这样可以省下一大部分移植freertos的系统平台工作!要记住我们的目的是用freertos而不是开发移植freertos

三、FreeRTOS配置与剪裁

通过条件编译进行系统配置,达到自己想要的功能。配置文件完成freertos的剪裁和配置
参照官网的教程进行配置,配置好了才能够使用。

四、中断配置和临界代码段

1.中断配置

分任务和中断配置优先级,需要先了解MCU架构中有关中断的相关知识,中断由硬件产生,当中断产生后,CPU会从当前中断流程跳转到其他地方进行继续工作,这个管理的过程通过中断管理嵌套向量中断控制器(NVIC)进行控制。

2.临界代码段的作用

临界代码段也叫做临界区,是指那些必须完整运行,不能被中断和任务调度打断的代码段,如外设的初始化需要严格的时序启动等等

Freertos进入临界段的时候需要先关闭中断,当处理完成临界段代码后再打开中断
【系统开发的了解】freeRTOS系统平台的使用_第4张图片

五、任务(相当于ROS的节点)

0.任务与协程

协程是为资源很小的MCU准备的,可以这么理解,协程就是一个轻量化的任务。协程和任务是独立的,不可以相互通讯,且使用的API是不一样的。因此Freertos已经不打算更新协程了。

1.多任务的理解

(多核心多线程)操作系统允许多个任务同时运行,这个称为多任务。实际上一个处理器核心再同一时刻仅仅能处理一个任务,因此多任务实时的安全的运行需要临界段保护和优先级机制。如果采用前后端系统就会造成任务堵塞,实时性较差

2.任务调度器的理解

操作系统中的任务调度器的任务就是决定再某一时刻处理器核心运行那个任务,RTOS的任务调度器切换每个任务的速度非常快,这样就虚拟出一个多任务的效果,ROTS的多任务机制是虚拟的,真正的多任务机制是由硬件决定的

实时操作系统各个任务之间的切换由任务调度器负责。任务调度器决定了再某一时刻运行哪一个任务。有的任务调度器的切换机制是给每个任务分配同样的时间,有的任务调度器的切换机制是按照优先级,优先执行优先级高的,同时保证在临界段的代码不会被打断。

任务调度器的工作方式有很多种,其中unix对每个任务分配的时间是一致的,时间到了不管有没有完成任务都会堵塞进行下一个任务,单数RTOS会对每个任务需要的响应时间进行一个预测,分配足够的时间,再根据任务的优先级进行调度。

任务调度逻辑
每个子任务中的延时是不会堵塞其他子任务的,每个子任务中的延时会把该任务(1)挂起,延时结束才会重新运行该子任务,直到该子任务运行结束,(2)删除任务,或者有更高优先级打断该子任务。该子任务才会结束。一个(3)时间片内一直在运行一个任务,当时间片用完后就切换到下一个任务运行。所以一般每个子任务中运行的时间都不太长,特别是最高优先级的子任务。但是在编程的时候不用这么想,想着多个任务是并行的就行,同时运行多个任务的main函数。

任务调度器的实现
任务调度器是通过任务堆栈实现的,任务堆栈就像一个section_list,不过不仅仅是一个顺序队列,而是一个优先级队列,任务堆栈确保当一个任务开始执行的时候其上下文环境(寄存器值等)和上一个任务退出的时候相同,下次直接从断点开始继续执行

3.任务优先级与任务数量

任务优先级可以重复但是不可以超过32,因此任务的数量是可以无限的!
任务调度器是通过任务堆栈实现的,任务堆栈就像一个section_list,不过不仅仅是一个顺序队列,而是一个优先级队列,任务堆栈确保当一个任务开始执行的时候其上下文环境(寄存器值等)和上一个任务退出的时候相同,下次直接从断点开始继续执行

4.任务的状态

1、运行态
2、就绪态
3、阻塞态
4、挂起态
【系统开发的了解】freeRTOS系统平台的使用_第5张图片
任务切换是任务管理机制的核心,什么时候切换等等对于操作系统很重要,让多任务有并行运行的效果,知道时间片是该任务的执行时间就好,时间片是可以自己设置的,最好不要太长,一个时间片一般是一个时钟节拍的长度。

5.任务创建\删除、挂起\恢复的API函数

创建\删除:
先设置好xTaskCreate()的6个输入变量,再调用xTaskCreate()函数就能创建一个任务了;调用vTaskDelete()这个函数就能删除该任务了,注意一点,可以在一个任务中创建其他任务,用于创建任务的任务不是死循环并且结束的时候删除自身这个任务。调用函数vTaskStartScheduler()开启FreeRTOS 的任务调度器。
【系统开发的了解】freeRTOS系统平台的使用_第6张图片
挂起\恢复:
void vTaskSuspend( TaskHandle_t xTaskToSuspend)函数挂起,
void vTaskResume( TaskHandle_t xTaskToResume) 函数恢复。在任务中调用。
BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume) 函数恢复。在中断中调用。
中断归中断,任务归任务,不要混淆。
【系统开发的了解】freeRTOS系统平台的使用_第7张图片

6.任务函数

任务函数是一个大循环,不可以让代码跑出循环而终止任务函数。终止任务函数的唯一方法是把任务delete掉。任务函数就像一个独立的main函数
【系统开发的了解】freeRTOS系统平台的使用_第8张图片
【系统开发的了解】freeRTOS系统平台的使用_第9张图片

7.任务控制块

用于储存任务的一些属性
【系统开发的了解】freeRTOS系统平台的使用_第10张图片

六、FreeRTOS 列表和列表项的定义、初始化、插入、删除、遍历

“把列表看成变量、列表项看成数组”

1.列表和列表项定义

列表和列表项是 FreeRTOS 的一个数据结构,列表被用来跟踪 FreeRTOS中的任务,列表项就是存放在列表中的项目。与列表相关的全部东西都在文件 list.c 和 list.h 中。在 list.h 中定义了一个叫 List_t 的结构体。理解列表和列表项的关系类似于果实和树干的关系,列表比喻成果实,列表项比喻成树干,管理果的,列表和列表项的定义是创建一个结构体实现的

2.列表的初始化

vListInitialise( List_t * const pxList ) 

3.列表项初始化

vListInitialiseItem( ListItem_t * const pxItem )

4.列表项插入

vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem )
vListInsertEnd (List_t * const pxList, ListItem_t * const pxNewListItem)

5.列表项的删除

UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )

6.列表的遍历

listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList )

7.列表项的插入和删除

在这里插入图片描述

七、FreeRTOS内核控制函数

【系统开发的了解】freeRTOS系统平台的使用_第11张图片

八、FreeRTOS任务调度辅助API函数

(一般是调试的时候用)
【系统开发的了解】freeRTOS系统平台的使用_第12张图片

九、FreeRTOS 时间管理

解释任务延时函数的实现过程,在一个任务函数中使用延时函数对这个任务延时,当执行延时函数的时候就会进行任务切换,并且此任务就会进入阻塞态,直到延时完成,任务重新进入就绪态。
FreeRTOS 延时函数的内部实现不用管,知道怎么用就行。
FreeRTOS 延时函数:vTaskDelay()/TaskDelayUntil()
函数 prvAddCurrentTaskToDelayedList()用于将当前任务添加到等待列表中

不管是什么系统,运行都需要有个系统时钟节拍,xTickCount 就是 FreeRTOS 的系统时钟节拍计数器。每个滴答定时器中断中 xTickCount 就会加一

十、FreeRTOS 队列通讯(队列可以理解成“全局变量”与“话题数据”)

类似于话题通讯,一个系统中不同模块的通讯,但是扇出的速度要比扇入的速度要快

freertos的队列通信,在中断要在ISR的API,不然发送的机制不支持

1)创建Queue
xQueueHandle test = xQueueCreate(10,sizeof(uint32_t));
2)发送msg
unsigned long msg3 = 88;
xQueueSendFromISR(test, &msg3, 0);
3)接收并判断msg
unsigned long msg4;
xQueueReceive(test, &msg4, 0);
if (msg4 == 88)
{
ESP_LOGW(TAG, “receive scuess”);
break;
}

.
.

0.通讯机制

任务与任务之间、任务与中断之间可以使用任务通知、消息队列(话题)、二值信号量、数值型信号量、递归互斥信号量、互斥信号量进行进程间的通讯与同步

一个任务或者中断服务需要和另外一个任务进行“沟通交流”,这个“沟通交流”的过程其实就是消息传递的过程。

在没有操作系统的时候两个应用程序进行消息传递一般使用全局变量的方式
FreeRTOS 对此提供了一个叫做“队列”的机制来完成任务与任务、任务与中断之间的消息传递,可以把“队列”理解成为全局变量。
队列不是属于某个特别指定的任务的,任何任务都可以向队列中发送消息,或者从队列中提取消息

1.出队定义

当任务尝试从一个队列中读取消息

2.出队阻塞定义

任务从一个队列中读取消息等待的时长。是由这个阻塞时间决定的,这个阻塞时间单位是时钟节拍数

3.入队定义

入队说的是向队列中发送消息,将消息加入到队列中。

4.入队堵塞定义

当一个任务向队列发送消息的话也可以设置阻塞时间。

5.队列使用过程

创建队列->队列初始化->向队列发送第一个消息->向队列发送第二个消息->从队列里面读取消息

6.创建队列函数

1、xQueueCreate() 
2、xQueueCreateStatic() 
3、xQueueGenericCreate() 
4、xQueueGenericCreateStatic()

7.队列初始化函数

1、prvInitialiseNewQueue()

8.向队列发送消息

【系统开发的了解】freeRTOS系统平台的使用_第13张图片

9.从队列里面读取消息

【系统开发的了解】freeRTOS系统平台的使用_第14张图片
参考链接
https://www.wenjiangs.com/doc/uoiwhsaj

十一、FreeRTOS信号量

信号量一般用来进行资源管理和任务同步。FreeRTOS中信号量又分为二值信号量、计数型信号量、互斥信号量和递归互斥信号量。不同的信号量其应用场景不同,但有些应用场景是可以互换着使用的。信号量用于控制共享资源访问的场景相当于一个上锁机制,代码只有获得了这个锁的钥匙 才能够执行。
1、共享资源的理解:某个停车场有100 个停车位,这 100 个停车位大家都可以用,对于大家来说这 100 个停车位就是共享资源。
2、信号量的理解:当前停车数量就是一个信号量
3、信号量值的理解:具体的停车数量就是这个信号量值

1.二值信号量(任务同步的应用场景)

使用公共电话,我们知道一次只能一个人使用电话,这个时候公共电话就只可能有两个状态:使用或未使用,如果用电话的这两个状态作为信号量的话,那么这个就是二值信号量。
在编写中断服务函数的时候我们都知道一定要快进快出,中断服务函数里面不能放太多的代码,否则的话会影响的中断的实时性。裸机编写中断服务函数的时候一般都只是在中断服务函数中打个标记,然后在其他的地方根据标记来做具体的处理过程。在使用 RTOS 系统的时候我们就可以借助信号量完成此功能,当中断发生的时候就释放信号量,中断服务函数不做具体的处理。具体的处理过程做成一个任务,这个任务会获取信号量,如果获取到信号量就说明中断发生了,那么就开始完成相应的处理,这样做的好处就是中断执行时间非常短。任务优先级确保了外设能够得到及时的处理,这样做相当于推迟了中断处理过程。

创建二值信号量
【系统开发的了解】freeRTOS系统平台的使用_第15张图片
释放信号量
在这里插入图片描述
获取信号量
在这里插入图片描述

2.计数型信号量(资源访问的应用场景)

当有车开出停车场的时候停车数量就会减一,也就是说信号量减一,此时你就可以把车停进去了,你把车停进去以后停车数量就会加一,也就是信号量加一。二值信号量其实就是一个只有一个队列项的队列,这个特殊的队列要么是满的,要么是空
的。只需要知道这个队列是满的还是空的。可以利用这个机制来完成任务与中断之间的同步。
一般用于时间计数、和资源管理两个方面

创建计数型信号量
在这里插入图片描述
获取信号量
在这里插入图片描述
释放互斥信号量
在这里插入图片描述

3.互斥信号量

互斥信号量也有优先级继承的机制,递归互斥信号量不能用在中断服务函数中

创建互斥信号量
在这里插入图片描述
获取信号量
在这里插入图片描述
释放互斥信号量
在这里插入图片描述

4.递归互斥信号量

递归互斥信号量可以看作是一个特殊的互斥信号量,已经获取了互斥信号量的任务就不能再次获取这个互斥信号量,但是递归互斥信号量不同,已经获取了递归互斥信号量的任务可以再次获取这个递归互斥信号量,而且次数不限!
互斥信号量也有优先级继承的机制,递归互斥信号量不能用在中断服务函数中
创建互斥信号量
在这里插入图片描述
释放递归互斥信号量

xSemaphoreGiveRecursive( xMutex ) 

获取递归互斥信号量

xSemaphoreTakeRecursive( xMutex, xBlockTime ) 

技巧

二值信号量可以理解成“中断中的标志位”
计数信号量可以理解成“计数自增变量”
互斥信号量可以理解成“带有优先级的二值信号,且这个二值信号被多个任务获取”
递归互斥信号量可以理解成“任务可以多次获取的互斥信号量”

十二、FreeRTOS 软件定时器

MCU 自带的定时器属于硬件定时器,当 MCU 的硬件定时器不够的时候就可以考虑使用 FreeRTOS 的软件定时器。FreeRTOS 也提供了定时器功能,软件定时器的精度肯定没有硬件定时器那么高,但是对于普通的精度要求不高的周期性处理的任务来说够了。

**软件定时器允许设置一段时间,当设置的时间到达之后就执行指定的功能函数,被定时器调用的这个功能函数叫做定时器的回调函数。**回调函数的两次执行间隔叫做定时器的定时周期,简而言之,当定时器的定时周期到了以后就会执行回调函数。

软件定时器的回调函数是在定时器服务任务中执行的,所以一定不能在回调函数中调用任何会阻塞任务的 API 函数!比如,定时器回调函数中千万不能调用 vTaskDelay()、vTaskDelayUnti(),还有一些访问队列或者信号量的非零阻塞时间的 API 函数也不能调用。

软件定时器分两种

单次定时器和周期定时器.单次定时器当定时时间到了以后就会执行一次回调函数,然后定时器就会停止运行;相反的,周期定时器一旦启动以后就会在执行完回调函数以后自动的重新启动

1.创建软件定时器

在这里插入图片描述

2.复位软件定时器

在这里插入图片描述

3.开启软件定时器

在这里插入图片描述

4.停止软件定时器

在这里插入图片描述

十三、FreeRTOS 事件标志组

可以理解成“一个中断标志位(信号量)的集合,易于管理”
1、事件位(标志位):类似于一个标志位变量
2、事件组(标志组):一个事件组就是一组的事件位,事件组中的事件位通过位编号来访问。当 configUSE_16_BIT_TICKS 为 1 的时候事件标志组可以存储 8 个事件位,当 configUSE_16_BIT_TICKS 为 0 的时候事件标志组存储 24 个事件位,类似于一个标志位数组

1.创建事件标志组

在这里插入图片描述

2.设置事件位

在这里插入图片描述

3.获取事件标志组值

在这里插入图片描述

4.等待指定的事件位

EventBits_t xEventGroupWaitBits()

十四、FreeRTOS 任务通知

可以使用任务通知来代替信号量、消息队列、事件标志组等这些东西

1.发送任务函数

【系统开发的了解】freeRTOS系统平台的使用_第16张图片

2.获取任务通知

【系统开发的了解】freeRTOS系统平台的使用_第17张图片

十五、FreeRTOS 低功耗 Tickless 模式

【系统开发的了解】freeRTOS系统平台的使用_第18张图片

十六、FreeRTOS 空闲任务

空闲任务是处理器空闲的时候去运行的一个任务,当系统中没有其他就绪任务的时候空闲任务就会开始运行,空闲任务最重要的作用就是让处理器在无事可做的时候找点事做,防止处理器无聊,因此,空闲任务的优先级肯定是最低的。

当 FreeRTOS 的调度器启动以后就会自动的创建一个空闲任务。
钩子函数类似回调函数。钩子函数是一个可选功能,可以通过宏定义来选择使用哪个钩子函数
【系统开发的了解】freeRTOS系统平台的使用_第19张图片

十七、FreeRTOS 内存管理

1 内存管理简介
2 内存碎片
3 heap_1 内存分配方法
4 heap_2 内存分配方法
5 heap_3 内存分配方法
6 heap_4 内存分配方法
7 heap_5 内存分配方法
8 内存管理实验

freertos系统平台会为每一个线程分配固定大小的堆栈,其中堆(stack)会自动排序保证每一个变量内存都是向下压实的。栈(heap)是碎片化的,用多少申请多少用完就释放。

一般来说,小数据的变量定义用堆(stack),大数据和变长度的对象和数据流用栈(heap)
考虑到系统平台的运行效率,堆(stack)会根据对象的作用域自动申请和释放内存,但是就是空间比较小;栈(heap)需要用户自己申请和释放内存,但就是空间比较大。

注意:
1、先定义指针,再用指针molloc内存,在释放内存时,要把对应的指针置为null
2、自己定义的数据结构一般用molloc和vportfree,只有对象才可以使用new和delete
【系统开发的了解】freeRTOS系统平台的使用_第20张图片
https://blog.csdn.net/weixin_43952192/article/details/108189300


注意

freertos的话题收发机制

1、在一个task中只能发一个任务话题,若发多个任务话题最后的话题会把之前的话题冲掉,导致之前的话题数据丢失(因为单片机是单核单进程的)

.
.

总结

接触各种开发系统平台的使用–ROS、cyber、freertos、navos)[开发导航系统必须要系统平台的支持

就算是做导航算法的开发,系统平台架构和使用的基本方法还是要懂的!

1.任务就是一个功能包,队列就是话题!把任务task看成一个节点,把软件定时器看成一个定时器。任务系列:包括任务创建、调度、删除、挂起、恢复、优先级六个方面
5、注意每个任务都是一个死循环,都要有一个while

2.列表和列表项系列:列表和列表项的定义、初始化、插入、删除、遍历五个方面
列表理解成普通变量、列表项理解成数组

3.队列系列:包括队列创建、初始化、发送消息到队列、读取队列的消息。队列可以理解成“全局变量”,4、freertos系统支持全局变量,但是全局变量不安全,优化的时候可以用消息队列代

4.在没有操作系统的时候,每个程序段进程用全局变量来传递消息,但是如果在操作系统中用全局变量来传递消息就会涉及到“资源管理”的问题,所以在实时操作系统中尽量用队列来代替全局变量。

5.多任务访问全局变量会带来共享资源管理问题,消息队列最终是用的全局变量!但是消息队列对这个全局变量做了保护,重点就是资源管理的保护!
队列比全局变量更具有针对性,但是不是特别严谨的场合,也可以用一下全局变量

6.信号量系列:包括各种信号量的创建、释放和获取
二值信号量可以理解成“中断中的标志位”
计数信号量可以理解成“计数自增变量”
互斥信号量可以理解成“带有优先级的二值信号,且这个二值信号被多个任务获取”
递归互斥信号量可以理解成“任务可以多次获取的互斥信号量”

7.事件标志组系列:包括事件标志组的创建、设置、获取
可以理解成“一个中断标志位(信号量)的集合,易于管理”

8.任务通知系列:包括任务通知发送、任务通知获取
可以使用任务通知来代替信号量、消息队列、事件标志组等这些东西

9.软件定时器系列:软件定时器允许设置一段时间,当设置的时间到达之后就执行指定的功能函数
注意区分硬件定时器和软件定时器的区别

10.临界段保护
不可被打断的程序要用临界区保护,并且临界区不能有任务切换的延时函数堵塞
重要的设备初始化或者串口等数据的收发要加入临界段,保证在临界段内没有中断和任务打断,优先执行。还有一点是,临界段中不能有引起任务调度的api函数,特别注意的是正点原子中的delay_ms()是会引起系统调度的,而,delay_xms()不会引起系统调度。

11.时间管理的系统延时函数是非堵塞的,但是中断函数中要避免使用时延函数,更不能使用系统时延函数。

相对延时:vTaskDelay();
绝对延时:vTaskDelayUntil(); 

系统使用这个定时器来完成时钟节拍的实现,是在滴答定时器的中断中实现的,调用了xTaskIncrementTick()这个函数进行freertos的时间管理
把无系统的代码段移植到实时操作系统的时候,不能把delayms()和系统的延时函数混用,不然会出现很奇怪的现象(系统跳读导致的)
调度器没启动前是不能调用系统延时的

12.一般的框架

int main(void)
{
/*
在启动调度前,为了防止初始化 STM32 外设时有中断服务程序执行,这里禁止全局中断(除了 NMI 和 HardFault)。
这样做的好处是:
1. 防止执行的中断服务程序中有 FreeRTOS 的 API 函数。
2. 保证系统正常启动,不受别的中断影响。
3. 关于是否关闭全局中断,大家根据自己的实际情况设置即可。
在移植文件 port.c 中的函数 prvStartFirstTask 中会重新开启全局中断。通过指令 cpsie i 开启,__set_PRIMASK(1)
和 cpsie i 是等效的。*/
    __set_PRIMASK(1);/* 硬件初始化 */
    bsp_Init();/* 创建任务 */
    AppTaskCreate();/* 创建任务通信机制 */
    AppObjCreate();/* 启动调度,开始执行任务 */
    vTaskStartScheduler();/*
如果系统正常启动是不会运行到这里的,运行到这里极有可能是用于定时器任务或者空闲任务的
heap 空间不足造成创建失败,此要加大 FreeRTOSConfig.h 文件中定义的 heap 大小:
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 17 * 1024 ) )*/
        while(1);
}

学习freertos的参考资料

FreeRTOS系统平台的相关使用
https://www.wenjiangs.com/doc/uoiwhsaj

(1)freertos的官网www.freertos.org
(2)freertos的官方指导手册(英文版)
161204_Mastering_the_FreeRTOS_Real_Time_Kernel-A_Hands-On_Tutorial_Guide

(3) freertos的官方API函数参考手册(英文版)
FreeRTOS_Reference_Manual_V9.0.0

(4) freertos正点原子的开发环境
1)STM32F429 FreeRTOS开发手册_V1.2
2)FreeRTOS实时内核使用指南-中文
3)RTOS低功耗设计原理及实现_TicklessMode(FreeRTOS的实现)

(5)Cortex-M内核架构的相关知识(用于理解任务切换的过程)
(1)Cortex M3权威指南(中文)
(2)Cortex M3与M4权威指南

你可能感兴趣的:(#,Freertos系统平台开发,freertos)