• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Interrupt Management
2
3
4## Basic Concepts
5
6An interrupt is a signal to the processor emitted by hardware or software indicating an event that needs immediate attention. An interrupt alerts the processor to a high-priority condition requiring the interruption of the current code being executed by the processor. When a hardware interrupt is triggered, the interrupt handler is located based on the interrupt ID and then executed to handle the interrupt.
7
8By using the interrupt mechanism, the CPU responds to the interrupt request (IRQ) from a peripheral only when required, and execute other tasks when the peripherals do not require the CPU. In this way, the CPU does not need to spend a lot of time in waiting and querying the peripheral status, which effectively improves the real-time performance and execution efficiency of the system.
9
10To understand interrupts, you need to know the following concepts:
11
12- Interrupt ID
13
14  Identifies an IRQ signal. The computer locates the device that sends the IRQ based on the interrupt ID.
15- IRQ
16
17  An electrical pulse signal sent to the CPU, alerting the CPU to a high-priority event requiring the interruption of the current code being executed by the CPU.
18- Interrupt priority
19
20  Prioritizes the sources that trigger interrupts based on the importance and urgency of interrupt events, so that the CPU can respond to and handle all interrupts in a timely manner.
21- Interrupt handler
22
23  A program executed by the CPU to respond to the IRQ from a peripheral. Each device that triggers an interrupt has its own interrupt handler.
24- Interrupt triggering
25
26  The interrupt source sends an interrupt signal to the interrupt controller. The interrupt controller arbitrates all pending interrupts, determines the priority, and sends the interrupt signal to the CPU. When an interrupt source generates an interrupt signal, the interrupt trigger is set to **1**, alerting the CPU to respond to the interrupt.
27- Interrupt vector
28
29  Entry address of an interrupt handler.
30- Interrupt vector table
31
32  An area for storing interrupt vectors. It stores the mapping between interrupt vectors and interrupt IDs.
33
34
35## Available APIs
36
37The following table describes APIs available for the OpenHarmony LiteOS-M interrupt module. For more details about the APIs, see the API reference.
38
39  **Table 1** APIs for creating and deleting an interrupt
40
41| API| Description|
42| -------- | -------- |
43| LOS_HwiCreate | Creates an interrupt and registers the interrupt ID, triggering mode, priority, and interrupt handler. When an interrupt is triggered, the interrupt handler will be called.|
44| LOS_HwiDelete | Deletes an interrupt based on the specified interrupt ID.|
45
46  **Table 2** APIs for enabling and disabling interrupts
47
48| API| Description|
49| -------- | -------- |
50| LOS_IntUnLock | Enables the CPU to respond to all IRQs.|
51| LOS_IntLock | Disables the CPU from responding to IRQs.|
52| LOS_IntRestore | Restores the interrupt status before the **LOS_IntLock** and **LOS_IntUnLock** operations are performed.|
53
54  **Table 3** APIs for other interrupt operations
55
56| API            | Description            |
57| :----------------- | ---------------- |
58| LOS_HwiTrigger     | Triggers an interrupt.      |
59| LOS_HwiEnable      | Enables interrupts.      |
60| LOS_HwiDisable     | Disables interrupts.      |
61| LOS_HwiClear       | Clears an interrupt manually.  |
62| LOS_HwiSetPriority | Sets the interrupt priority.|
63| LOS_HwiCurIrqNum   | Obtains the current interrupt ID.|
64
65
66## How to Develop
67
681. Call **LOS_HwiCreate** to create an interrupt.
69
702. Call **LOS_HwiTrigger()** to trigger an interrupt (write the related register of the interrupt controller to simulate an external interrupt) or trigger an interrupt by using a peripheral.
71
723. Call **LOS_HwiDelete()** to delete an interrupt. Use this API based on actual requirements.
73
74
75> **NOTE**
76> - Set the maximum number of interrupts supported and the number of configurable interrupt priorities based on the hardware.
77> - Avoid long interrupt disabling time or interrupt handler processing time. Otherwise, the CPU cannot respond to interrupts in a timely manner.
78> - Do not directly or indirectly call the API that causes scheduling, such as **LOS_Schedule**, during the interrupt response process.
79> - The input parameter of **LOS_IntRestore()** must be the return value of **LOS_IntLock()**, that is, the current program status register (CPSR) value before the interrupt is disabled.
80> - Interrupts 0 to 15 are for internal use of the Cortex-M series processors. You are advised not to apply for or create interrupts 0 to 15.
81
82
83## Development Example
84
85This example implements the following:
86
871. Create an interrupt.
88
892. Trigger an interrupt.
90
913. Delete an interrupt.
92
93The following sample code demonstrates how to create an interrupt, trigger the interrupt to invoke the interrupt handler, and delete the interrupt.
94
95The sample code is compiled and verified in **./kernel/liteos_m/testsuites/src/osTest.c**. Call **ExampleInterrupt()** in **TestTaskEntry**.
96
97
98```
99#include "los_interrupt.h"
100#include "los_compiler.h"
101
102/* Interrupt ID to verify */
103#define HWI_NUM_TEST 7
104
105/* Interrupt handler */
106STATIC VOID UsrIrqEntry(VOID)
107{
108    printf("in the func UsrIrqEntry\n");
109}
110
111/* Register a thread callback to trigger the interrupt */
112STATIC VOID InterruptTest(VOID)
113{
114    LOS_HwiTrigger(HWI_NUM_TEST);
115}
116
117UINT32 ExampleInterrupt(VOID)
118{
119    UINT32 ret;
120    HWI_PRIOR_T hwiPrio = 3; // Interrupt priority
121    HWI_MODE_T mode = 0;
122    HWI_ARG_T arg = 0;
123
124    /* Create an interrupt. */
125    ret = LOS_HwiCreate(HWI_NUM_TEST, hwiPrio, mode, (HWI_PROC_FUNC)UsrIrqEntry, arg);
126    if(ret == LOS_OK){
127        printf("Hwi create success!\n");
128    } else {
129        printf("Hwi create failed!\n");
130        return LOS_NOK;
131    }
132
133    TSK_INIT_PARAM_S taskParam = { 0 };
134    UINT32 testTaskID;
135
136	/* Create a thread with a low priority to verify interrupt triggering.*/
137    taskParam.pfnTaskEntry = (TSK_ENTRY_FUNC)InterruptTest;
138    taskParam.uwStackSize = OS_TSK_TEST_STACK_SIZE;
139    taskParam.pcName = "InterruptTest";
140    taskParam.usTaskPrio = TASK_PRIO_TEST - 1;
141    taskParam.uwResved = LOS_TASK_ATTR_JOINABLE;
142    ret = LOS_TaskCreate(&testTaskID, &taskParam);
143    if (LOS_OK != ret) {
144        PRINTF("InterruptTest task error\n");
145    }
146
147    /* Delay 50 ticks to release the scheduling of the current thread. */
148    LOS_TaskDelay(50);
149
150    /* Delete the registered interrupt. */
151    ret = LOS_HwiDelete(HWI_NUM_TEST, NULL);
152    if(ret == LOS_OK){
153        printf("Hwi delete success!\n");
154    } else {
155        printf("Hwi delete failed!\n");
156        return LOS_NOK;
157    }
158
159    return LOS_OK;
160}
161```
162
163
164## Verification
165
166The development is successful if the return result is as follows:
167
168```
169Hwi create success!
170in the func UsrIrqEntry
171Hwi delete success!
172```
173
174