打印
[其他]

(分享) Cortex-M0中断控制和系统控制(四)

[复制链接]
5617|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 两只袜子 于 2021-8-9 09:35 编辑

Cortex-M0系统控制块(SCB)是内核外设的主要模块之一,提供系统控制以及系统执行信息,包括配置,控制,上报系统异常等。


为了提高软件效率,CMSIS简化了SCB寄存器表示,在CMSIS中系统控制寄存器结构体:typedef struct
{
    __IM  uint32_t CPUID; /*!< Offset: 0x000 (R/ )  CPUID Base Register */
    __IOM uint32_t ICSR;  /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register */
    uint32_t RESERVED0;
    __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register */
    __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W)  System Control Register */
    __IOM uint32_t CCR; /*!< Offset:0x014 (R/W) Configuration Control Register */
    uint32_t RESERVED1;
    __IOM uint32_t SHP[2U];/*!< Offset: 0x01C (R/W)  System Handlers Priority Registers. [0] is RESERVED */
    __IOM uint32_t SHCSR;  /*!< Offset: 0x024 (R/W)  System Handler Control and State Register */
} SCB_Type;01CPUID







使用特权

评论回复
沙发
两只袜子|  楼主 | 2021-8-9 09:30 | 只看该作者
CPUID基地址寄存器包含处理器型号、版本等相关信息,是只读的,可以通过应用软件、调试器和烧录器等获取处理器的类型和版本信息。
Address: 0xE000ED00
Reset value: 0x410CC200

使用特权

评论回复
板凳
两只袜子|  楼主 | 2021-8-9 09:31 | 只看该作者
这个地方CPUID与我们经常提到的MCU的96位UID不同,CPUID是处理器的ID号,由ARM提供并实现,通过CPUID可以知道内核型号及版本等信息。而96位UID是MCU产品ID,属于MM32,由上海灵动微电子股份有限公司提供并按照一定的规则实现,96位的产品唯一身份标识所提供的参考号码对任意一个系列微控制器,在任何情况下都是唯一的。用户在何种情况下,都不能修改这个身份标识。

MCU还有一个DEV_ID编码,这个ID定义了MCU的器件号和硅片版本号,它是DBG_MCU的一个组成部分,并且映射到外部APB总线上。SW 调试口(2个引脚) 或通过用户代码都可以访问此编码。

DEV_ID地址:0x40013400 只支持32位访问,只读。

使用特权

评论回复
地板
两只袜子|  楼主 | 2021-8-9 09:32 | 只看该作者
本帖最后由 两只袜子 于 2021-8-9 09:34 编辑

在CMSIS驱动库中,可以直接使用“ SCB->CPUID ” 获取处理器ID。读取MM32F0130的CPUID、UID和DEV_ID如下所示:


CPUID (0x410CC200)解析处理器信息:



使用特权

评论回复
5
两只袜子|  楼主 | 2021-8-9 09:33 | 只看该作者
02

ICSR

(Interrupt Control and State Register)

提供:

NMI异常的设置挂起位

为PendSV和SysTick异常设置挂起和清除挂起位

表示:

正在处理的异常的异常编号

是否有被抢占的活动异常

最高优先级未决异常的异常编号

是否有任何中断待处理

Address: 0xE000ED04

Reset value: 0x0000 0000



ICSR中的某些控制位仅供调试使用,大多数情况下,应用程序只会用ICSR来控制或者检查系统异常挂起状态。

使用特权

评论回复
6
两只袜子|  楼主 | 2021-8-9 09:33 | 只看该作者
02

ICSR

(Interrupt Control and State Register)

提供:

NMI异常的设置挂起位

为PendSV和SysTick异常设置挂起和清除挂起位

表示:

正在处理的异常的异常编号

是否有被抢占的活动异常

最高优先级未决异常的异常编号

是否有任何中断待处理

Address: 0xE000ED04

Reset value: 0x0000 0000



ICSR中的某些控制位仅供调试使用,大多数情况下,应用程序只会用ICSR来控制或者检查系统异常挂起状态。

使用特权

评论回复
7
两只袜子|  楼主 | 2021-8-9 09:33 | 只看该作者
02

ICSR

(Interrupt Control and State Register)

提供:

NMI异常的设置挂起位

为PendSV和SysTick异常设置挂起和清除挂起位

表示:

正在处理的异常的异常编号

是否有被抢占的活动异常

最高优先级未决异常的异常编号

是否有任何中断待处理

Address: 0xE000ED04

Reset value: 0x0000 0000



ICSR中的某些控制位仅供调试使用,大多数情况下,应用程序只会用ICSR来控制或者检查系统异常挂起状态。

使用特权

评论回复
8
两只袜子|  楼主 | 2021-8-9 09:36 | 只看该作者
PendSV(可挂起的系统调用)异常对 OS 操作非常重要,其优先级可以通过编程设置。可以通过将中断控制和壮态寄存器 ICSR 的 bit28挂起位置1来触发PendSV中断。与SVC异常不同,它是不精确的,因此它的挂起状态可在更高优先级异常处理内设置,且会在高优先级处理完成后执行。利用该特性,若将PendSV设置为最低的异常优先级,可以让PendSV异常处理在所有其他中断处理完成后执行,这对于上下文切换非常有用,也是各种OS设计中的关键。在具有嵌入式OS的典型系统中,处理时间被划分为了多个时间片。

通过向中断控制和状态寄存器 ICSR 的 bit28 写入1挂起PendSV来启动PendSV中断,如果中断启用且有编写 PendSV 异常服务函数的话,则内核会响应 PendSV 异常,去执行PendSV 异常服务函数,这样就可以在PendSV中断服务函数中进行任务切换了。

