stm32/pendsv: Clean up pendsv IRQ handler and eliminate duplicate code.
This commit is contained in:
parent
1bcf4afb10
commit
b178958c07
@ -61,11 +61,16 @@ void pendsv_kbd_intr(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pendsv_isr_handler(void) {
|
__attribute__((naked)) void PendSV_Handler(void) {
|
||||||
// re-jig the stack so that when we return from this interrupt handler
|
// Handle a PendSV interrupt
|
||||||
|
//
|
||||||
|
// For the case of an asynchronous exception, re-jig the
|
||||||
|
// stack so that when we return from this interrupt handler
|
||||||
// it returns instead to nlr_jump with argument pendsv_object
|
// it returns instead to nlr_jump with argument pendsv_object
|
||||||
// note that stack has a different layout if DEBUG is enabled
|
// note that stack has a different layout if DEBUG is enabled
|
||||||
//
|
//
|
||||||
|
// For the case of a thread switch, swap stacks.
|
||||||
|
//
|
||||||
// on entry to this (naked) function, stack has the following layout:
|
// on entry to this (naked) function, stack has the following layout:
|
||||||
//
|
//
|
||||||
// stack layout with DEBUG disabled:
|
// stack layout with DEBUG disabled:
|
||||||
@ -88,20 +93,30 @@ void pendsv_isr_handler(void) {
|
|||||||
// sp[1]: 0xfffffff9
|
// sp[1]: 0xfffffff9
|
||||||
// sp[0]: ?
|
// sp[0]: ?
|
||||||
|
|
||||||
#if MICROPY_PY_THREAD
|
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
|
// Check if there is an active object to throw via nlr_jump
|
||||||
"ldr r1, pendsv_object_ptr\n"
|
"ldr r1, pendsv_object_ptr\n"
|
||||||
"ldr r0, [r1]\n"
|
"ldr r0, [r1]\n"
|
||||||
"cmp r0, 0\n"
|
"cmp r0, 0\n"
|
||||||
"beq .no_obj\n"
|
"beq .no_obj\n"
|
||||||
|
#if defined(PENDSV_DEBUG)
|
||||||
|
"str r0, [sp, #8]\n" // store to r0 on stack
|
||||||
|
#else
|
||||||
"str r0, [sp, #0]\n" // store to r0 on stack
|
"str r0, [sp, #0]\n" // store to r0 on stack
|
||||||
|
#endif
|
||||||
"mov r0, #0\n"
|
"mov r0, #0\n"
|
||||||
"str r0, [r1]\n" // clear pendsv_object
|
"str r0, [r1]\n" // clear pendsv_object
|
||||||
"ldr r0, nlr_jump_ptr\n"
|
"ldr r0, nlr_jump_ptr\n"
|
||||||
|
#if defined(PENDSV_DEBUG)
|
||||||
|
"str r0, [sp, #32]\n" // store to pc on stack
|
||||||
|
#else
|
||||||
"str r0, [sp, #24]\n" // store to pc on stack
|
"str r0, [sp, #24]\n" // store to pc on stack
|
||||||
|
#endif
|
||||||
"bx lr\n" // return from interrupt; will return to nlr_jump
|
"bx lr\n" // return from interrupt; will return to nlr_jump
|
||||||
|
|
||||||
".no_obj:\n" // pendsv_object==NULL
|
".no_obj:\n" // pendsv_object==NULL
|
||||||
|
|
||||||
|
#if MICROPY_PY_THREAD
|
||||||
|
// Do a thread context switch
|
||||||
"push {r4-r11, lr}\n"
|
"push {r4-r11, lr}\n"
|
||||||
"vpush {s16-s31}\n"
|
"vpush {s16-s31}\n"
|
||||||
"mrs r5, primask\n" // save PRIMASK in r5
|
"mrs r5, primask\n" // save PRIMASK in r5
|
||||||
@ -115,37 +130,14 @@ void pendsv_isr_handler(void) {
|
|||||||
"vpop {s16-s31}\n"
|
"vpop {s16-s31}\n"
|
||||||
"pop {r4-r11, lr}\n"
|
"pop {r4-r11, lr}\n"
|
||||||
"bx lr\n" // return from interrupt; will return to new thread
|
"bx lr\n" // return from interrupt; will return to new thread
|
||||||
".align 2\n"
|
#else
|
||||||
"pendsv_object_ptr: .word pendsv_object\n"
|
// Spurious pendsv, just return
|
||||||
"nlr_jump_ptr: .word nlr_jump\n"
|
|
||||||
);
|
|
||||||
#else
|
|
||||||
__asm volatile (
|
|
||||||
"ldr r0, pendsv_object_ptr\n"
|
|
||||||
"ldr r0, [r0]\n"
|
|
||||||
#if defined(PENDSV_DEBUG)
|
|
||||||
"str r0, [sp, #8]\n"
|
|
||||||
#else
|
|
||||||
"str r0, [sp, #0]\n"
|
|
||||||
#endif
|
|
||||||
"ldr r0, nlr_jump_ptr\n"
|
|
||||||
#if defined(PENDSV_DEBUG)
|
|
||||||
"str r0, [sp, #32]\n"
|
|
||||||
#else
|
|
||||||
"str r0, [sp, #24]\n"
|
|
||||||
#endif
|
|
||||||
"bx lr\n"
|
"bx lr\n"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Data
|
||||||
".align 2\n"
|
".align 2\n"
|
||||||
"pendsv_object_ptr: .word pendsv_object\n"
|
"pendsv_object_ptr: .word pendsv_object\n"
|
||||||
"nlr_jump_ptr: .word nlr_jump\n"
|
"nlr_jump_ptr: .word nlr_jump\n"
|
||||||
);
|
);
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
uint32_t x[2] = {0x424242, 0xdeaddead};
|
|
||||||
printf("PendSV: %p\n", x);
|
|
||||||
for (uint32_t *p = (uint32_t*)(((uint32_t)x - 15) & 0xfffffff0), i = 64; i > 0; p += 4, i -= 4) {
|
|
||||||
printf(" %p: %08x %08x %08x %08x\n", p, (uint)p[0], (uint)p[1], (uint)p[2], (uint)p[3]);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
@ -29,8 +29,4 @@
|
|||||||
void pendsv_init(void);
|
void pendsv_init(void);
|
||||||
void pendsv_kbd_intr(void);
|
void pendsv_kbd_intr(void);
|
||||||
|
|
||||||
// since we play tricks with the stack, the compiler must not generate a
|
|
||||||
// prelude for this function
|
|
||||||
void pendsv_isr_handler(void) __attribute__((naked));
|
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_STM32_PENDSV_H
|
#endif // MICROPY_INCLUDED_STM32_PENDSV_H
|
||||||
|
@ -290,15 +290,6 @@ void SVC_Handler(void) {
|
|||||||
void DebugMon_Handler(void) {
|
void DebugMon_Handler(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This function handles PendSVC exception.
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void PendSV_Handler(void) {
|
|
||||||
pendsv_isr_handler();
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* STM32F4xx Peripherals Interrupt Handlers */
|
/* STM32F4xx Peripherals Interrupt Handlers */
|
||||||
/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */
|
/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user