1. 中断系统概述:中断的概念、中断的作用、中断的分类
各位同学,咱们今天聊聊中断系统。说实话,中断这玩意儿,是嵌入式系统的灵魂。没有中断,你的CPU就得像个傻子一样轮询等待,效率低得吓人。我在联发科做芯片验证那会儿,有一次就因为中断优先级配置搞错了,导致系统在高速数据传输时频繁丢包,查了整整三天才找到问题。嗯,从那以后,我对中断系统就格外上心。
1.1 中断的概念
什么叫中断?说白了,就是CPU正在干一件事儿,突然被一个紧急事件打断了,它得先把手头的活儿放一放,去处理这个紧急事件,处理完了再回来接着干原来的活儿。
你想想看,这就像你正在写代码,突然电话响了。你接电话(处理中断),挂断后继续写代码。这个电话就是一次中断请求。
在计算机体系里,中断是一个硬件或软件发出的信号,它告诉CPU:「嘿,有个急事,你得先处理我!」CPU收到这个信号后,会暂停当前正在执行的程序,保存好现场(就是各种寄存器的值),然后跳到一个专门的中断服务程序(ISR)里去执行。等ISR执行完毕,再恢复现场,回到刚才被打断的地方继续执行。
核心要点:中断的本质是「暂停当前任务 → 处理紧急事件 → 恢复当前任务」。这个机制让CPU能够及时响应外部或内部的各种突发事件。
1.2 中断的作用
中断的作用,我总结下来主要有这么几点:
- 提高CPU利用率:没有中断的时候,CPU只能轮询检查各个设备的状态,大部分时间都在空转。有了中断,CPU可以安心做自己的事,等设备有需要了再通知CPU。我在做低功耗蓝牙芯片时,就靠中断把CPU的休眠时间从30%提升到了85%。
- 实时响应:外部事件一来,CPU能立刻响应。比如按键按下、数据到达、定时器溢出,这些都能通过中断快速处理。联发科的物联网芯片,中断响应延迟通常控制在几十个时钟周期以内。
- 任务切换:操作系统里的任务调度,本质上也是靠定时器中断来触发的。每次时钟滴答一下,OS就检查一下要不要切换任务。
- 错误处理:当硬件出现异常,比如非法指令、除零错误、总线错误,CPU会触发一个异常中断,让你有机会去处理这些错误,而不是直接死机。
个人经验:我在调试一个电机驱动项目时,发现电机偶尔会抖动一下。后来用逻辑分析仪抓了中断信号,才发现是中断服务程序执行时间太长,导致下一个中断被延迟了。所以,ISR里千万别做耗时操作,能放主循环的就放主循环。
1.3 中断的分类
中断的分类方式有很多种,咱们从最常见的角度来分:外部中断、内部中断和软件中断。
1.3.1 外部中断
外部中断,顾名思义,是由芯片外部的事件触发的。这些事件通过芯片的引脚输入,比如GPIO引脚上的电平变化、按键按下、外部传感器信号等。
在联发科的芯片上,外部中断通常可以配置为上升沿触发、下降沿触发、双边沿触发或者电平触发。我个人习惯用边沿触发,因为电平触发容易产生误判,尤其是在信号有毛刺的时候。
| 触发方式 | 说明 | 适用场景 |
|---|---|---|
| 上升沿触发 | 信号从低到高跳变时触发 | 按键释放检测 |
| 下降沿触发 | 信号从高到低跳变时触发 | 按键按下检测 |
| 双边沿触发 | 信号任何跳变都触发 | 编码器信号检测 |
| 电平触发 | 信号保持特定电平时持续触发 | 紧急停止信号 |
避坑指南:我曾经在一个工业控制项目里用了电平触发,结果因为信号线上有噪声,导致中断被反复触发,CPU几乎一直在处理中断,主程序根本跑不动。后来改成下降沿触发,再加一个20ms的软件消抖,问题就解决了。
1.3.2 内部中断
内部中断是由芯片内部的事件触发的,不需要外部引脚。常见的内部中断包括:
- 定时器中断:定时器计数溢出或者比较匹配时触发。这是嵌入式系统里最常用的中断之一,用来做周期性任务、PWM生成、延时等。
- DMA中断:DMA传输完成或者出错时触发。用DMA做大数据搬运,CPU可以完全解放出来。
- UART/SPI/I2C中断:串行通信接口在接收到数据或发送完成时触发。联发科的芯片,每个外设都有独立的中断线,可以单独使能。
- ADC中断:模数转换完成时触发。我在做传感器采集时,就靠ADC中断来读取转换结果,不用轮询等待。
- 异常中断:包括硬件故障、非法指令、总线错误等。这些属于不可屏蔽中断,CPU必须立即响应。
内部中断的好处是延迟低、可控性强。你想想看,外部中断还要经过引脚、电平转换、去抖等环节,内部中断直接从芯片内部走,快得多。
1.3.3 软件中断
软件中断,也叫软中断,是由程序主动触发的中断。在ARM Cortex-M系列里,这通常通过执行一条SVC(Supervisor Call)指令来实现。
软件中断的作用主要有两个:
- 系统调用:用户程序通过软件中断来请求操作系统提供服务,比如创建任务、申请内存、发送消息等。用户程序运行在非特权模式,通过SVC指令切换到特权模式,让OS内核来处理。
- 任务同步:在某些RTOS里,可以用软件中断来唤醒一个等待中的任务,或者触发一个延时执行的动作。
举个例子:在联发科的FreeRTOS移植中,任务切换就是通过PendSV(可挂起的系统调用)这个软件中断来实现的。每次定时器中断触发后,OS会检查是否需要切换任务,如果需要,就触发PendSV中断,在PendSV里完成上下文切换。这样做的好处是,把任务切换的时机推迟到所有高优先级中断处理完毕之后,避免了中断嵌套带来的复杂性。
1.4 中断优先级与嵌套
聊到中断分类,就不得不提中断优先级。联发科的芯片,中断优先级通常支持多级配置,比如MTK的ARM Cortex-M4芯片,支持8级或16级可编程优先级。
中断嵌套的意思是:当一个低优先级的中断正在执行时,来了一个高优先级的中断,CPU会暂停低优先级的中断服务程序,先去处理高优先级的,处理完再回来继续处理低优先级的。
这里有个坑,我当年踩过:中断嵌套层数太多,会导致栈空间暴涨。每个中断服务程序都要压栈保存现场,嵌套个三四层,栈就快爆了。所以,我建议在设计中断系统时,尽量控制嵌套深度,能用优先级分组解决的,就别搞太复杂的嵌套。
我的习惯:在联发科平台上,我一般把实时性要求高的中断(比如电机控制、通信协议时序)设为最高优先级,把数据采集、按键扫描这类不那么紧急的设为低优先级。这样既能保证关键任务的实时性,又不会让低优先级任务饿死。
1.5 小结
中断系统是嵌入式开发的基石。理解中断的概念、作用和分类,是写好嵌入式程序的第一步。外部中断让你能感知外部世界的变化,内部中断让你能精确控制芯片内部的各种资源,软件中断则提供了用户程序和操作系统之间的桥梁。
下一章,咱们会深入联发科芯片的中断控制器架构,看看硬件层面是怎么管理这些中断的。到时候我会拿MT7688和MT2625这两个芯片来举例,讲讲它们的中断向量表、中断使能寄存器、以及中断响应流程。嗯,敬请期待。