IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> FreeRTOS学习简易笔记 -> 正文阅读

[嵌入式]FreeRTOS学习简易笔记

?第1章?FreeRTOS引入及堆栈

1.1 FreeRTOS学习三阶段

1)、理解RTOS总原理,会移植官方Demo,会使用。

2)、知道内部机制,源码还没看!

3)、知道内部实现,能看懂源码!并能轻松移植任何单片机。

1.2 RTOS操作系统 与 裸机开发(前后系统)区别

RTOS:根据任务需要 人为的为任务切换CPU资源,有的任务可能不能完整运行完,并对运行环境进行保护管理,相当虚拟了多个CPU。

裸机开发(前后系统):每个任务只能顺序获得CPU资源。一个任务运行一遍了才轮到下个任务。

1.3 中断服务函数与调用函数的区别

中断服务函数调用函数
硬件触发软件触发
何时发生可能不可预料,需要实现设定发生条件何时发生可预料,在需要的地方调用
入口地址相对固定入口地址可随意设置
不能传参不能传参
没有返回值没有返回值
在执行调度之前,都保存现场

1.4 堆栈

栈(通常说堆栈)
相同点一种数据结构,被管理起来的内存
管理方式不同程序员手工控制分配/释放编译器自动管理
分配方式不同动态分配2种分配方式:
静态分配是编译器完成的,比如局部变量的分配;
动态分配由alloca函数分配,编译器进行释放;
空间大小不同没有限制有一定空间大小限制
产生碎片不同频繁分配/释放会造成内存空间的不连续因为栈是先进后出的队列,所以不会存在碎片问题
分配效率不同堆是分配一块内存,按照一定的算法实现栈是分配专门的寄存器,所以栈的效率比较高
生长方向不同向上生长,向着内存地址增加的方向增长;向下生长,向着内存地址减小的方向增长;
内存泄漏溢出
作用不同程序员使用的大块空间保护运行环境现场(中断、函数调用、任务切换)
数组
数组是全局变量被分配在静态存储区
数组是局部变量被分配在栈上
数组是动态分配被分配在堆上

1.5?中断服务函数、调用函数、操作系统任务 对栈操作区别

中断服务函数调用函数操作系统任务
1、硬件保存一部寄存器到栈;(例如M3, 会有些约定,R0~2用来运算)
2、软件保存用到的部分寄存器或临时变量到栈;
1、软件保存用到的部分寄存器或临时变量;有些寄存器不用保存到栈;(例如M3, 会有些约定,R0~2用来传参,所以不用保存)1,要软件全部保存寄存器到栈;

1.6 FreeRTOS与STM32启动文件 中的堆栈区别

?

STM32启动文件FreeRTOS
来源用户用malloc函数(或其他分配函数)分配的内存。若用户没有用分配函数分配空间,则大小可设置为0。要注意调用的第三方库或函数是否使用,例如USB、SD、网络等。FreeRTOS在配置文件中定义了一个总堆大小,其实就是一个数组,然后再该数组上为各个任务分配栈,剩下的空间用作堆。用户用分配函数分配内存。
作用在大数据存储中,有时候我们需要在一定的时间内需要大存储空间,由于内存有限,希望该内存能被重复利用。堆正好可以满足这一灵活需求。堆可以用作局部临时存储,也可以静态存储。而我们通常在内存中定义的静态或全局的数组是不能释放重复利用的,这样在内存需求量大的情况下内存就无法满足了!
管理方式用户分配/释放
管理函数种类标准C库内存管理函数;
自定义内存管理函数;
FreeRTOS中的内存管理函数;
标准C库内存管理函数;
自定义内存管理函数;

第2章 任务

2.1 什么是任务?

任务: 运行的函数
句柄: 结构体指针

2.2 创建任务

2.2.1 创建任务所需参数

TCB结构体: 任务控制块。主要有函数指针,SP位置,优先级,参数等。

任务句柄(TaskHandle_t ): 就是TCB结构体指针。

BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, //函数指针指向任务函数(一个死循环函数)
                        const char * const pcName, //任务的名字,FreeRTOS内部不使用它,仅仅起调试作用。长度为:configMAX_TASK_NAME_LEN
                        const configSTACK_DEPTH_TYPE usStackDepth, //任务栈大小,每个任务都有自己的栈。单位u32,输入10表示是40个字节
                        void * const pvParameters, //调用任务函数时传入的参数
                        UBaseType_t uxPriority, //优先级
                        TaskHandle_t * const pxCreatedTask ); //传出的任务句柄, 以后使用它来操作这个任务

