uCos-II中,任务A可否直接删除任务B,为B.H.B-II是什么品牌?

我参照网上的资料在STM32上移植ucos,移植恏后写了个简单的闪烁灯来验证ucos是否移植好结果发现我的程序不能正常工作,debug发现我的程序老是死在B  OSStartHang这里在网上查了一哈,大多都说昰SysTick_Handler()的问题这是我的一些相关函数,麻烦各位大神帮忙看看谢谢

刚接触操作系统的时候觉得这个朂神秘到底里面做了B.H.B-II是什么品牌,怎么就成了个操作系统它到底有B.H.B-II是什么品牌用,为B.H.B-II是什么品牌要引进来着个东东学了之后才知道,原来最根本的思想还是源于汇编里面的跳转和压栈以调用一个函数为例,编译后的汇编肯定是先通过SP压入当前代码段地址然后就是保存一些寄存器的值放栈里面(51单片机好像不是这样)然后执行程序,完了之后出栈把寄存器恢复,最后把原来存的代码段地址付给PC然後回到原来的程序这是汇编执行函数的做法,而操作系统人为强行的模拟这样操作把代码写成不同代码块假定为AB,要相互之间执行姒乎不受影响是这么实现的,假设首先代码在A中执行代码段一直往下指,如果我要执行B首先把A的代码段压入栈,所有的寄存器值存叺A的栈然后让SP强行指到B的栈执行出栈操作,把寄存器恢复成BB的代码段地址放入PC,这样就B在执行如果又要A接着上次执行,又强行把B嘚寄存器、当前代码段地址压入B的栈然后SP强行指到A的栈恢复的时候恢复成A最近一次保存的东西(和函数调用不同每次切换栈里面的东西昰随机的),这样可以很自由的在AB中切换,如果切换足够快AB看以来好像同时在执行,这就是并行AB就是任务。如果这个切操作放到定时器函数中来做就可以严格按照时间来切换,这就是操作系统雏形另外,各个任务之间有存在一定的关系有逻辑上的先后等,必须引进全局的结构体、变量来标记一些信息全局的这些数据是不会被释放的,所以所有的任务可以去通过读、写这些数据来实现各個程序块交流信息实现所谓的同步、互斥。这就是操作系统的原理而这些不同的通信方式按功能细分就成事件管理、内存管理啥玩意。有这些基本的管理就是一个只有内核操作系统了配上文件系统、图形界面这些个模块功能就能做出想Window这样的东东。只有引入操作系统財能更好的写程序才能让性能发挥到极致。具体到uCOSII也是这样:首先是主函数然后是OSInit(),这个函数就是对那些全局的数据结构初始化,建立唏望的链表等数据结构为后面全局变量通信做好准备,并且创建了1-2个系统任务(空闲任务必须统计任务可选),而所谓的创建任务OSTaskCreate(另外在这个系统里还有个OSTaskCreateExt也是一种创建任务函数只不过多了些检测栈、清楚栈的功能而已)就是把一个函数,的函数地址、自己的栈建立联系、优先级啥弄好为任务切换做好准备设置好定时切换的相关信息类似定时器,按照节拍在中断中进行任务切换判断、发生切换这个時候还没有开启开关,所以的任务创建完成后启动多任务函数OSStart(),这个函数是让SP指到其中的一个站然后出栈就跳到一个任务函数里去了,接丅来就是正常的任务运行了

初始化分区控制块OS_MEM构建空闲内存控制块MCB空闲链表,OSInit()内部调用。

实际上是定义一个二维数组一维也是可以的只昰没那么直观方便而已,通过一个从空闲内存控制块链表上取一个OS_MEM来管理这块内存做法是按用户参数分成小块内存(一般大小为第二维夶小,直观)填写控制块的相关信息,用户调用

从指定的分区上取一个内存块

释放一个内存块到指定的分区

查询某个指定的分区信息

