2--嵌入式操作系统FreeRTOS的原理与实现

2023-05-16

 

2--嵌入式操作系统FreeRTOS的原理与实现

 

 

摘自:http://xilinx.eetrend.com/article/7828

 

摘要:FreeRTOS是一个源码公开的免费的嵌入式实时操作系统,通过研究其内核可以更好地理解嵌入式操作系统的实现原理.本文主要阐述FreeRTOS系统中的任务调度机制、时间管理机制、任务管理机制以及内存分配策略的实现原理,并指出FreeRTOS在应用中的优缺点。

       在嵌入式领域中,嵌入式实时操作系统正得到越来越广泛的应用。采用嵌入式实时操作系统(RTOS)可以更合理、更有效地利用CPU的资源,简化应用软件的设计,缩短系统开发时间,更好地保证系统的实时性和可靠性。由于RTOS需占用一定的系统资源(尤其是RAM资源),只有μCOS-IIembOSsalvoFreeRTOS等少数实时操作系统能在小RAM单片机上运行。相对于COS-IIembOS等商业操作系统,FreeRTOS操作系统是完全免费的操作系统,具有源码公开、可移植、可裁减、调度策略灵活的特点,可以方便地移植到各种单片机上运行,其最新版本为2.6版。

1、FreeRTOS操作系统功能

       作为一个轻量级的操作系统,FreeRTOS提供的功能包括:任务管理、时间管理、信号量、消息队列、内存管理、记录功能等,可基本满足较小系统的需要。FreeRTOS内核支持优先级调度算法,每个任务可根据重要程度的不同被赋予一定的优先级,CPU总是让处于就绪态的、优先级最高的任务先运行。FreeRT0S内核同时支持轮换调度算法,系统允许不同的任务使用相同的优先级,在没有更高优先级任务就绪的情况下,同一优先级的任务共享CPU的使用时间。

       FreeRTOS的内核可根据用户需要设置为可剥夺型内核或不可剥夺型内核。当FreeRTOS被设置为可剥夺型内核时,处于就绪态的高优先级任务能剥夺低优先级任务的CPU使用权,这样可保证系统满足实时性的要求;当FreeRTOS被设置为不可剥夺型内核时,处于就绪态的高优先级任务只有等当前运行任务主动释放CPU的使用权后才能获得运行,这样可提高CPU的运行效率。

2、FreeRTOS操作系统的原理与实现

2.1 任务调度机制的实现

       任务调度机制是嵌入式实时操作系统的一个重要概念,也是其核心技术。对于可剥夺型内核,优先级高的任务一旦就绪就能剥夺优先级较低任务的CPU使用权,提高了系统的实时响应能力。不同于μCOS-IIFreeRTOS对系统任务的数量没有限制,既支持优先级调度算法也支持轮换调度算法,因此FreeRTOS采用双向链表而不是采用查任务就绪表的方法来进行任务调度。系统定义的链表和链表节点数据结构如下所示:
typedef struct xLIST{ //定义链表结构
unsigned portSHORPT usNumberOfItems;  //usNumberOfItems为链表的长度,为0表示链表为空
volatile xListItem * pxHead;  //pxHead为链表的头指针
volatile xListItem * pxIndex;  //pxIndex指向链表当前结点的指针
volatile xListItem xListEnd;  //xListEnd为链表尾结点
}xList;

struct xLIST_ITEM { //定义链表结点的结构
port Tick type xItem Value;  //xItem Value的值用于实现时间管理
                          //port Tick Type为时针节拍数据类型,
                          //可根据需要选择为16位或32
volatile struct xLIST_ITEM * pxNext;  //指向链表的前一个结点
void * pvOwner;  //指向此链表结点所在的任务控制块
void * pvContainer;  //指向此链表结点所在的链表
}

