IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> SylixOS 中断控制器 -> 正文阅读

[嵌入式]SylixOS 中断控制器

中断和异常
指在当前执行程序的某处出现一个事件,该事件需要处理器进行处理。通常,这种事情会导致从当前运行程序转移到被称为中断处理或异常处理的程序中。

一.异常向量表

系统入口
ARM(AArch32)架构中断向量表
在这里插入图片描述

1.Reset :
处理器在工作时, 突然按下重启键, 就会触发该异常;
2.Undefined instructions :
处理器执行的指令是有规范的, 如果尝试执行不符合要求的指令, 就会进入到该异常;
3.Software interrupt :
软中断, 软件中需要去打断处理器工作, 可以使用软中断来执行;
4.Prefetch Abort :
ARM 在执行指令的过程中, 要先去预取指令准备执行, 如果预取指令失败, 就会产生该异常;
5.Data :
读取数据失败;
6.IRQ:
普通中断;
7.FIQ :
快速中断, 快速中断要比普通中断响应速度要快一些;

(AArch32)异常向量表通常在0x00000000,也可以在0xffff0000
在哪个地址有cp15控制
在这里插入图片描述

ARM64(AArch64)架构异常向量表
在这里插入图片描述

异常向量表结构:
实际上有四张表,每张表有四个异常入口,分别对应同步异常,IRQ,FIQ 和 出错异常。
每一个异常入口不再仅仅占用 4bytes 的空间,而是占用 0x80 bytes空间,也就是说,每一个异常入口可以放置多条指令,而不仅仅是一条跳转指令

在ARM32中,每个向量表对应四个字节,每四个字节对应一条指令。ARM32入口对应0,每个指令对应四个字节,可计算偏移量。
在ARM64中,向量表中所有指令都设置好了地址。

MIPS32架构异常向量表
异常向量表设置到了入口地址
在这里插入图片描述
在这里插入图片描述

向量表结构,进入分支,加调试信息,知道向量表入口。

二.中断处理流程

串口中断,定时器中断都是IRQ中断
在这里插入图片描述

产生IRQ中断后,pc指针从上面的汇编跳到这个函数archIntEntry
在这里插入图片描述

这个函数就是中断入口archIntEntry(在base中)
不同模式对应不同的栈位置
第一步把cpu相关寄存器存入栈里,第二部调用系统定义好的中断进入函数。(API_InterEnter)
在这里插入图片描述

中断入口函数API_InterEnter中先中断嵌套值CPU_ulInterNesting++,然后调用archIntCtxSaveReg
在这里插入图片描述

archIntCtxSaveReg里面做一次中断保存寄存器
这个函数里面做了一次拷贝(archTaskCtCopy函数),前面中断入口archIntEntry里也做了拷贝
这里的拷贝再把中断存储到任务控制块TCB中
在这里插入图片描述

当异常进入(上面汇编的中断入口),把任务先存入IRQ对应的栈位置(临时保存)。
第二次保存时,存储到对应上下文的任务控制块TCB中(archTaskCtCopy函数)。
这两次保存才是完整的任务保存流程。

判断是不是第一次进入中断
在这里插入图片描述

第一次进入中断,获取CPU中断堆栈(不是第一次产生中断,则产生中断嵌套)
在这里插入图片描述

总结:1.保存到临时的IRQ对应的栈位置。2.上下文保存到TCB中。3.保存完后重新设置中断处理中栈处理的位置。4.后面是真正处理中断流程。

bspIntHandle处理中断的函数(bspLib.c中的bspIntHandle函数)
在这里插入图片描述

这个函数中获取中断号并调用archIntHandle
在这里插入图片描述

archIntHandle函数又回到BASE中的处理
先判断中断号是否合法;然后判断中断号是否可抢占;如果可抢占会发生嵌套,不可抢占进入API_InterVectorIsr中断总服务函数。
在这里插入图片描述

进入API_InterVectorIsr中断总服务函数
这个函数中会根据中断号调用驱动中定义的中断服务程序,获得中断返回值。
在这里插入图片描述

