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

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.  
  3. 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.  
  4. 这里的priority是0,1,2,3.函数内部会自动移位到对应的优先级最高2位:

  5. 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.  
  6. 3. IRQLATENCY的8位信号可以控制中断等待:设置为0,则以最快速度响应中断。

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

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

系统异常的控制寄存器

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

CMSIS->SHPR2,SHPR3

 
  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而言处理都一样,所以这里引用如下:

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 《The Definitive Guide to ARM Cortex-M0 and Cortex-M0+ Processors (2nd Edition)》是一本权威的指南,旨在深入介绍ARM Cortex-M0和Cortex-M0+处理器的原理和应用。 这本书的第二版对第一版进行了全面修订和更新,以反映最新的技术发展。它面向的读者包括学生、工程师和嵌入式系统开发人员,完全涵盖了ARM Cortex-M0和Cortex-M0+处理器的所有方面。 第二版首先从处理器的基础知识开始,介绍了ARM架构和处理器核心的基本概念。它详细解释了指令集、寄存器、内存管理单元和中断处理等关键组件的功能和作用。 接下来,该书深入探讨了由ARM Cortex-M0和Cortex-M0+处理器支持的编程模型和开发工具。它提供了大量的示例代码和实际应用案例,帮助读者更好地理解如何编写高效的嵌入式软件。 此外,该书还介绍了处理器的性能特征、能源管理、调试技术和硬件外设等方面的内容。读者可以了解到如何最大限度地利用ARM Cortex-M0和Cortex-M0+处理器的特性,提升系统的性能和效率。 总的来说,这本书是学习和使用ARM Cortex-M0和Cortex-M0+处理器的最佳指南。它通过清晰的解释、丰富的示例和实用的技巧,帮助读者掌握这些处理器的核心知识和开发技能。无论是初学者还是有经验的开发人员,都会从中受益,并能够更好地应用ARM Cortex-M0和Cortex-M0+处理器来开发高质量的嵌入式系统。 ### 回答2: 《The Definitive Guide to ARM Cortex-M0 and Cortex-M0 Processors》(第二版)是一本关于ARM Cortex-M0和Cortex-M0处理器的权威指南。它提供了深入的理解和学习这些处理器的各个方面和功能。 本书首先介绍了ARM Cortex-M0和Cortex-M0处理器的基础知识,包括其体系结构、指令集和寄存器等。读者可以通过这些基本概念来建立对这些处理器的整体理解。 接着,书中详细讲解了ARM Cortex-M0和Cortex-M0处理器的内部工作原理和特性。它解释了处理器的各个组成部分,例如ALU、寄存器文件、内存管理单元等,以及它们如何协同工作来执行指令和管理资源。读者可以通过深入理解处理器的内部机制,从而更好地编写和优化相关的代码。 此外,本书还介绍了软件开发工具和环境,为读者提供了使用ARM Cortex-M0和Cortex-M0处理器进行软件开发的基本知识。它涵盖了编程语言、编译器、仿真器和调试器等方面的内容,使读者能够充分利用这些工具来开发高效且可靠的嵌入式系统。 《The Definitive Guide to ARM Cortex-M0 and Cortex-M0 Processors》(第二版)还提供了大量的实例和案例研究,帮助读者更好地应用所学知识。此外,还提供了一些实用的技巧和技术,帮助读者避免常见的错误和问题,并提供了优化代码和系统性能的建议。 总之,本书是一本非常有价值的学习资料,适用于对ARM Cortex-M0和Cortex-M0处理器感兴趣的学生、工程师和研究人员。通过阅读本书,读者可以获得深入的理解和应用这些处理器的能力,从而更好地进行嵌入式系统开发。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值