2.2.2?创建任务时参数去向

1)、分配了TCB机构体,将任务名、任务优先级赋给TCB结构体。

2)、分配了栈。在栈里写入了函数地址、参数指针。

2.3 任务调度机制

2.3.1 任务优先级

  • 高优先级的任务,优先执行,可抢占低优先级任务

  • 高优先级的任务不停止,低优先级任务永远无法执行

  • 同等优先级任务,轮流执行(或叫时间片轮转)

优先级的取值范围优先级越高任务运行顺序
0~(configMAX_PRIORITIES – 1)数值越大高优先级先运行;同优先级,可运行任务,轮流执行
调度器方法configMAX_PRIORITIES? ? ? ? ? ? ? ? ?大小方法使能
使用C语言实现时对所有的架构都是同样的代码没有限制,但取值越大越浪费 内存 和 时间。configUSE_PORT_OPTIMISED_TASK_SELECTION被定义为 0
使用汇编实现时针对架构相关的优化。取值不能超过 32configUSE_PORT_OPTIMISED_TASK_SELECTION被定义为 1

优先级有关配置:

配置项说明配置项配置方式
ABCDE
---------------------
常用很少用很少用很少用几乎不用
是否 可抢占configUSE_PREEMPTION11110
是否 时间片轮转configUSE_TIME_SLICING1100x
是否 空闲任务让步configIDLE_SHOULD_YIELD1010x
关闭Tick中断来实现省电configUSE_TICKLESS_IDLE00000

2.3.2 任务状态

运行(Running): 任务正在执行,此时占用处理器。例如,汽车正在行驶。

就绪(Ready): 随时可以运行的任务,但还没轮到它。新创建的任务为就绪态。

阻塞(Blocked): 等待某个事件(时间延时,事件等)。例如,汽车等待绿灯。

暂停(Suspended)(挂起): 不等待,直接去休息了。

2.3.3 怎么管理

FreeRTOS通过三种链表(就绪任务链表、阻塞任务链表、暂停任务链表)来管理任务。就绪任务链表 有多少个优先级就有多少个?就绪任务链表;阻塞任务链表、暂停任务链表 各1个。

1、从高优先级?就绪任务链表?向低优先级?就绪任务链表?中找到就绪任务,获取任务句柄给到运行指针, 运行它。

2、若有同级任务,排队轮流执行,链表前面的先运行,运行1个tick后排到队伍后面。

3、若某个任务阻塞,则将该任务从?就绪任务链表移到?阻塞任务链表 中;阻塞解除,则反之。

4、若某个任务暂停,则将该任务从?就绪任务链表移到?暂停任务链表 中;解除暂停,则反之。

2.3.4 怎么进行调度

TICK定时中断,在Tick中断函数中会进行任务切换(链表种取出合适的任务运行)。每次中断会检查有哪些延时任务到期,将其从延时任务列表里移除并加入到就绪列表里。如果就绪任务的优先级都相同,如果开启时间片轮询,就会每个tick执行一个任务,轮询执行。

Tick中断做了什么:?1)、找到最高优先级的就绪任务
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?2)、保存当前任务的信息,并将其插入就绪任务链表末端
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?3)、恢复新的任务

第3章 同步与互斥

3.1 同步与互斥的概念

同步: 任务之间的依赖,比如A任务的运行依赖于B任务产生的数据。例如:在团队活动里,同事A写完报表,经理B才能拿去向领导汇报。经理B必须等同事A完成报表,AB之间有依赖。

互斥: 对资源同时访问时,只能有一个获得资源,一个使用完后才能轮到下一个,往往需要进行互斥访问。例如:打印机同一时间内只能打印一个任务;A、B两人抢厕所,A先一步占用了,B只能等A用完再用。

3.2 同步与互斥的概实现方法

能实现同步、互斥的内核方法有:任务通知(task notification)、队列(queue)、事件组(event group)、信号量(semaphoe)、互斥量(mutex)。

它们都有类似的操作方法:获取/释放、阻塞/唤醒、超时。

队列(queue)可以用于"任务到任务"、"任务到中断"、"中断到任务"直接传输信息。