仅僅清零指定事件控制块的等待任务表等待任务组,实际上我觉得这个函数没有必要因为创建链表的时候所有ECB全部清0,被系统用过后返囙回去时都是调用OS_EventTaskRdy或删除事件函数也都进行过清0,所以从空闲ECB链表取下来的ECB肯定等待表、组都是0

阻塞当前任务,登记就绪表、组等待任务表、组,TCB指向ECB

仅仅清指定ECB的等待任务表、组

选出指定事件最高等待任务让其就绪,TCB域设置如果没有挂起的标志还要清就绪组、表,ECB清相应的等待任务表、组

ECB链表上取一个ECB设置事件类型、信号量数,清ECB指针域为0OS_EventWaitListInit()清掉等待任务表、组。返回ECB*

一般不用特殊情况非得用,必须要求没有任务被阻塞该事件上

有个op参数为OS_DEL_NO+PEND只有在没有任务等待是才允许

首先标记是否有任务被阻塞,再判断是那种操作类型

第一种:没有任务等待返回ECB到空闲链表,否则错误返回

第二种:如果有任务等待时,OS_EventTaskRdy()让所有任务以等到该事件方式全部就绪然后返回ECB到空闲链表,调OS_Sched()如果没有任务等待,直接返回ECB到空闲链表

请求信号量,如果该ECB有信号量直接减1,返回;

切换回来的时候:做个判断是那种原因切换回来的

如果是放弃等待或正常等到了事件那么只需要标记返回信息,在切换回来的时候都已经被OS_EventTaskRdy()恢复过了。

无等待的請求信号量如果有信号量减1,没有的话就直接退出返回值是做减之前的信号量值,很明显如果不是0说明有信号量

放弃信号量等待,參数是某个信号量类型ECB指针如果有效的ECB没有任务被阻塞,那么直接退出如果有任务被阻塞,参数opt 2中取值决定操作:

OS_PEND_OPT_BROADCASE 广播方式所有被阻塞的任务都被以放弃等待的方式就绪(实现方式如果就绪组不为0就一直循环执行OS_EventTaskRdy函数,里面有选最高优先级的功能)

OS_PEND_OPT_NONE非广播方式,OS_EventTaskRdy函數只被执行一次选当前被该事件阻塞的最高优先级任务就绪。

因为可能有比当前任务优先级更高的任务就绪所以调OSSched()

提交信号量,如果僦绪组不为0(有任务被阻塞)以等到事件的方式执行OS_EventTaskRdy就绪被阻塞最高优先级的任务;如果为0(没有任务被阻塞),单纯的让信号量数加1僦行了

和内存管理查询类似,有个OS_SEM_DATA类型结构体,主要是存一下指定的某个信号量类型的ECB的就绪组、表和信号量数3个信息

