中断嵌套和IAP程序更新问题

[复制链接]
4954|3
 楼主| 云痕 发表于 2008-10-8 13:02 | 显示全部楼层 |阅读模式
我用的是LPC2365,MDK3.20<br />NXP原厂给的HOT_04.03&nbsp;VIC中,<br />static&nbsp;DWORD&nbsp;sysreg;&nbsp;/*&nbsp;used&nbsp;as&nbsp;LR&nbsp;register&nbsp;*/<br />#define&nbsp;IENABLE&nbsp;__asm&nbsp;{&nbsp;MRS&nbsp;sysreg,&nbsp;SPSR;&nbsp;MSR&nbsp;CPSR_c,&nbsp;#SYS32Mode&nbsp;}<br />#define&nbsp;IDISABLE&nbsp;__asm&nbsp;{&nbsp;MSR&nbsp;CPSR_c,&nbsp;#(IRQ32Mode|I_Bit);&nbsp;MSR&nbsp;SPSR_cxsf,&nbsp;sysreg&nbsp;}<br />每个中断函数进入后,SPSR存储于static&nbsp;DWORD&nbsp;sysreg,但这是一个全局变量而已,且LR未保存.高优先中断打断当前中断程序时,新的中断程序再次调用IENABLE,这样本次的SPSR覆盖了低优先的SPSR,并覆盖了LR,感觉这样是实现不了中断嵌套的.例子程序EXTINT_nested项目,EINT0_Handler()和Timer0Handler()内均调用了这个宏,感觉这样没有实现中断可嵌套.<br />我的工程仿照模板的中断处理模式处理的,测试过程中,短则几分钟,长则几个小时,系统失去响应.硬件仿真时进入指令异常PAbt_Addr.在绝大多数子函数的出入口都用查询模式的串口输出测试时,发现都是在执行return之后飞到PAbt_Addr,感觉返回地址被破坏了.<br />我的中断函数都如下:<br />void&nbsp;&nbsp;TIMER0_Handler(void)&nbsp;__irq<br />{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;IENABLE;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;function();<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IDISABLE;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;VICVectAddr&nbsp;=&nbsp;0x0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;通知VIC中断处理结束<br />}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />在AN10381.pdf官方文档内,文档内在一个.c文件内定义如下:<br />#define&nbsp;IENABLE&nbsp;/*&nbsp;Nested&nbsp;Interrupts&nbsp;Entry&nbsp;*/&nbsp;<br />__asm&nbsp;{&nbsp;MRS&nbsp;LR,&nbsp;SPSR&nbsp;}&nbsp;/*&nbsp;Copy&nbsp;SPSR_irq&nbsp;to&nbsp;LR&nbsp;*/&nbsp;<br />__asm&nbsp;{&nbsp;STMFD&nbsp;SP!,&nbsp;{LR}&nbsp;}&nbsp;/*&nbsp;Save&nbsp;SPSR_irq&nbsp;*/&nbsp;<br />__asm&nbsp;{&nbsp;MSR&nbsp;CPSR_c,&nbsp;#0x1F&nbsp;}&nbsp;/*&nbsp;Enable&nbsp;IRQ&nbsp;(Sys&nbsp;Mode)&nbsp;*/&nbsp;<br />__asm&nbsp;{&nbsp;STMFD&nbsp;SP!,&nbsp;{LR}&nbsp;}&nbsp;/*&nbsp;Save&nbsp;LR&nbsp;*/&nbsp;<br />//&nbsp;Macro&nbsp;for&nbsp;disabling&nbsp;interrupts,&nbsp;switching&nbsp;back&nbsp;to&nbsp;IRQ&nbsp;and&nbsp;relevant&nbsp;stack&nbsp;operations<br />#define&nbsp;IDISABLE&nbsp;/*&nbsp;Nested&nbsp;Interrupts&nbsp;Exit&nbsp;*/&nbsp;<br />__asm&nbsp;{&nbsp;LDMFD&nbsp;SP!,&nbsp;{LR}&nbsp;}&nbsp;/*&nbsp;Restore&nbsp;LR&nbsp;*/&nbsp;<br />__asm&nbsp;{&nbsp;MSR&nbsp;CPSR_c,&nbsp;#0x92&nbsp;}&nbsp;/*&nbsp;Disable&nbsp;IRQ&nbsp;(IRQ&nbsp;Mode)&nbsp;*/&nbsp;<br />__asm&nbsp;{&nbsp;LDMFD&nbsp;SP!,&nbsp;{LR}&nbsp;}&nbsp;/*&nbsp;Restore&nbsp;SPSR_irq&nbsp;to&nbsp;LR&nbsp;*/&nbsp;<br />__asm&nbsp;{&nbsp;MSR&nbsp;SPSR_cxsf,&nbsp;LR&nbsp;}&nbsp;/*&nbsp;Copy&nbsp;LR&nbsp;to&nbsp;SPSR_irq&nbsp;*/&nbsp;&nbsp;<br />然后调用时和前面的那个类似。<br />照这样子复制进我的项目后,编译提示下面之类错误:<br />SPISPI.c(79):&nbsp;error:&nbsp;#20:&nbsp;identifier&nbsp;&quot;SP&quot;&nbsp;is&nbsp;undefined<br />SPISPI.c(79):&nbsp;warning:&nbsp;#1287-D:&nbsp;LDM/STM&nbsp;instruction&nbsp;may&nbsp;be&nbsp;expanded<br />这是什么原因啊?有什么地方需要特殊设置的?<br /><br />按照ZLG2210模板内的例子,在irq.s内添加HandlerTIMER0&nbsp;&nbsp;&nbsp;TIMER0_Handler_ZLG&nbsp;<br />void&nbsp;Tim0_init(void)&nbsp;<br />{&nbsp;&nbsp;&nbsp;...//初始<br />&nbsp;&nbsp;&nbsp;&nbsp;install_irq(TIMER0_INT,&nbsp;(void&nbsp;*)HandlerTIMER0,&nbsp;5);&nbsp;<br />}&nbsp;<br />void&nbsp;&nbsp;TIMER0_Handler_ZLG(void)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;VICIntEnClr&nbsp;=&nbsp;1&nbsp;&lt&lt&nbsp;TIMER0_INT;&nbsp;<br />。。。<br />&nbsp;&nbsp;&nbsp;&nbsp;VICIntEnable&nbsp;|=&nbsp;1&nbsp;&lt&lt&nbsp;TIMER0_INT;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;VICVectAddr&nbsp;=&nbsp;0x0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;通知VIC中断处理结束<br />}<br />编译提示:DEMO_test.axf:&nbsp;Error:&nbsp;L6218E:&nbsp;Undefined&nbsp;symbol&nbsp;UART1_Handler_ZLG&nbsp;(referred&nbsp;from&nbsp;irq_zlg.o).<br />这个该怎么处理啊?irq_zlg.s里的那个宏里已经有EXPORT和IMPORT了的。也没弄过内嵌汇编,谁给支个招?<br /><br />///////////////////////IAP<br />我的项目有GSM无线网络远程更新程序的需求,新旧程序版本的ZI和ZW域大小不确定,不可预知。想法是扇区0~6作为新旧程序公共部分,存储Startup.s.target.c,以及main的在分散加载文件。7扇区作为非易失存储区,以及新旧版本程序切换标志。之后的扇区平分成2部分,每部分首地址作为新旧程主程序入口。main文件固定不变,根据扇区7内的一个标志量,在2个子函数上切换,这2个子函数就是我的新旧版本的主程序。可写分散加载文件时发现,InRoot$$section必须在根加载域,完成进入main()之前的ZI和ZW域的搬运,但由于我的新旧版本的ZI和ZW域是不同的,导致新的版本更新后,加载的ZI和ZW域还是旧的程序的内容,一直想不出解决办法。现在的想法是,在RAM区预留出一块空间,程序中的所有的全局变量,全部以绝对地址的方式映射过去,且所有变量在函数体内显式初始。这样程序更新后,虽然ZI和ZW加载的还是旧的程序的内容,占据一定空间,新的程序运行时,这块被旧程序占用的空间,永远不会被新程序用到。不知道这样能实现不,这样弄的话,工作量有点大,想先问下这方向是否已经错了?有人这么弄过么?或者有人做过这种ZI和ZW域不确定的远程程序升级?弄过的帮忙支个招啊<br />
 楼主| 云痕 发表于 2008-10-8 17:22 | 显示全部楼层

这问题太简单了?

没人愿意回答?
biehoff 发表于 2008-10-8 19:24 | 显示全部楼层

RE

这边的高人一般比较忙&nbsp;&nbsp;我菜&nbsp;先帮你顶下&nbsp;&nbsp;&nbsp;&nbsp;
l0p0c 发表于 2008-10-11 17:32 | 显示全部楼层

我正在弄裸机……

  
您需要登录后才可以回帖 登录 | 注册

本版积分规则

28

主题

75

帖子

0

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