HomeCore 0.1.3 (07b5544)
Bare-metal personal computer firmware for Cortex-M
Loading...
Searching...
No Matches

CPU-family mechanisms shared by every SoC using that CPU. More...

Collaboration diagram for Architecture:

Interrupt control

typedef uintptr_t arch_irq_key_t
 Saved interrupt mask state returned by arch_irq_lock().
 
arch_irq_key_t arch_irq_lock (void)
 Mask all configurable-priority interrupts.
 
void arch_irq_unlock (arch_irq_key_t key)
 Restore the interrupt mask saved by arch_irq_lock().
 
bool arch_irq_is_locked (void)
 Report whether interrupts are masked.
 
void arch_irq_entry (void)
 Common entry for every peripheral interrupt.
 
void arch_irq_enable (int irq)
 Enable a peripheral interrupt in the interrupt controller.
 
void arch_irq_disable (int irq)
 Disable a peripheral interrupt in the interrupt controller.
 
void arch_irq_set_priority (int irq, int priority)
 Set the priority of an interrupt or core exception.
 
void arch_irq_clear_pending (int irq)
 Clear a pending peripheral interrupt.
 
void arch_irq_set_pending (int irq)
 Set a peripheral interrupt pending.
 

Thread primitives

Scaffolding for a future scheduler.

No code calls these functions yet. The SVC and PendSV handlers they rely on currently call board_panic(), so arch_context_switch(), arch_context_switch_to(), and arch_yield() end in a fatal halt. Floating-point context is not preserved.

typedef void(* arch_thread_entry_t) (void *arg)
 Thread entry point.
 
typedef void(* arch_thread_exit_t) (void)
 Function the thread runs if its entry point returns.
 
void * arch_stack_init (void *stack_mem, size_t stack_size, arch_thread_entry_t entry, void *arg, arch_thread_exit_t exit)
 Build the initial stack frame for a new thread.
 
void arch_context_switch (void **old_sp, void *new_sp)
 Request a switch from the current thread to another one.
 
void arch_context_switch_to (void *new_sp)
 Start the first thread through a supervisor call.
 
void arch_yield (void)
 Set PendSV pending to request rescheduling.
 

CPU control

void arch_init (void)
 Point the vector table at the linked image and set core exception priorities.
 
void arch_cpu_idle (void)
 Wait for an interrupt.
 
void arch_cpu_halt (void)
 Mask interrupts and stop permanently.
 
void arch_cpu_reset (void)
 Request a system reset.
 
void arch_panic (void)
 Halt permanently after a fatal error, without reporting a message.
 

System timer

int arch_cpu_timer_init (uint32_t cpu_hz, uint32_t tick_hz)
 Start the periodic system timer.
 
void arch_cpu_timer_stop (void)
 Stop the system timer and its interrupt.
 

Detailed Description

CPU-family mechanisms shared by every SoC using that CPU.

The Cortex-M3 and Cortex-M4 ports share one implementation in src/arch/arm/cortex-m/. Unless noted otherwise, call these functions from foreground code.

Typedef Documentation

◆ arch_thread_entry_t

typedef void(* arch_thread_entry_t) (void *arg)

Thread entry point.

Parameters
argArgument passed to arch_stack_init().

Function Documentation

◆ arch_init()

void arch_init ( void  )

Point the vector table at the linked image and set core exception priorities.

Sets VTOR to the start of the linked vector table. It then gives PendSV the lowest priority, SysTick the next, and SVC the one above that. main() calls it once, before any other initialization.

◆ arch_cpu_idle()

void arch_cpu_idle ( void  )

Wait for an interrupt.

Returns after an interrupt becomes pending. It also returns while interrupts are masked.

◆ arch_cpu_halt()

void arch_cpu_halt ( void  )

Mask interrupts and stop permanently.

Executes a breakpoint followed by wait-for-interrupt in a loop. With a debugger attached, execution halts at the breakpoint. Without one, the breakpoint escalates to HardFault, whose handler calls board_panic().

◆ arch_cpu_reset()

void arch_cpu_reset ( void  )

Request a system reset.

Does not return on hardware.

◆ arch_panic()

void arch_panic ( void  )

Halt permanently after a fatal error, without reporting a message.