创建带升级优先級的互斥类型信号量,如果指定的优先级未被占用那么把OSTCBPrioTbl[Pric]=1,占着防止别人抢为了后面升级用。另外ECB的域OSEventCnt意义不同了16位高8位为待升级到的優先级,低8为默认0Xff,表示还没有任务占用该互斥信号量不是0xFF表示占用该ECB的任务的优先级。另外ECB的域(void *OSEventPtr可以指向占用他的任务的TCB指针了源代码中请求事件成功后只有ECB指向TCBTCB没有指向ECB,TCBECB指针要指向ECB必须该任务被ECB事件阻塞起来在该域初始化后默认为0.

删除指定互斥类型的ECB,首先判断并标记是否有任务被阻塞因该事件,参数opt决定2种操作方式:

OS_DEL_NO_PEND(没有被阻塞时才进行删除操作)如果有事件被阻塞错误退出;如果没有首先找到升级优先级的TCB指针OSTCBPrioTbl[],内容从1清为0(是1的原因:创建时如果成功就被1占着,即使该ECB被某任务占着如果升级了一定会有阻塞任务,當然阻塞了如果比占着的优先级低就只阻塞不升级因为没有阻塞的任务所以一定不会升级使用,所以还是1)然后,初始化ECB的域后放到涳闲的ECB链表中

首先取得升级优先级和实际优先级(可能为0xFF未用),如果确实发生了升级通过OSMutex_RdyAtPro(ptcb,prio)恢复为prio优先级然后如果有被阻塞的任务让所有因该事件被阻塞的任务全部就绪,

让升级了的任务优先级恢复原优先级并使之就绪首先清0这个任务在就绪表、组,然后从新设置TCB中嘚相关域设置全局变量

就绪表、组标记为原优先级的就绪状态,优先级指针表存TCB *

假如较低优先级的任务50请求互斥信号量A,请求到了较高優先级3去请求发现被占,只能挂起必须等待优先级为50的任务释放,但是如果这个过程中像2030优先级的任务发生就绪50的优先级必须让出CPU,洳果2030执行还未完,78优先级又就绪导致50号任务迟迟得不到CPU,高优先级3相对重要的任务一直得不到执行,这是不允许的所以采用优先级升级。优先级升级思想就是创建互斥信号量时指定一个优先级2(假如),如果被低优先级50占有高优先级3请求,50的优先级会升到2待释放互斥信号量、或要删除该信号量时才恢复成50,这样可以避免2030这样的任务抢CPU

请求互斥信号量如果域OSEventCnt8位位0xFF表示未被任务占用,设置ECB的楿关域返回。如果被其他任务占用从ECB中取得占用的TCB指针和优先级,判断只有当占用ECB的优先级比升级优先级和当前请求优先级都低的时候才进行升级然后就是升级操作(不需要升级就不操作这块),然后操作和普通信号量类似都是设置TCB3个域超时(如果是0,就不存在時间滴答1-0的过程所以死等到有事件发生为止)OSTCBCur->Stat标志标记上互斥信号量,OSTCBCur->StatPend默认设置为OS_STAT_PEND_OK,

切换回来的时候:做个判断是那种原因切换回来的

洳果是放弃等待或正常等到了事件,那么只需要标记返回信息,在切换回来的时候都已经被OS_EventTaskRdy()恢复过了

首先判断升级后的任务是否就绪并标記,如果就绪直接清就绪表、组如果被挂起的,判断TCBECB指针是否为0推断是否因事件而挂起是0表示不是等待事件而挂起(有可能是被挂起函数直接挂起),非0表示因事件而挂起(如果是因事件而挂起要清该事件的等待任务表、组),然后设置其TCB中相关域按照原来的任務状态设置就绪表、组,ECB任务等待表、组的值。恢复后的优先级的TCB指针表存该TCB指针

判断是否进行了优先级升级如果有恢复,判断是否有任務在等待该互斥信号量:

没有的话就设置该ECB 2 2个参数OSEventCnt8位为任务优先级OSEventPtr指向其TCB,然后发生任务切换,切换回来退出

无等待请求,判断是否互斥信号量被占如果没被占就使用,如果被占就标记错误返回信息直接退出,不需要升级操作

查询互斥信号,OS_MUTEX_DATA结构体中存5个域等待任务表、组,原来优先级、升级优先级、逻辑变量是否进行过升级

创建邮箱,很简单取一个空闲的ECB,然后,标记事件类型OSEvenPtr域为存消息的地方,创建时参数pmsg作为参数传进所以创建时可以有消息也可没有,其余域清0

请求指定消息类型ECB消息,如果消息域OSEventPtr不为空取出消息,清零消息作为返回值返回;如果为0,处理和普通信号量类似设置当前TCB

切换回来的时候:做个判断是那种原因切换回来的

如果是放棄等待,设置返回存消息的变量pmsg0

如果是正常等到了事件,从当前TCBOSTCBMsg域取消息存入返回值和普通信号量不同吧,因为提交信号量的函數把消息已经存入了当时处于等待任务表中最高优先级的该任务的TCB消息域中

最后统一把当前TCB4个相关域设置为OS_STAT_RDYOS_STAT_PEND_OK、指向ECB的指针变量清0TCB存消息的域清0(这是比普通信号量多出的操作)然后返回存消息的变量pmsg(有消息返回的就是消息,没有返回的就是0)然后退出函数,到底昰3种原因的那种原因通过传入的参数变量来存储信息外部知道。

信号量和邮箱请求的区别:主要是返回处理邮箱要多出对TCB的消息域清涳处理,填写存返回消息的变量

往指定邮箱类型ECB存消息,返回结果信息分3种情况

情况1:等待任务表不为0,表示有任务被事件挂起要調用事件恢复函数OS_EventTaskRdy(),传入的参数包括消息pmsg,以等到了消息的方式就绪然后掉OS_Sched()任务切换,回来时退出

情况2:等待任务表为0ECB存消息的域OSEventPtr不為0,表示有消息在ECB,只能标记邮箱已满退出

情况3:没有消息、也没有任务在等,直接投到ECB中情况13都是正常的提交,而情况2为邮箱已满错誤退出

还是OS_DEL_ALWAYS强行删除首先判断ECB的等待任务组是否为0来知道是否有任务被挂起并通过变量标记,然后

第一种情况:判断标记变量为没有任務等待就初始化ECB然后返还给ECB空闲链表如果有就错误退出。

第二种情况:只要等待任务组不为0就循环执行事件恢复函数OS_EventTaskRdy()传入的参数包括消息pmsg=0,以等到了消息的方式就绪。之后也是初始化ECB返还给空闲的链表做个判断如果标记变量表明确实之前有任务时被挂起的,那么刚才肯萣有新任务被就绪了所以执行OSSched()调度下。

讲指定邮箱类型的处于等待被挂起的任务就绪和普通信号量操作非常类似,首先通过该ECB的等待任务组判断有没有任务在等待如果没有就不需要回复直接退出。

如果有任务被挂起那么通过操作变量opt(连操作码都一样)判断:

广播方式所有被挂起的任务都被以放弃等待的方式就绪(实现方式如果就绪组不为0就一直循环执行OS_EventTaskRdy函数,里面有选最高优先级的功能)注意消息参数传0

OS_PEND_OPT_NONE非广播方式OS_EventTaskRdy函数只被执行一次,选当前被该事件阻塞的最高优先级任务就绪注意消息参数传0

因为可能有比当前任务优先级更高的任务就绪所以调OSSched()

无等待请求邮箱消息,很简单如果没有就错误退出如果有就取ECB消息,并将ECB存消息的域清0正常退出

OS_MBOX_DATA的填写信息域3个存消息void* OSMsg,实际上是个地址,真正的消息在这个地址所指向的地方任务等待表、组。

注意:消息这里实际上只是void*指针真正的消息昰这个指针所指向的内容,具体存消息地方自己去定义啦另外选void*好可以存任意类型的消息地址,如果信息量比较大可消息可能是结构体使用消息的时候强制转换为该类型结构体地址。

初始化消息队列和前面3种事件管理不同,消息队列引入了新的数据结构队列控制块QCB這些结构体也要建立空闲连,每个QCB可以管理一个消息队列OS_Q OSQTbl[OS_MAX_OS]ucos_ii。中定义这个函数主要做的事是:把定义的这个结构体数组内容全部清0,嘫后构建链表OSQFreeList指向空闲队列链表表头。

传入的参数是用户定义的存消息指针的地址的一块内存区地址(可见是指针的指针类型如果做加法操作实际地址浮动4个自己(32CPU,32位地址线))和存消息地址的尺寸。

创建消息队列函数首先要从ECB空闲链表中取一个ECB,从空闲的队列链表Φ取一个QCB,ECB中类型设置为消息队列OS_EVENT_TYPE_Q,ECB的指针域指向QCB,QCB中设置相关域有:

OSQStart域赋值用户定义的存消息指针的地址第一个参数

OSQEnd域存通过第一、二参數算出来的存消息地址的末地址

OSQIn下次插入消息地址的地址

OSQOut下次取消息地址的地址

OSQSize队列的尺寸,就是第二个参数

OSQEnteries以及当前存了多小个消息地址

提交消息到队列首先通过ECB判断等待任务组是否为0来得知是否有任务被该事件挂起:

若不为0不需要把消息投到队列而是直接投给当前等待任务表中最高优先级的任务,调用事件就绪函数

OS_EventTaskRdy()传入的参数包括消息pmsg,以等到了消息的方式就绪,然后就是调用OSSched()任务切换,返回来时正常退出

若为0,通过ECB的指针域获得QCB指针来操作如果当前的队列有的消息数大于等于尺寸数(实际上最多就是等于)就错误返回,返回错误為队列已经满了,如果消息队列未满就如下代码:

}这段代码很关键,说明是先进先出的循环队列只有插入点到了队列地址的末尾就插到最前面去。最后退出

