ucosiii应用开发指南挂起一个任务怎么恢复

嵌入式(6)
任务简介:
任务即由系统管理的程序实体,由三部分组成:
任务堆栈:本质是一个数组,不同的任务在创建前可以自己定义相关数组的大小;任务控制块:本质上是一个结构体,用于保存任务当前的各种状态信息,其成员只可用uCOSIII相关函数访问,用户不可直接访问;任务函数:即表达任务功能的地方,通过系统调用来切换,分为运行至完成型(完成后自我删除)和无限循环型(while(1));
任务还有一些其他属性,如优先级等等,这些在以后使用中会注意到;
任务状态:
用户角度:
休眠态:任务已经在CPU的flash中了,但未注册而不受UCOSIII管理;就绪态:系统为任务分配了任务控制块,并且满足运行的条件,任务已经在就绪队列中;运行态:任务获得CPU的使用权,正在运行;等待态:任务需要等待等待某个事件或外设,进入等待队列中,此时系统就会把CPU使用权转交给别的任务;中断服务态:当发送中断,当前正在运行的任务会被挂起,CPU转而去执行中断服务函数,此时任务即中断服务态;
操作系统角度:
有八种状态,且每种状态在操作系统中都有相关宏定义表示,而OS_TCB中也记录了任务当前属于哪种状态:从图中可以看出进入每种状态的条件(调用什么函数);
任务基本属性:
根据实际任务为相应任务分配合理大小的堆栈(--------具体方式应查一下);uCOSIII中建议用静态分配栈,动态会生成很多碎片;注意堆栈溢出情况,采取堆栈溢出检测:
MMU或MPU检测:配置硬件;具有堆栈溢出检测功能CPU:CPU堆栈指针SP高于/低于某个预定值产生异常;
这个预定值(stk_limit,堆栈限位)在创建任务时会作为OSTaskCreate()参数传给OS_TCB;此种堆栈限位值可以很接近堆栈底,任务运行时常存在一个寄存器(堆栈溢出检测寄存器)中;上下文切换时先让此寄存器指向NULL;再改变SP的值;之后再改变此寄存器值为新任务stk_
基于软件堆栈溢出检测:任务切换函数中添加相关代码,模拟硬件实现方式;
没有硬件可靠,且stk_limit值离堆栈底应远一点;
系统中的OSTaskStkChk()函数可以用于计算任务堆栈使用量;
uCOSIII优先级个数可为无穷大,默认的是64,由os_cfg.h中的OS_CFG_PRIO_MAX决定,值越小代表优先级越高;最高优先级任务(0优先级)为中断服务管理任务(OS_IntQTask()),最低优先级为系统的空闲任务;用户可以为用户任务设置优先级,但设置原则建议为:单调执行率调度法(执行频率高的任务优先级高):高优先级可以抢占低优先级,同优先级间采用轮转时间片调度;
任务相关操作:
任务创建:主要调用OSTaskCreate()函数,由于其参数表较为复杂,此处列出:
系统任务:
空闲任务(OS_IdleTask(),os_core.c):
是UCOSIII创建的第一个任务,亦是必须创建的任务,此任务在OSInit()内由系统创建;任务优先级为OS_CFG_PRIO_MAX-1,其他任务不允许使用此优先级;其他任务未就绪时,系统运行空闲任务;空闲任务内有两个计数器:
OSIdleTaskCtr:表示空闲任务活跃度;OSStatTaskCtr:由统计任务控制,统计程序运行CPU利用情况;
该任务有个OSIdleTaskHook()的函数,允许用户做一些额外操作,但这些操作不可使空闲任务进入等待态;
时钟节拍任务/时基任务(OS_TickTask(),os_tick.c):
用于处理时钟节拍,是必须创建的任务;任务优先级在os_cfg_app.h文件中OS_CFG_TICK_TASK_PRIO设置,其优先级应纸币用户系统中最重要的任务优先级低一点(通常设置为1或2);该任务等待时钟节拍(定时器)发送的信号,进入就绪态,启动任务;在此任务内,系统会遍历所有等待延时或指定时间内等待某内核对象的任务(即时钟节拍列表---时钟节拍轮)---关于此表在中文书79页,很有意思,此处不详述;更新时钟节拍列表大部分在临界区代码完成的;
统计任务(OS_StatTask(),os_stat.c):
可选任务,通过os_cfg.h中的OS_CFG_STAT_TASK_EN控制;任务优先级为os_cfg_app.h文件中OS_CFG_STST_TASK_PRIO设置;用于统计总CPU使用率,各任务CPU使用率,各任务堆栈使用量,CPU利用率从0~10000表示从0.00%~100.00%,具体计算方法不细述;使用此任务,main函数在调用OSStart()前只可创建一个用户任务,此任务中应先调用OSStatTaskCPUUsageInit()函数,然后才可创建其他任务;系统会把每个任务运行统计结果存入每个任务OS_TCB中;
定时任务(OS_TmrTask(),os_tmr.c):
是可选任务,由os_cfg.h中的OS_CFG_TMR_EN控制是否使用此任务;任务优先级为os_cfg_app.h文件中OS_CFG_TMR_TASK_PRIO设置,常设为中等优先级;和时钟节拍任务使用相同的中断源,但会对时钟节拍进行分频,多少个节拍后产生一个相关信号量;
中断服务管理任务(OS_IntQTask()、os_int.c):
是可选任务,由os_cfg.h中的OS_CFG_ISR_POST_DEFERRED_EN控制;当通过调度器解/上锁管理临界区时,ISR调用Post函数不会直接操纵等待表等,而是先放入一缓冲队列;中断结束之后进行任务切换,此时该任务会把相关消息、信号传递给对应任务;这种方式(延迟发布)降低了关中断时间;
任务就绪表:
就绪优先级位映射表(OSPrioTbl[]):
某一优先级有对应任务就绪,该表对应位会被置1;此表中优先级从左到右从上到下逐渐降低,这样在某些CPU中查找最高优先级速度会较快;该表相关配置和操作函数在os_prio.h/.c文件内;
就绪任务列表(OSRdyList[]):
是一个包含OS_CFG_PRIO_MAX项的结构体数组,每一项对应存储这个优先级任务的队列;操作就绪任务列表的函数在os_core.c文件内,包括创建新任务时会入就绪队列;初始化时该数组中相关元素相关元素都会被初始化;
任务调度:
调度方式:
是抢占式的,分为直接发布和延迟发布两种模式,最终结果一样:
直接发布:
中断服务函数中,直接向某个任务发布信号量或消息等;中断结束后直接进入更高优先级的任务,而不先返回原来任务;
延迟发布:
中断中将要发布的信息先放入相关缓冲队列中;退出中断后会进入最高优先级的中断服务管理任务(OS_IntQTask());该函数内根据消息队列发布相关操作,这有利于减少关中断事件;
任务向另一任务发送信号量或消息:
一个任务调用OS_XXX_Post()函数时,该函数结束后即发生任务调度;当OS_OPT_POST_NO_SCHED使能时则不发生任务调度;
当前任务调用STimeDly()或OSTimeDlyHMSM():
该任务会被放入等待延时列表(时钟节拍轮)中,启动调度器;
任务执行到需要等待一个事件发生时:
通常是调用了OS_XXX_Pend()函数,当前任务被放入等待事件列表中;若指定了等待的时间,还会入等待超时队列中;
任务取消等待一个事件:
任务调用OS_XXX_PendAbort()取消对一事件的等待,此时会从相关等待队列删除,系统重新调度;
创建任务,删除当前任务:此时亦会启动调度器;删除内核对象:
系统通知等待该内核任务,这些任务转入就绪态。重新调度;
有任务优先级被改变时;任务自我挂起或者解挂:
分别调用OSTaskSuspend()和OSTaskResume()函数;
退出所有嵌套中断时:
此时系统会检查这些中断是否使某些优先级任务进入就绪态;这时候任务调度通过OSIntExit()函数实现;
任务放弃当前时间片(礼让);
即调用OSSchedRoundRobinYield()函数;
用户手动调度:
即显式的调用OSSched()函数,这主要用于使能OS_OPT_POST_NO_SCHED时,调用OS_XXX_Post()函数不会产生调度时;这样可以一次发布多个信息后进行一次任务调度,而非每次发布后执行;
轮转时间片:
多个同优先级任务时,系统使用此方式管理,用户可使能或禁止;允许一个任务主动放弃CPU,即“礼让”,用户可在运行时改变默认时间片长度(QSTaskTimeQuantaSet()函数);可以为每个任务制定不同长度的时间片;
几个调度函数:
OSSched()函数:
该函数是任务级调度器,不可在ISR_Func内被调用;进入此函数时中断应关闭的,退出时中断应重新开始;扫描就绪任务表,一旦要调度,则调用任务级上下文切换函数;
OSIntExit()函数:
此函数通常会在ISR_Func结束时被调用来调度任务;当任务调度器未上锁,且是最后一层嵌套的中断中,该函数执行调度;查询任务就绪表,调用中断级上下文切换函数;
OS_SshedRoundRobin()函数:
用于进行同优先级下的时间片轮转调度;直接发布时由OSTimeTick()函数调用,延迟发布时由OS_IntQTask()函数调用;
上下文切换:
主要作用是将当前任务现场保存到任务堆栈中;不同CPU寄存器数不同,故这部分代码移植时应根据实际CPU修改,具体在os_cpu.h、os_cpu_c.c、os_cpu_a.asm文件中;寄存器中的PC和状态寄存器(SR)先入栈,这是硬件自动完成的,其他由软件入栈,任务堆栈指针不入栈,而直接存入OS_TCB中;具体的两个切换函数都是在os_cpu_a.asm中用汇编写的;
任务级OSCtxSw()函数:
先将当前任务相关寄存器存入任务堆栈,入栈顺序一般和中断时一样;将当前堆栈指针值存入当前任务OS_TCB中;将新任务OS_TCB中的任务堆栈指针值载入堆栈指针寄存器中;从新任务堆栈中依次弹栈,恢复现场;
中断级OSIntCtxSw()函数:
与任务级不同,中断级在切换前默认发生中断时CPU寄存器已被存入相关堆栈内;所以其只完成任务级的后两步;
任务挂起表:
功能概述:
当前任务等待某一内核对象或者消息时,用来记录的地方;其本质是一个个链表,每个内核对象或者消息对应一个链表,表中高优先级任务放在前面;链表的表头中记录等待对象的结构体被称为OS_PEND_OBJ,有以下元素:
Type:表明该表中元素等待的内核对象的类型,四个字节的ANSII码表示;NamePtr:指向该种内核对象的一个确切实体的名字;
任务挂起表内元素不是OS_TCB,而是OS_PEND_DATA结构体,位于任务自己的堆栈内;该结构体内指针可以指向自己的OS_TCB,而OS_TCB亦可指向自己的OS_PEND_DATA;
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:2110次
排名:千里之外&&&&uCOS-II任务创建挂起恢复和删除实验
&uCOS-II任务创建挂起恢复和删除实验
一个多任务程序,要求任务1式按键key检测任务,任务2为led控制任务,任务3是蜂鸣器控制任务。通过三个任务的切换,实现如下效果:蜂鸣器鸣叫并延时3s,进入等待按键状态,若有按键按下,则进入led流水闪烁阶段,无按键则继续等待。Led流水任务完成后,蜂鸣器鸣叫并延时3s,再进入等待按键阶段。
若举报审核通过,可奖励20下载分
被举报人:
举报的资源分:
请选择类型
资源无法下载
资源无法使用
标题与实际内容不符
含有危害国家安全内容
含有反动色情等内容
含广告内容
版权问题,侵犯个人或公司的版权
*详细原因:
VIP下载&&免积分60元/年(1200次)
您可能还需要
Q.为什么我点的下载下不了,但积分却被扣了
A. 由于下载人数众多,下载服务器做了并发的限制。若发现下载不了,请稍后再试,多次下载是不会重复扣分的。
Q.我的积分不多了,如何获取积分?
A. 获得积分,详细见。
完成任务获取积分。
论坛可用分兑换下载积分。
第一次绑定手机,将获得5个C币,C币可。
关注并绑定CSDNID,送10个下载分
下载资源意味着您已经同意遵守以下协议
资源的所有权益归上传用户所有
未经权益所有人同意,不得将资源中的内容挪作商业或盈利用途
CSDN下载频道仅提供交流平台,并不能对任何下载资源负责
下载资源中如有侵权或不适当内容,
本站不保证本站提供的资源的准确性,安全性和完整性,同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
操作系统下载排行
您当前C币:0&&&可兑换 0 下载积分
兑换下载分:&
消耗C币:0&
立即兑换&&
兑换成功你当前的下载分为 。前去下载资源
你下载资源过于频繁,请输入验证码
如何快速获得积分?
你已经下载过该资源,再次下载不需要扣除积分
uCOS-II任务创建挂起恢复和删除实验
所需积分:2
剩余积分:0
扫描微信二维码精彩活动、课程更新抢先知
VIP会员,免积分下载
会员到期时间:日
剩余下载次数:1000
uCOS-II任务创建挂起恢复和删除实验
剩余次数:&&&&有效期截止到:
你还不是VIP会员VIP会员享免积分 . 专属通道极速下载
VIP下载次数已满VIP会员享免积分 . 专属通道极速下载,请继续开通VIP会员
你的VIP会员已过期VIP会员享免积分 . 专属通道极速下载,请继续开通VIP会员ucos-iii任务
这回说下任务建立,那么我们看下任务控制块有哪些内容:
(这系统越来越大,任务控制块的内容也是越来越多了,呵呵)
struct os_tcb {
& & CPU_STK & & & & & & *StkP & & & & & & & & & & & & & &/*这是堆栈指针,指向任务自己的堆栈的操作端*/
& & void & & & & & & & &*ExtP & & & & & & & & & & & & & &/*如果我们还为任务建了数据缓冲区,就用这个指针指向这个地址*/
& & CPU_STK & & & & & & *StkLimitP & & & & & & & & & & & /*这是怕咱把堆栈用冒了,限制堆栈空间大小的*/
& & OS_TCB & & & & & & &*NextP & & & & & & & & & & & & & /*建立了任务,prio值一样的,就会连接在一起,不管你是什么状态,能不能动,这个是指向前一个任务控制块*/
& & OS_TCB & & & & & & &*PrevP & & & & & & & & & & & & & /* 指向后一个任务控制块*/
& & OS_TCB & & & & & & &*TickNextP
/*有些任务可能在睡觉呢,要经过一定的时钟节拍才会醒,这些任务就用这个连在一起*/
& & OS_TCB & & & & & & &*TickPrevP
/*同上,只不过,前一个指向前面的任务控制块,这个是指向后面的*/
& & OS_TICK_SPOKE & & & *TickSpokeP & & & & & & & & & & &/* 也是当任务被delay时用来管理任务的 */
& & CPU_CHAR & & & & & &*NameP & & & & & & & & & & & & & /* 给任务起名字,感觉没太大用处*/
& & CPU_STK & & & & & & *StkBaseP & & & & & & & & & & & &/* */
& & OS_TASK_PTR & & & & &TaskEntryA & & & & & & & & & & /* 指向任务的函数体*/
& & void & & & & & & & &*TaskEntryA & & & & & & & & & & &/*这个我就知道怎么用了,反正也没看到内核用到它,可能也是给用户的,给个0就行了,不用在意 */
& & OS_PEND_DATA & & & &*PendDataTblP & & & & & & & & & &/*任务会因为等资源而被挂起,这个就先不说了*/
& & OS_STATE & & & & & & PendOn; & & & & & & & & & & & & & &/* 指示任务被挂起下面说一下。 */
& & OS_STATUS & & & & & &PendS & & & & & & & & & & & &/* 挂起的状态 下面说*/
& & OS_STATE & & & & & & TaskS & & & & & & & & & & & & /* See OS_TASK_STATE_xxx任务的状态,下面说 & & & & & & & &*/
& & OS_PRIO & & & & & & &P & & & & & & & & & & & & & & &/* Task priority (0 == highest)优先级 & & & & & & & & & & */
& & CPU_STK_SIZE & & & & StkS & & & & & & & & & & & & & /* 堆栈的大小
& & OS_OPT & & & & & & & O & & & & & & & & & & & & & & & /* 留给任务的一些选项,下面说吧 & & & & & & & */
& & OS_OBJ_QTY & & & & & PendDataTblE & & & & & & & &/* Size of array of objects to pend on & & & & & & & & & &*/
& & CPU_TS & & & & & & & TS; & & & & & & & & & & & & & & & &/* 时间戳,得到任务建立的时间 & & & & & & & & & & & & & & */
& & OS_SEM_CTR & & & & & SemC & & & & & & & & & & & & & &/* 信号量,等说到这个资源时吧,这里不说了 & & & & & & & & */
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & /* DELAY / TIMEOUT这三个变量也是一言难尽 & & & & & & & & &*/
& & OS_TICK & & & & & & &TickCtrP & & & & & & & & & & & /* Previous time when task was & & & & & &ready & & & & & */
& & OS_TICK & & & & & & &TickCtrM & & & & & & & & & & &/* Absolute time when task is going to be ready & & & & & */
& & OS_TICK & & & & & & &TickR & & & & & & & & & & & &/* Number of ticks remaining for a match (updated at ... &*/
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & /* ... run-time by OS_StatTask() & & & & & & & & & & & & &*/
& & OS_TICK & & & & & & &TimeQ/*这两个说过了,不说了*/
& & OS_TICK & & & & & & &TimeQuantaC
#if OS_MSG_EN & 0u
& & void & & & & & & & &*MsgP & & & & & & & & & & & & & &/* 得到的消息资源就放在这 & & & & & & & & & & & & & & & & & & &*/
& & OS_MSG_SIZE & & & & &MsgS
/* 消息量*/
#if OS_CFG_TASK_Q_EN & 0u
& & OS_MSG_Q & & & & & & MsgQ; & & & & & & & & & & & & & & &/* 消息队列 & & & & & & & & & & */
#if OS_CFG_TASK_PROFILE_EN & 0u
& & CPU_TS & & & & & & & MsgQPendT & & & & & & & & & & &/* Time it took for signal to be received & & & & & & & & */
& & CPU_TS & & & & & & & MsgQPendTimeM & & & & & & & & & /* Max amount of time it took for signal to be received & */
#if OS_CFG_TASK_REG_TBL_SIZE & 0u
& & OS_REG & & & & & & & RegTbl[OS_CFG_TASK_REG_TBL_SIZE]; &/* Task specific registers & & & & & & & & & & & & & & & &*/
#if OS_CFG_FLAG_EN & 0u
& & OS_FLAGS & & & & & & FlagsP & & & & & & & & & & & & /* 等待的标志位资源 & & & & & & & & & & & & & & & */
& & OS_FLAGS & & & & & & FlagsR & & & & & & & & & & & & &/* & & & & & & & & */
& & OS_OPT & & & & & & & FlagsO & & & & & & & & & & & & &/* Options (See OS_OPT_FLAG_xxx)标志的选项 & & & & & & & */
#if OS_CFG_TASK_SUSPEND_EN & 0u
& & OS_NESTING_CTR & & & SuspendC & & & & & & & & & & & &/* Nesting counter for OSTaskSuspend()当一个任务的任务控制块为空时会用到这个 & & & & & & */
#if OS_CFG_TASK_PROFILE_EN & 0u
/*下面都是统计的,说到统计任务时候说吧*/
& & OS_CPU_USAGE & & & & CPUU & & & & & & & & & & & & &/* CPU Usage of task (0-100%) & & & & & & & & & & & & & & */
& & OS_CTX_SW_CTR & & & &CtxSwC & & & & & & & & & & & & &/* Number of time the task was switched in & & & & & & & &*/
& & CPU_TS & & & & & & & CyclesD & & & & & & & & & & & /* value of OS_TS_GET() - .CyclesStart & & & & & & & & & &*/
& & CPU_TS & & & & & & & CyclesS & & & & & & & & & & & /* Snapshot of cycle counter at start of task resumption &*/
& & OS_CYCLES & & & & & &CyclesT & & & & & & & & & & & /* Total number of # of cycles the task has been running &*/
& & OS_CYCLES & & & & & &CyclesTotalP & & & & & & & & & /* Snapshot of previous # of cycles & & & & & & & & & & & */
& & CPU_TS & & & & & & & SemPendT & & & & & & & & & & & /* Time it took for signal to be received & & & & & & & & */
& & CPU_TS & & & & & & & SemPendTimeM & & & & & & & & & &/* Max amount of time it took for signal to be received & */
#if OS_CFG_STAT_TASK_STK_CHK_EN & 0u
& & CPU_STK_SIZE & & & & StkU & & & & & & & & & & & & & /* Number of stack elements used from the stack & & & & & */
& & CPU_STK_SIZE & & & & StkF & & & & & & & & & & & & & /* Number of stack elements free on & the stack & & & & & */
#ifdef CPU_CFG_INT_DIS_MEAS_EN
& & CPU_TS & & & & & & & IntDisTimeM & & & & & & & & & & /* Maximum interrupt disable time & & & & & & & & & & & & */
#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN & 0u
& & CPU_TS & & & & & & & SchedLockTimeM & & & & & & & & &/* Maximum scheduler lock time & & & & & & & & & & & & & &*/
#if OS_CFG_DBG_EN & 0u
& & OS_TCB & & & & & & &*DbgPrevP
& & OS_TCB & & & & & & &*DbgNextP
& & CPU_CHAR & & & & & &*DbgNameP
/******************************************************************************************************
OS_STATE & & & & & & PendOn这个变量取如下值
#define &OS_TASK_PEND_ON_NOTHING & & & & & & &(OS_STATE)( &0u) &/* 不等任何资源
& & & & & & & & & & & */
#define &OS_TASK_PEND_ON_FLAG & & & & & & & & (OS_STATE)( &1u) &/* 如果是因为等待标志位被挂起的话PendOn等于这个值
#define &OS_TASK_PEND_ON_TASK_Q & & & & & & & (OS_STATE)( &2u) &/* 因等待消息而被挂起
& & & & & & &*/
#define &OS_TASK_PEND_ON_MULTI & & & & & & & &(OS_STATE)( &3u) &/* 如果是等待多个资源的话就赋这个值
#define &OS_TASK_PEND_ON_MUTEX & & & & & & & &(OS_STATE)( &4u) &/* 因等互诉信号而被挂起的话为这个值 & & & & & & & & & */
#define &OS_TASK_PEND_ON_Q & & & & & & & & & &(OS_STATE)( &5u) &/* 等待队列 & & & & & & & & & & & & & & & & & & & & & */
#define &OS_TASK_PEND_ON_SEM & & & & & & & & &(OS_STATE)( &6u) &/* 等待信号量 & & & & & & & & & & & & & & & & & & & & */
#define &OS_TASK_PEND_ON_TASK_SEM & & & & & & (OS_STATE)( &7u) &/* 这个和上面什么不同我还不清楚 & & & & & & & & & & & */
*******************************************************************************************************/
/******************************************************************************************************
TaskState任务状态(注意注释里的二进制值,你会发现更多)
#define &OS_TASK_STATE_RDY & & & & & & & & & &(OS_STATE)( &0u) &/* & 0 0 0 & & 就绪 & & & & & & & & & & & & & & & & & */
#define &OS_TASK_STATE_DLY & & & & & & & & & &(OS_STATE)( &1u) &/* & 0 0 1 & & delay延时 & & & & & & & & & & & & & & &*/
#define &OS_TASK_STATE_PEND & & & & & & & & & (OS_STATE)( &2u) &/* & 0 1 0 & & 因等资源而被挂起 & & & & & & & & & & & */
#define &OS_TASK_STATE_PEND_TIMEOUT & & & & & (OS_STATE)( &3u) &/* & 0 1 1 & & 因等资源而被挂起,并且在等资源时有时间限制*/
下面单说下面的状态是在调用了void & OSTaskSuspend (OS_TCB &*p_tcb,
& & & & & & & & & & &
OS_ERR &*p_err)后得到的
#define &OS_TASK_STATE_SUSPENDED & & & & & & &(OS_STATE)( &4u) &/* & 1 0 0 & & Suspended & & & & & & & & & & & & & & &*/
#define &OS_TASK_STATE_DLY_SUSPENDED & & & & &(OS_STATE)( &5u) &/* & 1 0 1 & & Suspended + Delayed or Timeout & & & & */
#define &OS_TASK_STATE_PEND_SUSPENDED & & & & (OS_STATE)( &6u) &/* & 1 1 0 & & Suspended + Pend & & & & & & & & & & & */
#define &OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED (OS_STATE)( &7u) &/* & 1 1 1 & & Suspended + Pend + Timeout & & & & & & */
这是说明该任务被删除了
#define &OS_TASK_STATE_DEL & & & & & & & & & &(OS_STATE)(255u)
前4个不用说了,说下SUSPENDED的吧,
如果原来是OS_TASK_STATE_RDY,调用了OSTaskSuspend 函数的话就会得到OS_TASK_STATE_SUSPENDED状态,这个状态就是不干活,
如果原来是OS_TASK_STATE_DLY,调用了OSTaskSuspend 函数的话就会得到OS_TASK_STATE_DLY_SUSPENDED
剩下的两个的同上。
如果一个任务是OS_TASK_STATE_DLY_SUSPENDED,如果延时时间到了,就会变成OS_TASK_STATE_SUSPENDED,这个状态还是不会干活的
如果这时调用了void &OSTaskResume (OS_TCB &*p_tcb,
& & & & & & & & & &
OS_ERR &*p_err)这时就会变成OS_TASK_STATE_RDY,这样就能干活了。
*******************************************************************************************************/
/******************************************************************************************************
& & OS_OPT & & & & & & & O 看英语就能明白了,不说了
#define &OS_OPT_TASK_NONE & & & & & & & & & &(OS_OPT)(0x0000u) &/* No option selected & & & & & & & & & & & & & & & & */
#define &OS_OPT_TASK_STK_CHK & & & & & & & & (OS_OPT)(0x0001u) &/* Enable stack checking for the task & & & & & & & & */
#define &OS_OPT_TASK_STK_CLR & & & & & & & & (OS_OPT)(0x0002u) &/* Clear the stack when the task is create & & & & & &*/
#define &OS_OPT_TASK_SAVE_FP & & & & & & & & (OS_OPT)(0x0004u) &/* Save the contents of any floating-point registers &*/
*******************************************************************************************************/
其他资源用到时说,这里说可能有点早,先说任务的建立吧
/******************************************************************************************************
void &OSTaskCreate (OS_TCB & & & &*p_tcb, &/*和以前不同,ucos-iii的任务控制块是要我们用的时候自己明名一个*/
& & & & & & & & & & CPU_CHAR & & &*p_name,
& & & & & & & & & & OS_TASK_PTR & &p_task,
& & & & & & & & & & void & & & & &*p_arg,
& & & & & & & & & & OS_PRIO & & & &prio,
& & & & & & & & & & CPU_STK & & & *p_stk_base,
& & & & & & & & & & CPU_STK_SIZE & stk_limit,
& & & & & & & & & & CPU_STK_SIZE & stk_size,
& & & & & & & & & & OS_MSG_QTY & & q_size,
& & & & & & & & & & OS_TICK & & & &time_quanta,
& & & & & & & & & & void & & & & &*p_ext,
& & & & & & & & & & OS_OPT & & & & opt,
& & & & & & & & & & OS_ERR & & & &*p_err)
& & CPU_STK_SIZE &
#if OS_CFG_TASK_REG_TBL_SIZE & 0u
& & OS_OBJ_QTY & & reg_
& & CPU_STK & & & *p_
& & CPU_STK & & & *p_stk_
& & CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
& & if (p_err == (OS_ERR *)0) {
& & & & OS_SAFETY_CRITICAL_EXCEPTION();
#ifdef OS_SAFETY_CRITICAL_IEC61508
& & if (OSSafetyCriticalStartFlag == DEF_TRUE) {
& & & &*p_err = OS_ERR_ILLEGAL_CREATE_RUN_TIME;
#if OS_CFG_CALLED_FROM_ISR_CHK_EN & 0u
& & if (OSIntNestingCtr & (OS_NESTING_CTR)0) { & & & & & & &/* ---------- CANNOT CREATE A TASK FROM AN ISR ---------- */
& & & & *p_err = OS_ERR_TASK_CREATE_ISR;
#if OS_CFG_ARG_CHK_EN & 0u & & & & & & & & & & & & & & & & &/* ---------------- VALIDATE ARGUMENTS ------------------ */
& & if (p_tcb == (OS_TCB *)0) { & & & & & & & & & & & & & & /* User must supply a valid OS_TCB & & & & & & & & & & & &*/
& & & & *p_err = OS_ERR_TCB_INVALID;
& & if (p_task == (OS_TASK_PTR)0) { & & & & & & & & & & & & /* User must supply a valid task & & & & & & & & & & & & &*/
& & & & *p_err = OS_ERR_TASK_INVALID;
& & if (p_stk_base == (CPU_STK *)0) { & & & & & & & & & & & /* User must supply a valid stack base address & & & & & &*/
& & & & *p_err = OS_ERR_STK_INVALID;
& & if (stk_size & OSCfg_StkSizeMin) { & & & & & & & & & & &/* User must supply a valid minimum stack size & & & & & &*/
& & & & *p_err = OS_ERR_STK_SIZE_INVALID;
& & if (stk_limit &= stk_size) { & & & & & & & & & & & & & &/* User must supply a valid stack limit & & & & & & & & & */
& & & & *p_err = OS_ERR_STK_LIMIT_INVALID;
& & if (prio &= OS_CFG_PRIO_MAX) { & & & & & & & & & & & & &/* Priority must be within 0 and OS_CFG_PRIO_MAX-1 & & & &*/
& & & & *p_err = OS_ERR_PRIO_INVALID;
#if OS_CFG_ISR_POST_DEFERRED_EN & 0u
& & if (prio == (OS_PRIO)0) {
& & & & if (p_tcb != &OSIntQTaskTCB) {
& & & & & & *p_err = OS_ERR_PRIO_INVALID; & & & & & & & & & /* Not allowed to use priority 0 & & & & & & & & & & & & &*/
& & & & & &
& & if (prio == (OS_CFG_PRIO_MAX - 1u)) {
& & & & if (p_tcb != &OSIdleTaskTCB) {
& & & & & & *p_err = OS_ERR_PRIO_INVALID; & & & & & & & & & /* Not allowed to use same priority as idle task & & & & &*/
& & & & & &
/*之前都是排错处理,这里就不说了。说下面的*/
& & OS_TaskInitTCB(p_tcb); & & & & & & & & & & & & & & & & &/* 给你这个任务控制块赋初值 & & & & & & & & &*/
& & *p_err = OS_ERR_NONE;
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & /* --------------- CLEAR THE TASK'S STACK --------------- */
& & if ((opt & OS_OPT_TASK_STK_CHK) != (OS_OPT)0) { & & & & /* 任务的一些选项设置,这里是看要不要查看任务堆栈 & & & & & & & & */
& & & & if ((opt & OS_OPT_TASK_STK_CLR) != (OS_OPT)0) { & & /* 这里是看要不要把不为0的清0,也不一定必要吧,下面初始化任务堆栈时会赋合适的值的*/
& & & & & & p_sp = p_stk_
& & & & & & for (i = 0u; i & stk_ i++) { & & & & & & & /* Stack grows from HIGH to LOW memory & & & & & & & & & &*/
& & & & & & & & *p_sp = (CPU_STK)0; & & & & & & & & & & & & /* Clear from bottom of stack and up! & & & & & & & & & & */
& & & & & & & & p_sp++;
& & & & & & }
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & /* ------- INITIALIZE THE STACK FRAME OF THE TASK ------- */
#if (CPU_CFG_STK_GROWTH == CPU_STK_GROWTH_HI_TO_LO)/*堆栈增涨方式是从高地址到低地址,还是低地址到高地址*/
& & p_stk_limit = p_stk_base + stk_/*堆栈限制区如果是从高到低的话,很明显是最后的从P_stk_base到p_stk_limit设为禁用*/
& & p_stk_limit = p_stk_base + (stk_size - 1u) - stk_/*如果从低到高的增涨方式,到从p_stk_limit到p_stk_base+(stk_size-1)设为禁用*/
& & p_sp = OSTaskStkInit(p_task, & &/*堆栈初始化*/
& & & & & & & & & & & & &p_arg,
& & & & & & & & & & & & &p_stk_base,
& & & & & & & & & & & & &p_stk_limit,
& & & & & & & & & & & & &stk_size,
& & & & & & & & & & & & &opt);
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & /* -------------- INITIALIZE THE TCB FIELDS ------------- */
& & p_tcb-&TaskEntryAddr = p_ & & & & & & & & & & & & &/* 任务函数的入口址 & & & & & & & & & & & & */
& & p_tcb-&TaskEntryArg &= p_ & & & & & & & & & & & & & /* 参数,不多说了 & & & & & & & & & & & & & & & */
& & p_tcb-&NamePtr & & & = p_ & & & & & & & & & & & & &/* 任务名,也就是字符串 & & & & & & & & & & & & & & & & & & & & */
& & p_tcb-&Prio & & & & &= & & & & & & & & & & & & & &/* 任务的优先级 & & & & & & & & & & & & & & &*/
& & p_tcb-&StkPtr & & & &= p_ & & & & & & & & & & & & & &/* 这是OSTaskStkInit的返回值,是堆栈能操作的一端 & & & & &*/
& & p_tcb-&StkLimitPtr & = p_stk_ & & & & & & & & & & /* 设置限制区
& & & & & & & & & & & & & &*/
& & p_tcb-&TimeQuanta & &= time_ & & & & & & & & & & /* 上节有说过,同一优先级值的任务的轮转
#if OS_CFG_SCHED_ROUND_ROBIN_EN & 0u
& & if (time_quanta == (OS_TICK)0) {
& & & & p_tcb-&TimeQuantaCtr = OSSchedRoundRobinDfltTimeQ
& & } else {
& & & & p_tcb-&TimeQuantaCtr = time_
& & p_tcb-&ExtPtr & & & &= p_ & & & & & & & & & & & & & /* 指向你为这个任务建的数据区地址 & & & & & & & & & & & & */
& & p_tcb-&StkBasePtr & &= p_stk_ & & & & & & & & & & &/* 任务的基地地,不代表堆栈从这开始操作,也不代表从反向开始操作。*/
& & p_tcb-&StkSize & & & = stk_ & & & & & & & & & & & &/* 任务堆栈的大小 & &*/
& & p_tcb-&Opt & & & & & = & & & & & & & & & & & & & & /* 任务的选项卡,上面还真说了 & & & & & & & & & & & & & & & & & & */
#if OS_CFG_TASK_REG_TBL_SIZE & 0u
& & for (reg_nbr = 0u; reg_nbr & OS_CFG_TASK_REG_TBL_SIZE; reg_nbr++) {
& & & & p_tcb-&RegTbl[reg_nbr] = (OS_REG)0; & & & & /*这里可以装数据*/
#if OS_CFG_TASK_Q_EN & 0u
& & OS_MsgQInit(&p_tcb-&MsgQ, & & & & & & & & & & & & & & & /* 初始化这个任务的消息 & & & & & & & & &*/
& & & & & & & & q_size);
& & OSTaskCreateHook(p_tcb); & & & & & & & & & & & & & & & &/* 调用勾子函数,要我们自己写,也可以是空的 & & & & & & & */
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & /* --------------- ADD TASK TO READY LIST --------------- */
& & OS_CRITICAL_ENTER();/*这两个下面说吧*/
& & OS_PrioInsert(p_tcb-&Prio);
& & OS_RdyListInsertTail(p_tcb);
#if OS_CFG_DBG_EN & 0u
& & OS_TaskDbgListAdd(p_tcb);
& & OSTaskQty++; & & & & & & & & & & & & & & & & & & & & & &/* 当前系统的任务数 & & & & & & & & & & & & & */
& & if (OSRunning != OS_STATE_OS_RUNNING) { & & & & & & & & /* OSRunning是不是运行状态如果还没调用OSStart的话就不是,那么到些返回 */
& & & & OS_CRITICAL_EXIT();
& & OS_CRITICAL_EXIT_NO_SCHED();
& & OSSched();/*要是调用过OSStart就到这进行任务调度*/
*******************************************************************************************************/
/******************************************************************************************************
OS_PrioInsert(p_tcb-&Prio)这个在上节说了,就是在建立任务时这个任务一定是就绪的,所以就会注册到OSPrioTbl[ix]中合适的位置。
OS_RdyListInsertTail说下这个函数,说到它了就不得不说下p_rdy_list,
struct &os_rdy_list {
& & OS_TCB & & & & & & &*HeadP & & & & & & & & & & & & & /* 同优先级的首个任务 */
& & OS_TCB & & & & & & &*TailP & & & & & & & & & & & & & /* 同优先级的末尾任务 */
& & OS_OBJ_QTY & & & & & NbrE & & & & & & & & & & & &/* 这个优先级的就绪任务数 & & */
OS_EXT & & & & & &OS_RDY_LIST & & & & & &OSRdyList[OS_CFG_PRIO_MAX]; 用这个结构体声明一个数组,数组长度是我们定义的优先级总数。
OS_CFG_RPIO_MAX是我们定义的,如果为64,也就是说任务的优先级可以是0~63的一个,(对了63,不可以用,是给空任务的,其它的也会因为一些系统任务,我们用户用不了)
void &OS_RdyListInsertTail (OS_TCB &*p_tcb)
& & OS_RDY_LIST &*p_rdy_
& & OS_TCB & & & *p_tcb2;
& & p_rdy_list = &OSRdyList[p_tcb-&Prio];
& & if (p_rdy_list-&NbrEntries == (OS_OBJ_QTY)0) { & & & & &/* CASE 0: Insert when there are no entries & & & & & & & */
& & & & p_rdy_list-&NbrEntries &= (OS_OBJ_QTY)1; & & & & & &/* & & & & This is the first entry & & & & & & & & & & & &*/
& & & & p_tcb-&NextPtr & & & & &= (OS_TCB & *)0; & & & & & &/* & & & & No other OS_TCBs in the list & & & & & & & & & */
& & & & p_tcb-&PrevPtr & & & & &= (OS_TCB & *)0;
& & & & p_rdy_list-&HeadPtr & & = p_ & & & & & & & & & &/* & & & & Both list pointers point to this OS_TCB & & & &*/
& & & & p_rdy_list-&TailPtr & & = p_
& & } else { & & & & & & & & & & & & & & & & & & & & & & & &/* CASE 1: Insert AFTER the current tail of list & & & & &*/
& & & & p_rdy_list-&NbrEntries++; & & & & & & & & & & & & & /* & & & & One more OS_TCB in the list & & & & & & & & & &*/
& & & & p_tcb-&NextPtr & & & & &= (OS_TCB & *)0; & & & & & &/* & & & & Adjust new OS_TCBs links & & & & & & & & & & & */
& & & & p_tcb2 & & & & & & & & &= p_rdy_list-&TailP
& & & & p_tcb-&PrevPtr & & & & &= p_tcb2;
& & & & p_tcb2-&NextPtr & & & & = p_ & & & & & & & & & &/* & & & & Adjust old tail of list's links & & & & & & & &*/
& & & & p_rdy_list-&TailPtr & & = p_
这段代码挺简单的,就是两部分,一:这是我们建的这个优先级上的第一个任务,那么这个任务的NextPtr和PrevPtr都指向0,然后
p_rdy_list[p_tcb-&Prio]-&HeadPtr和p_rdy_list[p_tcb-&Prio]-&TailPtr都指向这个任务,
二:先找出p_tcb-&Prio上任务的最后一个也就是p_rdy_list[p_tcb-&Prio]-&TailPtr指向的,然后这个任务的NextPtr指向我们新
建的任务,我们新建的任务的PrevPtr指向这个任务,然后p_rdy_list[p_tcb-&Prio]-&TailPtr指向我们新建的任务。
& & & & & & & & & & &OS_RDY_LIST
& & & & & & & & & & &+--------------+
& & & & & & & & & & &| TailPtr & & &|-----------------------------------------------+
& & & & & & & & & & &+--------------+ & & & & &OS_TCB & & & & & & & OS_TCB & & & & &| & & OS_TCB
& & & & & & & & & & &| HeadPtr & & &|------& +------------+ & & & +------------+ & &+-& +------------+
& & & & & & & & & & &+--------------+ & & & &| NextPtr & &|------&| NextPtr & &| ...... | NextPtr & &|-&0
& & & & & & & & & & &| NbrEntries=N | & & & &+------------+ & & & +------------+ & & & &+------------+
& & & & & & & & & & &+--------------+ & & 0&-| PrevPtr & &|&------| PrevPtr & &| ...... | PrevPtr & &|
& & & & & & & & & & & & & & & & & & & & & & &+------------+ & & & +------------+ & & & &+------------+
& & & & & & & & & & & & & & & & & & & & & & &: & & & & & &: & & & : & & & & & &: & & & &: & & & & & &:
& & & & & & & & & & & & & & & & & & & & & & &: & & & & & &: & & & : & & & & & &: & & & &: & & & & & &:
& & & & & & & & & & & & & & & & & & & & & & &+------------+ & & & +------------+ & & & &+------------+
& & OS_MsgQInit(&p_tcb-&MsgQ,这个先不说了,
& & & & & & & & q_size);
*******************************************************************************************************/
/******************************************************************************************************
来说任务调度吧OSSched
先说在哪些地方用到这个这个函数了
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OSTaskChangePrio
OSTaskCreate
OSTaskQPend
OSTaskQPendAbort
OSTaskResume
OSTaskSemPend
OSTaskSemPendAbort
OSTaskSuspend
OS_TaskQPost
OS_TaskSemPost
OSSchedUnlock
OSSchedRoundRobinYield
OSQPendAbort
OSTimeDlyHMSM
OSTimeDlyResume
OSSemPendAbort
OS_SemPost
OSMutexDel
OSMutexPend
OSMutexPendAbort
OSMutexPost
OSPendMulti
OSFlagPend
OSFlagPendAbort
OS_FlagPost
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
以上好像很多,但可以这么分类,
每次建立新的任务,因为你建的这个任务可能优先级会更高,为了实时性,就必需这时进行一次调度
等待资源事件(ucos-ii都是用event来管理的,都叫事件)或资源事件的发布,或是删除,再加上中止等待事件。
还有就是使当前任务休息时也要调度一次。
中断之后也会调度,但不是用这个函数。好了,大至就这4类了。
现在可以看这个函数了
void &OSSched (void)
& & CPU_SR_ALLOC();
& & if (OSIntNestingCtr & (OS_NESTING_CTR)0) { & & & & & & &/* 中断处理函数中不能调度 & & & & & & & & & & & & & & & & & &*/
& & & & & & & & & & & & & & & & & & & & & & & & & & /* Yes ... only schedule when no nested ISRs & & & & & & &*/
& & if (OSSchedLockNestingCtr & (OS_NESTING_CTR)0) { & & & &/* 调度上锁之后也不能 & & & & & & & & & & & & & & & & & & */
& & & & & & & & & & & & & & & & & & & & & & & & & & /* Yes & & & & & & & & & & & & & & & & & & & & & & & & & &*/
& & CPU_INT_DIS();
& & OSPrioHighRdy & = OS_PrioGetHighest(); & & & & & & & & &/* 得到最高优先级,一会说这个函数的执行 & & & & & & & & & */
& & OSTCBHighRdyPtr = OSRdyList[OSPrioHighRdy].HeadP
& & if (OSTCBHighRdyPtr == OSTCBCurPtr) { & & & & & & & & & /* 也许还是当前优先级最高,那样就不用切换任务了 & & & & & */
& & & & CPU_INT_EN(); & & & & & & & & & & & & & & & & & & & /* Yes ... no need to context switch & & & & & & & & & & &*/
#if OS_CFG_TASK_PROFILE_EN & 0u
& & OSTCBHighRdyPtr-&CtxSwCtr++; & & & & & & & & & & & & & &/* Inc. # of context switches to this task & & & & & & & &*/
& & OSTaskCtxSwCtr++; & & & & & & & & & & & & & & & & & & & /* Increment context switch counter & & & & & & & & & & & */
& & OS_TASK_SW(); & & & & & & & & & & & & & & & & & & & & & /* 进行切换,这个也是我们根据硬件平台自己写的,一会说下 & &*/
& & CPU_INT_EN();
*******************************************************************************************************/
/******************************************************************************************************
这时说下这个获得最高优先级的函数。
OS_PRIO &OS_PrioGetHighest (void)
& & CPU_DATA &*p_
& & OS_PRIO & &
& & prio &= (OS_PRIO)0;
& & p_tbl = &OSPrioTbl[0];
& & while (*p_tbl == (CPU_DATA)0) { & & & & & & & & & & & & /* Search the bitmap table for the highest priority & & & */
& & & & prio += DEF_INT_CPU_NBR_BITS; & & & & & & & & & & & /* DEF_INT_CPU_NBR_BITS正是OSPrioTbl[]的位长,也是说OSPrioTbl[n]能装多少了优先级*/
& & & & p_tbl++;
& & prio += (OS_PRIO)CPU_CntLeadZeros(*p_tbl); & & & & & & &/* Find the position of the first bit set at the entry & &*/
& & return (prio);
以前说过了就绪优先级的设置,都在OSPrioTbl[]中,如果你想找一个就绪的,优先级最高的一定要这里找。优先级的设置方法了,
所以我想应该都知道最高优先级在哪。先看OSPrioTbl[0],然后依次往下看,直到OSPrioTbl[OS_PRIO_TBL_SIZE]。
如果OSPrioTbl[0]不为0,就不用往下看了,
CPU_DATA &CPU_CntLeadZeros (CPU_DATA &val)
& & CPU_DATA &nbr_lead_
#if & (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_08)/*看咱单片机的字长,这回我就当咱的单片机字长是8位的*/
& & nbr_lead_zeros = CPU_CntLeadZeros08((CPU_INT08U)val);
#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16)
& & nbr_lead_zeros = CPU_CntLeadZeros16((CPU_INT16U)val);
#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32)
& & nbr_lead_zeros = CPU_CntLeadZeros32((CPU_INT32U)val);
#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_64)
& & nbr_lead_zeros = CPU_CntLeadZeros64((CPU_INT64U)val);
#else & & & & & & & & & & & & & & & & & & & & & & & & & & & & & /* See Note #1a. & & & & & & & & & & & & & & & & & & & &*/
& & nbr_lead_zeros = DEF_INT_CPU_U_MAX_VAL;
& & return (nbr_lead_zeros);
CPU_DATA &CPU_CntLeadZeros08 (CPU_INT08U &val)/至于16,32的就不说了/
#if &(!((defined(CPU_CFG_LEAD_ZEROS_ASM_PRESENT)) && \
& & & & (CPU_CFG_DATA_SIZE &= CPU_WORD_SIZE_08)))
& & CPU_DATA &
& & CPU_DATA &nbr_lead_
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & /* ---------- ASM-OPTIMIZED ----------- */
#if ((defined(CPU_CFG_LEAD_ZEROS_ASM_PRESENT)) && \
& & &(CPU_CFG_DATA_SIZE &= CPU_WORD_SIZE_08))
& & nbr_lead_zeros &= &CPU_CntLeadZeros((CPU_DATA)val);
& & nbr_lead_zeros -= (CPU_CFG_DATA_SIZE - CPU_WORD_SIZE_08) * DEF_OCTET_NBR_BITS;
#else & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & /* ----------- C-OPTIMIZED ------------ */
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & /* Chk bits [07:00] : & & & & & & & & & */
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & /* .. Nbr lead zeros = & & & & & & & .. */
& & ix & & & & & & &= (CPU_DATA)(val && &0u); & & & & & & & & & & & & & & & & & /* .. lookup tbl ix &= 'val' && &0 bits */
& & nbr_lead_zeros &= (CPU_DATA)(CPU_CntLeadZerosTbl[ix] + &0u); & & & & & & & &/* .. plus nbr msb lead zeros = &0 bits.*/
& & return (nbr_lead_zeros);
static &const &CPU_INT08U &CPU_CntLeadZerosTbl[256] = { & & & & & & & & & & & & & & /* Data vals : & & & & & & & & & & &*/
/* & 0 & &1 & &2 & &3 & &4 & &5 & &6 & &7 & &8 & &9 & &A & &B & &C & &D & &E & &F & */
& & 8u, &7u, &6u, &6u, &5u, &5u, &5u, &5u, &4u, &4u, &4u, &4u, &4u, &4u, &4u, &4u, &/* & 0x00 to 0x0F & & & & & & & & & */
& & 3u, &3u, &3u, &3u, &3u, &3u, &3u, &3u, &3u, &3u, &3u, &3u, &3u, &3u, &3u, &3u, &/* & 0x10 to 0x1F & & & & & & & & & */
& & 2u, &2u, &2u, &2u, &2u, &2u, &2u, &2u, &2u, &2u, &2u, &2u, &2u, &2u, &2u, &2u, &/* & 0x20 to 0x2F & & & & & & & & & */
& & 2u, &2u, &2u, &2u, &2u, &2u, &2u, &2u, &2u, &2u, &2u, &2u, &2u, &2u, &2u, &2u, &/* & 0x30 to 0x3F & & & & & & & & & */
& & 1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &/* & 0x40 to 0x4F & & & & & & & & & */
& & 1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &/* & 0x50 to 0x5F & & & & & & & & & */
& & 1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &/* & 0x60 to 0x6F & & & & & & & & & */
& & 1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &1u, &/* & 0x70 to 0x7F & & & & & & & & & */
& & 0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &/* & 0x80 to 0x8F & & & & & & & & & */
& & 0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &/* & 0x90 to 0x9F & & & & & & & & & */
& & 0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &/* & 0xA0 to 0xAF & & & & & & & & & */
& & 0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &/* & 0xB0 to 0xBF & & & & & & & & & */
& & 0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &/* & 0xC0 to 0xCF & & & & & & & & & */
& & 0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &/* & 0xD0 to 0xDF & & & & & & & & & */
& & 0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &/* & 0xE0 to 0xEF & & & & & & & & & */
& & 0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u, &0u & /* & 0xF0 to 0xFF & & & & & & & & & */
这个不难,看下程序不难理解,这个表也不难理解,我来用三个优先级举例(先假设只有我们这个三个优先级的任务,别想什么
空任务和统计任务等)10,12,20。用上一节的内容
对于10来说
ix=1,余数是2
对于12来说
ix=1,余数是4
对于20来说
ix=2,余数是4
OSPrioTbl[1]
|0|0|1|0|1|0|0|0|
OSPrioTbl[2]
|0|0|0|0|1|0|0|0|
图画的还算明白吧?就这么看吧,
首先因为OSPrioTbl[0]为0,Prio=Prio+8看OSPrioTbl[1]=40,好了不向下查了,调用这个函数CPU_CntLeadZeros
并且传入的参数是40,假设我们单片机是8位的调用CPU_CntLeadZeros08,同时这个40也会被传过来nbr_lead_zeros=2,
这时Prio再加2,就得10了。还有这个表是统计出来的,看下10,和12的例子大家应该能懂,要是有什么不懂可以问一下(邮箱是)
这个值是当前正在工作的任务
OSPrioHighRdy &这个值是当前最高的优先级值&
OSTCBHighRdyPtr这个指向当前最高优先级任务的任务块
OSTCBCurPtr
这个指向当前正在工作的任务
还有如果OSTCBCurPtr和OSTCBHighRdyPtr不一样,那么就会导致任务的切换。
*******************************************************************************************************/
/******************************************************************************************************
OS_TASK_SW
在这里我们要做的事是
OSPrioCur=OSPrioHighRdy
将当前的任务的内容保存入栈
OSTCBCurPtr=OSTCBHighRdyPt
将最高优先级任务的内容出栈
好了,os_task.c中大部分都和一些事件处理有关,还有一些没关的,但比较简单,就不说了。
下回说时钟节拍。
*******************************************************************************************************/&
文章评论 以下网友留言只代表其个人观点,不代表本网站的观点和立场。

我要回帖

更多关于 ucosii和ucosiii区别 的文章

 

随机推荐