0

0

从零开始学习UCOSII操作系统15–总结篇[通俗易懂]

看不見的法師

看不見的法師

发布时间:2025-07-14 09:56:31

|

225人浏览过

|

来源于php中文网

原创

大家好,又见面了,我是你们的朋友全栈君。

从零开始学习UCOSII操作系统15–总结篇

前言:在大学的时候,我们班级上面都有很多人觉得学习UCOSII(包括UCOSIII)是没什么厉害的,因为很多人都喜欢去学习Linux操作系统,但是,但是,真实的对整个UCOSII操作系统进行学习,我可以保证,如果你是基于源码级别的阅读的话,绝对是不简单的。仅仅是调用几个API的话,是永远用不好UCOSII的操作系统的。还有你真正学通了UCOSII操作系统的话,那么你对Linux操作系统的内核也不会有太大的难度。

参考:嵌入式实时操作系统UCOSII原理与应用

1、UCOSII操作系统是怎么管理任务的?

用图是最能表现的: (1)任务控制块是来管理任务的。 (2)其中UCOSII把所有的任务都是通过双向链表来连接到一起的,为什么?我难道不能使用数组来分配空间吗?

关键原因:在整个操作系统中,因为我们不知道用户到底需要多少个任务,所以使用链表的话,在编译后才确认的话,数组的方式优秀很多。

我个人认为这张图其实是有一些错误的: 比如里面写了指向任务的指针,我觉得是应该放置在任务堆栈里面的,因为创建任务的时候,是将任务的函数名,传递给任务堆栈,然后任务堆栈再传到CPU的SR寄存器中,实现任务切换的。

所谓的指向任务的指针:其实就是任务的函数的函数名。

从零开始学习UCOSII操作系统15–总结篇[通俗易懂]
2、UCOSII操作系统是怎么运行的?

(1)睡眠态:首先我们的任务是按需分配的,你想要多少个任务的话,那么我们就可以创建多少个任务。刚刚创建的任务是处于睡眠的状态的。

(2)就绪状态:如果系统为任务配备了任务控制块并且在任务的就绪表中进行了就绪登记的话,则任务就具备了运行的充分条件,这时候任务的状态就叫做就绪态。

(3)运行状态:处于就绪状态的任务如果经过UCOSII的位图机制,判断为处于最高优先级的任务的话,那么它就可以获得CPU的使用权,这时候就是运行状态。

(4)中断服务状态:这个真的就没有什么好说的了,连前后台系统都会存在的状态,触发到中断的条件,就会进入中断态,而且不管你是否处于运行态还是怎么样?

以上的4个状态是我认为UCOSII操作系统中必不可少的状态的。

(5)等待状态:这个状态的话,是可以通过裁剪UCOSII内核去掉的,其实这个状态就是为了满足任务之间的通讯和任务与中断服务子程序通信产生的一种状态。

从零开始学习UCOSII操作系统15–总结篇[通俗易懂]
3、UCOSII操作系统任务之间是通过什么进行通信的?

总所周知,UCOSII的任务是一个特殊的函数,没有类型,没有返回值。 里面是一个死循环。

那么为什么它能够跳出来执行别的任务? 它之所以能够跳出来跟别的任务进行通信的话,在下面的用户需要添加的代码中一定是有一个任务切换的函数调用的。实质上是CPU的SR寄存器中的任务堆栈的切换的过程。

那么它怎么跟别的任务进行通信? 常考题:Linux的进程间通信的方式: 信号量(互斥型信号量)、消息队列、共享内存、消息邮箱、事件标志组

其中UCOSII任务之间进行通信的方式除了共享内存,其余都存在。

ima.copilot
ima.copilot

腾讯大混元模型推出的智能工作台产品,提供知识库管理、AI问答、智能写作等功能

下载

其中有好几个是类型的: 比如信号量和互斥型信号量。使用这个是可以占用资源,或者同步任务的运行。

比如消息邮箱和消息队列,消息队列也称为多个消息邮箱,都是用来在任务之间传递数据的。

事件标记组:首先请求事件标记组的时候,通过一个整型数的某几个位,如果那几个位都已经置位或者都是为空的话,那么请求事件标记组的任务可以得到运行。

为什么需要互斥型信号量? 因为会产生任务优先级的反转问题?

什么是优先级反转?高优先级任务被低优先级任务剥脱CPU的使用权。 (1)假设现在有一个低的优先级任务占有CPU的内核,同时他占有了一些资源。 (2)此时,来了一个高优先级的任务,它想要得到这个资源,但是这个资源已经被低优先级的任务占有了。 (3)在后来来了一个中等优先级的任务,它因为优先级比低优先级的任务高,但是它的优先级没有高的优先级高,所以它强占CPU的使用权,继续执行。 (4)这时候,形成的情况就是中等优先级的任务比高优先级的任务更加早的执行,形成优先级反转的问题。

解决方案1: 如果低优先级任务占有的那个资源后,后面有更高的优先级任务到来的话,那么就把自己的优先级提高到那个想要占有优先级的任务。

解决方案2: 使用互斥型信号量。因为互斥型信号量,只有你自己请求,自己释放,不能通过别的任务释放,如果你请求一个已经请求过的互斥性信号量的话,那么直接跳过执行。