FreeRTOS中每个任务对应于一个任务控制块(TCB),其定义如下所示:
typedef struct tskTaskControlBlock {
portSTACK_TYPE * pxTopOfStack;  //
指向任务堆栈结束处
portSTACK_TYPE * pxStack;  //指向任务堆栈起始处
unsigned portSHORT usStackDepth;   //定义堆栈深度
signed portCHAR pcTaskName[tskMAX_TASK_NAME_LEN];  //任务名称
unsigned portCHAR ucPriority;   //任务优先级
xListItem xGenericListItem;   //用于把TCB插入就绪链表或等待链表
xListItem xEventListItem;   //用于把TCB插入事件链表(如消息队列)
unsigned portCHAR ucTCBNumber;   //用于记录功能
}tskTCB;

      FreeRTOS定义就绪任务链表数组为xList pxReadyTasksLists[portMAX_PRIORITIES]。其中portMAX_PRIORITIES为系统定义的最大优先级。若想使优先级为n的任务进入就绪态,需要把此任务对应的TCB中的结点xGenericListltem插入到链表pxReadyTasksLists[n]中,还要把xGenericListItem中的pvContainer指向pxReadyTasksLists[n]方可实现。

      当进行任务调度时,调度算法首先实现优先级调度。系统按照优先级从高到低的顺序从就绪任务链表数组中寻找usNumberOfItems第一个不为0的优先级,此优先级即为当前最高就绪优先级,据此实现优先级调度。若此优先级下只有一个就绪任务,则此就绪任务进入运行态;若此优先级下有多个就绪任务,则需采用轮换调度算法实现多任务轮流执行。

       若在优先级n下执行轮换调度算法,系统先通过执行(pxReadyTasksLists[n])→pxIndex=( pxReadyTasksLists[n ]) → pxlndex→pxNext语句得到当前结点所指向的下一个结点,再通过此结点的pvOwner指针得到对应的任务控制块,最后使此任务控制块对应的任务进入运行态。由此可见,在FreeRTOS中,相同优先级任务之间的切换时间为一个时钟节拍周期。

        以图1为例,设系统的最大任务数为pottMAX_PRIORITIES,在某一时刻进行任务调度时,得到pxReadyTasksLists[i]usNumberOfItems=O(i=2...portMAX_PRIORITIES)以及pxReadyTasksLists[1].usNumberOfItems=3。由此内核可知当前最高就绪优先级为l,且此优先级下已有三个任务已进入就绪态.由于最高就绪优先级下有多个就绪任务,系统需执行轮换调度算法实现任务切换;通过指针pxlndex可知任务l为当前任务,而任务lpxNext结点指向任务2,因此系统把pxIndex指向任务2并执行任务2来实现任务调度。当下一个时钟节拍到来时,若最高就绪优先级仍为1,由图可见,系统会把pxIndex指向任务3并执行任务3

1 任务调度示意

        为了加快任务调度的速度,FrecRTOS通过变量uxTopReadyPriotity跟踪当前就绪的最高优先级。当把一个任务加入就绪链表时,如果此任务的优先级高于ucTopReadyPriority,则把这个任务的优先级赋予ucTopReadyPriority。这样当进行优先级调度时,调度算法不是从portMAX_PRIORITIES而是从ucTopReadyPriority开始搜索。这就加快了搜索的速度,同时缩短了内核关断时间。

2.3 时间管理的实现

        FreeRTOS提供的典型时间管理函数是vTaskDelay(),调用此函数可以实现将任务延时一段特定时间的功能。在FreeRT0S中,若一个任务要延时xTicksToDelay个时钟节拍,系统内核会把当前系统已运行的时钟节拍总数(定义为xTickCount32位长度)加上xTicksToDelay得到任务下次唤醒时的时钟节拍数xTimeToWake。然后,内核把此任务的任务控制块从就绪链表中删除,把xTimeToWake作为结点值赋予任务的xItemValue,再根据xTimeToWake的值把任务控制块按照顺序插入不同的链表。若xTimeToWake > xTickCount,即计算中没有出现溢出,内核把任务控制块插入到pxDelayedTaskList链表;若xTimeToWak e< xTickCount,即在计算过程中出现溢出,内核把任务控制块插入到pxOverflowDelayedTaskust链表。

        每发生一个时钟节拍,内核就会把当前的xTick-Count1。若xTickCount的结果为0,即发生溢出,内核会把pxOverflowDelayedTaskList作为当前链表;否则,内核把pxDelaycdTaskList作为当前链表。内核依次比较xTickCotlrtt和链表各个结点的xTimcToWake。若xTick-Count等于或大于xTimeToWake,说明延时时间已到,应该把任务从等待链表中删除,加入就绪链表。

        由此可见,不同于μCOS—IIFreeRTOS采用的方式实现时间管理。其优点是时间节拍函数的执行时间与任务数量基本无关,而μCOS—IIOSTimcTick()的执行时间正比于应用程序中建立的任务数。因此当任务较多时,FreeRTOS采用的时间管理方式能有效加快时钟节拍中断程序的执行速度。