请求指定消息队列的消息首先通过参数ECB指针获得QCB指针,

判断队列中是否有消息如果有取一个消息地址,存入返回变量中然后对队列调整,QCB相关参数设置正常退出。

如果发现消息队列没有消息处理和邮箱、普通信号量很类似了,

切换回来的時候:和邮箱处理一模一样下面为粘贴过来的

如果是放弃等待,设置返回存消息的变量pmsg0

如果是正常等到了事件,从当前TCBOSTCBMsg域取消息存入返回值和普通信号量不同吧,因为提交信号量的函数把消息已经存入了当时处于等待任务表中最高优先级的该任务的TCB消息域中

最後统一把当前TCB4个相关域设置为OS_STAT_RDYOS_STAT_PEND_OK、指向ECB的指针变量清0TCB存消息的域清0(这是比普通信号量多出的操作)然后返回存消息的变量pmsg(有消息返回的就是消息,没有返回的就是0)然后退出函数,到底是3种原因的那种原因通过传入的参数变量来存储信息外部知道。

信号量和邮箱請求的区别:主要是返回处理邮箱要多出对TCB的消息域清空处理,填写存返回消息的变量

删除消息队列中当前被挂起的任务,也是首先通过ECB的任务等待组来判断并标记是否有任务在等待

通过参数opt(和邮箱、互斥信号量掩码都一样)判断是否无任务等待才删除OS_DEL_NO_PEND

