PebbleOS
Loading...
Searching...
No Matches
Macros | Typedefs | Functions
Interrupts

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.
 

Detailed Description

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_CONNECT(I2C1, 5, i2c_irq_handler, &s_i2c1_bus, 0);
// handler body; must not call the kernel
}
void i2c_init(void) {
}
void i2c_init(I2CBus *bus)
Initialize a bus.
void i2c_irq_handler(I2CBus *bus)
Controller interrupt handler.
#define PBL_IRQ_ZERO_LATENCY
Flag for an ISR that runs above PBL_IRQ_PRIO_MAX_SYSCALL.
Definition irq.h:99
#define PBL_IRQN(line)
Number of a SoC interrupt line from soc_irqs.h.
Definition irq.h:91
#define PBL_IRQ_CONNECT(line, prio, isr, arg, flags)
Bind a SoC interrupt line to a handler at build time.
Definition irq.h:115
void pbl_irq_enable(pbl_irq_t irq)
Enable an interrupt line.
#define PBL_IRQ_DIRECT(line, prio, flags)
Bind a SoC interrupt line to the handler body that follows the macro.
Definition irq.h:125

pbl_irq_lock() masks every interrupt that may call the kernel, and is how kernel objects protect their state:

s_pending |= flag;
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.

Macro Definition Documentation

◆ PBL_IRQ_CONNECT

#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.

Parameters
lineLine name, as in soc_irqs.h.
prioPriority in controller units, 0 being the most urgent.
isrHandler function.
argArgument passed to isr, may be empty.
flags0 or PBL_IRQ_ZERO_LATENCY.

◆ PBL_IRQ_DIRECT

#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.

Parameters
lineLine name, as in soc_irqs.h.
prioPriority in controller units, 0 being the most urgent.
flags0 or PBL_IRQ_ZERO_LATENCY.

◆ PBL_IRQ_PRIO_KERNEL

#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.

◆ PBL_IRQ_PRIO_MAX_SYSCALL

#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.

◆ PBL_IRQ_ZERO_LATENCY

#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.

◆ PBL_IRQN

#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.

Parameters
lineLine name.

Typedef Documentation

◆ pbl_irq_t

typedef uint16_t pbl_irq_t

Line of the SoC interrupt controller.

Function Documentation

◆ pbl_in_isr()

bool pbl_in_isr ( void  )

Check whether the caller runs in interrupt context.

Returns
true in an ISR or exception handler.

◆ pbl_irq_clear_pending()

void pbl_irq_clear_pending ( pbl_irq_t  irq)

Clear the pending state of an interrupt line.

Parameters
irqLine, see PBL_IRQN.

◆ pbl_irq_disable()

void pbl_irq_disable ( pbl_irq_t  irq)

Disable an interrupt line.

Parameters
irqLine, see PBL_IRQN.

◆ pbl_irq_enable()

void pbl_irq_enable ( pbl_irq_t  irq)

Enable an interrupt line.

Parameters
irqLine, see PBL_IRQN.

◆ pbl_irq_init()

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.

◆ pbl_irq_is_enabled()

bool pbl_irq_is_enabled ( pbl_irq_t  irq)

Check whether an interrupt line is enabled.

Parameters
irqLine, see PBL_IRQN.
Returns
true if enabled.

◆ pbl_irq_is_locked()

bool pbl_irq_is_locked ( void  )

Check whether pbl_irq_lock() is in effect.

Returns
true if interrupts are locked.

◆ pbl_irq_lock()

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.

◆ pbl_irq_set_pending()

void pbl_irq_set_pending ( pbl_irq_t  irq)

Mark an interrupt line pending, so its handler runs once enabled and unmasked.

Parameters
irqLine, see PBL_IRQN.

◆ pbl_irq_unlock()

void pbl_irq_unlock ( void  )

Undo one pbl_irq_lock(), unmasking interrupts at the outermost one.