uc/os外设中断和任务调度的关系

ucos常用函数功能

从野火上移植下来的代码,配置系统滴答为 1ms


  1. OS_TickListInsert() 函数将当前任务插入到节拍列表进行管理
  2. OS_RdyListRemove() 函数将当前任务从任务就绪列表中移除,并将系统切换至其他任务。
  3. OSTimeDlyResume () 函数用于直接结束其他任务(非当前任务)的延时
  4. OSTimeGet () 函数用于获取当前的时钟节拍计数值
  5. OSTimeSet () 函数用于设置当前的时钟节拍计数值
  6. OSTmrCreate ()
  7. OSTmrStart ()
  8. OSTmrStop ()
  9. OSTmrDel ()
  10. OSSemCreate ()
  11. OS_PendListInit() 函数初始化了多值信号量的等待列表。每个多值信号量都有一个等待列表,凡是等待该多值信号量的的任务都会被插入到这个等待列表
  12. OSSemPost () 函数用于发布多值信号量
  13. OS_Post() 函数是一个底层的发布函数,它不仅仅用来发布多值信号量,还可以发布互斥信号量、消息队列、事件标志组、任务消息队列和任务信号量
  14. 与OSSemPost () 多值信号量发布函数相对应,OSSemPend() 函数用于等待一个多值信号量。
  15. OSSemPendAbort() 函 数 用 于 中 止 任 务 对 一 个 多 值 信 号 量 的 等 待
  16. OSSemDel () 函数用于删除一个多值信号量
  17. OSSemSet () 函数用于设置多值信号量的计数值

-------------------------------以上没什么用可大概浏览一下-------------------------------

1).首先咱们先分析一下代码:手把手从头理解······

在这里插入图片描述
1.这是在创建一个任务开始函数之后,开启多任务。发现OSRunning已经被赋值为1啦然后我们看下一个图:
在这里插入图片描述在这里插入图片描述
2.这个时候就可以执行中断嵌套加1操作啦。

2).笔者刚接触ucos的时候考虑的第一个问题就是 任务调度外设中断 的关系是怎么样的???

咱们先来看几个函数:
在这里插入图片描述
咱们先从这几个函数的名字进行理解:
1.OS_CRITICAL_ENTER() //进操作系统临界区
2.CPU_CRITICAL_ENTER()//进CPU临界区
3.OSSchedLockNestingCtr++ //调度锁嵌套加一
4.CPU_CRITICAL_EXIT() //出CPU临界区

然后咱们再看一下进CPU临界区和出CPU临界区这两个函数都干了些什么,上图:
在这里插入图片描述
1.来,还是先从名字开始,CPU_INT_DIS()CPU中断失能(也就是禁止的意思,其实这就是常听说的关中断,具体怎么实现的往下看)。可以看到这个宏执行的是把CPU的状态寄存器的值SR保存到一个变量当中。这里先提一下,这个函数的功能都实现了关中断也就是禁止外设产生/响应中断,并保存当下CPU的状态应该包括R1-R15等一些寄存器的值。
2.具体是如何实现禁止外设产生中断的,来咱们再上一张图:
在这里插入图片描述
3.这段代码涉及到汇编大概是这样的,MRS和MSR是唯一可对PSR进行访问和修改的两个汇编操作,
第一句是把PRIMASK的值读取到R0寄存器当中
第二句是目前程序状态ID I(CPSR),I 也就是32位程序状态寄存器当中一个控制位 ISR(普通异常中断也就是外设产生的中断)的中断产生运行位。
第三句是BX分支也就是跳转的意思。

我也不太明白,大概肯定是对 ISR 的中断允许位进行啦操作,那肯定是为 1 ,关掉了所有外设的中断允许位。

下面就是提一下,除了那两句开关中断(外设中断,这个时候就不能产生外设中断请求)外,还有一个叫做 中断禁止测量开始函数中断禁止测量结束函数,这两个函数就是计算一下关、开中断这一段的时间长度,可能是为了满足实时这一特点。

接下来咱们再回到刚开始哪个图,在进CPU临界区出CPU临界区的之间有一个OSSchedLockNestingCtr++指令,俗称调度锁上锁,然后会有调度锁时间测量开始函数,其实也就是为了得到一个时间,当执行完进操作系统临界区和出操作系统临界区之间的这一些用户程序之后,在出操作系统临界区函数当中会执行调度锁时间测量结束函数最后得到一段执行操作系统临界区代码的时间,也是为了满足实时的要求

为什么要在进CPU临界区出CPU临界区内也就是关中断之后执行调度锁上锁呢,其实就是为了保证调度锁上锁不被异常中断写入/读出,然后再立刻开中断,这一段时间及其的短,可能就几个us,从而保证外设中断可以正常响应,毕竟在嵌入式当中外设产生的中断都是极其重要的甚至是致命性的。

-------------到了这里我觉得大家应该记住这几个名字,对我很有帮助---------------
来一个大概的流程图:

进操作系统临界区

 - 进CPU临界区
  • 执行调度锁上锁
 - `出CPU临界区`

