diff --git a/ports/renesas-ra/pendsv.c b/ports/renesas-ra/pendsv.c index 9c908addb58cb..f71c21814da71 100644 --- a/ports/renesas-ra/pendsv.c +++ b/ports/renesas-ra/pendsv.c @@ -31,13 +31,6 @@ #include "pendsv.h" #include "irq.h" -// This variable is used to save the exception object between a ctrl-C and the -// PENDSV call that actually raises the exception. It must be non-static -// otherwise gcc-5 optimises it away. It can point to the heap but is not -// traced by GC. This is okay because we only ever set it to -// mp_kbd_exception which is in the root-pointer set. -void *pendsv_object; - #if defined(PENDSV_DISPATCH_NUM_SLOTS) uint32_t pendsv_dispatch_active; pendsv_dispatch_t pendsv_dispatch_table[PENDSV_DISPATCH_NUM_SLOTS]; @@ -51,24 +44,6 @@ void pendsv_init(void) { NVIC_SetPriority(PendSV_IRQn, IRQ_PRI_PENDSV); } -// Call this function to raise a pending exception during an interrupt. -// It will first try to raise the exception "softly" by setting the -// mp_pending_exception variable and hoping that the VM will notice it. -// If this function is called a second time (ie with the mp_pending_exception -// variable already set) then it will force the exception by using the hardware -// PENDSV feature. This will wait until all interrupts are finished then raise -// the given exception object using nlr_jump in the context of the top-level -// thread. -void pendsv_kbd_intr(void) { - if (MP_STATE_MAIN_THREAD(mp_pending_exception) == MP_OBJ_NULL) { - mp_sched_keyboard_interrupt(); - } else { - MP_STATE_MAIN_THREAD(mp_pending_exception) = MP_OBJ_NULL; - pendsv_object = &MP_STATE_VM(mp_kbd_exception); - SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; - } -} - #if defined(PENDSV_DISPATCH_NUM_SLOTS) void pendsv_schedule_dispatch(size_t slot, pendsv_dispatch_t f) { pendsv_dispatch_table[slot] = f; @@ -90,10 +65,7 @@ void pendsv_dispatch_handler(void) { __attribute__((naked)) void PendSV_Handler(void) { // 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 - // note that stack has a different layout if DEBUG is enabled + // Calls any pending functions in pendsv_dispatch_table. // // For the case of a thread switch, swap stacks. // @@ -132,27 +104,6 @@ __attribute__((naked)) void PendSV_Handler(void) { ".no_dispatch:\n" #endif - // Check if there is an active object to throw via nlr_jump - "ldr r1, pendsv_object_ptr\n" - "ldr r0, [r1]\n" - "cmp r0, #0\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 - #endif - "mov r0, #0\n" - "str r0, [r1]\n" // clear pendsv_object - "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 - #endif - "bx lr\n" // return from interrupt; will return to nlr_jump - ".no_obj:\n" // pendsv_object==NULL - #if MICROPY_PY_THREAD // Do a thread context switch "push {r4-r11, lr}\n" @@ -178,7 +129,5 @@ __attribute__((naked)) void PendSV_Handler(void) { #if defined(PENDSV_DISPATCH_NUM_SLOTS) "pendsv_dispatch_active_ptr: .word pendsv_dispatch_active\n" #endif - "pendsv_object_ptr: .word pendsv_object\n" - "nlr_jump_ptr: .word nlr_jump\n" ); } diff --git a/ports/renesas-ra/pendsv.h b/ports/renesas-ra/pendsv.h index 9d7c3d94135d6..827692b8cf2d9 100644 --- a/ports/renesas-ra/pendsv.h +++ b/ports/renesas-ra/pendsv.h @@ -48,7 +48,6 @@ enum { typedef void (*pendsv_dispatch_t)(void); void pendsv_init(void); -void pendsv_kbd_intr(void); void pendsv_schedule_dispatch(size_t slot, pendsv_dispatch_t f); #endif // MICROPY_INCLUDED_RENESAS_RA_PENDSV_H diff --git a/ports/renesas-ra/uart.c b/ports/renesas-ra/uart.c index d17a1fc913fe0..c319b4c0a8dca 100644 --- a/ports/renesas-ra/uart.c +++ b/ports/renesas-ra/uart.c @@ -49,7 +49,7 @@ static KEYEX_CB keyex_cb[MICROPY_HW_MAX_UART] = {(KEYEX_CB)NULL}; static int chk_kbd_interrupt(int d) { if (d == mp_interrupt_char) { - pendsv_kbd_intr(); + mp_sched_keyboard_interrupt(); return 1; } else { return 0; diff --git a/ports/stm32/boards/common_isr_ram/common_isr.ld b/ports/stm32/boards/common_isr_ram/common_isr.ld index 7d8f9a64c28ca..2fcaf0e663993 100644 --- a/ports/stm32/boards/common_isr_ram/common_isr.ld +++ b/ports/stm32/boards/common_isr_ram/common_isr.ld @@ -14,7 +14,7 @@ flash (in main.c) along with the isr_vector above. */ . = ALIGN(4); - *(.text.pendsv_kbd_intr) + *(.text.mp_sched_keyboard_interrupt) *(.text.pendsv_schedule_dispatch) *(.text.storage_systick_callback) *(.text.SysTick_Handler) diff --git a/ports/stm32/pendsv.c b/ports/stm32/pendsv.c index 9c908addb58cb..f71c21814da71 100644 --- a/ports/stm32/pendsv.c +++ b/ports/stm32/pendsv.c @@ -31,13 +31,6 @@ #include "pendsv.h" #include "irq.h" -// This variable is used to save the exception object between a ctrl-C and the -// PENDSV call that actually raises the exception. It must be non-static -// otherwise gcc-5 optimises it away. It can point to the heap but is not -// traced by GC. This is okay because we only ever set it to -// mp_kbd_exception which is in the root-pointer set. -void *pendsv_object; - #if defined(PENDSV_DISPATCH_NUM_SLOTS) uint32_t pendsv_dispatch_active; pendsv_dispatch_t pendsv_dispatch_table[PENDSV_DISPATCH_NUM_SLOTS]; @@ -51,24 +44,6 @@ void pendsv_init(void) { NVIC_SetPriority(PendSV_IRQn, IRQ_PRI_PENDSV); } -// Call this function to raise a pending exception during an interrupt. -// It will first try to raise the exception "softly" by setting the -// mp_pending_exception variable and hoping that the VM will notice it. -// If this function is called a second time (ie with the mp_pending_exception -// variable already set) then it will force the exception by using the hardware -// PENDSV feature. This will wait until all interrupts are finished then raise -// the given exception object using nlr_jump in the context of the top-level -// thread. -void pendsv_kbd_intr(void) { - if (MP_STATE_MAIN_THREAD(mp_pending_exception) == MP_OBJ_NULL) { - mp_sched_keyboard_interrupt(); - } else { - MP_STATE_MAIN_THREAD(mp_pending_exception) = MP_OBJ_NULL; - pendsv_object = &MP_STATE_VM(mp_kbd_exception); - SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; - } -} - #if defined(PENDSV_DISPATCH_NUM_SLOTS) void pendsv_schedule_dispatch(size_t slot, pendsv_dispatch_t f) { pendsv_dispatch_table[slot] = f; @@ -90,10 +65,7 @@ void pendsv_dispatch_handler(void) { __attribute__((naked)) void PendSV_Handler(void) { // 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 - // note that stack has a different layout if DEBUG is enabled + // Calls any pending functions in pendsv_dispatch_table. // // For the case of a thread switch, swap stacks. // @@ -132,27 +104,6 @@ __attribute__((naked)) void PendSV_Handler(void) { ".no_dispatch:\n" #endif - // Check if there is an active object to throw via nlr_jump - "ldr r1, pendsv_object_ptr\n" - "ldr r0, [r1]\n" - "cmp r0, #0\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 - #endif - "mov r0, #0\n" - "str r0, [r1]\n" // clear pendsv_object - "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 - #endif - "bx lr\n" // return from interrupt; will return to nlr_jump - ".no_obj:\n" // pendsv_object==NULL - #if MICROPY_PY_THREAD // Do a thread context switch "push {r4-r11, lr}\n" @@ -178,7 +129,5 @@ __attribute__((naked)) void PendSV_Handler(void) { #if defined(PENDSV_DISPATCH_NUM_SLOTS) "pendsv_dispatch_active_ptr: .word pendsv_dispatch_active\n" #endif - "pendsv_object_ptr: .word pendsv_object\n" - "nlr_jump_ptr: .word nlr_jump\n" ); } diff --git a/ports/stm32/pendsv.h b/ports/stm32/pendsv.h index f97581e99a308..b90d2227ee4d4 100644 --- a/ports/stm32/pendsv.h +++ b/ports/stm32/pendsv.h @@ -51,7 +51,6 @@ enum { typedef void (*pendsv_dispatch_t)(void); void pendsv_init(void); -void pendsv_kbd_intr(void); void pendsv_schedule_dispatch(size_t slot, pendsv_dispatch_t f); #endif // MICROPY_INCLUDED_STM32_PENDSV_H diff --git a/ports/stm32/uart.c b/ports/stm32/uart.c index 65ecd9913d5db..91db91395eac1 100644 --- a/ports/stm32/uart.c +++ b/ports/stm32/uart.c @@ -1229,7 +1229,7 @@ void uart_irq_handler(mp_uint_t uart_id) { data &= self->char_mask; if (self->attached_to_repl && data == mp_interrupt_char) { // Handle interrupt coming in on a UART REPL - pendsv_kbd_intr(); + mp_sched_keyboard_interrupt(); } else { if (self->char_width == CHAR_WIDTH_9BIT) { ((uint16_t *)self->read_buf)[self->read_buf_head] = data; diff --git a/ports/stm32/usbd_cdc_interface.c b/ports/stm32/usbd_cdc_interface.c index 88a9cafe0c495..c0198d1bb49a6 100644 --- a/ports/stm32/usbd_cdc_interface.c +++ b/ports/stm32/usbd_cdc_interface.c @@ -315,7 +315,7 @@ int8_t usbd_cdc_receive(usbd_cdc_state_t *cdc_in, size_t len) { // copy the incoming data into the circular buffer for (const uint8_t *src = cdc->rx_packet_buf, *top = cdc->rx_packet_buf + len; src < top; ++src) { if (cdc->attached_to_repl && *src == mp_interrupt_char) { - pendsv_kbd_intr(); + mp_sched_keyboard_interrupt(); } else { uint16_t next_put = (cdc->rx_buf_put + 1) & (MICROPY_HW_USB_CDC_RX_DATA_SIZE - 1); if (next_put == cdc->rx_buf_get) {