We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi,
I am developing for an ARM Cortex-M7 core (NXP iMIMXRT1062 chip), which is a Thumb only processor. I am using MCUXpressoIDE 11.1 which is based on Eclipse.
I have a problem returning from SVCall. When free running, it usually ends up at address 0xdeadbeee (0xdeadbeef with last bit removed), or can be caught in the HardFault_Handler. When I step through using a debugger (GDB) it appears to work correctly.
in excep.S
SVC_Handler: // This call follows the ARM Architecture Procedure Calling Standard (AAPCS) // which pushes the following onto the stack from the calling function. // {r0-r3}, r12, LR, PC, xPSR // The LR currently set is the EXC_RETURN value which will cause the stack to // be unwound and the registers set to the initial values. .syntax unified // stack contains r0, r1, r2, r3 which are used as function arguments // Check whether we are using PSP or MSP (Handler mode always uses MSP) TST LR, #4 // Test EXC_RETURN to see which stack is expected. ITE EQ MOVEQ r1, sp // MSP in use MRSNE r1, psp // PSP in use LDR r3, [r1, #0x18] // excavate pc from stack // No need to check Thumb state LDRH r0, [r3,#-2] // Yes: Load halfword and... BIC r0, r0, #0xFF00 // ...extract comment field STMFD sp!, {LR} // push LR onto stack before call BL SVC_Handler_C // Call main part of handler LDMIA sp!, {LR} // retrieve LR from stack // Put r0 (return value) into stack as return value from this function. stm sp, {r0} // Set PC to LR (which contains EXC_RETURN value), which will unwind the // stack and restore the registers BX LR .syntax divided.endfunc
in excep_handlers.h
/** @brief Enumeration of operations performed by SVC. * The operation IDs need to fit into a uint8_t. */typedef enum{ C4_SVC_Reserved, C4_SVC_PRINT, C4_SVC_ADD, C4_SVC_USER,}C4_SVC_Op_t;
in excep_handlers.c
void *SVC_Handler_C(uint8_t SVC_type, void **args){ switch (SVC_type) { case C4_SVC_PRINT: printf((char *)*args, (int) *(args+1)); break; case C4_SVC_ADD: return (void *)((int)*args + (int)*(args+1)); break; case C4_SVC_USER: break; default: { pointer expt_frm_ptr = 0; // Get PSP - should this test whether to get PSP or MSP asm volatile ("MRS %0, psp" : "=r" (expt_frm_ptr) ); expt_frm_dump(expt_frm_ptr); // C4_PRINT_ERR_STRING is safe here as the exception handler is already executing in privileged // state so does not need to use the exception call mechanism. C4_PRINT_ERR_STRING("Unhandled option in %s(%d)\n", __PRETTY_FUNCTION__, SVC_type); while(1) {} } } return NULL;}
It is called like this:
int a1 = 3;int a2 = 5;int res = 0;asm("MOV r0, %1\n\tMOV r1, %2\n\tSVC %3\n\tMOV %0, r0\n\t":"=r"(res): \ "r"(a1), "r"(a2), "I" (C4_SVC_ADD));
The value of LR is 0xFFFF_FFF1 which is the expectd value of EXC_RETURN
0xFFFF_FFF1
EXC_RETURN
What am I doing wrong in the return?
thanks
Dan