打印
[uCOS/RTOS]

uCOS-II的中断服务怎么写?

[复制链接]
2961|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
请教前辈,uCOS-II的中断服务怎么写?

我看邵贝贝老师那本书上罗列了一下程序的步骤,但感觉像是利用汇编语言写中断服务的步骤。在C语言中,也不需要手动写出“保存CPU寄存器”之类的语句啊,在中断服务函数不是直接写用户代码就OK嘛!

邵贝贝老师的程序如下:

相关帖子

沙发
llpanda| | 2014-3-4 10:39 | 只看该作者
根据我个人的理解
在中断服务程序ISR中,如果可能引起任务的切换,需要加入OSINTEnter和OSINTExit
如果不可能引起任务切换,则不需要
实践中我这么做没有问题

另外,不需要去手动的保存全部的寄存器,例如在STM32下进入中断的时候,一半的主要寄存器就已经被压栈了。反证法,如果需要保存全部的寄存器,那么裸奔的程序ISR中也必须这么做。如果说哪里需要保存寄存器,UCOS移植代码中的任务切换部分,是需要去编程保存和恢复寄存器到任务堆栈的。

使用特权

评论回复
评分
参与人数 1威望 +3 收起 理由
robotouch + 3
板凳
robotouch|  楼主 | 2014-3-4 12:02 | 只看该作者
llpanda 发表于 2014-3-4 10:39
根据我个人的理解
在中断服务程序ISR中,如果可能引起任务的切换,需要加入OSINTEnter和OSINTExit
如果不可 ...

也就是说,中断服务不需要做寄存器操作;只有任务切换才需要哈!

使用特权

评论回复
地板
robotouch|  楼主 | 2014-3-4 20:34 | 只看该作者
llpanda 发表于 2014-3-4 10:39
根据我个人的理解
在中断服务程序ISR中,如果可能引起任务的切换,需要加入OSINTEnter和OSINTExit
如果不可 ...

根据我个人的理解
在中断服务程序ISR中,如果可能引起任务的切换,需要加入OSINTEnter和OSINTExit
如果不可能引起任务切换,则不需要
实践中我这么做没有问题


这句话的意思是,如果不加“OSINTEnter和OSINTExit”,即便中断服务执行过程中,有更高优先级的任务进入就绪态,中断服务结束后也会先回到断点处的任务,然后先进行任务切换哈!

使用特权

评论回复
5
llpanda| | 2014-3-5 11:37 | 只看该作者
robotouch 发表于 2014-3-4 20:34
根据我个人的理解
在中断服务程序ISR中,如果可能引起任务的切换,需要加入OSINTEnter和OSINTExit
如果不 ...

中断服务程序如果在执行中,还发生有其他的任务就绪了,那只能是该ISR被更高优先级的中断打断了,那个更高优先级的ISR调用了诸如POST等函数使新的任务就绪。当然,这种情况下,本中断返回后,还是会切换到那个最高优先级的任务的。
例如,在32下,使用PENDSV中断服务程序做任务切换的,它优先级最低,这样,高优先级的中断POST信号量,进行那个任务切换,触发PENDSV中断。而PENDSV比本中断优先级低,因此要等本ISR完成,才能进行任务切换,
所以,是完美的解决

使用特权

评论回复
6
maowa_2005| | 2014-3-5 11:43 | 只看该作者
ucos-ii是一个实时性内核,对实时性要求比较高,是一个抢占式内核,如果在中断服务程序中高优先级的任务进入就绪状态,那么中断服务结束后不会回到之前被中断的任务,而是直接进行任务切换,这时就需要将之前任务的寄存器进行入栈操作(任务自己的栈中,而不是中断模式的栈中),然后将高优先级任务的寄存器从栈中恢复出来,这个过程也就是平时所说的上下文切换。
至于大家讨论的寄存器的保存,我觉得其实是分为2个步骤的,如果任务1现在在运行,这时候来了一个中断,那么硬件会自动将任务1的寄存器中的值保存到中断模式的栈中(这个过程不需要程序员执行,由硬件自动完成),在中断程序中如果使优先级更高的任务2处于就绪状态,那么在中断程序执行完毕后,就需要执行任务2,但注意,这个时候由于中断没有直接返回到任务1中,所以任务1的寄存器仍然处于中断模式的栈中,这时就要多出一步,就是将中断模式栈中的寄存器,保存到任务1自己的栈中,然后就可以将任务2的寄存器从任务2的栈中恢复出来,继续执行任务2.
说这么多,其实重点就是如果中断程序中使能了高优先级的任务,那么之前的任务的上下文必须要保存到自己的栈中,否则就会出错,以上面的情况为例,如果任务1的寄存器仍然保存在中断模式的栈中,由于中断执行完毕后并没有返回到任务1,而是继续执行任务2,那么后面的一段时间内,任务1再次处于就绪态,要执行任务1的时候就会出错,因为任务1的寄存器并没有保存在自己的栈中,而是仍然在中断模式的栈中,所以在自己的栈中时无法恢复的

