LiteOS——MCU中断切换原理【拜托了,物联网!】

举报
o0龙龙0o 发表于 2021/09/21 21:16:06 2021/09/21
【摘要】 嵌入式经常会说到“中断”的概念,那中断到底是什么呢?MUC如何完成中断任务的呢?

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

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。