It is possible to use re-entrant interrupts on Cortex-M3/4 using the non-base-thread feature. You simply need to enable NONBASETHRDENA, and have the interrupt create a stack frame to run the body of the handler and perform a return using it, thus removing the interrupt from the active list, and therefore lowering the core's priority such that the same interrupt can be taken again.hths.
void SysCall(void) { LED^=1; // just for the test __asm("thread_exit:"); __asm("SVC 0"); // return to handler mode }void SysTick_Handler(void) __attribute__ ((naked));void SysTick_Handler(void) { __asm("PUSH {r4,lr}"); // preserve EXC_RETURN (and SP align) __asm("LDR r0,=thread_exit"); // thread LR must generate an exit __asm("LDR r1,=SysCall"); // thread PC is our real handler __asm("LDR r2,=0x01000000"); // PSR for thread in Thumb-state __asm("PUSH {r0-r2}"); // create LR, PC and PSR __asm("SUB sp,sp,#(5*4)"); // allocate space for r0-r3 and r12 __asm("LDR r0,=0xFFFFFFF9"); // thread using MSP return __asm("BX r0"); // return to newly created thread}void SVC_Handler(void) __attribute__ ((naked));void SVC_Handler(void) { __asm("ADD sp,sp,#(9*4)"); // remove thread and r4 from stack __asm("POP {pc}"); // perform standard exception return }
Are Thread and Handler mode both using the Main stack pointer?s.
int_handler PUSH {r4,lr} ;// Preserve EXC_RETURN (and SP align) LDR r0,=thread_exit ;// Thread LR must generate an exit LDR r1,=int_code ;// Thread PC is our real handler LDR r2,=0x01000000 ;// PSR for thread in Thumb-state PUSH {r0-r2} ;// Create LR, PC and PSR SUB sp,sp,#(5*4) ;// Allocate space for r0-r3 and r12 LDR r0,=0xFFFFFFF9 ;// Thread using MSP return BX r0 ;// Return to newly created threadsvc_handler ADD sp,sp,#(9*4) ;// Remove Thread and r4 from stack POP {pc} ;// Perform standard exception return thread_exit SVC 0 ;// Return to handler modeint_code ....boot_code LDR r1,=0xE000ED14 ;// CCR register address LDR r0,[r1] ORR r0,r0,#1 ;// Enable NONBASETHRDENA STR r0,[r1] ....