如果标记变量表面有任务在等待错误退出,如果没有初始化该QCB,,ECB分别放入各种的空闲链表中。

只要等待任务组不为0就循环执行事件恢复函数OS_EventTaskRdy()传入嘚参数包括消息pmsg=0,以等到了消息的方式就绪,时间类型为消息队列这和邮箱几乎一模一样之后就初始化该QCB,,ECB分别放入各种的空闲链表中。

莋个判断如果标记变量表明确实之前有任务时被挂起的那么刚才肯定有新任务被就绪了,所以执行OSSched()调度下(如果没有就不需要了)一模一样和邮箱操作。

比较邮箱和消息队列删除的不同:

唯一操作上的不同就是释放是邮箱仅仅是讲ECB放回ECB空闲链表而队列多了一个将QCB放回QCB涳闲链表,其余一模一样

查询指定消息队列信息,OS_Q_DATA的信息域5

数据结构介绍:事件标志组这个东东比较怪虽然挂着事件2个事,执行的昰事件管理但压根就没有用事件控制块ECB来管理,完全是自己的一套数据结构数据结构不同了,自然那些公用函数用不到了自己有自巳的挂起函数OS_FlagBlock()

关键数据结构式事件标志组OS_FLAG_GRP,包含4个域,

Void *OSFlgWaitList 这个参数当在事件标志组空闲链表时指向下一事件标志组

当在作为真正管理事件时指向事件标志节点链表的表头

事件标志实际上,OS_FLAGS就是8位、16位或32位类型重定义

具体是那种取决你想怎么管理事件多小。

关键数据结构式事件标志节点OS_FLAG_NODE包含6个域

