[ZLG-ARM] R14被莫名修改,导致函数不能正确返回,出现死循环

[复制链接]
3001|6
 楼主| xlander 发表于 2007-9-19 13:01 | 显示全部楼层 |阅读模式
先说一下环境:<br />lpc2220,模板是zlg网站上的最新版本。<br /><br /><br />概述:<br />我自己写了一个串口驱动,现在UART0自收自发,UART1自收自发都正常,UART0,UART1“接力”的时候会出现问题。<br />所谓的接力是指同时启用Uart0,Uart1,Uart0将自己收到的数据通过Uart1发送出去,同时,Uart1将自己收到的数据通过Uart0发送出去。<br /><br /><br />现象:<br />在我调试的时候发现,两个串口会正常工作一段时间,然后R14不知道什么样的原因被莫名其妙的修改,在下文所述的UART1_EnableTX(),以及于此类似的UART0_EnableTX(),函数返回时R14存储的值指向自身函数的入口,出现死循环的情况。<br /><br /><br />问题:<br />不知道各位有没有遇到过类似的情况?如果有,是什么样的原因造成的?<br />另外,有一个概念我一直没弄明白,假设当前程序正在Uart1的中断服务程序(低优先)中,然后这个时候产生了Uart0中断(高优先),程序会跳转到Uart0的中断服务程序中么?<br /><br /><br />供参考的资料:<br />void&nbsp;UART1_DisableTX()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;U1IER&nbsp;=&nbsp;U1IER&nbsp;&&nbsp;(~0x02);<br />}<br /><br />void&nbsp;UART1_EnableTX()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;U1IER&nbsp;=&nbsp;U1IER&nbsp;|&nbsp;0x02;<br />}<br /><br />UART1_EnableTX的汇编代码如下:<br />80005a48&nbsp;&nbsp;&nbsp;&nbsp;[0xe59f0114]&nbsp;&nbsp;&nbsp;ldr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,0x80005b64&nbsp;;&nbsp;=&nbsp;#0xe000c000<br />80005a4c&nbsp;&nbsp;&nbsp;&nbsp;[0xe5d00004]&nbsp;&nbsp;&nbsp;ldrb&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,[r0,#4]<br />80005a50&nbsp;&nbsp;&nbsp;&nbsp;[0xe3800002]&nbsp;&nbsp;&nbsp;orr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,r0,#2<br />80005a54&nbsp;&nbsp;&nbsp;&nbsp;[0xe59f1108]&nbsp;&nbsp;&nbsp;ldr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r1,0x80005b64&nbsp;;&nbsp;=&nbsp;#0xe000c000<br />80005a58&nbsp;&nbsp;&nbsp;&nbsp;[0xe5c10004]&nbsp;&nbsp;&nbsp;strb&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r0,[r1,#4]<br />80005a5c&nbsp;&nbsp;&nbsp;&nbsp;[0xe1a0f00e]&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pc,r14&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt==&nbsp;&nbsp;&nbsp;&nbsp;此处R14=0x80005a48,为函数的入口<br /><br />以下为串口驱动的代码:<br />其中队列部分参考了zlg的队列中间件,我的改动主要使其适合于前后台系统。<br /><br /><br />#define&nbsp;UART1_TXD_SEL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1&nbsp;&lt&lt&nbsp;16)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//P0.8<br />#define&nbsp;UART1_RXD_SEL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1&nbsp;&lt&lt&nbsp;18)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//P0.9<br />void&nbsp;UART1_InitTxdRxd(void)&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;PINSEL0&nbsp;|=&nbsp;UART1_TXD_SEL&nbsp;|&nbsp;UART1_RXD_SEL;}<br /><br />#define&nbsp;UART1_MODEMSEL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1&nbsp;&lt&lt&nbsp;20)&nbsp;|&nbsp;(1&nbsp;&lt&lt&nbsp;22)&nbsp;|&nbsp;(1&nbsp;&lt&lt&nbsp;24)&nbsp;|&nbsp;(1&nbsp;&lt&lt&nbsp;26)&nbsp;|&nbsp;(1&nbsp;&lt&lt&nbsp;28)&nbsp;|&nbsp;(1&nbsp;&lt&lt&nbsp;30)&nbsp;<br />void&nbsp;UART1_InitModem(void)&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;PINSEL0&nbsp;|=&nbsp;UART1_MODEMSEL;&nbsp;}<br /><br />volatile&nbsp;uint8&nbsp;acUart1RxBuff[UART1_RX_QUEUE_SIZE];<br />volatile&nbsp;uint8&nbsp;acUart1TxBuff[UART1_TX_QUEUE_SIZE];<br />volatile&nbsp;struct&nbsp;_tag_Queue&nbsp;stUart1RxQueue;<br />volatile&nbsp;struct&nbsp;_tag_Queue&nbsp;stUart1TxQueue;<br /><br />void&nbsp;/*&nbsp;&nbsp;__irq*/&nbsp;IRQ_UART1(void)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;uint8&nbsp;nState;<br />&nbsp;&nbsp;&nbsp;&nbsp;nState&nbsp;=&nbsp;(U1IIR&nbsp;&&nbsp;0x0E)&nbsp;&gt&gt&nbsp;1;<br />&nbsp;&nbsp;&nbsp;&nbsp;switch(nState)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;0x06://字符超时<br />&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;0x02://接收<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;QueuePushOneChar(&stUart1RxQueue,&nbsp;U1RBR);<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;case&nbsp;0x01://发送<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(QueuePullOneChar(&stUart1TxQueue,&nbsp;&nState)&nbsp;==&nbsp;1)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U1THR&nbsp;=&nbsp;nState;<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;case&nbsp;0x00://MODEM中断<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nState&nbsp;=&nbsp;U1MSR;<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;case&nbsp;0x03://接受线状态<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nState&nbsp;=&nbsp;U0LSR;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nState&nbsp;=&nbsp;U0RBR;<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;}<br />&nbsp;&nbsp;&nbsp;&nbsp;nEnterTimes1--;<br />&nbsp;&nbsp;&nbsp;&nbsp;VICVectAddr&nbsp;=&nbsp;0x00;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;中断处理结束&nbsp;&nbsp;&nbsp;&nbsp;<br />}<br /><br />void&nbsp;UART1_Init(void)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;UART1_InitTxdRxd();<br />&nbsp;&nbsp;&nbsp;&nbsp;QueueInit(acUart1RxBuff,&nbsp;UART1_RX_QUEUE_SIZE,&nbsp;&stUart1RxQueue);<br />&nbsp;&nbsp;&nbsp;&nbsp;QueueInit(acUart1TxBuff,&nbsp;UART1_TX_QUEUE_SIZE,&nbsp;&stUart1TxQueue);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;VICIntEnClr&nbsp;=&nbsp;1&nbsp;&lt&lt&nbsp;7;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//禁能中断<br />}<br /><br /><br />uint32&nbsp;UART1_SetMode(const&nbsp;UARTMODE&nbsp;*pMode)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;extern&nbsp;void&nbsp;IRQ_Def(void);<br />&nbsp;&nbsp;&nbsp;&nbsp;extern&nbsp;void&nbsp;UART1_Handler(void);<br />&nbsp;&nbsp;&nbsp;&nbsp;uint32&nbsp;i;<br />&nbsp;&nbsp;&nbsp;&nbsp;uint8&nbsp;nTemp;<br />&nbsp;&nbsp;&nbsp;&nbsp;if(UartEx_IsModeValid(pMode)&nbsp;==&nbsp;0)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;U1LCR&nbsp;=&nbsp;0x80;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;DLAB位置1<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;i&nbsp;=&nbsp;(Fpclk&gt&gt4)&nbsp;/&nbsp;pMode-&gtnBaudRate;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;设置串口波特率<br />&nbsp;&nbsp;&nbsp;&nbsp;U1DLM&nbsp;=&nbsp;i&nbsp;&gt&gt&nbsp;8;<br />&nbsp;&nbsp;&nbsp;&nbsp;U1DLL&nbsp;=&nbsp;i&nbsp;&&nbsp;0xFF;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;nTemp&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;nTemp&nbsp;|=&nbsp;(pMode-&gtnDataLen&nbsp;-&nbsp;5);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//数据长度<br />&nbsp;&nbsp;&nbsp;&nbsp;nTemp&nbsp;|=&nbsp;(pMode-&gtnStopBitLen&nbsp;-&nbsp;1)&nbsp;&lt&lt&nbsp;2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//停止位<br />&nbsp;&nbsp;&nbsp;&nbsp;if(pMode-&gtnParity&nbsp;!=&nbsp;0)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//是否校验<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nTemp&nbsp;|=&nbsp;(pMode-&gtnParity&nbsp;-&nbsp;1)&nbsp;&lt&lt&nbsp;4;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//校验方式<br />&nbsp;&nbsp;&nbsp;&nbsp;U1LCR&nbsp;=&nbsp;nTemp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;if(pMode-&gtnFullSignal&nbsp;!=&nbsp;0)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UART1_InitModem();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;U1FCR&nbsp;=&nbsp;0x01;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;使能FIFO,并设置触发点为1字节<br />&nbsp;&nbsp;&nbsp;&nbsp;U1IER&nbsp;=&nbsp;0x03;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;接收中断,发送中断<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;VICIntEnClr&nbsp;=&nbsp;1&nbsp;&lt&lt&nbsp;7;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//禁能中断<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;VICIntSelect&nbsp;&=&nbsp;(~(1&nbsp;&lt&lt&nbsp;7));&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//设置UART1中断分配为IRQ中断<br />&nbsp;&nbsp;&nbsp;&nbsp;VICVectCntl2&nbsp;=&nbsp;0x20&nbsp;|&nbsp;7;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//UART1中断<br />&nbsp;&nbsp;&nbsp;&nbsp;VICVectAddr2&nbsp;=&nbsp;(int)UART1_Handler;&nbsp;&nbsp;&nbsp;&nbsp;//设置UART1中断服务程序地址<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;VICDefVectAddr&nbsp;=&nbsp;(int)IRQ_Def;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;VICIntEnable&nbsp;=&nbsp;1&nbsp;&lt&lt&nbsp;7;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//使能中断<br />&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;1;<br />}<br />void&nbsp;UART1_DisableRX()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;U1IER&nbsp;=&nbsp;U1IER&nbsp;&&nbsp;(~0x01);<br />}<br />void&nbsp;UART1_EnableRX()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;U1IER&nbsp;=&nbsp;U1IER&nbsp;|&nbsp;0x01;<br />}<br />void&nbsp;UART1_DisableTX()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;U1IER&nbsp;=&nbsp;U1IER&nbsp;&&nbsp;(~0x02);<br />}<br />void&nbsp;UART1_EnableTX()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;U1IER&nbsp;=&nbsp;U1IER&nbsp;|&nbsp;0x02;<br />}<br /><br />uint8&nbsp;&nbsp;UART1_Send(const&nbsp;uint8&nbsp;*pnData,&nbsp;uint8&nbsp;nDataLen)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;volatile&nbsp;struct&nbsp;_tag_Queue&nbsp;*pstQueue&nbsp;=&nbsp;&stUart1TxQueue;<br />&nbsp;&nbsp;&nbsp;&nbsp;uint8&nbsp;nLen;<br />&nbsp;&nbsp;&nbsp;&nbsp;uint8&nbsp;temp;<br />&nbsp;&nbsp;&nbsp;&nbsp;UART1_DisableTX();<br />&nbsp;&nbsp;&nbsp;&nbsp;nLen&nbsp;=&nbsp;QueuePushIn(pstQueue,&nbsp;pnData,&nbsp;nDataLen);<br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;((U1LSR&nbsp;&&nbsp;0x00000020)&nbsp;!=&nbsp;0)<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;UART0发送保持寄存器空&nbsp;*/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;QueuePullOut(pstQueue,&nbsp;1,&nbsp;&temp);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;发送最初入队的数据&nbsp;*/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U1THR&nbsp;=&nbsp;temp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;UART1_EnableTX();<br />&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;nLen;<br />}<br /><br />uint8&nbsp;UART1_Receive(uint8&nbsp;*pnData,&nbsp;uint8&nbsp;nDataLen)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;volatile&nbsp;struct&nbsp;_tag_Queue&nbsp;*pstQueue&nbsp;=&nbsp;&stUart1RxQueue;<br />&nbsp;&nbsp;&nbsp;&nbsp;uint8&nbsp;nLen&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;if(QueueGetSize(pstQueue)&nbsp;&gt=&nbsp;nDataLen)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UART1_DisableRX();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;QueuePullOut(pstQueue,&nbsp;nDataLen,&nbsp;pnData);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UART1_EnableRX();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nLen&nbsp;=&nbsp;nDataLen;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;nLen;<br />}
bald 发表于 2007-9-19 13:32 | 显示全部楼层

