uC/OS学习笔记1

news/2025/2/22 20:07:46

 

这几天稍微空闲点,看了一下uC/OS,用的教材是人民邮电的《uC/OS-II内核分析、移植与驱动程序开发》,刚开始感觉他写的有点稀里糊涂的,自己理一下头绪。
uC/OS看到现在,让我感叹这个系统真的是用空间换取时间的典范,把所有的东西都先建立好,通过查表或者是保存一大堆变量,目的就是要用的时候就能随手拿到,不用再进行计算了,感叹一下。

先列一下比较重要的几个量(MAX_TASKS表示最大任务个数,LOWEST_PRIO指最低优先级数):
OSRunning:用于标识多任务环境是否已经开启运行,在OSStart()函数里启动任务后就置为True。

OSIntNesting:用于标识中断嵌套层数。产生一次中断可以调用OSIntEnter()函数使该值自增1,处理完一次中断再调用OSIntExit()自减1。

OS_TCB:一个结构体变量,每建立一个任务都会为该任务指定一个OS_TCB,包含该任务的栈顶指针,任务优先级,任务状态字,延时节拍等所有相关信息。每个任务的OS_TCB都存在于一个双向链表内,并使变量OSTCBList指向最后建立的那个任务的OS_TCB。

OS_STK:任务堆栈,每个任务都有一个自己的堆栈空间,用于保存寄存器,状态值,和任务的入口地址。这个堆栈与系统栈没有什么关系,只是用户为一个任务分配的存储任务信息的空间,只需要是一个连续的存储空间即可。

OSRdyGrp,OSRdyTbl[ ]:用于标识就绪的任务。uC/OS根据优先级唯一确定一个任务,也即一个优先级只能分配给一个任务。OSRdyTbl[ ]里保存(MAX_TASKS/8+1)个字节,每个字节又有8个Bit,从最低位开始分别对应0~LOWEST_PRIO优先级的任务,任务就绪时就将该任务的优先级所在Bit置1,否则清0。
OSRdyGrp完全是为了找到最高优先级方便而设立的,将OSRdyTbl[ ]里每个字节代表的8个任务划为一个组,只要某一组内有就绪任务时,OSRdyGrp的相应位就置1。比如,只要OSRdyTbl[0]不为0,则OSRdyGrp的第0位就置1,依次类推。

OSPrioCur:这是一个整型数,表示当前执行任务的优先级数。

OSPrioHighRdy:一个整型数,表示当前最高级别的就绪任务的优先级数。

OSTCBHighRdy:这是一个指针,它指向最高优先级就绪任务的OS_TCB。

OSTCBCur:一个指针,指向当前执行任务的OS_TCB。

OSTCBTbl[ ]:初始化时建立的一块存储空间,一共建立了MAX_TASKS个OS_TCB空间。并令变量OSTCBFreeList总是指向下一个可用的OS_TCB空间。当新建立一个任务时,就将一个空的OS_TCB空间分配给它使用。

OSTCBPrioTbl[]:这是一个指针数组,用于保存就绪任务的OS_TCB地址,一共有MAX_TASKS个值,依次对应0~LOWEST_PRIO优先级的任务。当某一优先级未分配给一个任务时,该数组对应元素的值为(void *)0,当某优先级的任务分配给一个处于就绪态的任务时,对应元素的内容就被写入该任务的OS_TCB所在地址。

拿到没用过的系统,首先就想知道它是怎么用的,对于一个实时操作系统,先要解决以下几个问题:
如何切换任务
uC/OS多任务的原理是,在某个任务重新获得CPU控制权的时候,先把上一个执行的任务的所有寄存器以及它的返回地址保存起来,然后把现在要执行的任务的所有变量恢复到操作寄存器里,然后使PC指向这个任务的处理函数。而保存和恢复变量的重要媒介就是每个任务独有的堆栈空间,这点跟中断处理的过程几乎一样,重新获得CPU的任务可以看成是中断函数,原先执行的看成是被中断的函数,只不过uC/OS是模拟中断来切换任务,所有堆栈的保存和恢复要在移植不同处理器的时候根据实际情况来完成,目的只有一个,就是模拟中断的压栈和出栈操作。
uC/OS引起任务切换的功能函数主要是两个,任务级的切换是OSSched(),中断级的切换由OSIntExit()完成。而前者中真正实现切换操作的是OS_TASK_SW()宏,后者真正实现切换功能的是OSIntCtxSw(),这个宏如何实现,移植不同的处理器有不同的处理方法,目的仍然是,把现场处理的跟真正发生了中断一样,该保存的保存,该恢复的恢复。
因此可以得到,uC/OS切换任务时可以有两种方法,第一种是拥有CPU控制权的任务主动调用函数OSTimeDly()、OSTaskSuspend()等这类函数把控制权交出来,重新分配给下一个优先级高的任务,实际上是依靠OSSched()调度任务。第二种方法是CPU产生中断,把当前任务的控制权剥夺掉,令它挂起,从而使下一优先级的任务得以执行,当然,如果中断没有令当前任务挂起,中断返回后它依然是最高优先级的话,CPU将继续被它控制。