Behaves like arch_cpu_halt(). Prefer board_panic(), which reports a message when the console is available.

◆ arch_irq_lock()

arch_irq_key_t arch_irq_lock ( void  )

Mask all configurable-priority interrupts.

Nested use is safe when each key is passed to arch_irq_unlock() in reverse order. Callable from interrupt context.

Returns
Mask state to pass to arch_irq_unlock().

◆ arch_irq_unlock()

void arch_irq_unlock ( arch_irq_key_t  key)

Restore the interrupt mask saved by arch_irq_lock().

Re-enables interrupts only if they were enabled when key was taken.

Parameters
keyValue returned by the matching arch_irq_lock() call.

◆ arch_irq_is_locked()

bool arch_irq_is_locked ( void  )

Report whether interrupts are masked.

Warning
Declared but not implemented by any port. A call fails to link.
Returns
true if interrupts are masked.

◆ arch_irq_entry()

void arch_irq_entry ( void  )

Common entry for every peripheral interrupt.

The SoC vector tables point each implemented peripheral vector here. It reads the active interrupt number and calls the generated dt_irq_dispatch(), which runs the handler of the device that owns the interrupt in the device description. Runs in interrupt context.

◆ arch_irq_enable()

void arch_irq_enable ( int  irq)

Enable a peripheral interrupt in the interrupt controller.

Parameters
irqDevice IRQ number from the SoC's CMSIS header. Negative numbers select core exceptions, which this function ignores.

◆ arch_irq_disable()

void arch_irq_disable ( int  irq)

Disable a peripheral interrupt in the interrupt controller.

Parameters
irqDevice IRQ number from the SoC's CMSIS header. Negative numbers select core exceptions, which this function ignores.

◆ arch_irq_set_priority()

void arch_irq_set_priority ( int  irq,
int  priority 
)

Set the priority of an interrupt or core exception.

Parameters
irqIRQ number from the SoC's CMSIS header. Negative numbers select configurable core exceptions.
priorityPriority level. Lower values are more urgent. Only the implemented priority bits (__NVIC_PRIO_BITS) are kept.

◆ arch_irq_clear_pending()

void arch_irq_clear_pending ( int  irq)

Clear a pending peripheral interrupt.

Parameters
irqDevice IRQ number from the SoC's CMSIS header.

◆ arch_irq_set_pending()

void arch_irq_set_pending ( int  irq)

Set a peripheral interrupt pending.

Parameters
irqDevice IRQ number from the SoC's CMSIS header.

◆ arch_cpu_timer_init()

int arch_cpu_timer_init ( uint32_t  cpu_hz,
uint32_t  tick_hz 
)

Start the periodic system timer.

Starts SysTick from the core clock. Each tick interrupt calls k_tick().

Parameters
cpu_hzCore clock frequency, normally board_cpu_clock_hz().
tick_hzInterrupt frequency. It must divide cpu_hz exactly.
Return values
0The timer is running.
-1tick_hz is zero, exceeds cpu_hz, or does not divide it exactly, or the reload value does not fit the 24-bit counter.

◆ arch_stack_init()

void * arch_stack_init ( void *  stack_mem,
size_t  stack_size,
arch_thread_entry_t  entry,
void *  arg,
arch_thread_exit_t  exit 
)

Build the initial stack frame for a new thread.

The stack top is aligned down to 8 bytes. The function then writes an exception frame followed by zeroed callee-saved registers, which takes 64 bytes. The stack size is not validated.

Parameters
stack_memLowest address of the thread stack.
stack_sizeStack size in bytes.
entryThread entry point, loaded into the program counter.
argArgument passed to entry.
exitFunction run if entry returns.
Returns
Initial stack pointer for arch_context_switch() or arch_context_switch_to().

◆ arch_context_switch()

void arch_context_switch ( void **  old_sp,
void *  new_sp 
)

Request a switch from the current thread to another one.

Records both stack pointers and sets PendSV pending.

Parameters
old_spWhere to save the current thread's stack pointer.
new_spStack pointer of the thread to resume.

◆ arch_context_switch_to()

void arch_context_switch_to ( void *  new_sp)

Start the first thread through a supervisor call.

Parameters
new_spStack pointer returned by arch_stack_init().