interrupt management

This article is shared from the China Mobile OneOS WeChat public account "Interruption Management".

Interruption refers to the process of computer operation, when there are some unexpected situations that need to be dealt with in time, the CPU can automatically stop the running program and transfer to the program that handles the unexpected situation, and returns to the original suspended program after processing to continue running. Interrupts are an exception, and handling exceptions correctly and avoiding errors is a very important part of improving software stability.

Interrupt work mechanism

The interrupt vector table is the entry point of all interrupt handlers, generally at address 0 of the address space, because interrupt handling is strongly related to the chip architecture, the Cortex-M series will be described below.

On the Cortex-M core, all interrupts are handled using the interrupt vector table. When an interrupt is triggered, the processor can determine which interrupt source it is, and then look up the interrupt vector table and jump to the corresponding location for processing. This requires that the address pointer of each interrupt service routine must be attached to a unified address, and this address must be set to the interrupt vector offset register, which is 0x08000000 by default.

 interrupt processing

In the operating system interrupt management, the interrupt handler is divided into three parts, the interrupt preamble program, the user interrupt service program, and the interrupt follow-up program.

interrupt preamble

Save the running scene, the implementation methods of different CPU architectures are different. For Cortex-M, this work is done automatically by hardware, and software does not need to be processed. When an interrupt is triggered, the processor will automatically press the context registers (PSR, PC, LR, R12, R3-R0) of the current running part into the interrupt stack.

Call the os_interrupt_enter interface, which adds 1 to the global variable os_interrupt_nest and uses it to interrupt the nested record. The code is as follows:

void os_interrupt_enter(void)
{
    os_base_t level;
    level = os_hw_interrupt_disable();
    g_os_interrupt_nest ++;
    os_hw_interrupt_enable(level);
}

User Interrupt Service Routine

In the user interrupt service routine, if other high-priority tasks are blocked and waiting resources are released or other conditions make a higher-priority task ready, the os_hw_context_switch_interrupt interface will be called to switch tasks. If there is no release of resources, etc., the switch will not be performed, and the original task will be returned after the execution of the interrupt program is completed.

The implementation of os_hw_context_switch_interrupt is related to the CPU architecture. In the Cortex-M architecture, this function will set the task to be switched to a global variable, and then trigger a low-priority PendSV exception. After the current interrupt processing is completed, it will switch to the PendSV exception handling function Execution, PendSV is an exception of the Cortex-M series specially used to assist context switching.

interrupt subsequent program

Call the os_interrupt_leave() function to decrement the global variable g_os_interrupt_nest by 1. The code is as follows:

void os_interrupt_leave(void)
{
    os_base_t level;
    level = os_hw_interrupt_disable();
    g_os_interrupt_nest--;
    os_hw_interrupt_enable(level);
}

If the task switching is not performed during the interrupt processing, the context of the task before the interrupt is directly restored, and if the task switching is performed during the interrupt, the context of the switching task is restored. For scenarios with task switching, the timing relationship of the entire interrupt process is shown in the figure below.

Schematic diagram of the interruption process

break nesting

If a higher-priority interrupt is triggered during the execution of the interrupt service routine, the current interrupt routine will be suspended and the high-priority interrupt service routine will be executed; after the execution of the high-priority interrupt is completed, the suspended execution continues. If task switching is involved in the execution, it will wait for all interrupt execution to complete and enter pendSV for context switching, as shown in the following figure.

Interrupt Nesting Diagram

The interrupt management interface is designed as follows:

(1) Hook up the interrupt service routine

(2) Mask the interrupt source

(3) Turn on the interrupt source

(4) Turn off global interrupts

(5) Restore global interrupt

(6) Interrupt entry notification

(7) Interrupt exit notification

{{o.name}}
{{m.name}}

Guess you like

Origin my.oschina.net/u/5443273/blog/5513419