使用特权

评论回复
7
robotouch|  楼主 | 2014-3-6 08:00 | 只看该作者
maowa_2005 发表于 2014-3-5 11:43
ucos-ii是一个实时性内核,对实时性要求比较高,是一个抢占式内核,如果在中断服务程序中高优先级的任务进 ...

多谢前辈!“这时就要多出一步,就是将中断模式栈中的寄存器,保存到任务1自己的栈中”,这一动作由谁来完成?

使用特权

评论回复
8
robotouch|  楼主 | 2014-3-6 08:01 | 只看该作者
llpanda 发表于 2014-3-5 11:37
中断服务程序如果在执行中,还发生有其他的任务就绪了,那只能是该ISR被更高优先级的中断打断了,那个更 ...

前辈您好,您举的这个例子我没太看懂,能否再详细讲一下?谢谢了

使用特权

评论回复
9
SevenWans| | 2014-3-7 21:11 | 只看该作者
我也很想知道,其他都很清楚,就是被这个中断搞得晕乎乎的

使用特权

评论回复
10
maowa_2005| | 2014-3-8 14:27 | 只看该作者
robotouch 发表于 2014-3-6 08:01
前辈您好,您举的这个例子我没太看懂,能否再详细讲一下?谢谢了

简单的说就是假如说现在系统中只有2个任务,任务1和任务2,任务2个优先级比较高,假设现在任务1正在执行,这个时候CPU会执行任务1的代码,在执行任务1的过程中,这个时候来了个中断,此时任务1就会被打断,它的寄存器就由硬件自动保存在该中断模式的栈中,然后进入中断服务子程序执行,这个时候应该执行的是中断服务子程序中的代码,在执行过程中,这个时候需要在中断处理函数中去判断之前的任务1是不是依然是就绪队列中优先级最高的任务,如果发现此时发现优先级更高的任务2处于了就绪状态,那么在中断服务子程序结束后,就不会返回到之前被中断的任务1中了,而是直接进行任务2,将任务2栈中的寄存器恢复出来进行执行,但首先要将中断栈中的任务1的寄存器转到任务1自己的栈中。上述整个过程都是在中断子程序中进行的(代码在一个汇编文件中,需要自己写汇编代码),所以要搞清楚的是,发生中断的时候,寄存器是由硬件自动保存,而你上面提到的“这时就要多出一步,就是将中断模式栈中的寄存器,保存到任务1自己的栈中”,这一动作由谁来完成?是在中断子程序中完成的,代码需要自己去修改或添加
希望可以帮到你,有什么问题共同讨论才会进步

使用特权

评论回复
11
robotouch|  楼主 | 2014-3-8 16:15 | 只看该作者
maowa_2005 发表于 2014-3-8 14:27
简单的说就是假如说现在系统中只有2个任务,任务1和任务2,任务2个优先级比较高,假设现在任务1正在执行 ...

谢谢前辈,了然许多了!:handshake

使用特权

评论回复
12
maowa_2005| | 2014-3-10 16:02 | 只看该作者
robotouch 发表于 2014-3-8 16:15
谢谢前辈,了然许多了!

客气,多交流

使用特权

评论回复
13
宙斯之神| | 2014-3-12 11:29 | 只看该作者
这个中断服务可以参考单片机参考

使用特权

评论回复
14
robotouch|  楼主 | 2014-3-12 19:41 | 只看该作者
宙斯之神 发表于 2014-3-12 11:29
这个中断服务可以参考单片机参考

:handshake

使用特权

评论回复
15
wl08| | 2014-4-16 16:18 | 只看该作者
好好学习,天天相上

使用特权

评论回复
16
文峰聊书斋| | 2014-4-26 10:03 | 只看该作者
我回去在看看。怎么没看懂,奇怪。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

58

主题

313

帖子

2

粉丝