|
PebbleOS
|
Interrupt locking and build-time interrupt binding. More...
Macros | |
| #define | PBL_IRQ_PRIO_KERNEL CONFIG_KERNEL_IRQ_PRIO_KERNEL |
| NVIC priority of the kernel's own interrupts (tick, context switch). | |
| #define | PBL_IRQ_PRIO_MAX_SYSCALL CONFIG_KERNEL_IRQ_PRIO_MAX_SYSCALL |
| Most urgent NVIC priority from which kernel calls are allowed. | |
| #define | PBL_IRQN(line) ((pbl_irq_t)PBL_SOC_IRQN_##line) |
Number of a SoC interrupt line from soc_irqs.h. | |
| #define | PBL_IRQ_ZERO_LATENCY (1U << 0) |
| Flag for an ISR that runs above PBL_IRQ_PRIO_MAX_SYSCALL. | |
| #define | PBL_IRQ_CONNECT(line, prio, isr, arg, flags) ARCH_IRQ_CONNECT(PBL_SOC_IRQN_##line, line##_IRQn, prio, isr, arg, flags) |
| Bind a SoC interrupt line to a handler at build time. | |
| #define | PBL_IRQ_DIRECT(line, prio, flags) ARCH_IRQ_DIRECT(PBL_SOC_IRQN_##line, line##_IRQn, prio, flags) |
| Bind a SoC interrupt line to the handler body that follows the macro. | |
Typedefs | |
| typedef uint16_t | pbl_irq_t |
| Line of the SoC interrupt controller. | |
Functions | |
| void | pbl_irq_lock (void) |
| Mask interrupts up to PBL_IRQ_PRIO_MAX_SYSCALL. | |
| void | pbl_irq_unlock (void) |
| Undo one pbl_irq_lock(), unmasking interrupts at the outermost one. | |
| bool | pbl_in_isr (void) |
| Check whether the caller runs in interrupt context. | |
| bool | pbl_irq_is_locked (void) |
| Check whether pbl_irq_lock() is in effect. | |
| void | pbl_irq_init (void) |
| Install the vector table and program the priority of every bound line. | |
| void | pbl_irq_enable (pbl_irq_t irq) |
| Enable an interrupt line. | |
| void | pbl_irq_disable (pbl_irq_t irq) |
| Disable an interrupt line. | |
| bool | pbl_irq_is_enabled (pbl_irq_t irq) |
| Check whether an interrupt line is enabled. | |
| void | pbl_irq_set_pending (pbl_irq_t irq) |
| Mark an interrupt line pending, so its handler runs once enabled and unmasked. | |
| void | pbl_irq_clear_pending (pbl_irq_t irq) |
| Clear the pending state of an interrupt line. | |
Interrupt locking and build-time interrupt binding.
SoC interrupt lines are bound to their handlers at build time; there is no runtime handler registration and the vector table lives in flash. A line is named after its PBL_SOC_IRQN_<line> define in the SoC's soc_irqs.h, which matches the CMSIS <line>_IRQn name. Binding a line twice fails to link. pbl_irq_init() programs the priority of every bound line at boot, so drivers only enable and disable them:
pbl_irq_lock() masks every interrupt that may call the kernel, and is how kernel objects protect their state:
| #define PBL_IRQ_CONNECT | ( | line, | |
| prio, | |||
| isr, | |||
| arg, | |||
| flags | |||
| ) | ARCH_IRQ_CONNECT(PBL_SOC_IRQN_##line, line##_IRQn, prio, isr, arg, flags) |
Bind a SoC interrupt line to a handler at build time.
The handler is called as isr(arg) with whatever type isr takes; an empty arg calls isr(). Expands to a definition, at file scope, where the SoC's CMSIS header is included.
| line | Line name, as in soc_irqs.h. |
| prio | Priority in controller units, 0 being the most urgent. |
| isr | Handler function. |
| arg | Argument passed to isr, may be empty. |
| flags | 0 or PBL_IRQ_ZERO_LATENCY. |
| #define PBL_IRQ_DIRECT | ( | line, | |
| prio, | |||
| flags | |||
| ) | ARCH_IRQ_DIRECT(PBL_SOC_IRQN_##line, line##_IRQn, prio, flags) |
Bind a SoC interrupt line to the handler body that follows the macro.
| line | Line name, as in soc_irqs.h. |
| prio | Priority in controller units, 0 being the most urgent. |
| flags | 0 or PBL_IRQ_ZERO_LATENCY. |
| #define PBL_IRQ_PRIO_KERNEL CONFIG_KERNEL_IRQ_PRIO_KERNEL |
NVIC priority of the kernel's own interrupts (tick, context switch).
Raw 8-bit priority register value, from CONFIG_KERNEL_IRQ_PRIO_KERNEL.
| #define PBL_IRQ_PRIO_MAX_SYSCALL CONFIG_KERNEL_IRQ_PRIO_MAX_SYSCALL |
Most urgent NVIC priority from which kernel calls are allowed.
Raw 8-bit priority register value (lower is more urgent), from CONFIG_KERNEL_IRQ_PRIO_MAX_SYSCALL. pbl_irq_lock() masks this level and every less urgent one.
| #define PBL_IRQ_ZERO_LATENCY (1U << 0) |
Flag for an ISR that runs above PBL_IRQ_PRIO_MAX_SYSCALL.
pbl_irq_lock() does not mask it, and it must not call into the kernel. Required for any priority more urgent than PBL_IRQ_PRIO_MAX_SYSCALL, which is a build error otherwise.
| #define PBL_IRQN | ( | line | ) | ((pbl_irq_t)PBL_SOC_IRQN_##line) |
Number of a SoC interrupt line from soc_irqs.h.
For example, PBL_IRQN(I2C1) is PBL_SOC_IRQN_I2C1.
| line | Line name. |
| typedef uint16_t pbl_irq_t |
Line of the SoC interrupt controller.
| bool pbl_in_isr | ( | void | ) |
Check whether the caller runs in interrupt context.
| void pbl_irq_clear_pending | ( | pbl_irq_t | irq | ) |
Clear the pending state of an interrupt line.
| irq | Line, see PBL_IRQN. |
| void pbl_irq_init | ( | void | ) |
Install the vector table and program the priority of every bound line.
Called once at boot, before any interrupt is enabled.
| bool pbl_irq_is_enabled | ( | pbl_irq_t | irq | ) |
Check whether an interrupt line is enabled.
| irq | Line, see PBL_IRQN. |
| bool pbl_irq_is_locked | ( | void | ) |
Check whether pbl_irq_lock() is in effect.
| void pbl_irq_lock | ( | void | ) |
Mask interrupts up to PBL_IRQ_PRIO_MAX_SYSCALL.
Nestable; balance each call with pbl_irq_unlock(). Usable from threads and ISRs. Interrupts flagged PBL_IRQ_ZERO_LATENCY are not masked.
| void pbl_irq_set_pending | ( | pbl_irq_t | irq | ) |
Mark an interrupt line pending, so its handler runs once enabled and unmasked.
| irq | Line, see PBL_IRQN. |
| void pbl_irq_unlock | ( | void | ) |
Undo one pbl_irq_lock(), unmasking interrupts at the outermost one.