我用的是LPC2365,MDK3.20<br />NXP原厂给的HOT_04.03 VIC中,<br />static DWORD sysreg; /* used as LR register */<br />#define IENABLE __asm { MRS sysreg, SPSR; MSR CPSR_c, #SYS32Mode }<br />#define IDISABLE __asm { MSR CPSR_c, #(IRQ32Mode|I_Bit); MSR SPSR_cxsf, sysreg }<br />每个中断函数进入后,SPSR存储于static DWORD sysreg,但这是一个全局变量而已,且LR未保存.高优先中断打断当前中断程序时,新的中断程序再次调用IENABLE,这样本次的SPSR覆盖了低优先的SPSR,并覆盖了LR,感觉这样是实现不了中断嵌套的.例子程序EXTINT_nested项目,EINT0_Handler()和Timer0Handler()内均调用了这个宏,感觉这样没有实现中断可嵌套.<br />我的工程仿照模板的中断处理模式处理的,测试过程中,短则几分钟,长则几个小时,系统失去响应.硬件仿真时进入指令异常PAbt_Addr.在绝大多数子函数的出入口都用查询模式的串口输出测试时,发现都是在执行return之后飞到PAbt_Addr,感觉返回地址被破坏了.<br />我的中断函数都如下:<br />void TIMER0_Handler(void) __irq<br />{ <br /> IENABLE;<br /><br /> function();<br /> <br /> IDISABLE; <br /> VICVectAddr = 0x0; // 通知VIC中断处理结束<br />}<br /> <br />在AN10381.pdf官方文档内,文档内在一个.c文件内定义如下:<br />#define IENABLE /* Nested Interrupts Entry */ <br />__asm { MRS LR, SPSR } /* Copy SPSR_irq to LR */ <br />__asm { STMFD SP!, {LR} } /* Save SPSR_irq */ <br />__asm { MSR CPSR_c, #0x1F } /* Enable IRQ (Sys Mode) */ <br />__asm { STMFD SP!, {LR} } /* Save LR */ <br />// Macro for disabling interrupts, switching back to IRQ and relevant stack operations<br />#define IDISABLE /* Nested Interrupts Exit */ <br />__asm { LDMFD SP!, {LR} } /* Restore LR */ <br />__asm { MSR CPSR_c, #0x92 } /* Disable IRQ (IRQ Mode) */ <br />__asm { LDMFD SP!, {LR} } /* Restore SPSR_irq to LR */ <br />__asm { MSR SPSR_cxsf, LR } /* Copy LR to SPSR_irq */ <br />然后调用时和前面的那个类似。<br />照这样子复制进我的项目后,编译提示下面之类错误:<br />SPISPI.c(79): error: #20: identifier "SP" is undefined<br />SPISPI.c(79): warning: #1287-D: LDM/STM instruction may be expanded<br />这是什么原因啊?有什么地方需要特殊设置的?<br /><br />按照ZLG2210模板内的例子,在irq.s内添加HandlerTIMER0 TIMER0_Handler_ZLG <br />void Tim0_init(void) <br />{ ...//初始<br /> install_irq(TIMER0_INT, (void *)HandlerTIMER0, 5); <br />} <br />void TIMER0_Handler_ZLG(void)<br />{<br /> VICIntEnClr = 1 << TIMER0_INT; <br />。。。<br /> VICIntEnable |= 1 << TIMER0_INT; <br /> VICVectAddr = 0x0; // 通知VIC中断处理结束<br />}<br />编译提示:DEMO_test.axf: Error: L6218E: Undefined symbol UART1_Handler_ZLG (referred from 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 /> |
|