2.4 内存分配策略

        每当任务、队列和信号量创建的时候,FreeRTOS要求分配一定的RAM。虽然采用malloc()free()函数可以实现申请和释放内存的功能,但这两个函数存在以下缺点:并不是在所有的嵌入式系统中都可用,要占用不定的程序空间,可重人性欠缺以及执行时间具有不可确定性。为此,除了可采用malloc()free()函数外,FreeRTOS还提供了另外两种内存分配的策略,用户可以根据实际需要选择不同的内存分配策略。

        1种方法是,按照需求内存的大小简单地把一大块内存分割为若干小块,每个小块的大小对应于所需求内存的大小。这样做的好处是比较简单,执行时间可严格确定,适用于任务和队列全部创建完毕后再进行内核调度的系统;这样做的缺点是,由于内存不能有效释放,系统运行时应用程序并不能实现删除任务或队列。

        2种方法是,采用链表分配内存,可实现动态的创建、删除任务或队列。系统根据空闲内存块的大小按从小到大的顺序组织空闲内存链表。当应用程序申请一块内存时,系统根据申请内存的大小按顺序搜索空闲内存链表,找到满足申请内存要求的最小空闲内存块。为了提高内存的使用效率,在空闲内存块比申请内存大的情况下,系统会把此空闲内存块一分为二。一块用于满足申请内存的要求,一块作为新的空闲内存块插入到链表中。

       下面以图2为例介绍方法2的实现。假定用于动态分配的RAM共有8KB,系统首先初始化空闲内存块链表,把8KB RAM全部作为一个空闲内存块。当应用程序分别申请1KB2KB内存后,空闲内存块的大小变为5KB32KB的内存使用完毕后,系统需要把2KB插入到现有的空闲内存块链表。由于2 KB<5KB,所以把这2 KB插入5KB的内存块之前。若应用程序又需要申请3 KB的内存,而在空闲内存块链表中能满足申请内存要求的最小空闲内存块为5KB,因此把5KB内存拆分为2部分,3KB部分用于满足申请内存的需要,2KB部分作为新的空闲内存块插入链表。随后1KB的内存使用完毕需要释放,系统会按顺序把1KB内存插入到空闲内存链表中。

2 采用空闲内存块链表进行内存管理

       方法2的优点是,能根据任务需要高效率地使用内存,尤其是当不同的任务需要不同大小的内存的时候。方法二的缺点是,不能把应用程序释放的内存和原有的空闲内存混合为一体,因此,若应用程序频繁申请与释放随机大小的内存,就可能造成大量的内存碎片。这就要求应用程序申请与释放内存的大小为有限个固定的值(如图2中申请与释放内存的大小固定为l KB2 KB3 KB)。方法2的另一个缺点是,程序执行时间具有一定的不确定性。

       μCOS—II提供的内存管理机制是把连续的大块内存按分区来管理,每个分区中包含整数个大小相同的内存块。由于每个分区的大小相同,即使频繁地申请和释放内存也不会产生内存碎片问题,但其缺点是内存的利用率相对不高。当申请和释放的内存大小均为一个固定值时(如均为2 KB)FreeRTOS的方法2内存分配策略就可以实现类似μCOS—的内存管理效果。

2.5 FreeRTOS的移植

       FreeRTOS操作系统可以被方便地移植到不同处理器上工作,现已提供了ARMMSP430AVRPICC8051F等多款处理器的移植。FrceRTOS在不同处理器上的移植类似于μC0SII,故本文不再详述FreeRTOS的移植。此外,TCPIP协议栈μIP已被移植到FreeRTOS上,具体代码可见FreeRTOS网站。