最后执行中断退出API_InterExit函数
在这里插入图片描述

中断嵌套值CPU_ulInterNesting–(可根据这个值来判断有些函数是否在中断中调用)
在这里插入图片描述

执行中断调度,中断退出之前,在调度表找出最应该调度的任务。
执行中断返回,调度那个最应该调度的任务,返回上下文。
在这里插入图片描述

进入中断前要保存上下文,中断返回后恢复上下文(恢复的上下文不一定和之前保存的上下文一样,因为中断退出函数中会执行中断调度,找出最应该执行的任务然后返回)。

中断处理流程总结:
1.archIntEntry 向量表入口跳转的位置。将正文保存到 IRQ 模式栈中。
2.API_InterEnter 将中断嵌套计数增加。将 IRQ 模式栈中的寄存器信息保存到 TCB 上下文中。
3.bspIntHandle 从中断控制器中获取中断号。调用注册好的中断服务程序
4.API_InterExit 将中断嵌套计数减少。调度。恢复上下文

API_InterStackBaseGet
中断的处理流程在指定的栈区域;
可统计中断堆栈的使用量(flag)

bspIntHandle(需要实现的函数,不同中断处理器流程不同)
不同中断控制器处理流程不同
调用 archIntHandle,是否开嵌套

API_InterExit
中断中的调度接口
中断上下文的恢复

中断嵌套流程:
先禁用当前中断的中断号(避免当前中断号再产生中断),然后接收其它中断号。其他中断进入时,会判断是不是第一次中断(根据中断嵌套值),然后处理中断流程与上面类似。当中断退出时流程与正常中断不同,嵌套中断不会回到调度的任务而是回到上一个中断。
在这里插入图片描述
中断嵌套(优先级高的中断会抢占优先级低的中断)
1.中断嵌套开启的时机
archIntHandle ——> API_InterVectorIsr
2.中断嵌套栈使用的变化
继续使用当前IRQ模式栈
3.中断嵌套的返回
不会调度,不会从异常加载上下文,而是回到上一次异常位置

核间中断:有自己的处理分支_SmpProclpi(多核)
普通中断:根据中断号,找到对应中断服务程序
链式中断:根据中断号,遍历中断服务程序,判断返回值
设置链式中断的方法:
API_InterVectorSetFlag(LW_IRQ_4, LW_IRQ_FLAG_QUEUE);

三.中断控制器的实现

bspIntInit 中断控制器的初始化
bspIntVectorEnable/bspIntVectorDisable 中断使能/中断禁能(对应MASK寄存器)
bspIntVectorSetPriority/bspIntVectorGetPriority 中断优先级设置/中断优先级获取
bspIntVectorSetTarget/bspIntVectorGetTarget 中断绑核设置/中断绑核获取
bspMpInt 核间中断触发

S3C2440的中断控制器 单核,结构简单
ARM GIC V1,V2 Distributor+CPU Interface
ARM GIC V3,V4

关中断
KN_INT_DISABLE/KN_INT_ENABLE
在这里插入图片描述

Disable IRQ Interrupts
多核处理器,每个核都有自己的I位
关中断只是关闭本核的中断

2440中断接口实现