这里是用户程序,因为未关中断所以可以产生外设中断,但不能进行任务调度,调度锁上锁
这里是用户程序,因为未关中断所以可以产生外设中断,但不能进行任务调度,调度锁上锁

 - 进CPU临界区 
  • 调度锁解锁,才有可能执行任务调度
 - 出CPU临界区

出操作系统临界区

在出操作系统临界区函数当中会计算从进来到完成这段的时间。


延迟发布:

OS_CFG_ISR_POST_DEFERRED_EN当这个宏为1的时候采用的是延时发布,大家可以搜索一下这个宏大概看一看怎么回事。
延时发布是通过给调度器上锁的方式来保护操作系统临界区的代码。,在延迟发布下基本不存在关中断这一情况(排除关中断给任务调度器上锁一这一操作)

下面论述一段过程,如果在中断服务函数当中进行信号量、消息或者事件标志组的post发布那么会是一种什么样子的情况???
前提是咱们在中断服务函数当中执行,
在这里插入图片描述这个函数当中会对中断嵌套标志位加一,之后执行操作系统的发布函数,假如说是OSSempost()信号量的发布,来上图:
在这里插入图片描述
方框当中判定中断嵌套标志位,目前为1(因为在进入中断服务函数的时候执行的那个函数就加一啦),之后执行OS_IntQPost()这个函数,通过名字我们就能看出来叫做中断队列发布。在图上椭圆圈起来的才是信号量发布函数。
OS_IntQPost()那就讲讲这个中断队列发布函数:他是一个用来post的任务级函数,他享有任务级的最高优先级0,可以把请求发布的信号量、消息等这种操作交给它来完成。先说一下这样做的目的大概就明白啦,在中断服务函数当中要尽可能的少占用时间,做到响应中断立刻执行再清除中断。而post发布函数需要执行大量的代码这样大大的降低啦效率。中断队列处理任务提取出发布函数调用的信息后重新开中断,锁定任务调度器,然后进行发布函数调用,相当于发布函数调用一直是在任务级代码中进行的,这样本来应该在中断中处理的代码(发布函数调用)就被放到了任务级完成。中断队列处理任务将中断队列处理完,将自身挂起,并重新启动任务调度来运行处于最高优先级的就绪任务。如果原先被中断的任务仍然是最高优先级的就绪任务,则UCOSIII恢复运行这个任务。

还有一个名字叫做 中断服务管理任务,这个就是哪个中断队列发布函数。
延迟发布模式下,UCOSIII通过锁定任务调度来保护临界段代码。

这个中断队列发布函数队列的大小是10,也就是最多十级外设中断的嵌套且都进行了post发布函数才有这种情况,那不太可能。
在这里插入图片描述
这个函数会把post发布函数加到就绪组和就绪表当中且优先级传递的是0,享有最高的优先级。
当从中断服务函数当中退出来执行:在这里插入图片描述
它的时候,要进行一次任务调度,当然肯定是调度的中断队列发布函数进行post的发布,因为改函数具有最高优先级。
在这里插入图片描述
然后被执行信号量的发布函数(因为上面拿信号量举的例子),发布之后在该函数的最后我们可以发现有一个任务调度,那么就会执行等待信号量的任务级函数当中优先级最高的那个,是不是 - -,看图:
在这里插入图片描述

到这里基本上就完啦,那么就最后来一下总结呗!

1.外设中断的优先级要比任务级调度优先级要高。
2.外设中断除了在短暂的关中断当中无法响应中断,其他地方都可以(外设中断允许高优先级的中断打断低优先级的中断)
3.采用延时发布,目的是节省中断服务函数,而替换成任务级函数发布。
4.操作系统临界区的代码会受到外设中断的打断,但是中断服务函数执行完成之后会再返回中断的地址继续执行,因为有个一个调度锁上锁不可能执行任务调度函数。
5.在操作系统临界区的代码,因为调度锁上锁而不能执行每1ms的任务调度,假设任务调度成功,那不就去执行其他任务函数啦嘛,那你这个任务怎么办。
6.在书写规范上希望,对不希望打断的任务或者可能再执行的时候被任务调度,那么都加上操作系统临界区。
7.因为时间戳的这个功能,希望可以加上来模拟执行代码的时间。

8.所有的系统任务像挂起、恢复等在最后都要人为的执行一次任务调度。
9.如果是在中断服务函数当中执行的系统任务那么都会被挂起到中断队列任务,因为采用的是延迟发布,在退出中断服务函数的时候OSIntExit()将会执行任务调度并且调度到优先级为0的中断队列发布函数当中,由该函数执行系统任务,其实就是把这样的工作都变成了任务级函数。

10.如果是在操作系统临界区内执行系统任务,那么系统任务会执行完成,但是不会执行任务调度,因为调度锁此时被上锁,在退出操作系统临界区的时候也不会执行任务调度,只能等到时间片的到来。
11.在本任务当中执行挂起自身任务,不管任务优先级的高或者低都不会再继续执行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值