有中断嵌套问题,中断服务程序入口处保护LR

  
 楼主| xlander 发表于 2007-9-19 13:41 | 显示全部楼层

怎么保护

bald:<br />对这个&quot;中断嵌套&quot;一点概念没有,尽管搜索了论坛,但是都没有一个系统的教程,请问有没有相关的资料,或者您能给出一些示意性的代码么?谢谢。
 楼主| xlander 发表于 2007-9-19 13:49 | 显示全部楼层

re

我之前就已经在irq.s加入:<br /><br />UART0_Handler&nbsp;&nbsp;HANDLER&nbsp;IRQ_UART0<br />UART1_Handler&nbsp;&nbsp;HANDLER&nbsp;IRQ_UART1<br /><br />这样做是不是就是说已经进行了有关“中断嵌套”的保护,除此之外,还需要做什么?<br />
bald 发表于 2007-9-19 14:17 | 显示全部楼层

参考一下子程序嵌套例程

我对C不熟悉,不过加一句汇编十分方便<br />在子程序中嵌套中只要进入后加一句:STR&nbsp;SP!,{LR}就可以了。不过中断服务程序LR还需要加上一个偏移量。<br />当然结束中断进程也需要相应的出栈操作<br />
 楼主| xlander 发表于 2007-9-19 15:13 | 显示全部楼层

