第10章 内存管理与中断管理
核心主线是:LiteOS 如何管理 RAM 内存资源,以及如何处理中断事件。
一、本章总体框架
第十章节可以分成两大部分:
- 内存管理
- 内存管理基本概念;
- 静态内存分配;
- 动态内存分配;
- 静态内存池;
- 动态内存堆;
LOS_MemboxInit、LOS_MemboxAlloc、LOS_MemboxFree;LOS_MemInit、LOS_MemAlloc、LOS_MemFree。
- 中断管理
- 异常与中断;
- 同步异常与异步异常;
- 中断运行机制;
- 中断嵌套;
- 中断延迟;
- 接管中断与非接管中断;
LOS_HwiCreate、LOS_HwiDelete;- 中断服务程序设计原则。
这一章最重要的理解是:
内存管理解决“RAM 如何分配和回收”; 中断管理解决“外部紧急事件如何打断 CPU 并得到响应”。
二、内存管理是什么?
LiteOS 内存管理模块用于管理系统内存资源,是操作系统核心模块之一。它主要负责:
- 内存初始化;
- 内存分配;
- 内存释放。
在普通 C 程序里,我们可能会用:
malloc();
free();但是在嵌入式操作系统中,一般不直接使用标准库的 malloc/free,而是使用操作系统提供的内存管理接口。
原因主要有三点:
- 小型嵌入式设备 RAM 很小,标准库函数不一定可用;
malloc/free的实现可能占用较多代码空间;- 标准库内存管理函数不一定适合实时系统,安全性和确定性不足。
所以 LiteOS 提供自己的内存管理函数,例如:
LOS_MemAlloc();
LOS_MemFree();
LOS_MemboxAlloc();
LOS_MemboxFree();三、静态内存分配与动态内存分配
LiteOS 内存分配分成两类:
- 静态内存分配;
- 动态内存分配。
1. 静态内存分配
静态内存分配是指:
在静态内存池中分配用户初始化时预设固定大小的内存块。
也就是说,内存池中每个块大小是固定的,初始化后不能改变。
优点
- 分配速度快;
- 释放速度快;
- 无内存碎片;
- 实时性较好;
- 安全性较高。
缺点
- 只能分配固定大小的内存块;
- 不够灵活;
- 如果块太大,会浪费空间;
- 如果块太小,可能不够用。
适合场景:
- 安全要求高的系统;
- 内存块大小固定的场景;
- 对实时性要求高的场景;
- 不允许动态内存分配的嵌入式系统。
2. 动态内存分配
动态内存分配是指:
在动态内存池中,根据用户需要分配指定大小的内存块。
它更像我们平时理解的“按需申请内存”。
优点
- 可以按需分配;
- 灵活性高;
- 适合大小不确定的数据结构;
- 能提高内存利用率。
缺点
- 分配和释放时间可能更长;
- 可能产生内存碎片;
- 实时性不如静态内存池;
- 如果忘记释放,会造成内存泄漏。
适合场景:
- 数组大小不确定;
- 数据包长度不固定;
- 临时缓冲区;
- 运行时才知道内存需求的任务。
四、为什么需要动态内存?
举数组的例子。
假设要定义一个 float 数组:
float Arr[];问题是:
数组到底应该定义多大?
如果定义太小,可能越界; 如果定义太大,又浪费 RAM。
在嵌入式系统中,RAM 很珍贵,所以不能随便浪费。
动态内存分配的意义就是:
程序运行时需要多大,就申请多大;用完后及时释放。
例如:
float *Arr = LOS_MemAlloc(pool, size);这样就不需要提前写死数组大小。
五、LiteOS 内存分配算法
LiteOS 提供多种内存分配算法,默认使用 BestFit,也就是最佳适应算法。
1. BestFit 最佳适应算法
BestFit 的思想是:
每次分配内存时,寻找最合适大小的空闲内存块,尽量避免“大材小用”。
例如用户需要 100 字节,如果系统里有:
- 128 字节空闲块;
- 512 字节空闲块;
- 1024 字节空闲块;
BestFit 会优先选择 128 字节的块。
优点
- 尽量减少浪费;
- 尽量保留大块连续空间;
- 有助于减少碎片。
缺点
- 需要遍历空闲块链表;
- 时间复杂度是
O(n); - 分配时间不确定。
2. TLSF 算法
LiteOS 提供 TLSF 动态内存管理算法。
TLSF 的特点是:
时间复杂度为
O(1),分配时间相对固定。
这对实时系统很重要。
因为实时系统不仅关心能不能分配内存,还关心:
多久能完成分配?
如果分配时间不确定,就可能影响实时性。
六、嵌入式系统中的 RAM 分布
程序的不同段位于不同存储区域:
| 段 | 位置 | 含义 |
|---|---|---|
text 段 |
Flash | 存放程序代码 |
data 段 |
RAM | 存放已初始化全局变量 |
bss 段 |
RAM | 存放未初始化全局变量 |
| heap 堆 | RAM | LiteOS 管理的动态内存 |
| MSP 栈 | RAM 末尾附近 | 主栈指针使用空间 |
一般来说:
text在 Flash 中,data和bss在 RAM 中。 除去data、bss和 MSP 栈之后,剩余 RAM 可以作为 LiteOS 的 heap 进行动态内存管理。
注:
- heap 起始地址通常在
bss段结束之后; - heap 结束地址通常在 MSP 栈起始地址之前。
所以系统动态内存池并不是随便来的,而是 RAM 中一段连续区域。
七、动态内存管理的运行机制
动态内存管理主要包括三个过程:
- 初始化内存;
- 分配内存;
- 释放内存。
1. 初始化内存
LiteOS 在内核初始化时会初始化系统管理的内存堆。
常见配置包括:
OS_SYS_MEM_ADDR
OS_SYS_MEM_SIZE其中:
OS_SYS_MEM_ADDR:动态内存池起始地址;OS_SYS_MEM_SIZE:动态内存池大小。
初始化函数是:
LOS_MemInit();不过通常在内核初始化阶段已经自动调用,用户不需要手动重复初始化。
2. 分配内存
动态内存分配函数是:
LOS_MemAlloc();基本形式:
void *p = LOS_MemAlloc(pool, size);含义是:
从指定内存池
pool中申请size字节内存。
如果成功,返回内存地址; 如果失败,返回 NULL。
分配时系统会遍历内存块链表,寻找合适大小的空闲块。如果空闲块比需要的更大,系统可能会把它切割成两部分:
- 一部分分给用户;
- 另一部分继续作为空闲块留在内存池中。
这样可以提高内存利用率。
3. 释放内存
释放函数是:
LOS_MemFree();基本形式:
LOS_MemFree(pool, p);含义是:
把之前从内存池中申请的内存块归还给系统。
嵌入式系统内存有限,所以用完一定要释放。
否则会出现:
- 内存泄漏;
- 后续任务申请内存失败;
- 系统长期运行后崩溃。
八、静态内存池管理
静态内存池本质上是一块静态数组。
它由两部分组成:
- 控制块;
- 若干相同大小的内存块。
静态内存池控制块保存:
- 内存块大小;
- 内存块总数;
- 已使用内存块数量;
- 空闲内存块链表。
结构类似:
typedef struct {
UINT32 uwBlkSize;
UINT32 uwBlkNum;
UINT32 uwBlkCnt;
LOS_MEMBOX_NODE stFreeList;
} LOS_MEMBOX_INFO;可以这样理解:
静态内存池就是提前切好的固定大小小格子,需要时拿一个,用完再放回去。
九、静态内存池的开发流程
静态内存池使用流程是:
- 规划一块内存区域作为静态内存池;
- 调用
LOS_MemboxInit()初始化; - 调用
LOS_MemboxAlloc()分配内存块; - 调用
LOS_MemboxFree()释放内存块; - 调用
LOS_MemboxClr()清除内存块内容。
1. 定义静态内存池
例如:
#define MEM_BOXSIZE 50
#define MEM_BLKSIZE 3
static UINT32 BoxMem[MEM_BOXSIZE * MEM_BLKSIZE];这里用数组保证内存连续。
2. 初始化静态内存池:LOS_MemboxInit
函数形式:
LOS_MemboxInit(pBoxMem, uwBoxSize, uwBlkSize);参数含义:
| 参数 | 含义 |
|---|---|
pBoxMem |
内存池起始地址 |
uwBoxSize |
内存池总大小 |
uwBlkSize |
每个内存块大小 |
示例:
LOS_MemboxInit(&BoxMem[0], MEM_BOXSIZE, MEM_BLKSIZE);初始化后,系统会:
- 在内存池头部放置控制块;
- 根据块大小计算能切分多少块;
- 把所有可用内存块链接成空闲链表。
注意:
- 内存池地址必须有效;
- 内存块大小不能为 0;
- 内存池大小要大于控制块大小;
- 内存池地址要按要求对齐。
3. 分配静态内存块:LOS_MemboxAlloc
函数:
LOS_MemboxAlloc(pBoxMem);示例:
UINT32 *p_Num = NULL;
p_Num = (UINT32 *)LOS_MemboxAlloc(BoxMem);如果成功,返回内存块地址; 如果失败,返回 NULL。
分配过程可以理解为:
从空闲链表头部取出第一个空闲块,并返回给用户。
4. 释放静态内存块:LOS_MemboxFree
函数:
LOS_MemboxFree(pBoxMem, pBox);示例:
LOS_MemboxFree(BoxMem, p_Num);含义:
把
p_Num指向的内存块归还给BoxMem这个静态内存池。
释放时,系统会把该内存块重新插入空闲链表。
5. 清除内存块内容:LOS_MemboxClr
函数:
LOS_MemboxClr(pBoxMem, pBox);示例:
LOS_MemboxClr(BoxMem, p_Num);作用:
把指定内存块中的内容清零。
这常用于避免旧数据残留。
十、静态内存和动态内存对比
| 对比项 | 静态内存池 | 动态内存堆 |
|---|---|---|
| 分配大小 | 固定块大小 | 按需分配 |
| 灵活性 | 较低 | 较高 |
| 分配速度 | 快 | 相对慢 |
| 碎片问题 | 无碎片 | 可能有碎片 |
| 实时性 | 好 | 取决于算法 |
| 安全性 | 高 | 需要注意泄漏和碎片 |
| 适合场景 | 固定大小对象 | 不确定大小数据 |
考试可以这样答:
静态内存池适合大小固定、实时性和安全性要求高的场景;动态内存适合大小不确定、需要按需申请的场景,但要注意碎片和内存泄漏。
十一、中断是什么?
中断属于异步异常。
对中断的解释是:
CPU 正在处理某件事情时,外部某一事件请求 CPU 迅速处理,CPU 暂停当前工作,转去处理该事件,处理完后再回到原来被打断的地方继续执行。
例如:
- 按键按下;
- 串口收到数据;
- 定时器计数到达;
- 传感器产生报警;
- DMA 传输完成。
中断的作用是:
让 CPU 不必一直轮询外设状态,而是在外设真正需要处理时再响应,提高系统效率和实时性。
十二、异常、同步异常和异步异常
1. 异常
异常是导致处理器脱离正常执行流程、转向执行特殊代码的事件。
异常如果不处理,可能导致系统错误甚至崩溃。
2. 同步异常
同步异常由处理器内部事件引起,通常与当前执行的指令有关。
例如:
- 除零错误;
- 非法指令;
- 非对齐访问;
- 存储访问错误。
特点:
必须立即处理,否则程序无法继续正确执行。
3. 异步异常
异步异常通常由外部硬件事件引起。
中断就是典型的异步异常。
例如:
- 按键中断;
- 串口中断;
- 外部传感器中断。
特点:
可以延迟处理,某些情况下甚至可以忽略。
十三、中断相关硬件
和中断相关的硬件主要有三类:
- 外设
- 中断控制器
- CPU
1. 外设
外设是中断源。
例如:
- GPIO;
- USART;
- TIM;
- ADC;
- DMA;
- I2C;
- SPI。
外设产生事件后,会向中断控制器发出中断请求。
2. 中断控制器
中断控制器负责管理中断请求。
它会判断:
- 哪个中断来了;
- 是否允许响应;
- 优先级如何;
- 是否支持嵌套。
在 Cortex-M 系列中,常见中断控制器是:
NVIC
3. CPU
CPU 最终响应中断。
当中断被允许响应时,CPU 会:
- 暂停当前任务;
- 保存现场;
- 跳转到中断服务程序;
- 执行 ISR;
- 恢复现场;
- 回到原程序继续执行。
十四、中断相关术语
中断相关的重点术语
| 术语 | 含义 |
|---|---|
| 中断号 | 标识某个中断源的编号 |
| 中断请求 | 外设请求 CPU 处理事件 |
| 中断优先级 | 决定多个中断同时发生时谁先处理 |
| 中断向量 | 中断服务程序入口地址 |
| 中断向量表 | 保存所有中断入口地址的表 |
| 中断处理程序 | ISR,真正处理中断的函数 |
| 中断触发 | 产生中断请求的动作 |
| 中断触发类型 | 上升沿、下降沿、电平触发等 |
| 临界段 | 不希望被中断打断的代码段 |
十五、中断的运行机制
CPU 响应中断的一般流程是:
- 保存当前处理器状态;
- 查找中断向量;
- 把中断处理程序入口地址载入 PC;
- 执行中断服务程序;
- 中断处理完成后恢复现场;
- 回到被打断的位置继续执行。
可以背成:
保存现场 → 查找入口 → 执行 ISR → 恢复现场 → 返回原程序。
十六、中断发生的两种环境
中断可能发生在两种环境中:
- 任务上下文;
- 中断服务程序上下文。
1. 任务运行时发生中断
这是最常见的情况。
某个任务正在运行时,外设产生中断。CPU 会打断当前任务,保存任务上下文,转去执行中断服务程序。
ISR 执行完成后,CPU 恢复任务上下文,继续执行原任务。
2. 中断服务程序中发生更高优先级中断
这就是中断嵌套。
例如:
- 中断 1 正在执行;
- 此时中断 2 发生;
- 如果中断 2 优先级更高;
- CPU 会打断中断 1,先执行中断 2;
- 中断 2 完成后,再回到中断 1。
LiteOS 允许中断嵌套,也就是说优先级更高的中断可以打断正在执行的低优先级中断。
十七、中断为什么要“快进快出”?
中断可以打断任何任务,不管该任务优先级多高。
因此 ISR 如果执行太久,会影响:
- 任务调度;
- 其他中断响应;
- 系统实时性;
- 低优先级中断响应;
- 高优先级任务执行。
所以中断服务程序中应该只做简单处理。
推荐做法:
- 判断中断来源;
- 清除中断标志位;
- 设置标志;
- 释放信号量或写事件;
- 尽快退出。
复杂处理交给任务完成。
例如:
void USART_IRQHandler(void)
{
if (USART 收到数据)
{
保存少量必要信息;
LOS_SemPost(Sem_Handle);
清除中断标志;
}
}然后在任务中:
while (1)
{
LOS_SemPend(Sem_Handle, LOS_WAIT_FOREVER);
处理串口数据;
}这就是:
中断负责通知,任务负责处理。
十八、中断延迟
中断延迟是本章重点。
定义:
中断延迟是指从硬件中断发生到开始执行中断服务程序第一条指令之间的时间。
也就是:
硬件中断发生 → ISR 第一条指令执行
之间的时间。
中断延迟由哪些部分组成?
可以概括为:
中断延迟 = 识别中断时间 + 等待中断打开时间 + 关闭中断时间
其中:
- 识别中断时间
- CPU 查找中断源;
- 读取中断向量;
- 查找中断向量表;
- 跳转 ISR。
- 等待中断打开时间
- 如果系统当前关闭中断,中断会被挂起;
- 等系统重新打开中断后才能响应。
- 关闭中断时间
- 临界段中系统不允许中断打断;
- 临界段越长,中断延迟越大。
所以要记住:
临界段要尽量短,中断关闭时间越短,系统实时性越好。
十九、接管中断与非接管中断
两种方式:
- 接管中断
- 非接管中断
1. 接管中断
接管中断是指:
系统中的中断由 RTOS 软件统一管理。
LiteOS 接管中断版本支持:
- 中断初始化;
- 中断创建;
- 中断删除;
- 中断使能;
- 中断屏蔽;
- 中断共享。
如果使用接管中断,需要配置:
LOSCFG_PLATFORM_HWI = YES
LOSCFG_PLATFORM_HWI_LIMIT也就是开启硬件中断管理功能,并配置系统支持的最大中断数。
2. 非接管中断
非接管中断更接近裸机方式。
用户自己:
- 配置中断;
- 使能中断;
- 编写中断服务程序;
- 在中断中使用信号量、事件等 IPC 通知任务。
非接管中断版本支持:
- 中断使能;
- 中断屏蔽。
它比较简单,适合初学者和普通移植场景。
二十、LiteOS 接管中断的常用函数
1. 创建硬件中断:LOS_HwiCreate
函数形式:
LOS_HwiCreate(
HWI_HANDLE_T uwHwiNum,
HWI_PRIOR_T usHwiPrio,
HWI_MODE_T usMode,
HWI_PROC_FUNC pfnHandler,
HWI_ARG_T uwArg
);参数含义:
| 参数 | 含义 |
|---|---|
uwHwiNum |
硬件中断号 |
usHwiPrio |
中断优先级 |
usMode |
中断模式 |
pfnHandler |
中断服务程序 |
uwArg |
传给中断服务程序的参数 |
示例:
LOS_HwiCreate(KEY1_INT_EXTI_IRQ,
0,
0,
KEY1_IRQHandler,
0);创建中断时,LiteOS 会:
- 检查中断服务函数是否为空;
- 检查中断号是否合法;
- 检查中断是否已经注册;
- 检查优先级是否合法;
- 设置中断向量;
- 使能 NVIC 中断;
- 设置中断优先级。
2. 删除硬件中断:LOS_HwiDelete
函数:
LOS_HwiDelete(uwHwiNum);作用:
删除已创建的硬件中断。
删除后:
- 系统不再响应该中断;
- 中断号和中断服务程序的映射关系被解除;
- 中断会被禁用。
二十一、使用接管中断时的注意事项
强调几点:
- 创建中断不等于初始化中断;
- 外设中断初始化仍然需要用户自己写。
- 中断号要根据具体芯片查找;
- 例如 STM32F10x 中可以在
stm32f10x.h中找到。
- 例如 STM32F10x 中可以在
- 中断优先级数值越低,优先级越高;
- 默认优先级范围通常是 0~7。
- 中断服务程序不能耗时太长;
- 否则影响其他中断响应。
- 关闭中断后不能执行引起调度的函数;
- 否则可能导致系统异常。
二十二、非接管中断方式
非接管中断方式和裸机基本类似。
使用步骤一般是:
- 配置 GPIO;
- 配置 EXTI;
- 配置 NVIC;
- 编写中断服务函数;
- 中断中设置标志或释放信号量;
- 任务中处理具体业务。
在 Cortex-M 上,LiteOS 遵循与裸机中断一致的方法。如果用户需要自定义中断服务程序,只需要定义与启动文件中相同名称的函数,覆盖弱符号即可。
例如启动文件中有:
DCD EXTI0_IRQHandler用户就可以写:
void EXTI0_IRQHandler(void)
{
...
}二十三、中断向量表
中断向量表保存了各个中断服务程序的入口地址。
STM32 启动文件中通常会有类似内容:
DCD Reset_Handler
DCD NMI_Handler
DCD HardFault_Handler
DCD PendSV_Handler
DCD SysTick_Handler
DCD EXTI0_IRQHandler
DCD EXTI1_IRQHandler
...每个 DCD 后面跟着一个处理函数入口。
当某个中断发生时,CPU 根据中断号查找中断向量表,找到对应 ISR 地址,然后跳转执行。
所以:
中断向量表就是“中断号到中断处理函数地址”的映射表。
二十四、中断管理实验
实验主要是按键外部中断。
基本思路是:
- 创建两个按键中断;
- 编写对应 ISR;
- 按键触发中断;
- 中断服务程序中设置标志或释放信号量;
- 任务获取信号量后通过串口输出信息。
中断服务程序示例逻辑:
static void KEY1_IRQHandler(void)
{
if (EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET)
{
Trigger_Num = 1;
LED1_TOGGLE;
EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE);
}
}关键点是:
ISR 中只做简单处理,并清除中断标志位。
如果不清除中断标志位,可能会反复进入中断。
二十五、内存管理与中断管理的联系
这两个部分看起来不一样,但都属于操作系统底层核心能力。
| 模块 | 解决问题 | 关键点 |
|---|---|---|
| 内存管理 | RAM 怎么分配和释放 | 防止浪费、碎片、泄漏 |
| 中断管理 | 外部事件怎么及时响应 | 快进快出、低延迟、正确清标志 |
内存管理偏“资源管理”; 中断管理偏“实时响应”。
它们共同服务于 LiteOS 的稳定运行。
二十六、本章重点背诵版
1. 内存管理定义
LiteOS 内存管理模块用于管理系统内存资源,是操作系统核心模块之一,主要包括内存初始化、内存分配和内存释放。LiteOS 一般不使用标准库 malloc/free,而使用自身提供的内存管理函数。
2. 静态内存分配
静态内存分配是在静态内存池中分配用户初始化时预设固定大小的内存块。其优点是分配和释放效率高、无内存碎片、安全性高;缺点是只能分配固定大小的内存块,灵活性较差。
3. 动态内存分配
动态内存分配是在动态内存池中根据用户指定大小按需分配内存块。其优点是灵活、按需分配;缺点是耗时较多,可能产生内存碎片,也可能出现内存泄漏。
4. 静态内存池常用函数
LOS_MemboxInit(); // 初始化静态内存池
LOS_MemboxAlloc(); // 分配静态内存块
LOS_MemboxFree(); // 释放静态内存块
LOS_MemboxClr(); // 清除内存块内容5. 动态内存常用函数
LOS_MemInit(); // 初始化动态内存池
LOS_MemAlloc(); // 申请动态内存
LOS_MemFree(); // 释放动态内存6. 中断定义
中断是指 CPU 正在执行当前任务时,外部事件请求 CPU 迅速处理,CPU 暂停当前任务,转去执行中断服务程序,处理完成后再返回原程序继续执行。中断属于异步异常。
7. 中断处理流程
中断处理流程为:外设产生中断请求,CPU 响应中断,保存当前上下文,查找中断向量表,跳转到中断服务程序执行,执行完成后恢复上下文,并返回被打断的位置继续运行。
8. 中断延迟
中断延迟是从硬件中断发生到开始执行中断服务程序第一条指令之间的时间。它主要由识别中断时间、等待中断打开时间和关闭中断时间组成。临界段越长,中断关闭时间越长,中断延迟越大。
9. 接管中断与非接管中断
接管中断是指中断由 LiteOS 统一管理,支持中断创建、删除、使能、屏蔽和共享等功能;非接管中断类似裸机方式,由用户自己配置中断、使能中断和编写中断服务程序。
10. 中断服务程序设计原则
中断服务程序应尽量短小,做到快进快出。ISR 中不应执行复杂耗时操作,不应调用可能阻塞或引起调度的函数,通常只设置标志、释放信号量或写事件,然后由任务完成具体处理。
二十七、考试可能这样问
题目1:LiteOS 为什么不直接使用 malloc/free?
答:
在嵌入式系统中,标准库 malloc/free 不一定可用,而且实现可能占用较多代码空间,不适合 RAM 较小的设备;同时其安全性和实时性不一定满足嵌入式操作系统要求。因此 LiteOS 提供自己的内存管理接口,如 LOS_MemAlloc、LOS_MemFree、LOS_MemboxAlloc、LOS_MemboxFree 等。
题目2:静态内存分配和动态内存分配有什么区别?
答:
静态内存分配是在静态内存池中分配固定大小的内存块,分配释放效率高、无碎片、实时性好,但灵活性差;动态内存分配是在动态内存池中按需分配用户指定大小的内存块,灵活性高,但耗时较多,可能产生内存碎片和内存泄漏。
题目3:LiteOS 静态内存池如何使用?
答:
LiteOS 静态内存池的使用流程是:先规划一块连续内存区域作为静态内存池,然后调用 LOS_MemboxInit() 初始化内存池;需要内存时调用 LOS_MemboxAlloc() 分配固定大小内存块;使用完成后调用 LOS_MemboxFree() 释放内存块;必要时可调用 LOS_MemboxClr() 清除内存块内容。
题目4:LiteOS 动态内存管理的流程是什么?
答:
LiteOS 动态内存管理流程包括初始化、分配和释放。系统在内核初始化时调用 LOS_MemInit() 初始化动态内存堆;用户需要内存时调用 LOS_MemAlloc() 从内存池中分配指定大小内存块;使用完毕后调用 LOS_MemFree() 将内存归还给系统。
题目5:什么是中断?
答:
中断是指 CPU 正在执行某个任务时,外部事件请求 CPU 立即处理,CPU 暂停当前工作,保存现场,转去执行中断服务程序,处理完成后恢复现场,并回到原程序继续执行。中断属于异步异常,常用于处理按键、串口、定时器等紧急外设事件。
题目6:中断处理过程是什么?
答:
中断处理过程包括:外设产生中断请求;CPU 响应中断并保存当前上下文;根据中断号查找中断向量表;跳转到对应中断服务程序执行;中断服务程序处理完成后恢复上下文;最后返回原程序继续执行。
题目7:什么是中断延迟?
答:
中断延迟是指从硬件中断发生到开始执行中断服务程序第一条指令之间的时间。它包括识别中断时间、等待中断打开时间和关闭中断时间。系统关闭中断或处于临界段时,中断会被延迟响应,因此临界段应尽量短。
题目8:接管中断和非接管中断有什么区别?
答:
接管中断是指中断由 LiteOS 统一管理,支持中断创建、删除、使能、屏蔽和共享等功能,常用函数有 LOS_HwiCreate() 和 LOS_HwiDelete()。非接管中断则类似裸机方式,由用户自行配置中断、使能中断和编写中断服务程序,LiteOS 只提供基本的中断使能和屏蔽能力。
题目9:为什么中断服务程序要尽量短?
答:
中断可以打断任务运行,甚至影响其他中断响应。如果中断服务程序执行时间过长,会增加中断延迟,影响系统实时性。因此 ISR 应尽量快进快出,只做必要操作,如清除中断标志、设置标志位、释放信号量或写事件,复杂处理应放到任务中完成。
二十八、本章一句话总结
第十章节可以这样总结:
内存管理负责 LiteOS 中 RAM 的初始化、分配和释放,静态内存池强调固定块、高效率和无碎片,动态内存强调按需分配和灵活性;中断管理负责外部紧急事件的响应,CPU 通过保存现场、查找中断向量、执行 ISR 和恢复现场完成中断处理,实际开发中应减少中断延迟,ISR 要快进快出,并尽量通过信号量或事件通知任务完成复杂处理。