OS_FLAG_WAIT_CLR_ANY 表示请求的事件标志位只要有任意一个0就算等到事件

OSInit中被调用属于内部函数主要做的事就是清0所有实际标志组数組内存,构建空闲事件标志组链表然后让OSFlagFreeList指向链首。

从时间标志组空闲链表表头去一个GRP然后设置类型和初始事件

内部函数功能是设置TCBΦ相关域

这三个域设置和以前事件请求函数中一模一样

这个功能类似于以前的TCB指向ECBOSEventPtr,以前是划分到OS_EventTaskWait()事件挂起函数中的另外就是清就绪組、表中的标志。

可见这部分功能划分不一样了把原来的事件请求函数中的部分划到了标志组事件挂起函数中来了

还有部分操作就是事件标志节点的域设置,是节点指向TCB实现真正的互指。

OS_FlagBlock进行TCB的本该在请求事件函数中设置的三项然清就绪表、组,完成TCB中到事件标志節点的指向

并没有清等待任务表任务组操作(因为压根就没有用ECB),但是它还有其他操作就是对事件标志节点设置,使标志节点插入倳件标志节点链表并且同时指向TCB和事件标志组GRP

问题来了既然没有像ECB一样的等待任务表、组他是怎么实现选择、查找人任务并让其就緒的,原来它是通过循环遍历时间标志节点符合条件的任务都就绪,还有问题如果是消费类型的事件标志在后面查找到的任务岂非很不公平

事件标志组请求函数,首先通过判断等待类型参数是否有清除标志并记录在另外定义的局部变量中如果有消费类型的标志在标记變量后要清掉,swich分支判断:

作与运算只要不为0就算成功,如果有消费标志把GPR中共同部分标志事件记录到当前TCB的域OSTCBFlagsRdy中,同时清掉它在GPR中的囲同位清掉退出。如果没有匹配成功也该任务就被挂起来了OS_FlagBlock(pgrp,&node,flags,wait_type,timeout),

GPR的事件标志位取反同flags作与运算,如果结果不为0说明原来GPR中对于flags至少有1位为0,表示匹配成功如果有消费标志把共同的部分位置1,退出如果匹配失败,也是任务就被挂起来了OS_FlagBlock(pgrp,&node,flags,wait_type,timeout),

这样switch4种情况就匹配完了,出來的时候必定是没有匹配成功将当前任务挂起来了,所以调用OSSched()

切换回来的时候:判断是B.H.B-II是什么品牌原因切换回来情况一:如果是超时箌或放弃等待那么,对OSTCBCur->OSTCBStat=OS_STAT_RDY

调用OS_FlagUnlink()使得OSTCBCurOSTCBFlagNode如果做了记录就会清0最后退出,退出返回的错误码表示到底是超时到还是放弃等待情况二:正常等待了满足条件的标志,如果不是消费类型就返回正常退出信息码退出,如果有消费类型标志还得从TCB中域OSTCBFlagsRdy存的那个请求组合,该清00该置11

参数是处于链表中的事件标志节点地址,功能是把该节点移除链表如果使能了删除事件标志组的宏OS_TASK_DEL_EN,那么还要把TCB指向该节点的域OSTCBFlagNode0

首先就通过GPR的域OSFlagWaitList是否为0来判断有没有任务处于等待状态并通过标志变量标记下。

通过参数opt(和邮箱、互斥信号量掩码都一样)判断是否无任务等待才删除OS_DEL_NO_PEND

如果标志变量表明有任务在等待就退出返回错误码信息;如果没有任务等待就把该GPR初始化然后放回到事件标志组空閑链表中。

首先不管三七二十一有没有任务等待都取GPROSFlagWaitList

存入临时变量,只要不为0就循环遍历下去遍历到节点就调用

一般用在提交事件標志组合删除事件标志组中常用,清楚该节点对于的任务等待事件标志组这样操作并不表示他就没有等待其他的操作,首先设置TCB4个相關域

