|
HomeCore 0.1.3 (07b5544)
Bare-metal personal computer firmware for Cortex-M
|
CPU-family mechanisms shared by every SoC using that CPU. More...
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. | |
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 void(* arch_thread_entry_t) (void *arg) |
Thread entry point.
| arg | Argument passed to arch_stack_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.
| void arch_cpu_idle | ( | void | ) |
Wait for an interrupt.
Returns after an interrupt becomes pending. It also returns while interrupts are masked.
| 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().
| void arch_cpu_reset | ( | void | ) |
Request a system reset.
Does not return on hardware.
| 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_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.
| 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.
| key | Value returned by the matching arch_irq_lock() call. |
| bool arch_irq_is_locked | ( | void | ) |
Report whether interrupts are masked.
true if interrupts are masked. | 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.
| void arch_irq_enable | ( | int | irq | ) |
Enable a peripheral interrupt in the interrupt controller.
| irq | Device IRQ number from the SoC's CMSIS header. Negative numbers select core exceptions, which this function ignores. |
| void arch_irq_disable | ( | int | irq | ) |
Disable a peripheral interrupt in the interrupt controller.
| irq | Device IRQ number from the SoC's CMSIS header. Negative numbers select core exceptions, which this function ignores. |
| void arch_irq_set_priority | ( | int | irq, |
| int | priority | ||
| ) |
Set the priority of an interrupt or core exception.
| irq | IRQ number from the SoC's CMSIS header. Negative numbers select configurable core exceptions. |
| priority | Priority level. Lower values are more urgent. Only the implemented priority bits (__NVIC_PRIO_BITS) are kept. |
| void arch_irq_clear_pending | ( | int | irq | ) |
Clear a pending peripheral interrupt.
| irq | Device IRQ number from the SoC's CMSIS header. |
| void arch_irq_set_pending | ( | int | irq | ) |
Set a peripheral interrupt pending.
| irq | Device IRQ number from the SoC's CMSIS header. |
| 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().
| cpu_hz | Core clock frequency, normally board_cpu_clock_hz(). |
| tick_hz | Interrupt frequency. It must divide cpu_hz exactly. |
| 0 | The timer is running. |
| -1 | tick_hz is zero, exceeds cpu_hz, or does not divide it exactly, or the reload value does not fit the 24-bit counter. |
| 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.
| stack_mem | Lowest address of the thread stack. |
| stack_size | Stack size in bytes. |
| entry | Thread entry point, loaded into the program counter. |
| arg | Argument passed to entry. |
| exit | Function run if entry returns. |
| 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.
| old_sp | Where to save the current thread's stack pointer. |
| new_sp | Stack pointer of the thread to resume. |
| void arch_context_switch_to | ( | void * | new_sp | ) |
Start the first thread through a supervisor call.
| new_sp | Stack pointer returned by arch_stack_init(). |