stm32和cortex M3学习内核简单总结
1.stm32综述
2.寄存器组
3.操作模式和特权级别
4.存储器映射
5.中断和异常
6.其他
Stm32综述
这可以说是我第一款认真学习的单片机了,学完这个就要开启我通往arm9的大门了,接下来把我学到的东西做一个系统的概述:
上图是stm32的系统结构。
使用哈弗体系结构,取指和取数据分离,
ICODE指令总线连接到flash闪存指令存储区,这个存储区的地址在0x00000000-0x1FFFFFFF之间,负责取指操作。
DCODE数据总线负责在0x00000000-0x1FFFFFFF之间的数据访问操作。这个数据存储区可以是SPRAM也可以是闪存和外设。
系统总线:负责在0x20000000-0xDFFFFFFF和0xE0100000-0xFFFFFFFF之间所有的数据传送。
注:看到这你可能会迷惑,M3内核不是只有指令总线和数据总线吗?对的,但是指令总线和ICODE指令总线不是一个,选取一张M3内核样例处理器的图就明白了:
个人理解,D-code总线和系统总线都是来源于M3内核引出的数据总线。
DMA通过总线矩阵直接和内存相连。
总线矩阵协调内核和DMA对SPRAM,闪存,外设的访问。
AHP总线桥接两个APB总线,两个APB总显得最高速度不同,APB1最高速度限于36MHz,APB2限于72MHz。两个APB总线上挂接着不同速率的设备。
Stm32f10系列的静态SPRAM为64K,起始地址为0x20000000.
Stm32的启动方式有以下几种:
下面的是stm32的时钟树,stm32有四个不同的时钟源:
1.HSE时钟:高速外部时钟信号,来自于外部晶振:可作为系统时钟源,也可被PLL倍频之后宫系统时钟使用。
2.HSI时钟:高速内部时钟信号,来自于内部RC振荡器:可直接作为系统时钟,或者二分频之后作为PLL输入,倍频之后供系统使用。
3.LSE时钟:低速外部时钟,来自于外部晶振:为定时时钟或者其他定时功能提供
4.LSI时钟:低速内部时钟,来自于内部RC振荡器:在停机或者待机的模式下,为独立看门狗或者自动唤醒单元提供时钟。
经过一些列倍频,分频得到了几个和开发有关的时钟:
1.SYSCLK:系统时钟大部分时钟的来源
2.HCLK:由AHB预分频器输出得到,高速总线AHB的时钟信号
3.FCLK:由AHB预分频器输出得到,自由运行时钟。
4.PCLK1:外设时钟,由APB1预分频器得到,最大36MHz
5.PCLK2:外设时钟,由APB2预分频器得到,最大72MHz
时钟树如下:
Stm32的GPIO的8种模式:
(1)GPIO_Mode_AIN 模拟输入
(2)GPIO_Mode_IN_FLOATING 浮空输入
(3)GPIO_Mode_IPD 下拉输入
(4)GPIO_Mode_IPU 上拉输入
(5)GPIO_Mode_Out_OD 开漏输出
(6)GPIO_Mode_Out_PP 推挽输出
(7)GPIO_Mode_AF_OD 复用开漏输出
(8)GPIO_Mode_AF_PP 复用推挽输出
4种输入:模拟输入和明显接受模拟信号,比如用于ADC,上拉输入和下拉输入就是默认时高电平和低电平。浮空输入在芯片内部既没有接上拉电阻也没有接下拉电阻,引脚电压是个不确定值,输入阻抗较大,常用语I2c,USART。
4种输出:分复用和非复用,复用为分配给片上外设,非复用为用作正常的IO口。推免输出为正常的输出,而在开漏输出模式,IO口可以由外部电路改变为低电平或不变。所以开漏模式可以读IO输入电平变化,实现C51的IO双向功能。
当年看不懂的东西,现在越发清晰。
寄存器组
这一部分就属于M3内核中的知识了。
M3内核中的寄存器主要如下:
下面挨个解释
M3使用的是双堆栈,复位之后默认使用MSP,默认是特权级,如果想要切换需要手动修改。而上面的MSP和PSP的用途只是一种推荐用途,并不是一定要那么用,比如说复位之后你可以不修改,那么你的常规代码就一直是特权级,使用MSP(我就是这样滴。。方便至上)。
这个寄存器又叫LR寄存器,那么当函数是一级调用的时候,就可以将返回地址直接存到LR中,省去了访问内存,提高了效率,当函数调用高于一级,则需将前面的LR中的值压栈,以便存储新的值。
当进入异常的时候,LR寄存器的值更新为特殊的EXE_RETURN:
就是PC嘛。。。。
特殊功能寄存器一定要在特权级才能被访问(使用MSR和MRS指令),至于是Thread 模式还是handler模式无所谓。
详细功能如下:
xPSR属于三合一寄存器,可以分出三个子状态寄存器
通过MRS和MSR这三个寄存器可以单独访问,也可以两两组合访问,也可以三合一访问,这个寄存器大致如下(看下就好):
其实除了修改上面的寄存器可以开关中断,M3还有专门的开关中断指令:
CONTROL寄存器功能如下:
操作模式和特权等级
操作模式分为Thread模式和Handler模式,特权等级分为特权级和用户级。用户的程序代码一定是Thread模式,而异常一定是handler模式,用户程序代码程序代码可以是特权级和用户级,但是异常只能是特权级。
Thread模式+用户级,就不能访问系统控制空间(SCS)和特殊寄存器(除了APSR)。
特权级切换到用户级很容易,修改下control寄存器就好,用户级切换到特权级的方式只有触发一个异常,切换到handler模式,这个时候是特权级,然后修改control寄存器的零位,再返回就是特权级。
下图是一个各种切换的示意图:
这种设定的大致用意就是我们写普通代码的时候设置为用户级,这样的话可以防止对SCS和特殊寄存器这种敏感地带的误操作,想要访问这些的话就只能通过进入handler模式一步步去访问,而且这样的话异常是特权级用MSP,普通的用户代码使用户级用PSP,不会出现数据意外互相干扰和破坏,这样的话整个系统的可靠性就会很好,当然我们写小程序的时候不必这么拘谨,反正我一般都是一直特权级小程序。
存储器映射
M3将内存分为8个主块,每块512MB,先上一张M3内核的存储器映射:
所谓的SCS如下:
所谓的位带就是将位带区的1bit膨胀为位带别名区的32bit也就是一个字,通过访问位带别名区就能达到访问这个bit的目的,优势如下:
当然位带还有一个明显的好处,就是在多任务的系统中,两个任务同时去修改一个共享寄存器其中的两个bit的话可能会出现“紊乱现象”,所以就需要将“读-改-写”三条指令加上临界区等手段,但是有了位段,M3直接去写那个bit的位带别名区就可以了,这样就成为了一个原子操作。
不过上面的图确实是粗线条,下面上芯片手册的详细图片一张:
M3有些数据传送指令支持非对齐数据传送,如LDR/LDRH/LDRSH。其他指令不支持。
对按字传送来说,任何一个不能被4整除的地址都是非对齐的。而对于板子,任何一个不能被2整除的地址都是非对齐的。
M3支持大端模式和小端模式,但是推荐使用小端模式。M3的大端模式是“字节不变大端”。
中断和异常
异常是指任何打断程序顺序执行的事件。在很多时候,中断和异常这两个概念是不做区分的,所以我以下也就不作区分了。
M3的异常系统简直就是它的精华所在。
M3的异常分为系统异常和外部中断。
系统异常如下(stm32沿用):
外部中断M3内核支持240个,stm32只使用其中60个:
所有的异常,除了复位,NMI,硬FAULT优先级为-3,-2,-1固定,剩下的都是可编程优先级。
优先级:
M3内核中优先级寄存器为8位,这8位不用全用到,最少用到3位(MSB对齐),stm32只用到其中高四位,所以stm32总共有16种优先级。
M3内核中对于外部中断有抢占优先级和响应优先级,高抢占优先级的中断可以打断低抢占优先级的中断。抢占优先级相同的两个中断同时到达,响应响应优先级高的中断。如果两个中断一切相同,那么响应序列号更小的那个。
因为外部中断的优先级寄存器总共八位,所以需要对其进行划分,响应优先级至少有一位,所以M3中外部中断抢占优先级最多其实是有128个而不是256个。下图是从bit5开始划分,总共用到三位设置优先级:
具体的芯片决定优先级用到多少位,以及从哪一位开始划分抢占和响应,stm32用到4位设置中断,有5种分组:组0从7bit划分(全部都是响应优先级),组1从6bit划分,组2从5bit划分,组3从4bit划分,组4从3bit划分(就是只用到抢占优先级)。
向量表:
当发生了异常需要响应的时候,M3需要定位其服务例程的入口地址,这些入口地址就存在所谓的“向量表”。缺省情况下,这张表存在0地址处(当然也可修改NVIC中的向量表偏移寄存器来重定位向量表),每一个表项占4字节。
如下:
首先向量表的开头是主堆栈的地址。
可以看出,不论如何一个向量表至少包含下面4个表项:
1.MSP初始值
2.复位向量
3.NMI
4.硬fault服务例程
中断的输入与挂起:
当中断输入脚被置为有效后,该中断就被悬起,到了系统中它的优先级最高的时候,就会得到响应。
但是当某个中断得到响应之前,其悬起位被清除,则中断被取消。(所以stm32都是在中断服务程序的最后清除中断标志位)
当某中断的服务例程开始执行的时候,就称此中断进入了“活跃”状态,并且其悬起位会被自动清除。
SVC和PENDSVC:
首先SVC(系统服务调用)和PENDSVC(可挂起系统服务调用)的区别在于SVC异常必须立即得到相应,而PENDSVC则不是,他可以像普通中断一样被挂起,知道其他重要任务完成才执行它,挂起PENDSVC的方式为:手工写入NVIC的PENDSVC挂起寄存器。
SVC的用途:操作系统可以不让用户直接访问硬件,而是通过触发SVC异常来使用SVC系统调用来让用户程序简介访问硬件。好处:1.OS负责具体硬件,用户程序不必花费心思控制硬件。2.OS的代码应该是经过充分的测试的,所以整个系统可靠性高健壮性好。3.用户程序无需在特权级下执行,无需担忧因误操作让系统瘫痪。4.通过SVC机制,用户程序与硬件无关。
PENDSVC的用处:上下文切换,如ucos上下文切换就是用到PENDSVC的。
NVIC:
中断向量控制器,也就是控制中断向量的地方,每个外部中断(系统中断由SCB控制)都在其中的寄存器占有一席之地,寄存器列表如下:
其中悬起寄存器可以系统自动设置,也可以手工修改以悬起一个中断。
软件中断寄存器也蛮重要的,如下:
中断的响应和返回:
中断的响应:
8个寄存器以及入栈顺序如下:
中断的返回:
首先触发中断返回的指令有三种:
返回了之后,做如下两件事:
1.出栈,回复现场
2.更新NVIC寄存器
咬尾中断:
一图以蔽之:
其他
总结了一天,终于到了这一步,还有些零碎的知识点写上:
M3的堆栈是向下生长的。
M3取指,解码,执行三级流水,因为其采用哈弗体结构,所以取指和访存可以同时执行,M3内部有解码模块,所以构成了三级流水。
stm32和cortex M3学习内核简单总结的更多相关文章
- ARM 架构、ARM7、ARM9、STM32、Cortex M3 M4 、51、AVR 之间有什么区别和联系?(转载自知乎)
ARM架构: 由英国ARM公司设计的一系列32位的RISC微处理器架构总称,现有ARMv1~ARMv8种类. ARM7: 一类采用ARMv3或ARMv4架构的,使用冯诺依曼结构的内核. ...
- STM32学习之路入门篇之指令集及cortex——m3的存储系统
STM32学习之路入门篇之指令集及cortex——m3的存储系统 一.汇编语言基础 一).汇编语言:基本语法 1.汇编指令最典型的书写模式: 标号 操作码 操作数1, 操作数2,... ...
- 【freertos】002-posix模拟器设计与cortex m3异常处理
目录 前言 posix 标准接口层设计 模拟器的系统心跳 模拟器的task底层实质 模拟器的任务切换原理 cortex M3/M4异常处理 双堆栈指针 双操作模式 栈帧 EXC_RETURN 前言 如 ...
- ARM Cortex M3系列GPIO口介绍(工作方式探讨)
一.Cortex M3的GPIO口特性 在介绍GPIO口功能前,有必要先说明一下M3的结构框图,这样能够更好理解总线结构和GPIO所处的位置. Cortex M3结构框图 从图中可以看出 ...
- 【ARM-Linux开发】ARM7 ARM9 ARM Cortex M3 M4 有什么区别
ARM7 ARM9 ARM Cortex M3 M4 区别 arm7 arm9 可以类比386和奔腾, 不同代,arm9相比arm7指令集和性能都有所增强,arm7和arm9都有带mmu和无mmu的版 ...
- IIC驱动学习笔记,简单的TSC2007的IIC驱动编写,测试
IIC驱动学习笔记,简单的TSC2007的IIC驱动编写,测试 目的不是为了编写TSC2007驱动,是为了学习IIC驱动的编写,读一下TSC2007的ADC数据进行练习,, Linux主机驱动和外设驱 ...
- Linux 内核开发—内核简单介绍
内核简单介绍 Linux 构成 Linux 为什么被划分为系统空间和内核空间 隔离核心程序和应用程序,实现对核心程序和数据的保护. 什么内核空间,用户空间 内核空间和用户空间是程序执行的两种不同的状态 ...
- ARM Cortex M3(V7-M架构)硬件启动程序 一
Cortex-m3启动代码分析笔记 启动代码文件名是STM32F10X.S,它的作用先总结下,然后再分析. 启动代码作用一般是: 1)堆和栈的初始化: 2)中断向量表定义: 3)地址重映射及中断向量表 ...
- Implementation of Serial Wire JTAG flash programming in ARM Cortex M3 Processors
Implementation of Serial Wire JTAG flash programming in ARM Cortex M3 Processors The goal of the pro ...
随机推荐
- Closing the Sim-to-Real Loop: Adapting Simulation Randomization with Real World Experience
Closing the Sim-to-Real Loop: Adapting Simulation Randomization with Real World Experience 模拟到实际循环闭环 ...
- 算法习题---5.7丑数(Uva136)
一:题目 丑数是指不能被除了2,,5以外的素数整除的数.将丑数从小到大排序 ,,,,,,,,,,,.... 求第1500个丑数 (一)求解方法 对于任意丑数x,他的2x,3x,5x都是丑数. 二:代码 ...
- 为什么在MySQL数据库中无法创建外键?(MyISAM和InnoDB详解)
问题描述:为什么在MySQL数据库中不能创建外键,尝试了很多次,既没有报错,也没有显示创建成功,真实奇了怪,这是为什么呢? 问题解决:通过查找资料,每次在MySQL数据库中创建表时默认的情况是这样的: ...
- 3D游戏引擎设计 实时计算机图形学的应用方法 第2版 pdf 带索引书签目录
3D游戏引擎设计 实时计算机图形学的应用方法 第2版 目录 第1章 概述1.1 图形硬件和游戏发展史1.2 本书版本与软件发展史1.3 章节导读 第2章 图形系统2.1 基础知识2.1.1 坐标系 ...
- 【JS新手教程】replace替换一个字符串中所有的某单词
JS中的replace方法可以替换一个字符串中的单词.语句的格式是: 需要改的字符串.replace(字符串或正则表达式,替换成的字符串) 如果第一个参数用字符串,默认是找到该字符串中的第一个匹配的字 ...
- react——Table组件
/* * 构建数据列 * */ tableColumns = (currentData) => { let group = lodashGroupBy(currentData, 'level1' ...
- servlet中ServletContainerInitializer的简单说明
根据官方文档到的说明 public interface ServletContainerInitializer Interface which allows a library/runtime to ...
- ubuntu18.10 安装nodejs
进入官网下载页面 下载对应版本 2.解压tar.xz文件在linux下,大部分情况下不能直接解压tar.xz的文件. 需要用 xz -d xxx.tar.xz 将 xxx.tar.xz解压成 xxx. ...
- python基础篇(一)
PYTHON基础篇(一) 变量 赋值 输入,输出和导入 A:输入 B:输出 C:导入 运算符 A:算数运算符 B:比较运算符 C:赋值运算符 D:位运算符 E:逻辑运算符 F:成员运算符 G:身份运算 ...
- [Oracle] - 使用32位 PLSQL(PL/SQL Developer)登陆64位Oracle失败之解决
配置环境 Oracle服务端oracle_winx64_12c_database.iso Oracle客户端instantclient-basiclite-nt-12.1.0.1.0.zip 集成开发 ...