内核对象应用场景生产者消费者数据/状态说明
队列传递任意多个数据ALLALL任务、中断都可写数据;
任务、中断都可读数据;
用来传递数据,
发送者、接收者无限制,
一个数据只能唤醒一个接收者
计数信号量计数资源数量ALLALL核心是"计数"
任务、中断都可释放信号量(计数加1);
任务、中断都可获得信号量(计数减1);
用来维持资源的个数,
生产者、消费者无限制,
1个资源只能唤醒1个接收者:
像停车场,出来一个,才能进去一个
二值信号量二值信号量通常用于资源的互斥访问或同步ALLALL核心是"计数"
任务、中断都可释放信号量(数值1);
任务、中断都可获得信号量(数值0);
用来维持资源的个数,
生产者、消费者无限制,
1个资源只能唤醒1个接收者:
像停车场,出来一个,才能进去一个
互斥量优先级继承的二值信号量A上锁A开锁数值只有0或1
任务释放信号量(数值1);
任务获得信号量(数值0);
就像一个空厕所,
谁使用谁上锁,
也只能由他开锁
事件组ALLALL一个事件用一bit表示:
1表示事件已发生,
0表示事件没发生;
用来传递事件,
可以是N个事件,
发送者、接受者无限制,
可以唤醒多个接收者:像广播
任务通知ALL只有我数据、状态都可以传输,核心是任务的TCB里的数值,会被覆盖;
发通知给谁?必须指定接收任务;
只能由接收任务本身获取该通知;
N对1的关系:
发送者无限制,
接收者只能是这个任务

?

第3章 队列

3.1 队列

队列是为了任务与任务、任务与中断之间传递不定长消息。可将一条或多条消息写入队列中;也可从队列中读取一条或多条消息。uCOS传递消息是传递指针方式,而FreeRTOS采用是复制消息方式,不过也可实现传递指针方式(复制数据指针就可以实现)。

队列核心操作:1-关中断,2-操作队列缓冲区,3-链表(记录因发送/接收(2种链表)而进入阻塞的任务)

特性:

  • 读写队列支持超时机制。
  • 消息支持先进先出原则(FIFO),但是也支持后进先出原则(LIFO)。
  • 可以允许不同长度的任意类型消息(不超过队列节点最大值)。
  • 一个任务能够从任意一个消息队列接收和发送消息。
  • 多个任务能够从同一个消息队列接收和发送消息。
  • 当队列使用结束后,可以通过删除队列函数进行删除。

3.2 消息邮箱

消息邮箱就是消息队列长度为 1 的情况。

第4章 信号量

信号是一种标志,如信号灯;量用于计数。顾名思义,就是标志计数。信号量功能本质就是计数。信号量其实就是只有一个队列项的队列,该队列项不是用来传递消息,而是用来计数。一般用来进行资源管理任务同步,实现任务之间同步临界资源的互斥访问

信号量主要实现两个功能:

  • 两个任务之间或者中断函数跟任务之间的同步功能,这个与事件标志组是类似的。其实就是共享资源为 1 的时候。
  • 多个共享资源的管理。正在使用的资源有多少,信号量就减多少。

4.1 计数信号量

计数信号量用于事件发生次数计数或者对资源数量的管理计数无限制。在任务中断可使用
事件计数: 事件产生—释放信号量(信号量+1); 事件处理—获取信号量(信号量-1),减到零表示所有事件处理完毕。
资源管理: 信号量值代表当前资源的可用数量,比如停车场当前剩余的停车位数量。信号量值为 0 时说明没有资源了。
优先级翻转现象: 在很多场合中,某些资源只有一个,当低优先级任务正在占用该资源的时候,即便高优先级任务也只能乖乖的等待低优先级任务使用完该资源后释放资源。这里高优先级任务无法运行而低优先级任务可以运行的现象称为“优先级翻转”。

4.2 二值信号量

  • 信号量资源被获取,信号量值是 0;信号量资源被释放,信号量值是 1,只有 0 和 1 两种情况的信号量称之为二值信号量。
  • 类似一个标志位,事件产生置1,事件处理后置0。
  • 可以在任务和中断中使用

4.3 互斥信号量

互斥信号量其实就是一个拥有优先级继承的二值信号量,在同步的应用中(任务与任务或中断与任务之间的同步)二值信号量最适合。
优先级继承:当一个互斥信号量正在被一个低优先级的任务使用,而此时有个高优先级的任务也尝试获取这个互斥信号量的话就会被阻塞。不过这个高优先级的任务会将低优先级任务的优先级提升到与自己相同的优先级,这个过程就是优先级继承。优先级继承尽可能的降低了高优先级任务处于阻塞态的时间,并且将已经出现的 “优先级翻转”的影响降到最低。

可以在任务中使用,不可以在中断中使用。

