Cortex-M0【中断向量表】【中断控制和系统控制】【硬件错误后仿真器的作用】

Cortex-M0中断向量表

__Vectors       DCD     __initial_sp              ; Top of Stack
                DCD     Reset_Handler             ; Reset Handler
                DCD     NMI_Handler               ; NMI Handler
                DCD     HardFault_Handler         ; Hard Fault Handler
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     SVC_Handler        ; SVCall Handler
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     PendSV_Handler   ; PendSV Handler
                DCD     SysTick_Handler   ; SysTick Handler

下文摘录于:http://blog.csdn.net/fervor_heart/article/details/8288914

这里向前辈敬礼!

NMI (Non Maskable Interrupt)——不可屏蔽中断(即CPU不能屏蔽)

无论状态寄存器中 IF 位的状态如何,CPU收到有效的NMI必须进行响应;NMI是上升沿有效;中断类型号固定为2;它在被响应时无中断响应周期.不可屏蔽中断通常用于故障处理(如:协处理器运算出错,存储器校验出错,I/O通道校验出错等).

  IF = Interrupt Flag(中断状态)  在DSP等学习中NMI解释同样为“不可屏蔽中断”,其英文解释为“External Non-Maskable Interrupt”

下文摘录于:http://blog.csdn.net/guozhongwei1/article/details/49544671

这里向前辈敬礼!

SVC和PendSV

SVC(系统服务调用,亦简称系统调用)和PendSV(可悬起系统调用),它们多用于在操作系统之上的软件开发中。SVC 用于产生系统函数的调用请求。例如,操作系统不让用户程序直接访问硬件,而是通过提供一些系统服务函数,用户程序使用SVC 发出对系统服务函数的呼叫请求,以这种方法调用它们来间接访问硬件。因此,当用户程序想要控制特定的硬件时,它就会产生一个SVC 异常,然后操作系统提供的SVC 异常服务例程得到执行,它再调用相关的操作系统函数,后者完成用户程序请求的服务。 
这种“提出要求——得到满足”的方式,很好、很强大、很方便、很灵活、很能可持续发展。首先,它使用户程序从控制硬件的繁文缛节中解脱出来,而是由OS 负责控制具体的硬件。第二,OS 的代码可以经过充分的测试,从而能使系统更加健壮和可靠。第三,它使用户程序无需在特权级下执行,用户程序无需承担因误操作而瘫痪整个系统的风险。第四,通过SVC 的机制,还让用户程序变得与硬件无关,因此在开发应用程序时无需了解硬件的操作细节,从而简化了开发的难度和繁琐度,并且使应用程序跨硬件平台移植成为可能。开发应用程序唯一需要知道的就是操作系统提供的应用编程接口(API),并且了解各个请求代号和参数表,然后就可以使用SVC 来提出要求了(事实上,为使用方便,操作系统往往会提供 
一层封皮,以使系统调用的形式看起来和普通的函数调用一致。各封皮函数会正确使用SVC指令来执行系统调用——译者注)。其实,严格地讲,操作硬件的工作是由设备驱动程序完成的,只是对应用程序来说,它们也是操作系统的一部分。如图7.14 所示 
 
SVC 异常通过执行”SVC”指令来产生。该指令需要一个立即数,充当系统调用代号。SVC异常服务例程稍后会提取出此代号,从而解释本次调用的具体要求,再调用相应的服务函数。例如,

SVC 0x3 ; 调用3 号系统服务
  • 在SVC 服务例程执行后,上次执行的SVC 指令地址可以根据自动入栈的返回地址计算出。找到了SVC 指令后,就可以读取该SVC 指令的机器码,从机器码中萃取出立即数,就获知了请求执行的功能代号。如果用户程序使用的是PSP,服务例程还需要先执行
MRS Rn,PSP

指令来获取应用程序的堆栈指针。通过分析LR 的值,可以获知在SVC 指令执行时,正在使用哪个堆栈。 
由CM3 的中断优先级模型可知,你不能在SVC 服务例程中嵌套使用SVC 指令(事实上这样做也没意义),因为同优先级的异常不能抢占自身。这种作法会产生一个用法fault。同理,在NMI 服务例程中也不得使用SVC,否则将触发硬fault。