2.6 FreeRTOS的不足

      相对于常见的μCOS—II操作系统,FreeRTOS操作系统既有优点也存在不足。其不足之处,一方面体现在系统的服务功能上,如FreeRTOS只提供了消息队列和信号量的实现,无法以后进先出的顺序向消息队列发送消息;另一方面,FreeRTOS只是一个操作系统内核,需外扩第三方的GUI(图形用户界面)TCPIP协议栈、FS(文件系统)等才能实现一个较复杂的系统,不像μCOS-II可以和μCGUIμCFSμCTCP-IP等无缝结合。

3、结 论

      作为一个源码公开的操作系统,学习FreeRTOS可以更好地掌握嵌入式实时操作系统的实现原理;作为一个免费的操作系统,采用FreeRTOS可在基本满足较小系统需要的情况下降低系统成本、简化开发难度。在实践中,采用FreeRTOS操作系统和MSP430单片机构成的温度控制系统稳定可靠,实现了较好的控制效果。相信随着时间的发展,FreeRTOS会不断完善其功能,以更好地满足人们对嵌入式操作系统实时性、可靠性、易用性的要求。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

2--嵌入式操作系统FreeRTOS的原理与实现 的相关文章

  • 头文件中定义和声明的问题

    头文件中定义和声明的问题 1 头文件中不可以放变量的定义 xff01 一般头文件中只是放变量的声明 xff0c 因为头文件要被其他文件包含 include xff0c 如果把定义放在头文件的话 xff0c 就不能避免多次定义变量 C 43
  • Apache中更改PHP版本型号

    如何对服务器PHP版本进行升级 xff0c 详看我另外一篇博文 xff0c 这篇文章我们将讲述如何在Apache中更改PHP版本型号 Step1 xff1a 查看Apache用的PHP什么版本 新建一个文档 xff0c 命名为info ph
  • 简述AGV通信接口标准-VDA5050

    引言 德国汽车工业协会 德语 xff1a Verband der Automobilindustrie e V 简称VDA xff0c 通过 其 34 VDA 5050 34 接口 xff0c 早在2019年起 xff0c 不同制造商的车辆
  • C语言结束输入(两种方法)

    方法1 xff1a 输入数据 while getchar 61 39 n 39 scanf 34 d 34 amp Data data i 43 43 61 Data 方法2 xff1a for i 61 0 i lt 100 amp am
  • OpenCV(项目)车牌识别3 -- 模板匹配

    目录 一 基础理论 1 思想 2 大致过程 二 详细过程 1 首先需要模板库 2 得到模板 3 原图限定大小 4 模板匹配 5 匹配所有子文件夹 xff0c 保存最佳得分 xff08 最匹配项 xff09 三 大致过程 xff08 细分类
  • PMP项目管理中的重要角色

    PMP及PMBOK有个大问题 xff0c 就是没有统一的角色职责及流程 xff0c 考试也是随意性很强 xff0c 这给考生带来很多困扰 一个管理体系 xff0c 首先是人员分工安排 比如 xff1a PRINCE2 xff0c 明确的组织
  • 书房再次升级啦~~

    国庆长假 xff0c 在家里面一顿折腾 xff0c 墙全部重新粉刷 xff0c 书房 卧室 客厅三种不同颜色 书房的颜色是当时在装饰城的展厅里面偷偷扣的墙皮 xff0c 在多乐士店色卡里面对出来的 xff0c 哈哈 ps 这篇日志的照片是用
  • 基于K近邻法的手写数字图像识别

    数字图像处理课程论文 题目 xff1a 数字图像识别 摘要 模式识别 PatternRecognition 是一项借助计算机 xff0c 就人类对外部世界某一特定环境中的客体 过程和现象的识别功能 xff08 包括视觉 听觉 触觉 判断等
  • Ubuntu 16.04升级内核到20.04

    一 首先需要从16 04 18 04 sudo mv etc apt sources list sudo mv etc apt sources list d list 1 改变源 xff08 粘贴下面这一段到终端并运行 xff09 cat
  • 互斥和二进制信号量的使用

    1 二进制信号量 semBCreate SEM Q FIFO SEM Q PRIORITY SEM EMPTY SEM FULL 有两个作用 xff1a xff08 1 xff09 任务间的互斥 xff0d xff0d 同一个任务获取和释放
  • 【C++】关于以下划线开头的变量名

    系 统头文件里将宏名 变量名 内部函数名用 34 34 开 头就是为了避免与用户用的名字冲突 因为当你 xff03 include 系 统头文件时 xff0c 这些文件里的名字都有了定义 xff0c 如果与你用的名字冲突 xff0c 就可能
  • 1689_MATLAB处理Excel文件提升篇

    全部学习汇总 xff1a GreyZhang g matlab MATLAB once used to be my daily tool After many years when I go back and read my old lea
  • 1690_Python中的复数数据类型

    全部学习汇总 xff1a GreyZhang python basic My learning notes about python github com 之前总结的知识中设计的数据类型有整形 浮点 字符串等 xff0c 这些类型表示的都是
  • linux 命令终端提示符显示-bash-4.1#

    昨晚对服务器自带Python升级后 xff0c 终端就不是以前root 64 主机 43 路径的显示方式了 查了很多资料 xff0c 有人说是root目录下 bash profile和 bash两个文件缺失 xff0c 但我的这两个文件是存
  • 1691_python学习笔记之week3_递归

    全部学习汇总 xff1a GreyZhang python basic My learning notes about python github com 最初接触递归的时候觉得这个有点不好理解 xff0c 怎么能够有这种思维方式 xff1
  • 1692_Git版本控制管理 21-40

    全部学习汇总 xff1a GreyZhang toolbox 常用的工具使用查询 xff0c 非教程 xff0c 仅作为自我参考 xff01 github com 我曾经多次在工作中接触软件版本管理 xff0c 接触过多个公司的软件版本管理
  • 1693_Python处理Excel学习小结 21-41

    全部学习汇总 xff1a GreyZhang python basic My learning notes about python github com 说起来这是我来到北京之后开始接触的第一个新技术 xff0c 我对此痴迷 xff0c
  • 1694_week1_MIT使用Python编程学习手记1

    全部学习汇总 xff1a GreyZhang python basic My learning notes about python github com 首先说明一下 xff0c 这部分信息的整理只是我个人的理解 由于自己的知识功底以及英
  • 1695_week2_算法与函数(MIT使用Python编程学习手记)

    全部学习汇总 xff1a GreyZhang python basic My learning notes about python github com 首先说明一下 xff0c 这部分信息的整理只是我个人的理解 由于自己的知识功底以及英
  • 1696_C语言中变量默认初始化初值探究测试

    全部学习汇总 xff1a GreyZhang c basic little bits of c github com 欢迎路过的YUAN类朋友相互沟通交流 xff0c 也欢迎各位随时指点指正 以下是我的联系方式 xff1a 微信 xff1a