代码语言:javascript代码运行次数:0运行复制
void task1(void * pada){    for(;;)    {        //用户需要添加的代码    }}
4、UCOSII操作系统的内存管理

参考:https://www.cnblogs.com/apollius/archive/2013/03/26/2981429.html UCOSII中动态内存管理的C语言实现:

嵌入式编程比较关心的就是内存大小,在有限的内存中实现动态和静态的代码分配是有学问的,对于像malloc这类在运行的时候从堆中请求内存的函数,诺调用次数太多可能会造成内存的快速消息。

将所有已经分配好的空间计算好,利用全局变量分配到静态的代码空间中。 实际使用时调用自己编写好的内存管理函数从这块静态空间中申请内存。

内存的总体大小是受控的,所有涉及到动态内存的地方实际上都已经被预先分配好,在编译时候写在静态代码区。

INT8U Buff8U [40][32]; INT16U Buff16U[40][32];

从零开始学习UCOSII操作系统15–总结篇[通俗易懂]

每个内存管理块中记录了对应存储的数据地址(EntryAddr),当前可用的数组的地址(FreeAddr),当内存进行分配时候,这一位会进行偏移操作,指向还没有被分配的存储数组。而这些管理块也需要一个总的数组来存储其位置,否则这些指针也是无法初始化的指针。并且新建一个指针(*MMUFREE)指向当前还未被分配,可以用的管理块数组中位置。

代码语言:javascript代码运行次数:0运行复制
MMUType     MMUPool[MMU_BUFF_MAX];  //Store all the MMUsMMUType    *MMUFree;                //Pointer to the available MMUType in MMUPoolMMUType    *MMUBuff8;            //Controller of Buff8UMMUType    *MMUBuff16;           //Controller of Buff16U
从零开始学习UCOSII操作系统15–总结篇[通俗易懂]

可以看出核心思想是,所有需要实际存储的指针都由数组来保存,所有指针最终指向一个实际的变量,诺要使用这种内存管理,第一步要做的就是初始化MMUPOOL初始化内存池。调用MEMInit()之后将内部所有的成员形成一个链表,由MMUFree指向最开头的一个。

从零开始学习UCOSII操作系统15–总结篇[通俗易懂]

这样一来就可以为内存管理块分配一个实际的对象了,调用MemCreate()可以分配一个实际的对象给内存管理块,并且将内存管理与实际的内存存储去联系在一起。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/135897.html原文链接:https://javaforall.cn

相关专题

更多
C语言变量命名
C语言变量命名

c语言变量名规则是:1、变量名以英文字母开头;2、变量名中的字母是区分大小写的;3、变量名不能是关键字;4、变量名中不能包含空格、标点符号和类型说明符。php中文网还提供c语言变量的相关下载、相关课程等内容,供大家免费下载使用。

379

2023.06.20

c语言入门自学零基础
c语言入门自学零基础

C语言是当代人学习及生活中的必备基础知识,应用十分广泛,本专题为大家c语言入门自学零基础的相关文章,以及相关课程,感兴趣的朋友千万不要错过了。

607

2023.07.25

c语言运算符的优先级顺序
c语言运算符的优先级顺序

c语言运算符的优先级顺序是括号运算符 > 一元运算符 > 算术运算符 > 移位运算符 > 关系运算符 > 位运算符 > 逻辑运算符 > 赋值运算符 > 逗号运算符。本专题为大家提供c语言运算符相关的各种文章、以及下载和课程。

348

2023.08.02

c语言数据结构
c语言数据结构

数据结构是指将数据按照一定的方式组织和存储的方法。它是计算机科学中的重要概念,用来描述和解决实际问题中的数据组织和处理问题。数据结构可以分为线性结构和非线性结构。线性结构包括数组、链表、堆栈和队列等,而非线性结构包括树和图等。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

255

2023.08.09

c语言random函数用法
c语言random函数用法

c语言random函数用法:1、random.random,随机生成(0,1)之间的浮点数;2、random.randint,随机生成在范围之内的整数,两个参数分别表示上限和下限;3、random.randrange,在指定范围内,按指定基数递增的集合中获得一个随机数;4、random.choice,从序列中随机抽选一个数;5、random.shuffle,随机排序。

583

2023.09.05

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

519

2023.09.20

c语言get函数的用法
c语言get函数的用法

get函数是一个用于从输入流中获取字符的函数。可以从键盘、文件或其他输入设备中读取字符,并将其存储在指定的变量中。本文介绍了get函数的用法以及一些相关的注意事项。希望这篇文章能够帮助你更好地理解和使用get函数 。

630

2023.09.20

c数组初始化的方法
c数组初始化的方法

c语言数组初始化的方法有直接赋值法、不完全初始化法、省略数组长度法和二维数组初始化法。详细介绍:1、直接赋值法,这种方法可以直接将数组的值进行初始化;2、不完全初始化法,。这种方法可以在一定程度上节省内存空间;3、省略数组长度法,这种方法可以让编译器自动计算数组的长度;4、二维数组初始化法等等。

595

2023.09.22

桌面文件位置介绍
桌面文件位置介绍

本专题整合了桌面文件相关教程,阅读专题下面的文章了解更多内容。

0

2025.12.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 0.6万人学习

Rust 教程
Rust 教程

共28课时 | 3.9万人学习

Kotlin 教程
Kotlin 教程

共23课时 | 2.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号