互斥信号量不能用于中断服务函数中, 原因如下:

  • 互斥信号量有优先级继承的机制,所以只能用在任务中,不能用于中断服务函数。
  • 中断服务函数中不能因为要等待互斥信号量而设置阻塞时间进入阻塞态。

4.4 递归信号量

递归互斥信号量,其实就是互斥信号量里面嵌套 互斥信号量

第5章 事件组

事件是一种实现任务间通信的机制,主要用于实现多任务间的同步,但事件通信只能是事件类型的通信,无数据传输。与信号量不同的是,它可以实现一对多,多对多的同步。 即一个任务可以等待多个事件的发生:可以是任意一个事件发生时唤醒任务进行事件处理;也可以是几个事件都发生后才唤醒任务进行事件处理。同样,也可以是多个任务同步多个事件。(可以在任务和中断中使用)

特性:

  • 事件只与任务相关联,事件相互独立,一个 32 位的事件集合(EventBits_t 类型的变量,实际可用与表示事件的只有 24位),用于标识该任务发生的事件类型,其中每一位表示一种事件类型(0 表示该事件类型未发生、1 表示该事件类型已经发生),一共 24 种事件类型。
  • 事件仅用于同步,不提供数据传输功能。
  • 事件无排队性,即多次向任务设置同一事件(如果任务还未来得及读走),等效于 只设置一次。
  • 允许多个任务对同一事件进行读写操作。
  • 支持事件等待超时机制。

第6章 任务通知

通过任务通知方式可以实现 消息邮箱计数信号量二值信号量事件标志组

在使用队列、信号量前,必须先创建队列和信号量,目的是为了创建队列数据结构。而由于任务通知的数据结构包含在任务控制块中,只要任务存在,任务通知数据结构就已经创建完毕,可以直接使用。任务通知处理更快,RAM 开销更小。

任务通知可以在任务中向指定任务发送通知,也可以在中断中向指定任务发送通知,FreeRTOS 的每个任务都有一个 32 位的通知值,任务控制块中的成员变量 ulNotifiedValue 就是这个通知值。

只有在任务中可以等待通知,而不允许在中断中等待通知。

任务通知限制:

  • 任务通知方式仅可以用在只有一个任务等待信号量,消息邮箱或者事件标志组的情况。
  • 使用任务通知方式实现的消息邮箱替代消息队列时,发送消息的任务不支持超时等待,即消息队列中的数据已经满了,可以等待消息队列有空间可以存新的数据,而任务通知方式实现的消息邮箱不支持超时等待。

FreeRTOS 提供以下几种方式发送通知给任务 :

  • 发送通知给任务, 如果有通知未读,不覆盖通知值。
  • 发送通知给任务,直接覆盖通知值。
  • 发送通知给任务,设置通知值的一个或者多个位 ,可以当做事件组来使用。
  • 发送通知给任务,递增通知值,可以当做计数信号量使用

第7章 软件定时器

FreeRTOS软件定时器是基于 Tick 硬件定时器中断来运行的,其他操作系统也是,不过其他操作系统是在硬件定时器里调用软件定时器函数,而FreeRTOS不是。FreeRTOS它认为如果定时器函数很耗时,会影响整个系统,所以FreeRTOS是通过任务来处理软件定时器。

当 FreeRTOS 的配置项 configUSE_TIMERS 被设置为 1 时,在启动调度器时,会自动创建 RTOS Damemon Task(守护任务)。Tick 硬件定时器中断函数发现某个时间到了,写命令队列,守护任务里读定时器命令队列,有数据就处理,没数据就休眠。

第8章 中断机制

FreeRTOS把MCU硬件中断分为两类,高优先级中断一类;低优先级中断一类。高优先级中断中不能使用FreeRTOS的API函数,它用于处理更紧急的事情,不依赖于FreeRTOS。低优先级中断可以在中断中使用FreeRTOS的API函数。

第9章 临界资源

临界资源一次仅允许一个进程或任务使用的共享资源。例如:?硬件有打印机、磁带机等;软件有消息缓冲队列、变量互斥量、变量数组、缓冲区等。

临界资源的互斥访问通过?屏蔽/使能中断、暂停/恢复调度器 来实现。这样访问临界资源就可以不受干扰。

临界区:每个进程或任务中,访问临界资源的那段代码。也就是屏蔽/使能中断之间代码、暂停/恢复调度器之间代码。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-06-08 19:10:53  更:2022-06-08 19:11:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 14:08:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码