随机推荐

  • 1697_python编程_assertions and exceptions

    全部学习汇总 xff1a GreyZhang python basic My learning notes about python github com 这部分主要关于程序中的异常类型以及处理方式 exception 常见的异常类型 ex
  • 1698_python编程_测试与debug

    全部学习汇总 xff1a GreyZhang python basic My learning notes about python github com 学习了一下这一周的课程 xff0c 讲的主要是测试以及Bug调试方面的东西 在之前我
  • 1699_simulink代码生成配置初级方案

    全部学习汇总 xff1a GreyZhang g matlab MATLAB once used to be my daily tool After many years when I go back and read my old lea
  • 1700_VIM代码自动补齐配置

    全部学习汇总 xff1a GreyZhang editors skills Summary for some common editor skills I used github com 欢迎路过的YUAN类同胞相互交流 xff0c 指点指
  • Python2 备份网站目录并上传百度网盘

    最近用WordPress建了个个人博客 xff0c 本着数据无价的原则编写了本脚本对数据库和网址目录进行备份并上传到百度网盘里 话不多说 xff0c 下面就该Python脚本的程序依赖 代码说明及使用方法进行叙述 一 程序依赖 1 安装Py
  • 1701_week5_效率与搜索

    全部学习汇总 xff1a GreyZhang python basic My learning notes about python github com 这一周的课程很早就学完了 xff0c 碰上自己昼夜加班周末不休的时段一直也没有整理学
  • 1702_week6_面向对象编程

    全部学习汇总 xff1a GreyZhang python basic My learning notes about python github com 放一下自己的联系方式 xff0c 软件爱好者欢迎交流 邮箱 xff1a greyzh
  • 1703_LibreOffice常用功能使用体验

    全部学习汇总 xff1a GreyZhang windows skills some skills when using windows system github com 首先需要说明的是我不是一个重度Office用户 xff0c 甚至算
  • 1704_Linux与Windows使用体验对比

    全部学习汇总 xff1a GitHub GreyZhang little bits of linux My notes on the trip of learning linux 我在我的微博上发过几次对比两个操作系统使用体验的微博 xff
  • 1705_Python处理中文经验与实践

    全部学习汇总 xff1a GreyZhang python basic My learning notes about python github com 曾经在很长的一段时间内 xff0c Python处理中文的时候真是把我难坏了 总觉得
  • 1706_Python中带余数除法

    全部学习汇总 xff1a GitHub GreyZhang python basic My learning notes about python 欢迎路过的YUAN类朋友们 xff0c 希望我们能够相互交流共同成长 如有错误或者不足希望及
  • 1707_Python中的多成员处理

    全部学习汇总 xff1a GreyZhang python basic My learning notes about python github com 欢迎路过的YUAN类朋友们 xff0c 希望我们能够相互交流共同成长 如有错误或者不
  • 1708_Simulink中取数组元素

    全部学习汇总 xff1a GitHub GreyZhang g matlab MATLAB once used to be my daily tool After many years when I go back and read my
  • STM32F407 CUBEMX+HAL库完成对XPT2064触摸屏控制芯片的驱动

    硬件介绍 首先介绍一下硬件 xff0c 我购买的液晶屏大小为480 320 xff0c 液晶屏控制芯片为ST996S xff0c 两者均采用SPI通讯协议 xff0c 这节只讲触摸屏控制芯片XPT2064的部分 如果你需要阅读有关液晶屏控制
  • C++ (STL BOOST) 智能指针的一些解析

    C 43 43 xff08 STL BOOST xff09 智能指针的一些解析 xff0c 包括智能指针的原理 xff0c 智能指针的一些使用 只有了解了原理才能真正用对他们 现在blog的文章几乎就是一把抄 郁闷 C 43 43 里面内存
  • Python安装第三方库PIL时失败的解决办法

    Python中 xff0c 安装第三方模块 xff0c 是通过setuptools这个工具完成的 Python有两个封装了setuptools的包管理工具 xff1a easy install和pip 目前官方推荐使用pip 安装一个第三方
  • 在VMware上安装Ubuntu详细教程

    目录 1 先下载好VMware Workstation Pro 2 下载Ubuntu系统镜像 3 在VMware新建虚拟机 4 开启虚拟机 xff0c 安装Ubuntu 这时我们发现由于窗口太小无法安装 作为全球最流行且最有影响力的Linu
  • 树莓派 Linux 下的串口通讯 (C语言)

    运行环境 xff1a Ubuntu14 04 树莓派3B 43 功能 xff1a 实现串口数据的收发 main c文件 include 34 com h 34 define BUFFER SIZE 30 最大缓存区 char pstr 61
  • 1--FreeRTOS操作系统介绍

    1 FreeRTOS 操作系统介绍 第3章 FreeRTOS 读作 34 free arr toss 34 是一个嵌入式系统使用的开源实时操作系统 FreeRTOS 被设计为 小巧 xff0c 简单 xff0c 和易用 xff0c 能支持许
  • 2--嵌入式操作系统FreeRTOS的原理与实现

    2 嵌入式操作系统FreeRTOS的原理与实现 摘自 xff1a http xilinx eetrend com article 7828 摘要 xff1a FreeRTOS 是一个源码公开的免费的嵌入式实时操作系统 xff0c 通过研究其