/*********************************************************************************************************
  中断相关
*********************************************************************************************************/
/*********************************************************************************************************
** 函数名称: bspIntInit
** 功能描述: 中断系统初始化
** 输  入  : NONE
** 输  出  : NONE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
VOID  bspIntInit (VOID)
{
    API_InterVectorSetFlag(LW_IRQ_4,  LW_IRQ_FLAG_QUEUE);               /*  EINT 4 ~ 7                  */
    API_InterVectorSetFlag(LW_IRQ_5,  LW_IRQ_FLAG_QUEUE);               /*  EINT 8 ~ 23                 */
    API_InterVectorSetFlag(LW_IRQ_0,  LW_IRQ_FLAG_SAMPLE_RAND);         /*  EINT 0 used to sample random*/
}
/*********************************************************************************************************
** 函数名称: bspIntHandle
** 功能描述: 中断入口
** 输  入  : NONE
** 输  出  : NONE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
VOID  bspIntHandle (VOID)
{
    REGISTER UINT32   uiIrqVic = rINTOFFSET;

    archIntHandle((ULONG)uiIrqVic, LW_FALSE);
}
/*********************************************************************************************************
** 函数名称: bspIntVectorEnable
** 功能描述: 使能指定的中断向量
** 输  入  : ulVector     中断向量
** 输  出  : NONE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
VOID  bspIntVectorEnable (ULONG  ulVector)
{
    INTER_CLR_MSK((1u << ulVector));
}
/*********************************************************************************************************
** 函数名称: bspIntVectorDisable
** 功能描述: 禁能指定的中断向量
** 输  入  : ulVector     中断向量
** 输  出  : NONE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
VOID  bspIntVectorDisable (ULONG  ulVector)
{
    INTER_SET_MSK((1u << ulVector));
}
/*********************************************************************************************************
** 函数名称: bspIntVectorIsEnable
** 功能描述: 检查指定的中断向量是否使能
** 输  入  : ulVector     中断向量
** 输  出  : LW_FALSE 或 LW_TRUE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
BOOL  bspIntVectorIsEnable (ULONG  ulVector)
{
    return  (INTER_GET_MSK((1u << ulVector)) ? LW_FALSE : LW_TRUE);
}
/*********************************************************************************************************
** 函数名称: bspIntVectorSetPriority
** 功能描述: 设置指定的中断向量的优先级
** 输  入  : ulVector     中断向量号
**           uiPrio       优先级
** 输 出  : ERROR CODE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
#if LW_CFG_INTER_PRIO > 0

ULONG   bspIntVectorSetPriority (ULONG  ulVector, UINT  uiPrio)
{
    return  (ERROR_NONE);
}
/*********************************************************************************************************
** 函数名称: bspIntVectorGetPriority
** 功能描述: 获取指定的中断向量的优先级
** 输  入  : ulVector     中断向量号
**           puiPrio      优先级
** 输 出  : ERROR CODE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
ULONG   bspIntVectorGetPriority (ULONG  ulVector, UINT  *puiPrio)
{
    *puiPrio = 0;
    return  (ERROR_NONE);
}

#endif                                                                  /*  LW_CFG_INTER_PRIO > 0       */
/*********************************************************************************************************
** 函数名称: bspIntVectorSetTarget
** 功能描述: 设置指定的中断向量的目标 CPU
** 输 入  : ulVector      中断向量号
**           stSize        CPU 掩码集内存大小
**           pcpuset       CPU 掩码
** 输 出  : ERROR CODE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
#if LW_CFG_INTER_TARGET > 0

ULONG   bspIntVectorSetTarget (ULONG  ulVector, size_t  stSize, const PLW_CLASS_CPUSET  pcpuset)
{
    return  (ERROR_NONE);
}
/*********************************************************************************************************
** 函数名称: bspIntVectorGetTarget
** 功能描述: 获取指定的中断向量的目标 CPU
** 输 入  : ulVector      中断向量号
**           stSize        CPU 掩码集内存大小
**           pcpuset       CPU 掩码
** 输 出  : ERROR CODE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
ULONG   bspIntVectorGetTarget (ULONG  ulVector, size_t  stSize, PLW_CLASS_CPUSET  pcpuset)
{
    LW_CPU_ZERO(pcpuset);
    LW_CPU_SET(0, pcpuset);
    return  (ERROR_NONE);
}

#endif                                                                  /*  LW_CFG_INTER_TARGET > 0     */

四.其他异常的处理流程

1.进入异常时的上下文保存。可返回类型的异常的返回
2.未定义异常与FPU的关系
3.异常产生时的信息分析

未定义异常与FPU

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-03-06 13:17:11  更:2022-03-06 13:17:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 8:52:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码