* Fix bug in irq_remove_shared_handler and add test #823 * Add comments to irq_handler_chain.S Co-authored-by: Luke Wren <wren6991@gmail.com>
This commit is contained in:
@ -103,6 +103,9 @@
|
||||
#define PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY 0x80
|
||||
#endif
|
||||
|
||||
#define PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY 0xff
|
||||
#define PICO_SHARED_IRQ_HANDLER_LOWEST_ORDER_PRIORITY 0x00
|
||||
|
||||
// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_IRQ, Enable/disable assertions in the IRQ module, type=bool, default=0, group=hardware_irq
|
||||
#ifndef PARAM_ASSERTIONS_ENABLED_IRQ
|
||||
#define PARAM_ASSERTIONS_ENABLED_IRQ 0
|
||||
@ -224,6 +227,9 @@ irq_handler_t irq_get_exclusive_handler(uint num);
|
||||
* rule of thumb is to use PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY if you don't much care, as it is in the middle of
|
||||
* the priority range by default.
|
||||
*
|
||||
* \note The order_priority uses \em higher values for higher priorities which is the \em opposite of the CPU interrupt priorities passed
|
||||
* to irq_set_priority() which use lower values for higher priorities.
|
||||
*
|
||||
* \see irq_set_exclusive_handler()
|
||||
*/
|
||||
void irq_add_shared_handler(uint num, irq_handler_t handler, uint8_t order_priority);
|
||||
|
@ -287,7 +287,6 @@ void irq_remove_handler(uint num, irq_handler_t handler) {
|
||||
struct irq_handler_chain_slot *prev_slot = NULL;
|
||||
struct irq_handler_chain_slot *existing_vtable_slot = remove_thumb_bit(vtable_handler);
|
||||
struct irq_handler_chain_slot *to_free_slot = existing_vtable_slot;
|
||||
int8_t to_free_slot_index = get_slot_index(to_free_slot);
|
||||
while (to_free_slot->handler != handler) {
|
||||
prev_slot = to_free_slot;
|
||||
if (to_free_slot->link < 0) break;
|
||||
@ -325,7 +324,7 @@ void irq_remove_handler(uint num, irq_handler_t handler) {
|
||||
}
|
||||
// add slot back to free list
|
||||
to_free_slot->link = irq_hander_chain_free_slot_head;
|
||||
irq_hander_chain_free_slot_head = to_free_slot_index;
|
||||
irq_hander_chain_free_slot_head = get_slot_index(to_free_slot);
|
||||
} else {
|
||||
// since we are the last slot we know that our inst3 hasn't executed yet, so we change
|
||||
// it to bl to irq_handler_chain_remove_tail which will remove the slot.
|
||||
|
@ -54,17 +54,18 @@ irq_handler_chain_slots:
|
||||
.endr
|
||||
|
||||
irq_handler_chain_first_slot:
|
||||
push {lr}
|
||||
ldr r0, [r1, #4]
|
||||
adds r1, #1
|
||||
mov lr, r1
|
||||
bx r0
|
||||
push {lr} // Save EXC_RETURN token, so `pop {pc}` will return from interrupt
|
||||
ldr r0, [r1, #4] // Get `handler` field of irq_handler_chain_slot
|
||||
adds r1, #1 // r1 points to `inst3` field of slot struct. Set Thumb bit on r1,
|
||||
mov lr, r1 // and copy to lr, so `inst3` is executed on return from handler
|
||||
bx r0 // Enter handler
|
||||
|
||||
irq_handler_chain_remove_tail:
|
||||
mov r0, lr
|
||||
subs r0, #9
|
||||
mov r0, lr // Get start of struct. This function was called by a bl at offset +4,
|
||||
subs r0, #9 // so lr points to offset +8. Note also lr has its Thumb bit set!
|
||||
ldr r1, =irq_add_tail_to_free_list
|
||||
blx r1
|
||||
pop {pc}
|
||||
pop {pc} // Top of stack is EXC_RETURN
|
||||
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user