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