PendSV: 
另一个相关的异常是PendSV(可悬起的系统调用),它和SVC 协同使用。一方面,SVC异常是必须立即得到响应的(若因优先级不比当前正处理的高,或是其它原因使之无法立即响应,将上访成硬fault——译者注),应用程序执行SVC 时都是希望所需的请求立即得到响应。另一方面,PendSV 则不同,它是可以像普通的中断一样被悬起的(不像SVC 那样会上访)。OS 可以利用它“缓期执行”一个异常——直到其它重要的任务完成后才执行动作。悬起PendSV 的方法是:手工往NVIC 的PendSV 悬起寄存器中写1。悬起后,如果优先级不够高,则将缓期等待执行。 
PendSV 的典型使用场合是在上下文切换时(在不同任务之间切换)。例如,一个系统中有两个就绪的任务,上下文切换被触发的场合可以是:

  • 执行一个系统调用
  • 系统滴答定时器(SYSTICK)中断,(轮转调度中需要) 
    举个简单的例子来辅助理解。假设有这么一个系统,里面有两个就绪的任务,并且通过SysTick 异常启动上下文切换。如图7.15 所示。 

    上图是两个任务轮转调度的示意图。但若在产生SysTick 异常时正在响应一个中断,则SysTick 异常会抢占其ISR。在这种情况下,OS 不得执行上下文切换,否则将使中断请求被延迟,而且在真实系统中延迟时间还往往不可预知——任何有一丁点实时要求的系统都决不能容忍这种事。因此,在CM3 中也是严禁没商量——如果OS 在某中断活跃时尝试切入线程模式,将触犯用法fault 异常。 

    为解决此问题,早期的OS 大多会检测当前是否有中断在活跃中,只有没有任何中断需要响应时,才执行上下文切换(切换期间无法响应中断)。然而,这种方法的弊端在于,它可以把任务切换动作拖延很久(因为如果抢占了IRQ,则本次SysTick 在执行后不得作上下文切换,只能等待下一次SysTick 异常),尤其是当某中断源的频率和SysTick 异常的频率比较接近时,会发生“共振”。 
    现在好了,PendSV 来完美解决这个问题了。PendSV 异常会自动延迟上下文切换的请求,直到其它的ISR 都完成了处理后才放行。为实现这个机制,需要把PendSV 编程为最低优先级的异常。如果OS 检测到某IRQ 正在活动并且被SysTick 抢占,它将悬起一个PendSV 异常,以便缓期执行上下文切换。如图7.17 所示 

    个中事件的流水账记录如下:

    1. 任务 A 呼叫SVC 来请求任务切换(例如,等待某些工作完成)
    2. OS 接收到请求,做好上下文切换的准备,并且pend 一个PendSV 异常。
    3. 当 CPU 退出SVC 后,它立即进入PendSV,从而执行上下文切换。
    4. 当 PendSV 执行完毕后,将返回到任务B,同时进入线程模式。
    5. 发生了一个中断,并且中断服务程序开始执行
    6. 在 ISR 执行过程中,发生SysTick 异常,并且抢占了该ISR。
    7. OS 执行必要的操作,然后pend 起PendSV 异常以作好上下文切换的准备。
    8. 当 SysTick 退出后,回到先前被抢占的ISR 中,ISR 继续执行
    9. ISR 执行完毕并退出后,PendSV 服务例程开始执行,并且在里面执行上下文切换
    10. 当 PendSV 执行完毕后,回到任务A,同时系统再次进入线程模式。

Cortex-M0中断控制和系统控制 

本文摘录于:http://blog.csdn.net/jasenmaodj/article/details/46941605

版权归原作者所有,这里向前辈致敬!

一. NVIC和系统控制块特性

  1. 1. 灵活的中断管理:使能/禁止中断,优先级配置

  2. 2. 硬件嵌套中断支持

  3. 3. 向量化的异常入口

  4. 4. 中断屏蔽

  5. 5. NVIC寄存器的起始地址:0xE000E100, 对其访问必须是每次32bit

  6. 6. SCB的起始地址: 0xE000E010,也是每次32bit访问。

二. 中断使能和清除使能

   1. 中断寄存器是可编程的,用于控制中断请求(异常编号16以上)的使能(SETENA)和禁止(CLRENA), 如下所示:

这里说一下:

对于ARM M0而言,SysTick_Handler是第15号中断,从16号开始是NVIC所控制的外部中断,最多只能有32个外部中断

  1. 2. 使能/禁止 中断的代码:

  2. 1). C代码:

  1. *(volatile unsigned long) (0xE000E100) = 0x4 ; //使能#2中断

  2. *(volatile unsigned long) (0xE000E180) = 0x4 ; //禁止#2中断

       2). 汇编代码:
  • LDR R0, =0xE000E100 ; //SETEAN寄存器的地址
  1. MOVS R1, #04 ; //设置#2中断

  2. STR R1, [R0] ; //使能中断#2

       3). CMSIS标准设备驱动函数:
  1. void NVIC_EnableIRQ(IRQn_Type_IRQn); //使能中断#IRQn;

  2. void NVIC_DisableIRQ(IRQn_Type_IRQn); //禁止中断#IRQn;

三. 中断挂起和清除挂起:

   1. 可以通过操作中断挂起(SETPEND)和清除挂起(CLRPEND),这两个寄存器来访问和修改中断挂起状态。

如果软件配置挂起中断就是软中断的实现!

  1. 2.挂起/清除挂起的代码:

  2. 1). C代码:

  1. *(volatile unsigned long)(0xE000E100) = 0x4 ; //使能中断#2

  2. *(volatile unsigned long)(0xE000E200) = 0x4 ; // 挂起中断#2

  3. *(volatile unsigned long)(0xE000E280) = 0x4 ; // 清除中断#2的挂起状态

        2). 汇编代码:
  1. LDR R0, =0xE000E100 ; //设置使能中断寄存器地址

  2. MOVS R1, #0x4 ; //中断#2

  3. STR R1, [R0] ; //使能#2中断

  4. LDR R0, =0xE000E200 ; //设置挂起中断寄存器地址

  5. MOVS R1, #0x4 ; //中断#2

  6. STR R1, [R0] ; //挂起#2中断

  7. LDR R0, =0xE000E280 ; //设置清除中断挂起寄存器地址

  8. MOVS R1, #0x4 ; //中断#2

  9. STR R1, [R0] ; //清除#2的挂起状态

        3). CMSIS标准设备驱动函数:
  1. void NVIC_SetPendingIRQ(IRQn_Type_IRQn) ; //设置一个中断挂起

  2. void NVIC_ClearPendingIRQ(IRQn_Type_IRQn); //清除中断挂起

  3. void NVIC_GetPendingIRQ(IRQn_Type_IRQn) ; //读取中断挂起状态

四. 中断优先级:(0xE000E400~0xE000E41C)

  1. 1. 每个外部中断都有一个对应的中断有先级寄存器,每个优先级都是只有一个字节且只有最高2Bit有效;

  2. 2. NVIC支持字传输,所以每次访问都会涉及4个中断优先级寄存器。

也就是说ARM MO只是支持四级优先级,并且高优先级中断能够打断低优先级中断。

  1. 3. 设置中断优先级代码:(先读一个字,再修改对应字节,最后整个字写回)

  2. 1). C代码:

  • unsigned long temp; //定义一个临时变量
  1. temp = *(volatile unsigned long)(0xE000E400); //读取IRP0值

  2. temp &= (0xFF00FFFF |(0xC0 << 16)); //修改中断#2优先级为0xC0

  3. *(volatile unsigned long)(0xE000E400) = temp; //设置IPR0

        2). 汇编代码:
  • LDR R0, =0xE000E100 ; //设置使能中断寄存器地址
  1. MOVS R1, #0x4 ; //中断#2

  2. STR R1, [R0] ; //使能#2中断

  3. LDR R0, =0xE000E200 ; //设置挂起中断寄存器地址

  4. MOVS R1, #0x4 ; //中断#2

  5. STR R1, [R0] ; //挂起#2中断

  6. LDR R0, =0xE000E280 ; //设置清除中断挂起寄存器地址

  7. MOVS R1, #0x4 ; //中断#2

  8. STR R1, [R0] ; //清除#2的挂起状态

        3). CMSIS标准设备驱动函数:
  1. void NVIC_SetPriority(IRQn_Type_IRQn, uint32_t priority) ; //设置中断优先级

  2. uint32_t NVIC_GetPriority(IRQn_Type_IRQn); //读取中断优先级

  3. 这里的priority是0,1,2,3.函数内部会自动移位到对应的优先级最高2位:

  4. void NVIC_SetPriority(2, 3) ; //设置#2中断的优先级为0xC0