如何查找最高优先级
uC/OS把一个字节可能的256个值的所有优先级状况都做成一个表OSUnMapTbl[ ],比如,如果字节的值为7,即0000 0111,那么任务0,1,2都处于就绪态,最高优先级当然是0,那么OSUnMapTbl[7] == 0,因此,先通过y = OSUnMapTbl[OSRdyGrp]找到最高优先级的组y,然后通过x = OSUnMapTbl[OSRdyTbl[OSRdyGrp]]得到这个组里的最高优先级任务号x。因为uC/OS最大任务数不超过64,可以把优先级数看成是一个六位的二进制数,高三位表示所在组,低三位表示组内的号,因此y<<3+x就是找到的最高优先级数了,实在佩服OSUnMapTbl[ ]的设计。

 


http://www.niftyadmin.cn/n/3354281.html

相关文章

Cache的使用

1.Cache与Session的区别每个用户都有自己单独的Session对象但是放在Cache中的数据是大家共享的 protected void SetCache() { //判断缓存是否为空 if (Cache["UserInfo"] null) { Bll.UserInfoBll userInfobll new Bll.UserInfoBll(); //如果为空了&#xff0c;需要…

uC/OS学习笔记2

引 言&#xff1a;1 uC/OS-II的运行机制  在嵌入式系统的应用中&#xff0c;实时性是一个重要的指标&#xff0c;而优先级翻转是影响系统实时性的重要问题。本文着重分析优先级翻转问题的产生和影响&#xff0c;以及在uC/OS-II中的解决方案。  uC/OS-II采用基于固定优先级的…

java小面试题

1、声明式事务和编程式事物的区别&#xff1a; 编程式事务需要你在代码中直接加入处理事务的逻辑,可能需要在代码中显式调用beginTransaction()、commit()、rollback()等事务管理相关的方法,如在执行a方法时候需要事务处理,你需要在a方法开始时候开启事务,处理完后。在方法结束…

将建设中公路项目的滑模施工节奏和要点掌握

产出公路项目路平石模具的主要步骤目前大多数依赖于施工机械设备&#xff0c;对于建设中的节奏和管理是相互促进的&#xff0c;准确的将建设工作落实是重点&#xff0c;施工的要点落实的要切实有效才行&#xff0c;整体的节奏在于进度的跟进&#xff0c;以及对于建设方面重点工…

施工机械在路平石模具建设方面的质量控制标准

对于质量的控制方面的建设工作&#xff0c;在公路施工中建设方面采用机械设备来实现&#xff0c;在符合了涉及的要求&#xff0c;在制作的过程中和交付的环节进行检查&#xff0c;记录一些对于通用要求有帮助的环节&#xff0c;来实现项目建设的突破和发展。 对于建设路缘石等品…

uC/OS学习比较3

OSTimeDly 在Task中&#xff0c;一般执行一段时间之后调用OSTimeDly推迟一段时间再继续运行&#xff0c;OSTimeDly将本进程从Ready TCBList中删除&#xff0c;然后将Delay的时间设置给OSTCBDly&#xff0c;最后调用OS_Sched进行进程调度。 void OSTimeDly (INT16U ticks) { INT…

msql小技巧

前言&#xff1a; mysql同样的设置&#xff0c;在不同的环境下 &#xff0c;由于内存&#xff0c;访问量&#xff0c;读写频率&#xff0c;数据差异等等情况&#xff0c;可能会出现不同的结果&#xff0c;因此简单地根据某个给出方案来配置mysql是行不通的&#xff0c;最好能使…

node.js从入门到放弃(二)

上章讲了学习node&#xff0c;应该去学习什么&#xff0c;对这些框架去进行学习现在咋们聊聊如何用原生来进行操作 主要来讲一下events-事件触发器 events是什么东西呢&#xff1f;他的英文翻译&#xff0c;活动&#xff0c;事件的意思&#xff0c;在计算机语言离也是事件的意思…