LiteOS——MCU中断切换原理【拜托了,物联网!】
0、前沿
嵌入式经常会说到“中断”的概念,那中断到底是什么呢?MUC如何完成中断任务的呢?
1、中断概念
中断(Interrupt)是指处理器接收到来自硬件或软件的信号,提示发生了某个事件,应该被注意,这种情况就称为中断。
通常,在接收到来自外围硬件(相对于中央处理器和内存)的异步信号,或来自软件的同步信号之后,处理器将会进行相应的硬件/软件处理。发出这样的信号称为进行中断请求(interrupt request,IRQ)。硬件中断导致处理器通过一个运行信息切换(context switch)来保存执行状态(以程序计数器和程序状态字等寄存器信息为主);软件中断则通常作为MCU指令集中的一个指令,以可编程的方式直接指示这种运行信息切换,并将处理导向一段中断处理代码。中断在计算机多任务处理,尤其是即时系统中尤为有用。这样的系统,包括运行于其上的操作系统,也被称为“中断驱动的”。
2、中断过程
在实际运行中,一旦设备通过某引脚N向MCU发出中断指令,后者便向MUC的INTR引脚发送中断信号。MCU通过INTA引脚通知MCU中断有效(这个过程实际上还包括对此MCU的选址),后者即通过地址总线将对应引脚N的中断类型码发送给MCU。MCU得到中断类型码后,先进行现场保护
保护现场:
1️⃣状态寄存器进行压栈;
2️⃣关闭中断;
3️⃣将当前代码段寄存器CS和程序计数器IP压栈。
现场保护完成后,MCU开始按照前述的两步骤翻译中断程序入口地址。在得到中断处理程序地址之后但调用中断处理程序之前,CPU会再检查一下NMI引脚是否有信号,以防在刚才的处理过程中忽略了可能的NMI中断。NMI的优先级始终高于INTR。
在程序结束时,应该按与压栈保护时相反的顺序弹出各寄存器的值。中断程序的最后一句始终是IRET指令,这条指令将栈顶6个字节分别弹出并存入IP、CS和FLAGS寄存器,完成了现场的还原。
3、中断类型
常见MCU架构定义的中断类型分为 :
- 外部中断(External Interrupt),指来自处理器核外部的中断,例如 GPIO、UART 等产生的中断
- 计时器中断(Timer Interrupt) ,指来自计时器的中断
- 软件中断(Software Interrupt) ,指来自软件自己触发的中断
- 调试中断(Debug Interrupt),专用于实现调试器
4、中断控制器
Cortex-M 系列包含一个 NVIC(嵌套中断向量控制器)提供硬件嵌套中断服务。在中断发生时,NVIC 自动取出对应的服务例程入口地址,并且直接调用,无需软件判定中断源。另外 M 系列包含一个基本的 systick 定时器,配合 NVIC 工作,用于系统计数。
5、LiteOS的中断管理
Huawei LiteOS对传统MCU控制中使用中断进行管理处理,其中断特性为:
- 中断共享,且可配置。
- 中断嵌套,即高优先级的中断可抢占低优先级的中断,且可配置。
- 使用独立中断栈,可配置。
- 可配置支持的中断优先级个数。
- 可配置支持的中断数。
LIteOS在开发中断程序会涉及到创建中断、设置中断亲和性、使能中断、触发中断、屏蔽中断、删除中断一些列操作
#include "los_hwi.h"
#include "los_typedef.h"
#include "los_task.h"
STATIC VOID HwiUsrIrq(VOID) //中断服务程序,触发后跳转到这里执行。
{
printf("\n in the func HwiUsrIrq \n");
}
/* cpu0 trigger, cpu0 response */
UINT32 It_Hwi_001(VOID)
{
UINT32 ret;
UINT32 irqNum = 26; /* ppi */
UINT32 irqPri = 0x3;
ret = LOS_HwiCreate(irqNum, irqPri, 0, (HWI_PROC_FUNC)HwiUsrIrq, 0); //创建中断,中断好配置,中断服务函数地址说明,优先级配置
if (ret != LOS_OK) {
return LOS_NOK;
}
#ifdef LOSCFG_KERNEL_SMP
ret = LOS_HwiSetAffinity(irqNum, CPUID_TO_AFFI_MASK(ArchCurrCpuid())); //设置中断亲和性
if (ret != LOS_OK) {
return LOS_NOK;
}
#endif
ret = LOS_HwiEnable(irqNum);//使能中断
if (ret != LOS_OK) {
return LOS_NOK;
}
ret = LOS_HwiTrigger(irqNum);/
if (ret != LOS_OK) {
return LOS_NOK;
}
LOS_TaskDelay(1);
ret = LOS_HwiDisable(irqNum);//去使能中断
if (ret != LOS_OK) {
return LOS_NOK;
}
ret = LOS_HwiDelete(irqNum, NULL);//删除中断服务连接,释放内存
if (ret != LOS_OK) {
return LOS_NOK;
}
return LOS_OK;
}
上面利用代码进行简要明。使用这些前提都是在LiteOS设置中打开和配置好中断功能。
【拜托了,物联网!】有奖征文火热进行中:https://bbs.huaweicloud.com/blogs/296704
- 点赞
- 收藏
- 关注作者
评论(0)