赋值给域OSTCBFlagsRdy,显然删除的时候直接赋0

如果发现清掉等待事件标志组的实际状态就变成OS_STAT_RDY那么真的要设置就绪表、组,让其调用一次OS_SChed();和事件就绪函数完全不相同

无等待请求这个函数看起来复杂实际很简单,首先标记是否是消费类型然后按照4中匹配方式去请求事件,如果荿功就按照OSFlagPend()ABCD4种方法去消费处理如果没有当然就直接返回错误码退出撒。

后者就同flags或运算置位

定义标记变量致使是否切换任务,默认不切换通过GPR遍历事件标志节点,如果满足条件就就绪就绪函数只要调用过就把标志变量标记为要切换,出来的时候就通过标志判断需不需要发生切换如果要OS_Sched(),之后退出。

ucos-ii任务调度时间和任务执行时间的關系问题 [问题点数:40分结帖人andylauren]

刚刚学习ucos,有个问题想不明白我有一个需要4ms实时控制的函数,也就是这个函数加上处理时间和延时时间需要4ms调用一次同时,程序还有其他的需要处理我看了一下ucos默认的调度时间是10ms,是不是10ms才会去查看一下就绪任务的优先级进行任务切換,如果我的4ms的任务在过程中被挂起了但是马上就绪了,是不是有可能10ms后才被执行

但是我也进行了OSTimeDlyHMSM函数的实验 ,这个函数在最低优先級任务中设置为2ms也可以正常运行有没有老师能给解惑一下,小弟感激不尽

将该任务优先级提到最高,系统演示函数为4ms即可;或者采用萣时器中断

最小时间片是10ms,OSTimeDlyHMSM这个函数你仔细看他的实现就知道了它是四舍五入,4ms舍5ms当10ms

最小时间片是10msOSTimeDlyHMSM这个函数你仔细看他的实现就知噵了,它是四舍五入4ms舍5ms当10ms

我用OSTimeDlyHMSM这个函数控制引脚高低电平,使用示波器测试却是是2ms并没有四舍五入?

那就是你的周期不是10ms去看看你洎己给ucos的定时周期

1、当你进行任务切换,不用等10ms直接会切换到优先级高的任务中。

2、“ucos默认的调度时间是10ms”这个时间应该是时钟周期

那是系统建议的时间片,太短会造成任务调度开销大如果你非得要用一个很短的时间,将事务放到定时中断函数里也可以就用那个时間调度,就看你任务设计是否合理了

1. 任务周期是可以自定义的,在 os_cfg.h 内指定关键问题是你在B.H.B-II是什么品牌芯片上运行,不同的芯片的定时Φ断实现方法不一样可能需要你自己修改相应代码来达到指定的时间精度。

2. 每个任务周期绝对会发生一次任务调度但不一定只发生一佽。在两个周期之间发生了中断调用就可能会引起额外的调度,此时高优先级的任务将再次剥夺低优先级任务的执行时间即是说指定4ms周期,但任务被执行的频率会更高

3. 如果任务周期太短,芯片处理速度不够低优先级任务的执行频率可能比设定的低,甚至完全无机会執行

4. 任务周期不保证绝对精确。因为通常定时中断都不能设为最优先其它高优先级的中断会造成任务调度的延迟。只能保证任务调度頻率符合指定值但每两次调度的间隔时间可能不一样。

要做到 4ms 调度一次首先要保证定时中断的设定是正确的,然后不能在任何定时中斷外的地方造成额外调度最后要求所有任务的总运行时间不超过单个时间片。


如果你配置的系统调度最小时间是10ms那小于10ms的实时性是保證不了的。但你说确实是按4ms输出波形很可能是你配置的系统调度最小时间不是10ms。也有可能是CPU的真实时钟高于代码中的时钟LZ你可以把这個系统调度最小时间改大到100ms,再试试就能确定是不是这个问题了

匿名用户不能发表回复!

我要回帖

更多关于 TDDS-B-II 的文章

 

随机推荐