使用特权

评论回复
9
两只袜子|  楼主 | 2021-8-9 09:38 | 只看该作者
03
AIRCR
(Application Interrupt and Reset Control Register)
AIRCR为数据访问和系统的复位控制提供字节序状态。

要写入该寄存器,您必须写入0x05FA VECTKEY 字段,否则处理器将忽略写入。
Address: 0xE000ED0C
Reset value: 0xFA05 0000

任何对该寄存器的写操作,都必须将0x05FA写入到AIRCR[30:16],否则写操作将无效,若需要半字读取,需要写入0xFA05。


使用特权

评论回复
10
两只袜子|  楼主 | 2021-8-9 09:39 | 只看该作者
应用程序中系统执行软复位函数:__STATIC_INLINE void NVIC_SystemReset(void)
{
    __DSB();  //确保所有未完成的内存访问包括缓冲写入在重置之前完成
    SCB->AIRCR  = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
                   SCB_AIRCR_SYSRESETREQ_Msk);
    __DSB();    //确保完成内存访问

    for(;;) /* wait until reset */
    {   
        __NOP();
    }
}
04
SCR
(System Control Register)
SCR 控制进入和退出低功耗状态的特性。
Address: 0xE000ED10
Reset value: 0x0000 0000


SCR(系统控制)寄存器可以选择使用立即休眠还是退出时休眠,当SCR寄存器的SLEEPONEXIT位为0的时候使用立即休眠,当为 1 的时候使用退出时休眠。

MM32F0130执行进入stop模式实现函数:void PWR_EnterSTOPMode(u32 regulator, u8 stop_entry)
{
    PWR->CR |= regulator;

    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;

    (stop_entry == PWR_STOPEntry_WFI) ? __WFI() : __WFE();
}
05
CCR
(Configuration and Control Register)
CCR 是只读寄存器,指示 Cortex-M0 处理器行为的某些方面。
Address: 0xE000ED14
Rese
t value: 0x0000 0204



SCB->CCR寄存器控制除数为零和未对齐内存访问是否触发用法HardFault。


使用特权

评论回复
11
两只袜子|  楼主 | 2021-8-9 09:41 | 只看该作者
06
SHPR
(System Handler Priority Registers)
因为在ARMv7-M架构上才有SHPR1,所以 Cortex – M0使用系统优先级寄存器只有SHPR2和SHPR3,而没有SHPR1。

SHPR2-SHPR3 寄存器设置具有可配置优先级的异常处理程序的优先级级别,从0到192。

SHPR2-SHPR3 是可字访问的。

要使用 CMSIS 访问系统异常优先级,可以使用CMSIS函数:uint32_t NVIC_GetPriority(IRQn_Type IRQn)
void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)

系统故障处理程序,以及每个处理程序的优先级字段和寄存器是:


6.1
SHPR2 (System Handler Priority Register 2)
Address: 0xE000ED1C
Reset value: 0x0000 0000


6.2
SHPR3 (System Handler Priority Register 3)
如果您的设备未实现 SysTick 计时器,则此字段为保留字段
Address: 0xE000 ED20
Reset value: 0x0000 0000

SVCall、PendSV和SysTick可编程的中断多用于在操作系统之上的软件开发中。SVC用于产生系统函数的调用请求,例如,操作系统不让用户程序直接访问硬件,而是通过提供一些系统服务函数,用户程序使用SVC发出对系统服务函数的呼叫请求,以这种方法调用它们来间接访问硬件。因此,当用户程序想要控制特定的硬件时,它就会产生一个SVC异常,然后操作系统提供的SVC异常服务例程得到执行,它再调用相关的操作系统函数,后者完成用户程序请求的服务。

另一个相关的异常是 PendSV,它和 SVC 协同使用。一方面, SVC异常是必须立即得到响应的(若因优先级不比当前正处理的高, 或是其它原因使之无法立即响应, 将上访成Hardfault),应用程序执行 SVC 时都是希望所需的请求立即得到响应。另一方面,PendSV则不同,它是可以像普通的中断一样被挂起的(不像SVC那样会上访)。OS可以利用它“延期执行”一个异常——直到其它重要的任务完成后才执行动作。挂起 PendSV 的方法是:程序中往NVIC的PendSV挂起寄存器中写 1。挂起后, 如果优先级不够高,则将延期等待执行。PendSV 的典型使用场合是在上下文切换时(在不同任务之间切换)。有两个就绪的任务,上下文切换被触发的场合可以是:
执行一个系统调用
系统滴答定时器(SysTick)中断,(轮转调度中需要)
ARMv7-M和ARMv6-M都有的SCB寄存器名称相同,但是ARMv7-M寄存器数量和有效控制bit位比ARMv6-M丰富了不少。一般来说,ARMv6-M向上兼容ARMv7-M,这意味着应用层和系统为ARMv6-M开发的级别软件无需修改即可在 ARMv7-M 上执行,这也是Arm从一个平台切换到另一个平台可以很快速的完成切换的原因,有兴趣深入研究可以参考《ARMv6-M Architecture Reference Manual》白皮书。











使用特权

评论回复
12
内政奇才| | 2021-8-16 13:20 | 只看该作者
学习了

使用特权

评论回复
13
zhanan| | 2023-1-24 16:16 | 只看该作者
MDK523,调试的时候,[View]-[System Viewer]-[Core Peripherals]-[System Control and Configuration] 弹出窗口
窗口里面显示 上面是SCB->SCR ,下面是 SCB->CCR,似乎是显示错了,上面的应该是CCR,下面的应该是SCR。
有注意到这个情况的吗?后来版本升级有没有改过来?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2038

主题

7363

帖子

10

粉丝