新的参考资料

新的参考资料,调试过程中发现的。<br /><br />我调试软件用的是ADS。<br /><br />程序正常的时候:<br />cpsr为NzcvqiFt_SYS,即系统模式,spsr为Unavailable<br />不管是进入还是退出UART0_EnableTX(),都无变化<br /><br />程序进入“死循环”的时候:<br />cpsr为NzcvqIFt_IRQ,即系统模式,spsr为NzcvqiFt_SYS<br /><br />但是死循环的程序UART0_EnableTX()从来没有在中断服务程序里调用过。<br /><br />请高人帮我分析下。<br />是程序跑飞,还是怎么回事儿?或者是别的什么地方出了什么问题?比方说队列.<br />
 楼主| xlander 发表于 2007-9-19 15:23 | 显示全部楼层

to bald

以下是zlg模板中的代码,估计能解决中断嵌套的问题。<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;MACRO<br />$IRQ_Label&nbsp;HANDLER&nbsp;$IRQ_Exception_Function<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EXPORT&nbsp;&nbsp;$IRQ_Label&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;The&nbsp;label&nbsp;for&nbsp;exports&nbsp;输出的标号<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IMPORT&nbsp;&nbsp;$IRQ_Exception_Function&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;The&nbsp;imported&nbsp;labels&nbsp;引用的外部标号<br /><br />$IRQ_Label<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SUB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LR,&nbsp;LR,&nbsp;#4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;Calculate&nbsp;the&nbsp;returning&nbsp;address&nbsp;计算返回地址<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;STMFD&nbsp;&nbsp;&nbsp;SP!,&nbsp;{R0-R3,&nbsp;R12,&nbsp;LR}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;Protects&nbsp;the&nbsp;task&nbsp;environments&nbsp;保存任务环境<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MRS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;R3,&nbsp;SPSR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;Protects&nbsp;the&nbsp;status&nbsp;variable&nbsp;保存状态<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;STMFD&nbsp;&nbsp;&nbsp;SP,&nbsp;{R3,LR}^&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;Protects&nbsp;SPSR&nbsp;and&nbsp;SP&nbsp;in&nbsp;user&nbsp;status,&nbsp;Notice:&nbsp;DO&nbsp;NOT&nbsp;write&nbsp;back.保存SPSR和用户状态的SP,注意不能回写<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;If&nbsp;the&nbsp;SP&nbsp;is&nbsp;written&nbsp;back,&nbsp;it&nbsp;should&nbsp;be&nbsp;adjusted&nbsp;to&nbsp;its&nbsp;appropriate&nbsp;value&nbsp;later.如果回写的是用户的SP,所以后面要调整SP<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NOP<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SUB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SP,&nbsp;SP,&nbsp;#4*2<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MSR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CPSR_c,&nbsp;#(NoInt&nbsp;|&nbsp;SYS32Mode)&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;Switch&nbsp;to&nbsp;the&nbsp;System&nbsp;Mode&nbsp;切换到系统模式&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$IRQ_Exception_Function&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;call&nbsp;the&nbsp;C&nbsp;interrupt&nbsp;handler&nbsp;funtion&nbsp;调用c语言的中断处理程序<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MSR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CPSR_c,&nbsp;#(NoInt&nbsp;|&nbsp;IRQ32Mode)&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;Switch&nbsp;bak&nbsp;to&nbsp;IRQ&nbsp;mode&nbsp;切换回irq模式<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LDMFD&nbsp;&nbsp;&nbsp;SP,&nbsp;{R3,LR}^&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;Recover&nbsp;SPSR&nbsp;and&nbsp;SP&nbsp;in&nbsp;user&nbsp;status,&nbsp;Notic:&nbsp;DO&nbsp;NOT&nbsp;write&nbsp;back.&nbsp;恢复SPSR和用户状态的SP,注意不能回写<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;If&nbsp;the&nbsp;SP&nbsp;is&nbsp;written&nbsp;back,&nbsp;it&nbsp;should&nbsp;be&nbsp;adjusted&nbsp;to&nbsp;its&nbsp;appropriate&nbsp;value&nbsp;later.如果回写的是用户的SP,所以后面要调整SP<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MSR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SPSR_cxsf,&nbsp;R3<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ADD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SP,&nbsp;SP,&nbsp;#4*2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LDMFD&nbsp;&nbsp;&nbsp;SP!,&nbsp;{R0-R3,&nbsp;R12,&nbsp;PC}^&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;
您需要登录后才可以回帖 登录 | 注册

本版积分规则

65

主题

165

帖子

0

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