SYD8801设置中断优先级的方法如下:

NVIC_SetPriority(GPIO_IRQn, 3);
    NVIC_SetPriority(UART0_IRQn, 0);

五. 异常屏蔽寄存器(PRIMASK)

  1. .对时间敏感的应用,需要用PRIMASK来屏蔽掉除NMI和硬件错误异常以外的其他所有中断和异常。

  2. 2.PRIMASK只有1Bit有效,默认为0,为1时起屏蔽作用。

  3. 3.操作PRIMASK的代码:

  4. 1). 汇编代码:

  1. MOVS R0, #1 ;

  2. MSR PRIMASK, R0 ; //使用MSR指令设置PRIMASK值

  2). CPS指令:
  1. CPSIE i ; //清除PRIMASK值

  2. CPSID i ; //设置PRIMASK值

  3). CMSIS标准设备驱动函数:
  1. void _enable_irq(void) ; //清除PRIMASK值

  2. void _disable_irq(void) ; //设置PRIMASK值

六. 中断输入和挂起行为

  1. 1. Cortex-M0允许电平触发和脉冲触发两种方式;

  2. 2. 每个外部中断请求都会对应一个挂起状态寄存器,且只有1bit,当开始处理这个异常时,硬件会自动清除挂起状态;

  3. 3. 大多数外设都是使用电平触发,当执行中断服务程序并且清除外设中断信号之前,该信号一直为高:

4. 使用脉冲触发中断时,至少持续1个时钟周期:

七. 中断等待 (中断确认 –> 中断服务处理开始执行)

  1. 1. Cortex-M0中断默认等待的时间为16个时钟周期;

  2. 2. 中断等待的条件:

  3. 1). 改中断使能并且没有被PRIMASK屏蔽掉;

  4. 2). 存储器系统没有任何等待。

  5. 3. IRQLATENCY的8位信号可以控制中断等待:设置为0,则以最快速度响应中断。

八. 系统异常的控制寄存器(SHPR2,SHPR3)

1. Cortex-M0处理器只有SVC、PendSV和SysTick 3个与OS相关的系统异常才具有可编程的 优先级

2. 符合CMSIS的设备驱动,可使用如下方式访问:

  1. 3. 中断控制状态寄存器(ICSR, 0xE000ED04):

  2. P139, 表9.6

  3. 4. 符合CMSIS的设备驱动,可使用 "SCB -> ICRS" 来访问。

九. 系统控制寄存器(0xE000E000~0xE000EFFF)

  1. 1. SCS包括NVIC、调试控制、SysTick定时器;

  2. 2. CPU ID基址寄存器(0xE000ED00),只读,包含处理器ID信息,"SCB -> CPUID" 访问;

  3. 3. 应用中断和复位控制寄存器(AIRCR, 0xE000ED0C):

  4. 1). 用于应用程序请求系统复位,识别系统的大小端,以及清除所有的异常活动状态:

  1. 2). CMSIS 设备驱动,可以使用 "SCB -> AIRCR" 来访问;

  2. 3). CMSIS 设备驱动, 请求系统复位的函数:

             Void NVIC_SystemReset(void);

十. 配置和控制寄存器(CCR, 0xE000ED14)

  1. 1. CCR 只读, 决定了栈的双字节对齐设置和非对称访问的处理;

  2. 2. CMSIS 设备驱动,可以使用 "SCB -> CCR" 来访问;

硬件错误后仿真器的作用

M0内核在发生硬件错误后依旧会输出一些调试信息,以下内容摘录于:《Fundamentals_in_debugging_nRF5x_systems - Hard Fault on nRF52.pdf》,因为对于M0而言处理都一样,所以这里引用如下:

Cortex-M0(5)---Cortex-M0【中断向量表】【中断控制和系统控制相关推荐

  1. Cortex M3 NVIC与中断控制

    Cortex M3 NVIC与中断控制 宗旨:技术的学习是有限的,分享的精神是无限的. 一.NVIC概览 --嵌套中断向量表控制器 NVIC 的寄存器以存储器映射的方式来访问,除了包含控制寄存器和中断 ...

  2. 软件和硬件都是对生活的高度抽象---论中断控制(ARM体系编程)

    不同的芯片体系设计在集成电路系统设计阶段其实都遵循大体一致的设计思想,芯片设计发展那么多年,真正为人所熟知的就是X86架构和ARM架构,当然还有日渐没落的MIPS,其他都是一些简单的控制器芯片体系.而 ...

  3. 定时器中断控制LED闪烁(每隔1s)---普中科技开发仪

    定时器中断o,利用中断控制LED闪烁每隔1s闪烁一次(精确的1s) notes: (1)工作方式寄存器TMOD ,低四位用于To,高四位用于T1,(GATE,C/T- ,M1,M0) 一般让GATE ...

  4. Cortex-M3 NVIC与中断控制

    一.NVIC概览 --嵌套中断向量表控制器 NVIC 的寄存器以存储器映射的方式来访问,除了包含控制寄存器和中断处理的控制逻辑之外, NVIC 还包含了 MPU. SysTick 定时器以及调试控制相 ...

  5. STM32之中断控制LED灯

    STM32中断控制LED灯 一.中断 1. 中断地址 2. 中断优先级 3. 中断响应过程 二.新建工程 三.编写代码 四.运行结果 五.总结 参考 一.中断 在处理器中,中断是一个过程,即CPU在正 ...

  6. 微型计算机原理中断实验,微机原理实验---中断控制实验.doc

    微机原理实验---中断控制实验 深 圳 大 学 实 验 报 告 课程名称: 微机计算机设计 实验项目名称: 8259 中断控制实验 学院: 信息工程学院 专业: 电子信息工程 指导教师: 报告人: 学 ...

  7. CC2530基础实验:(2)外部中断控制LED亮灭

    目录 前言 一.实验相关电路图 二.实验相关理论与寄存器 1.中断相关的基础概念 2.CC2530 的中断系统 3.CC2530 的中断处理函数编写方法 4.CC2530 的外部中断 三.源码分析 前 ...

  8. 用51单片机中断控制LED灯亮灭

    用51单片机中断控制LED灯亮灭 #include<reg51.h>//头文件 sbit LED=P2^0;//位定义LED灯 sbit k3=P3^2;//位定义按键 void dela ...

  9. 应广单片机PFS123按键中断控制数码管显示例程

    目录 应广单片机PFS123按键中断控制数码管显示视频 led数码管图片 应广单片机PFS123按键中断控制数码管显示代码 应广科技网址,开发工具,PMS123规格书:http://www.padau ...

最新文章

  1. CodeForces - 1324F Maximum White Subtree(树形dp)
  2. java的int、char、long、float、double对byte的转换,在通信的时候会用到
  3. java pojo 是什么_什么是POJO
  4. 你敢在post和get上刁难我,就别怪我装逼了
  5. eclise去连接mysql,Eclipse如何连接MySQL
  6. Python自动化运维开发----基础(十二)函数
  7. 使用CucumberJS,让JavaScript与行为驱动开发结合
  8. 软件测试文档类型有哪些?
  9. 【博弈论】耶鲁大学公开课--博弈论Problem Set 1--Solution
  10. 给系统闹钟设置时间Alarm
  11. 多态 继承 封装 打印输出长方形 正方形 圆形的周长和面积
  12. linux 安装守护进程supervisor
  13. 漏洞分析丨HEVD-0x6.UninitializedStackVariable[win7x86]
  14. POJ No. 3253 Fence Repair
  15. 小程序canvas文字信息绘制图片,模拟器正常保存图片,真机无法保存图片报错downloadFile:fail downloadFile protocol must be http or https
  16. 全球主要的域名争议解决机构有哪些?
  17. Unity实现众多平台一键社会化分享(ShareSDK)
  18. Java web学习day12 Cookie
  19. TSINGSEE青犀视频再度荣获腾讯云+社区2022年度优秀作者!
  20. python基础之Requests库

热门文章

  1. 查看云服务器系统的命令,查看云服务器系统的命令
  2. 嵌入式实时操作系统Ucos3
  3. libev源码分析(一)libev数据结构整理
  4. CAN 总线嵌入式驱动编程
  5. mysql建立修改表存储过程_MySQL数据库创建、表的创建、存储过程、触发器
  6. Linux服务器备份mySQL数据库_远程linux服务器mysql数据库定期备份和删除
  7. 计算机专业自我总结1000字,计算机专业自我鉴定范文1000字
  8. mysql 存在也插入_Mysql 不存在则插入,存在则更新
  9. python编写排列组合,密码生产功能
  10. 枚举类型的用法 很不错的定义不同类型的工具