[ZLG-ARM] LPC213X ucos-II 中断处理的改进

[复制链接]
 楼主| 枯竹 发表于 2008-4-8 17:47 | 显示全部楼层 |阅读模式
我使用LPC2136做了一个项目,使用的是ZLG提供的UCOS-II&nbsp;V2.52的模板。其中用到了LPC2136的2个串口,波特率为115200。在调试测序时,发现串口总是莫名其妙的丢失数据,溢出标志置位。本来FIFO触发字符个数为8,后改触发字符个数为1时故障依然。经过调试后发现,当多个中断同时触发时,CPU来不及处理所致。分析中断部分源程序,发现每次中断服务程序退出时,都要查找一次最高优先级的任务,完成一次任务的切换,中断处理比较耗时,针对这个问题,我修改了部分代码,使程序在执行完所有的被挂起的中断后再进行任务的查找和切换。程序改进后效果明显,没再出现数据丢失的现象。我把我的经验和教训写在这里,希望给大家以借鉴,少走弯路,避免出现和我一样的问题。<br />另外,当改动STARTUP.S的启动代码时,一定要确保异常向量表的累加和为零!!!!<br />
 楼主| 枯竹 发表于 2008-4-8 17:50 | 显示全部楼层

一部分代码

INT32U&nbsp;InstallHandler(INT32U&nbsp;routine,&nbsp;INT8U&nbsp;vector,&nbsp;INT8U&nbsp;channel,&nbsp;INT8U&nbsp;irq_mode)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;INT32U&nbsp;old_routine;<br />&nbsp;&nbsp;&nbsp;&nbsp;volatile&nbsp;INT32U&nbsp;&nbsp;&nbsp;&nbsp;*addr;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;addr&nbsp;=&nbsp;(volatile&nbsp;INT32U&nbsp;*)&VICVectAddr0;<br />&nbsp;&nbsp;&nbsp;&nbsp;old_routine&nbsp;=&nbsp;addr[vector];<br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(vector&nbsp;&gt&nbsp;15&nbsp;||&nbsp;channel&nbsp;&gt&nbsp;20)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;old_routine;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;addr[vector]&nbsp;=&nbsp;routine;<br />&nbsp;&nbsp;&nbsp;&nbsp;addr&nbsp;=&nbsp;(volatile&nbsp;INT32U&nbsp;*)&VICVectCntl0;<br />&nbsp;&nbsp;&nbsp;&nbsp;addr[vector]&nbsp;=&nbsp;0x20&nbsp;|&nbsp;channel;<br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(FIQ_MODE&nbsp;==&nbsp;irq_mode)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VICIntSelect&nbsp;|=&nbsp;(1&nbsp;&lt&lt&nbsp;channel);<br />&nbsp;&nbsp;&nbsp;&nbsp;VICIntEnable&nbsp;=&nbsp;1&nbsp;&lt&lt&nbsp;channel;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;old_routine;<br />}<br /><br /><br />void&nbsp;IRQ_Def_Exception(void)<br />{&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;//VICVectAddr&nbsp;=&nbsp;0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;change&nbsp;it&nbsp;to&nbsp;your&nbsp;code&nbsp;&nbsp;&Otilde;&acirc;&Ograve;&raquo;&frac34;&auml;&Igrave;&aelig;&raquo;&raquo;&Icirc;&ordf;×&Ocirc;&frac14;&ordm;&micro;&Auml;&acute;ú&Acirc;&euml;<br />}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;VICInit(void)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;//extern&nbsp;void&nbsp;IRQ_Handler(void);<br />&nbsp;&nbsp;&nbsp;&nbsp;//extern&nbsp;void&nbsp;Timer0_Handler(void);<br />&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;long&nbsp;*vec_addr;<br />&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;long&nbsp;*ctr_addr;<br />&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;char&nbsp;i;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;vec_addr&nbsp;=&nbsp;(unsigned&nbsp;long&nbsp;*)&VICVectAddr0;<br />&nbsp;&nbsp;&nbsp;&nbsp;ctr_addr&nbsp;=&nbsp;(unsigned&nbsp;long&nbsp;*)&VICVectCntl0;<br />&nbsp;&nbsp;&nbsp;&nbsp;VICIntEnClr&nbsp;=&nbsp;0xffffffff;<br />&nbsp;&nbsp;&nbsp;&nbsp;VICDefVectAddr&nbsp;=&nbsp;(uint32)IRQ_Def_Exception;<br />&nbsp;&nbsp;&nbsp;&nbsp;VICVectAddr&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(i=0;&nbsp;i&lt16;&nbsp;i++)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*vec_addr&nbsp;=&nbsp;(unsigned&nbsp;long)IRQ_Def_Exception;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*ctr_addr&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vec_addr++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ctr_addr++;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;}<br /><br /><br />typedef&nbsp;&nbsp;void&nbsp;&nbsp;(*BSP_PFNCT)(void);<br /><br /><br /><br />/*********************************************************************************************************/<br />void&nbsp;IRQ_Handle_Exception&nbsp;(void)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;BSP_PFNCT&nbsp;&nbsp;&nbsp;&nbsp;pfnct;<br />&nbsp;&nbsp;&nbsp;&nbsp;while(1)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pfnct&nbsp;=&nbsp;(BSP_PFNCT)VICVectAddr;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//VICVectAddr&nbsp;=&nbsp;&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(pfnct&nbsp;!=&nbsp;(BSP_PFNCT)0)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pfnct&nbsp;();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VICVectAddr&nbsp;=&nbsp;&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(pfnct&nbsp;==&nbsp;IRQ_Def_Exception)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VICVectAddr&nbsp;=&nbsp;&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;<br />}<br />
lhzw2001 发表于 2008-4-15 18:52 | 显示全部楼层

LZ能不能做个详细点的说明呢?

  
ljt8015 发表于 2012-7-1 10:19 | 显示全部楼层
发现每次中断服务程序退出时,都要查找一次最高优先级的任务,完成一次任务的切换.

能不能将 别的中断服务退出时的任务切换  取消掉么?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

4

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部

2

主题

4

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部