谁知道在ucosii中断-ii里面如何写中断程...

查看: 2116|回复: 5
原子哥的UCOSII例程中,产生中断是先进UCOSII还是直接进如中断服务程序???
主题帖子精华
新手上路, 积分 33, 距离下一级还需 17 积分
在线时间0 小时
我看到有些UCOSII的移植方法说:把STM32中断入口地址与uCOS-II的中断管理机制联系在一起。
并且用到一下函数配置中断:
bsp_int.c提供几个关键的中断操作函数:
void& BSP_IntDis&&&&&&& (CPU_DATA& int_id)&&&&&&&& //关闭指定中断
void& BSP_IntDisAll&&& (void)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //关闭所有中断
void& BSP_IntEn&&&&&&&& (CPU_DATA& int_id)&&&&&&&& //使能指定中断
void& BSP_IntVectSet (CPU_DATA&&&&&& int_id,
CPU_FNCT_VOID& isr)& //用这个函数把用户编写的中断函数的首地址放在中断入口处.中断发生后,系统调用用户中断函数.
void& BSP_IntPrioSet& (CPU_DATA&&& int_id,CPU_INT08U& prio)&&&&&&& //设置中断优先级
//////////////////
但是本人菜鸟,不太明白,感觉上面的方法挺好,不知各位大神以为如何???
希望有个例程最好!!!!
主题帖子精华
在线时间484 小时
如果没有关闭总中断的话,是直接进入中断的&.否则,等总中断开启后,再进入.
我是开源电子网站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺:
微信公众平台:正点原子
主题帖子精华
新手上路, 积分 33, 距离下一级还需 17 积分
在线时间0 小时
回复【2楼】正点原子:
---------------------------------
多谢原子哥,UCOSII还是很值得继续学习的。
主题帖子精华
在线时间0 小时
uC/OS-II有中断管理功能吗?请指明出处。
于停用该账号:http://www.microstar.club
主题帖子精华
新手上路, 积分 33, 距离下一级还需 17 积分
在线时间0 小时
回复【4楼】styleno1:
---------------------------------
看ucosii官网的STM32移植工程代码,里面有:BSP_IntDis,BSP_IntDisAll,void&&BSP_IntEn等函数。
(官网工程:&V2.0的库,ucosii版本&V2.86)
并且有些博客说把STM32中断入口地址与uCOS-II的中断管理机制联系在一起。
见博文《uCOS-II移植-STM32F10x_Keil》/apollius/archive//2987020.html
主题帖子精华
在线时间0 小时
回复【5楼】秦629:
---------------------------------
看了原文,它们属于中断管理无可厚非,我期待过高了。
于停用该账号:http://www.microstar.club
Powered byucos ii下的硬中断服务问题-电子产品世界论坛
ucos ii下的硬中断服务问题
&&&&&& 前天在做实验时,想在ucos ii
系统下触发一下外部中断玩玩,可没想到,按常归的中断要求编写完中断服务例程后,程序竟然跑飞了,触发按键中断后,我调试了一下,程序在一个默认的异常服务死循环里出不来了,我就郁闷了,想了之后,以为当OS
控制系统后在不同优先级任务间切换,不能再响应来自外部事件触发的中断呢,所以程序崩溃了呢,后来才发现,这是一个多么可笑的想法啊,呵呵,现在终于弄明白了,写点心得记录下来,以便完全理解。
&&&&&&&& 看了ucos
ii对中断的要求后才发现错哪了,任务调度之所以分为任务级任务调度和中断级任务调度,就是因为这个原因,学那么长时间了,竟然还不知道中断级任务调度是怎么调用了,悲剧啊,思而不学则殆,学而不思则惘,唉,把状态改了,以作警示,很明显,任务级任务调度是在任务间切换时调用的,具体什么时候调用呢?当一个任务有延时时,就会调用以便让一个更高优先级的任务进入就绪状态。而中断级任务调度呢,当然是在中断时调用以便让&&这么简单的道理,怎么想不到呢?好像从来没想过这个问题&&。
&&& 查资料后发现了这两个函数:OSIntEnter()和OSIntExit(),这两个函数是用来干啥呢?看源码吧!
void& OSIntEnter (void)
&&& if (OSRunning == TRUE)
&&&&&&& if (OSIntNesting & 255)
&&&&&&&&&& {
&&&&&&&&&&& OSIntNesting++;&&&&&&&&&&&&&&&&&&&&& /* Increment
ISR nesting level&&&&&&&&&&&&&&&&&&&&&&& */
&&&&&&&&&& }
&&&&&& 这个函数的源码真简单啊,不就是让一个变量加1吗?再来看一下注释:
Description: This function is used to notify uC/OS-II that you are about to
service an interrupt
*&&&&&&&&&&&&& service routine (ISR).& This allows
uC/OS-II to keep track of interrupt nesting and thus
*&&&&&&&&&&&&& only
perform rescheduling at the last nested ISR.
* Arguments& :
* Returns&&& : none
* Notes&&&&& : 1) This function should
be called with interrupts already disabled
*&&&&&&&&&&&&& 2) Your ISR can
directly increment OSIntNesting without calling this function
*&&&&&&&&&&&&&&&& OSIntNesting has been declared 'global'.&
*&&&&&&&&&&&&& 3) You MUST still call OSIntExit() even though you increment
OSIntNesting directly.
*&&&&&&&&&&&&& 4) You MUST invoke OSIntEnter() and
OSIntExit() in pair.& In other words, for every call
*&&&&&&&&&&&&&&&& to
OSIntEnter() at the beginning of the ISR you MUST have a call to OSIntExit() at
*&&&&&&&&&&&&&&&& end of the ISR.
*&&&&&&&&&&&&& 5) You are allowed to
nest interrupts up to 255 levels deep.
*&&&&&&&&&&&&& 6) I removed the
OS_ENTER_CRITICAL() and OS_EXIT_CRITICAL() around the increment
*&&&&&&&&&&&&&&&& OSIntEnter() is always called with interrupts
解释如下:& 这个函数用来通知OS我们正准备进入中断服务例程,这允许OS保持中断嵌套的路径(次数),
以便于仅在最后一次嵌套的中断退出时才执行任务调度。
1.这个函数应当在关闭中断的情况下调用,为啥?涉及到全局变量的操作了吧,也就是在调用前后加下它哥俩:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()。
&2.可以直接增加OSIntNesting,而不必调用这个函数,因为这个变量是全局的!
&3.一定要调用OSIntExit()这个函数,即使你直接增加OSIntNesting这个变量。也就是说,上面两个函数是哥俩,一定要成对使用,但是由于大哥本质上只是增加了中断嵌套次数,可以不用大哥,但一定得用小弟,为啥?下面再细说!
& 后央三句自己看吧,挺简单的!
再看老二函数源码:
void& OSIntExit (void)
#if OS_CRITICAL_METHOD ==
3&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& /* Allocate storage for CPU status register
&&& OS_CPU_SR& cpu_
&&& if (OSRunning == TRUE)
&&&&&&& OS_ENTER_CRITICAL();
&&&&&&& if (OSIntNesting & 0)
{&&&&&&&&&&&&&&&&&&&&&&&&&&& /* Prevent OSIntNesting from wrapping&&&&&&
&&&&&&&&&&& OSIntNesting--;
&&&&&&& if ((OSIntNesting ==
0) && (OSLockNesting == 0)) { /* Reschedule only if all ISRs complete
&&&&&&&&&&& OSIntExitY&&& = OSUnMapTbl[OSRdyGrp];&&&&&&&&& /* ... and
not locked.&&&&&&&&&&&&&&&&&&&&& */
&&&&&&&&&&& OSPrioHighRdy =
(INT8U)((OSIntExitY && 3) +
OSUnMapTbl[OSRdyTbl[OSIntExitY]]);
&&&&&&&&&&& if (OSPrioHighRdy !=
OSPrioCur) {&&&&&&&&&&&&& /* No Ctx Sw if current task is highest rdy
&&&&&&&&&&&&&&& OSTCBHighRdy& =
OSTCBPrioTbl[OSPrioHighRdy];
&&&&&&&&&&&&&&&
OSCtxSwCtr++;&&&&&&&&&&&&&&&&&&&&&&&&&&&&& /* Keep track of the number of ctx
switches */
&&&&&&&&&&&&&&& OSIntCtxSw();&&&&&&&&&&&&&&&&&&&&&&&&&&&&& /*
Perform interrupt level ctx switch&&&&&& */
&&&&&&&&&&& }
&&&&&&& OS_EXIT_CRITICAL();
源码不多,也不少,不过关键的需要理解的就那一行:OSIntCtxSw(),这是啥?中断级任务调度函数啊,终于出来了,看它的注释吧:
*********************************************************************************************************
*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
* Description: This function is used to notify uC/OS-II that
you have completed serviving an ISR.& When
*&&&&&&&&&&&&& the last nested ISR
has completed, uC/OS-II will call the scheduler to determine
*&&&&&&&&&&&&& a new, high-priority task, is ready to run.
Arguments& : none
* Returns&&& : none
* Notes&&&&& : 1) You MUST
invoke OSIntEnter() and OSIntExit() in pair.& In other words, for every
*&&&&&&&&&&&&&&&& to OSIntEnter() at the beginning of the ISR you MUST
have a call to OSIntExit() at the
*&&&&&&&&&&&&&&&& end of the
*&&&&&&&&&&&&& 2) Rescheduling is prevented when the scheduler is locked
(see OS_SchedLock())
翻译如下:这个函数用来通知OS我们已经完成了中断服务程充,当最后一次被嵌套的中断也完成时,OS将调用scheduler来决定是否有一个新的,更高优先级的任务,已经主绪。(当然没有更高的时就恢复被中断的任务)
&&&&& 总结:我遇到情况的主要原因大概是,当按普通方法写中断服务例程时,没有通知操作系统,触发中断时当前执行任务被中断,然后退出中断服务例程时,系统找不到原先被中断的任务,不知道该干啥,所以就进入了默认异常处理程序,死在里面出不来了,呵呵,不知道这样理解对不对,呵呵!
我也遇到了这样的情况,我用的是按键触发中断,就是一直死在那里出不来,你是怎么解决的.......
能把你的解决后的源码发我一份吗?
这个其实是操作系统内核任务调度的精华所在:
裸奔的程序,中断产生后,CPU根据中断优先级和使能情况,及时响应中断,保护现场和恢复现场,PC指针和现场寄存器数据都保持在系统的堆栈中,由CPU自行处理进栈和出栈,然后根据PC指针继续之前被中断所打断的程序执行;
在uCOS-II中就不一样了,每一个任务都有自己的退栈,用于保持自己的现场数据和寄存器,中断服务程序也是如此,所以从中断返回时,必须调用操作系统内核的任务切换函数(或者宏),才能恢复之前被打断的优先级最高的任务的执行,或者心就绪的最高优先级任务(通过恢复任务堆栈的方式,注意这里每个任务的堆栈所占的内存RAM的空间不一样,处于不同的全局数组)
我的情况是这样的,将ucos移植到S3C2410上之后,我先只建立了一个任务TASK1(优先级10),就是打印123(我加几个任务都可以,已测试)。后来跟楼主的想法一样,想加个外部中断的任务TASK2(优先级5)玩玩,我加的是用按键控制LED。全速运行时,由于开始没有按键触发中断,只是在两个任务间简单的切换,当我触发按键后,就一直循环运行在按键中断服务程序中,为什么说一直循环运行在中断服务程序中呢,我在服务程序中加了一句打印消息之后再全速运行,触发中断就一直在DNW上打印消息......而不切换到TASK1,不知道这是为什么?
我的问题好像跟楼主的相似......
我的情况是这样的,将ucos移植到S3C2410上之后,我先只建立了一个任务TASK1(优先级10),就是打印123(我加几个任务都可以,已测试)。后来跟楼主的想法一样,想加个外部中断的任务TASK2(优先级5)玩玩,我加的是用按键控制LED。全速运行时,由于开始没有按键触发中断,只是在两个任务间简单的切换,当我触发按键后,就一直循环运行在按键中断服务程序中,为什么说一直循环运行在中断服务程序中呢,我在服务程序中加了一句打印消息之后再全速运行,触发中断就一直在DNW上打印消息......而不切换到TASK1,不知道这是为什么?
你清中断标志了吗?
你是说再中断服务程序中清中断标志还是?
当然是在中断服务程序中啊
我用的中断服务程序是原先裸板上的程序,我看了哈,中断清了。我在中断服务程序中加了两句OSIntNesting-=3;
&&& OSTimeDly(2);后,再全速运行,触发中断后就可以切换出来(切换到任务1),但是还是有在DNW上显示中断服务程序中的打印消息,只不过打印消息的次数有限(比如说100次),打印完消息后就切换到TASK1,TASK1运行完后又切换到中断服务程序中的打印消息,打印100后再切换到TASK1,反复。。。。。中途触发按键的话也会响应中断去运行中断服务程序.
我解释下为什么我要加OSIntNesting-=3;我设断点调试的时候发现运行到中断服务程序的时候,OSIntNesting为3,我就尝试的;后来也尝试OSIntNesting-=6或9,都可以....
为什么要加 OSTimeDly(2);我想的话,在中断服务程序中要切换出去(也就是要把CPU的控制权要交出去,需要OSTimeDly()或挂起任务,我就尝试了哈)
不知道是为什么,我觉得我的情况跟楼主的很相似........
那是因为中断嵌套计数器OSIntNesting&0,内核是不能进行任务调度的,详见内核任务调度函数源代码。
匿名不能发帖!请先 [
Copyright (C) 《电子产品世界》杂志社 版权所有【图文】第4章 ucosII中的中断和时钟_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
第4章 ucosII中的中断和时钟
||文档简介
电子商务运营专才|
总评分3.7|
浏览量10624
&&嵌​入​式​实​时​操​作​系​统​的​课​件​,​供​大​家​参​考​

​还​有​两​份​由​于​太​大​传​不​了​,​有​需​要​的​可​以​百​度​H​I​我​索​取​哦​~
大小:14.95MB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢

参考资料

 

随机推荐