Defines | |
#define | save_context_from_irq() |
#define | restore_context() |
#define | enable_IRQ_and_FIQ() |
#define | disable_IRQ_and_FIQ() |
Typedefs | |
typedef int | miosix_private::interrupt_t |
Functions | |
void | miosix::IRQfind_next_thread () |
void | system_reboot () |
void | miosix_private::disable_interrupts () |
void | miosix_private::enable_interrupts () |
interrupt_t | miosix_private::disable_and_save_interrupts () |
void | miosix_private::restore_interrupts (interrupt_t i) |
bool | miosix_private::are_interrupts_enabled () |
int | miosix_private::atomic_swap (int newval, int *var) |
Contains functions and macros that can be used to write drivers for hardware peripherals. These functions, plus the IRQ methods of the Queue class provide a way to transfer data between an interrupt routine and user code, and a way to cause preemption inside an interrupt routine to wake a higher priority Thread waiting on some hardware peripheral.
#define disable_IRQ_and_FIQ | ( | ) |
Value:
{ \ asm volatile(".set I_BIT, 0x80 \n\t" \ ".set F_BIT, 0x40 \n\t" \ "mrs r0, cpsr \n\t" \ "orr r0, r0, #I_BIT|F_BIT \n\t" \ "msr cpsr_c, r0 \n\t" \ :::"r0"); \ }
#define enable_IRQ_and_FIQ | ( | ) |
Value:
{ \ asm volatile(".set I_BIT, 0x80 \n\t" \ ".set F_BIT, 0x40 \n\t" \ "mrs r0, cpsr \n\t" \ "and r0, r0, #~(I_BIT|F_BIT) \n\t" \ "msr cpsr_c, r0 \n\t" \ :::"r0"); \ }
#define restore_context | ( | ) |
Value:
{ \ asm volatile( /*load ctxsave and dereference the pointer*/ \ /*also add 64 to make it point to "top of stack"*/ \ "ldr lr,=ctxsave \n\t" \ "ldr lr,[lr] \n\t" \ "add lr,lr,#64 \n\t" \ /*restore spsr*/ \ /*after this instructions, lr points to ctxsave[15] (return address)*/ \ "ldmda lr!,{r1} \n\t" \ "msr spsr,r1 \n\t" \ /*restore all thread registers except pc*/ \ "ldmdb lr,{r0-lr}^ \n\t" \ /*add a nop as required after ldm ^ (read ARM reference about ldm(2))*/ \ "nop \n\t" \ /*now that lr points to return address, return from interrupt*/ \ "ldr lr,[lr] \n\t" \ "movs pc,lr \n\t"); \ }
#define save_context_from_irq | ( | ) |
Value:
{ \ asm volatile( /*Adjust lr, because the return address in a ISR has a 4 bytes offset*/ \ "sub lr,lr,#4 \n\t"); \ save_context_from_swi(); \ }
typedef int miosix_private::interrupt_t |
Definition of a type that can hold interrupt status.
bool miosix_private::are_interrupts_enabled | ( | ) |
This function returns true if interrupts are enabled
int miosix_private::atomic_swap | ( | int | newval, | |
int * | var | |||
) |
Atomic swap, may be used to implement critical sections efficiently. If the cpu supports it implemented using the cpu assembler intruction, else emulated by disabling the kernel. The implementation on the ARM7 cpu uses the dedicated assembler instruction.
newval | new value to be written to var | |
var | pointer to a variable |
interrupt_t miosix_private::disable_and_save_interrupts | ( | ) |
This function stores the interrupt status in the return value, and if interrupts are enabled, disables them (irq only).
void miosix_private::disable_interrupts | ( | ) |
disable interrupts (irq only) Note that this does not disable fiq.
void miosix_private::enable_interrupts | ( | ) |
enable interrupts (irq only)
void miosix::IRQfind_next_thread | ( | ) |
This function is used to developed interrupt driven peripheral drivers.
Can be used ONLY inside an IRQ (and not when interrupts are disabled) to find next thread in READY status. If the kernel is paused, does nothing. Can be used for example if an IRQ causes a higher priority thread to be woken, to change context. Note that to use this function the IRQ must use the macros to save/restore context defined in portability.h
void miosix_private::restore_interrupts | ( | interrupt_t | i | ) |
This function restores the interrupt status in the condition before disable_and_save_interrupts() was called.
i | interrupt status, as returned by disable_and_save_interrupts() |
void system_reboot | ( | ) |
Used after an unrecoverable error condition to restart the system, even from within an interrupt routine.