Interrupt Handlers¶
The Interrupt Heirarchy¶
Freedom Metal conceptualizes interrupts as a heirarchy of interrupt controllers.
This heirarchy is established by the interrupt heirarchy of the target platform
itself. Presently, the interrupt heirarchy for a given platform is best documented
by the target’s DeviceTree representation, which can be found in
bsp/<target-name>/design.dts
.
In Freedom Metal, the heirarchy is a tree. The nodes of the tree consist of
struct metal_interrupt
:
-
struct
metal_interrupt
A handle for an interrupt.
And the vertices of the tree consist of interrupt id
.
The CPU Interrupt Controller¶
The CPU interrupt controller is the top of the interrupt heirarchy. It must be initialized before any other interrupt controllers are initialized. In example:
struct metal_cpu *cpu0 = metal_cpu_get(0);
if(!cpu) {
/* Unable to get CPU handle */
}
struct metal_interrupt *cpu_int = metal_cpu_interrupt_controller(cpu0);
if(!cpu_int) {
/* Unable to get CPU interrupt handle */
}
metal_interrupt_init(cpu_int);
The CPU interrupt must be enabled for the CPU to receive any interrupts, and any enabled interrupts can be masked by disabling the CPU interrupt.
int rc = 0;
/* Enable the CPU interrupt */
rc = metal_interrupt_enable(cpu_int, 0);
if(rc != 0) {
/* Failed to enable the CPU interrupt */
}
/* Disable the CPU interrupt */
rc = metal_interrupt_disable(cpu_int, 0);
if(rc != 0) {
/* Failed to disable the CPU interrupt */
}
Interrupt Handlers¶
Interrupt handlers must conform to the following function signature:
-
typedef void (*
metal_interrupt_handler_t
)(int, void*) Function signature for interrupt callback handlers.
Therefore, an interrupt handler might look like:
void my_interrupt_handler(int id, void *priv_data) {
/* Contents of handler */
}
Registering an Interrupt Handler¶
Interrupt handlers are registered with the interrupt controller for the interrupt they are servicing. For example, if we want to register a CPU timer interrupt:
struct metal_interrupt *timer_int = metal_cpu_timer_interrupt_controller(cpu0);
if(!timer_int) {
/* Failed to get timer interrupt controller */
}
metal_interrupt_init(timer_int);
int timer_id = metal_cpu_timer_get_interrupt_id(cpu0);
int rc = metal_interrupt_register_handler(timer_int, timer_id, my_interrupt_handler, cpu0);
if(rc != 0) {
/* Failed to register interrupt handler */
}
Additional Documentation¶
Additional documentation for the interrupt handler API can be found in the CPU API reference and the Interrupt API reference.