[应用相关] 阅读stm32m3架构编程手册随笔

[复制链接]
101|0
Puchou 发表于 2025-11-7 07:36 | 显示全部楼层 |阅读模式
最近在研究freeRTOS的最小实现的代码,于是遇到了一堆“怪物”如下:

48414690c40496074f.png

搞得我血压升高,满脸不适,于是过了一天我便想办法弄来了一本内核宝典,想要把它研究清楚。

首先,翻开编程手册的目录页:

44431690c4044d1257.png

一. 目录

第一章节主要围绕文档介绍:1.排版规范 2.寄存器的缩写列表 3.stm32m3处理器及其核心外设(重点,有三个:1,nvic中断向量控制器 2.scb系统控制块 3.systimer系统定时器)

第二章节主要围绕着cortex-m3处理器:1.编程模型 2.存储模型 3.异常模型 4 故障处理(故障时异常的子集)5.电源管理

第三章节主要围绕着cortex-m3处理器的指令集:1.指令集概要 2.内建函数(用以解决anis无法直接执行的一些cortex-m3的一些指令)3.关于指令说明  4.内存访问指令 5.基本的数据处理指南(guide你使用一些命令) 6.乘除的数据处理指南 7.饱和指令 8.位域指令 9.其他说明的介绍

第四章节主要围绕cortex-m3 核心的寄存器:1.关于stm32核心外设 2.mpu内存保护单元 3.nvic中断向量控制器 4.scb系统控制块 5.systick timer系统时钟定时器

二.第一章节

        跳过1.1和1.2章节,我们来到了1.3部分,出现了一幅图主要是描述为内核服务的系统组件

69658690c403f9b344.png

他们分别是: 1.​​Bus Matrix​ 内核通过此矩阵访问 SRAM、外设、调试接口等,相当于内核的​​                                    交通调度中心​​。

                       2.​​Code Interface​ 内核从此接口​​获取指令​​(从Flash加载程序代码)

                       3.Debug Access Port 调试器通过此接口​​暂停/控制内核​​,查看寄存器状态

                       4.Data Watchpoints​ 监视内核访问的​​指定内存地址​​(如变量),触发调试事件

                       5.​​Flash Patch​ 在调试时​​动态修改Flash中的代码​​,绕过内核执行的原始指令

                       6.​​SRAM Interface 内核通过此接口读写​​运行时数据​​(变量、堆栈)

        2.接下来就讲了一些这个处理器的有点,像是高代码密度等待,然后就到了重要的部分:核心外设

         56725690c4039af8ff.png

三.第二章 Cortex-M3处理器

        文章一开始就介绍了以下Cortex-M3处理器有两种处理器模式和两级软件执行权限

12884690c4033d24c2.png

     两种模式即线程模式和中断模式,这个不用解释。

     两个特权模式即有特权和无特权,无特权模式的限制有 1.只能有限地去执行MSR和MRS指令并且不能使用CPS指令 2.不能访问系统定时器 NVIC SCB 3.严格限制访问内存和外设 (一般在单片机上电复位 ​​OS内核运行都是特权模式,但是用户任务​是非特权模式 主要是为了隔离保护,防止任务破坏核心资源​)

      另外这个特权模式的切换主要是在CONTROL寄存器进行的。

98841690c402c03e12.png

        如上图所示,位0是用来切换特权/非特权模式。

        在结尾提到非特权模式如果想要切换特权模式可以使用svc指令触发svc中断来修改CONTROL寄存器。

        2.1.2 又讲了Stack,说处理器使用可一个完全递减时的栈,意味着栈指针一直指向最后一个栈项目,处理器实现了两个独立的栈(主栈和进程栈),选择可参考上面的CONTROL寄存器,但注意中断只能选择主栈,如下图所示:

63985690c40276d82a.png

        2.1.3是核心寄存器

         86195690c402352b4d.png

        以上需要**,三个大类,一类是通用寄存器(0-12),一类是中间的栈指针、链接寄存器,程序计数器,最后是特殊寄存器。

        接下来,我将开始从通用寄存器开始介绍。

       1.通用寄存器中 R14,R12,R3,R2,R1,R0具有会自动保存到任务栈中的功能但是R4~R11需要保存。

        2. Link Register 存储着返回的子程序调用、函数调用和异常的信息,复位的时候值为0xFFFFFFFF

        示例如下:

        main:                           ; 主函数

        MOV R0,        #1         ;R0 = 1

        MOV R1,        #2         ; R1 = 2 BL add_func ;

        调用 add_func → **自动保存返回地址到 LR** ... ; 返回后继续执行此处 add_func: ; 加法函数 ADD R0, R0, R1 ; R0 = R0 + R1 BX LR ; **跳回 LR 保存的地址** → 返回 main

        3.Program counter 这个存储的是当前程序的地址,访问必须是半字对齐,复位以后在0x00000004这个地址

         接下来轮到特殊寄存器

        1.PSR 程序状态寄存器

         30419690c401c3206b.png

        可以看出这个psr是由apsr ipsr 和 espr拼凑而成互相之间不干扰。初次之外开可以用msr等指令自行组成自定义的寄存器,类型如下



         68854690c40165dac8.png

        接下来将列出apsr ipsr epsr

        1.apsr(application program status register)

39999690c401107448.png

        2.ipsr(interrupt program status register)

    41639690c400a41cfc.png    

        3.execution program status register

         88902690c40021a46c.png

        ICI:这是stm32精华所在,当程序进行r1到r12的保存任务的时候,出现了中断,这个时候i有ci就会在epsr[15:12]标记下一个要执行的状态r3,这样就能在中断返回的时候继续加载r3以后的操作,这也是stm32相较于esp32在实时性的一个优势。

        接下来就到了异常掩码寄存器类(PRIMASK FAULTMASK BASEPRI CONTROL),他们的应用场景很广阔,比如:CAN 总线通信(位定位) 电机换向(MOSFET开关) 数字电源控制(PWM 占空比更新)
————————————————
版权声明:本文为CSDN博主「Gary Studio」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_73991989/article/details/148953069

您需要登录后才可以回帖 登录 | 注册

本版积分规则

97

主题

300

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部