STM32(1):系统架构地址映射

STM32(1):系统架构&地址映射

前提摘要

  1. 个人说明:

    • 限于时间紧迫以及作者水平有限,本文错误、疏漏之处恐不在少数,恳请读者批评指正。意见请留言或者发送邮件至:“Email:noahpanzzz@gmail.com”
    • 本博客的工程文件均存放在:GitHub:https://github.com/panziping。
    • 本博客的地址:CSDN:https://blog.csdn.net/ZipingPan
  2. 参考:

    • 正点原子
    • 野火
    • ST数据手册
  3. 日期:


正文

系统架构

CPU的核心主要功能为运算器和控制器,但是CPU并不具备数据存储的功能。CPU与外界存储器建立数据通道分为“哈佛结构”和“冯诺伊曼结构”两种不同思路。

在这里插入图片描述

冯诺伊曼结构的优点是总线资源占用少,缺点是执行效率较低,冯诺伊曼结构执行程序的同时不能读取数据。而相反的是哈佛结构的优点是执行效率较高,缺点是总线资源占用多,哈佛结构执行程序的同时能够读取数据。

如今半导体技术发展迅速,对于资源限制已经没有那么严重了。

ST-ARM

ST公司设计的ARM架构芯片,采用的是“哈佛结构”,ICode总线直接连接到Flash,而不需要经过经过总线矩阵。

在这里插入图片描述

上图为STM32F1系列系统架构图。

地址映射

Cortex-M3
  1. ARM Cortex-M3架构,32位CPU,所以就有32位地址线和数据线。
  2. 32位地址线决定了CPU的地址空间为4G(2^32 = 4G,按字节寻址)。

地址映射规则

  1. 芯片外接外部RAM和外部ROM的时候,RAM和ROM器件都是独立器件,并没有地址一说,或者说都只有自己的绝对地址,且从0x00开始。而对于CPU来说,0x00地址只能有1个,所以外接器件挂到CPU上时只能做地址映射,如RAM的地址为0x3000 0000, ROM地址为0x4000 0000, 这样CPU就做了统一编址。
  2. 32位地址线决定了CPU的地址空间为4G,这些地址要统一分配使用,所以说内存(RAM)、外设(寄存器)和存储器(RAM)都需要被映射到这个4G空间里面,但是哪些占用低地址,哪些占用高地址?
  3. 这些问题已经被ARM的设计者给设计好了的,地址从高到低如何使用,已经被规定好,而我们只需要学习这些规则就好了。掌握规则,并使用规则。
  4. 因此可以想象到:ARM体系结构中,系统上电或复位后,处理器将从地址0x00处取第一条指令,因此,上电的时候,地址0x00处必须是非易失性的ROM或FLASH。
  5. CPU地址总线的地址,由硬件电路控制其具体含义。物理地址中很大一部分是留给内存条中的内存的,但也常被映射到其他存储器上 (如显存、BIOS等)。就生成了物理地址,这个物理地址被放到CPU的地址线上。
  6. 物理地址空间,一部分给物理RAM(内存)用,一部分给总线用,这是由硬件设计来决定的,但物理RAM一般不能上到4G,因为还有一部分要给总线用(总线上还挂着别的许多设备)。一般是把低端物理地址给RAM用,高端物理地址给总线用。

总结:地址映射就是给地址进行命名的过程。

存储器映射
  1. 存储器本身不具有地址信息,它的地址是由芯片厂商或用户分配的,给存储器分配地址的过程就称为存储器映射。
  2. 在这 4G 的地址空间中,ARM 平均分成了 8 个块,每块 512MB,每个块也都规定了用途。每个块的大小都有 512MB,显然这是非常大的,芯片厂商在每个块的范围内设计各具特色的外设时并不一定都用得完,都是只用了其中的一部分而已。
序号用途地址范围
Block 0Code0x0000 0000 ~ 0x1FFF FFFF(512MB)
Block 1SRAM0x2000 0000 ~ 0x3FFF FFFF(512MB)
Block 2片上外设0x4000 0000 ~ 0x5FFF FFFF(512MB)
Block 3FSMC 的 bank1 ~ bank20x6000 0000 ~ 0x7FFF FFFF(512MB)
Block 4FSMC 的 bank3 ~ bank40x8000 0000 ~ 0x9FFF FFFF(512MB)
Block 5FSMC 寄存器0xA000 0000 ~ 0xCFFF FFFF(512MB)
Block 6没有使用0xD000 0000 ~ 0xDFFF FFFF(512MB)
Block 7Cortex-M3 内部外设0xE000 0000 ~ 0xFFFF FFFF(512MB)

在这里插入图片描述

上图为STM32F1系列存储器映射列表。

寄存器映射
  1. 寄存器是单片机内部一种特殊的内存,可以实现对单片机各个功能的控制,给寄存器分配地址的过程称为寄存器映射。
大类小类说明
内存寄存器内核相关寄存器包含R0~R15、xPSR、特殊功能寄存器等
内存寄存器中断控制寄存器包含NVIC和SCB相关寄存器,NVIC有:ISER、ICER、ISPR、IP等;SCB有:VTOR、AIRCR、SCR等
内存寄存器SysTick寄存器包含CTRL、LOAD、VAL和CALIB四个寄存器
内存寄存器内存保护寄存器可选功能,STM32F103没有
内存寄存器调试系统寄存器ETM、ITM、DWT、IPIU等相关寄存器
外设寄存器包含GPIO、UART、IIC、SPI、TIM、DMA等各种外设

如果没有给寄存器映射,那么操作寄存器就会变得特别复杂。

以GPIOA ODR寄存器为例,GPIOA ODR的地址为0x4001 080C(寄存器地址=总线基地址+外设偏移地址+寄存器偏移量,以GPIOA_ODR为例,GPIOA_ODR=0x4001 0000 + 0x800 + 0x0C = 0x4001 080C。需要注意的是AHB总线基地址是从0x4001 8000开始的,但是在程序中定义是从0x4002 0000开始,将SDIO的地址单独独立出来)。

那么直接操作寄存器地址:

*(unsigned int *)(0x4001 080C)=0xFFFF;

定义一个名字之后再操作:

#define GPIOA_ODR *(unsigned int *)(0x4001 080C)
GPIOA_ODR =0xFFFF;

但是这样直接操作寄存器还是很复杂,因为寄存器的数量是非常多的。

结构体映射

由于寄存器都是连续排列的,所以可以使用结构体进行映射(以GPIOA寄存器为例)。

typedef struct
{
	__IO uint32_t CRL;
	__IO uint32_t CRH;
	__IO uint32_t IDR;
	__IO uint32_t ODR;
	__IO uint32_t BSRR;
	__IO uint32_t BRR;
	__IO uint32_t LCKR;
}GPIO_TypeDef;

#define PERIPH_BASE           ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */
#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)
#define GPIOA_BASE            (APB2PERIPH_BASE + 0x0800)
#define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)

那么GPIOA中CRL、CRH、IDR、ODR、BSRR、BRR、LCKR各个地址:

&GPIOA->CRL:0x40010800
&GPIOA->CRH:0x40010804
&GPIOA->IDR:0x40010808
&GPIOA->ODR:0x4001080c
&GPIOA->BSRR:0x40010810
&GPIOA->BRR:0x40010814
&GPIOA->LCKR:0x40010818

注:关于__IO

#ifdef __cplusplus
  #define     __I     volatile                /*!< defines 'read only' permissions      */
#else
  #define     __I     volatile const          /*!< defines 'read only' permissions      */
#endif
#define     __O     volatile                  /*!< defines 'write only' permissions     */
#define     __IO    volatile                  /*!< defines 'read / write' permissions   */

volatile的英文解释是易变化的,不稳定的。所以在变量的前面加这个修饰符目的是让CPU去内存中读取数据,而不是CPU去寄存器读取数据。

由于外部因素使得内存中存放该变量的值发生了改变,如果CPU不访问内存,而是直接读取寄存器的旧值,则读取的是错误的,导致程序失败。

总结

本文均为原创,欢迎转载,请注明文章出处:CSDN:https://blog.csdn.net/ZipingPan/ARM。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。

非原创博客会在文末标注出处,由于时效原因,可能并不是原创作者地址(已经无法溯源)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/509804.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基因组Survey分析

流程图&#xff1a; 图片来源&#xff1a;https://www.jianshu.com/p/94da86093843 一、Fastp质控 二、NT比对 一般选择第六个输出格式 结果示例&#xff1a; 三、k-mer分析 软件&#xff1a;GCE/genomescope 分析目的&#xff1a;预估基因组大小&#xff0c;重复序列比…

团聚金刚石研磨液为高性能研磨抛光材料 中机新材是国内领先供应商

团聚金刚石研磨液为高性能研磨抛光材料 中机新材是国内领先供应商 团聚金刚石研磨液是一种高性能研磨抛光材料&#xff0c;是以团聚金刚石微粉为原料采用特殊配方配制而成。团聚金刚石微粉是由金刚石微粉、粘结剂经特殊工艺处理集合而成的球形磨料。金刚石微粉制备方式多样&am…

4年经验来面试20K的测试岗,一问三不知,我还真不如去招应届生。

公司前段缺人&#xff0c;也面了不少测试&#xff0c;结果竟然没有一个合适的。一开始瞄准的就是中级的水准&#xff0c;也没指望来大牛&#xff0c;提供的薪资在10-20k&#xff0c;面试的人很多&#xff0c;但平均水平很让人失望。看简历很多都是4年工作经验&#xff0c;但面试…

使用Java流API构建树形结构数据

简介&#xff1a; 在实际开发中&#xff0c;构建树状层次结构是常见需求&#xff0c;如组织架构、目录结构或菜单系统。本教案通过解析给定的Java代码&#xff0c;展示如何使用Java 8 Stream API将扁平化的菜单数据转换为具有层级关系的树形结构。 1. 核心类定义 - Menu Data…

中科驭数超低时延网络解决方案入选2023年度金融信创优秀解决方案

近日&#xff0c;由中国人民银行领导、中国金融电子化集团有限公司牵头组建的金融信创生态实验室发布「2023年度第三期金融信创优秀解决方案」&#xff0c;中科驭数超低时延网络解决方案从众多方案中脱颖而出&#xff0c;成功入选&#xff0c;代表了该方案的技术创新和金融实践…

Servlet基础 管理员注册页面

管理员注册页面 index.jsp <% page language"java" import"java.util.*" pageEncoding"UTF-8"%> <% String path request.getContextPath(); String basePath request.getScheme()"://"request.getServerName()":&quo…

Linux下javaweb项目部署

javaweb项目部署测试 测试环境&#xff1a;centos7 下载安装jdk rpm -ivh jdk-8u131-linux-x64.rpm 下载安装MySQL wget https://downloads.mysql.com/archives/get/p/23/file/mysql-community-server-5.7.33-1.el7.x86_64.rpm https://downloads.mysql.com/archives/get/p…

Android12 简单的共享内存驱动实现 参考Ashmem

Android12 共享内存驱动实现 SOC&#xff1a;RK3568 system&#xff1a;Android12 概述&#xff1a; 1. 概述 Ashmem&#xff08;Anonymous Shared Memory&#xff0c;Android 匿名共享内存&#xff09;&#xff0c;它基于 mmap 系统调用&#xff0c;可以让不同进程将同一段…

DHCP服务

DHCP简介 DHCP&#xff08;DynamicHost ConfigurationProtocol&#xff0c;动态主机配置协议&#xff09;通常被应用在大型的局域网络环境中&#xff0c;主要作用是集中的管理、分配IP地址&#xff0c;使网络环境中的主机动态的获得IP地址、Gateway地址、DNS服务器地址等信息&…

Flutter应用在App Store上架的完整指南

本文探讨了使用Flutter开发的iOS应用能否上架&#xff0c;以及上架的具体流程。苹果提供了App Store作为正式上架渠道&#xff0c;同时也有TestFlight供开发者进行内测。合规并通过审核后&#xff0c;Flutter应用可以顺利上架。但上架过程可能存在一些挑战&#xff0c;因此可能…

Git版本管理使用手册 - 8 -拉取开发分支、提交代码、查看提交日志

开发者从仓库获取开分支&#xff08;检出分支以及分支切换&#xff09; 根据仓库地址克隆的本地仓库&#xff0c;目录中默认是master的代码&#xff0c;即工作区是master代码&#xff0c;需要某一开发分支时&#xff0c;需要在工作区切换或者idea中先更新再切换分支&#xff0…

【java】关于String、StringBuffer和StringBuilder的那些事

在之前的文章中我们曾简单介绍过String这个引用类型变量&#xff0c;其实它还有许多特性&#xff0c;还有StringBuffer和StringBuilder这两个方法在字符串操作中也有非常重要的地位&#xff0c;接下来就由小编带大家梳理一下吧&#x1f44a; 目录 一、String 1、构造方法 2、…

RIP协议(路由信息协议)

一、RIP协议概述 RIP协议&#xff08;Routing Information Protocol&#xff0c;路由信息协议&#xff09;是一种基于距离矢量的内部网关协议&#xff0c;即根据跳数来度量路由开销&#xff0c;进行路由选择。 相比于其它路由协议&#xff08;如OSPF、ISIS等&#xff09;&#…

【Web】记录Polar靶场<中等>难度题一遍过(全)

目录 到底给不给flag呢 写shell 注入 某函数的复仇 xxe SSTI unpickle BlackMagic 反序列化 找找shell 再来ping一波啊 wu 代码审计1 你的马呢&#xff1f; ezphp 随机值 phpurl search file PlayGame csdn 反正持续一个月&#xff0c;感觉XYCTF…

MS SQL Server STUFF 函数实战 统计记录行转为列显示

目录 范例运行环境 视图样本设计 数据统计要求 STUFF函数实现 小结 范例运行环境 操作系统&#xff1a; Windows Server 2019 DataCenter 数据库&#xff1a;Microsoft SQL Server 2016 视图样本设计 假设某一视图 [v_pj_rep1_lname_score] 可查询对某一被评价人的绩效…

有单片机基础,准备过一遍freertos,之后再学linux

应届生我觉得继续把单片机深入一下比较好。 站在公司的角度思考一下&#xff0c;个人觉得应该有以下结论&#xff1a; 1 大公司具备技术资金等优势&#xff0c;因此喜欢学历好&#xff0c;理论扎实能够攻坚的人。倾向于培养各个领域的专家&#xff0c;共同构建自己产品的竞争…

网络安全之IP地址证书的重要性

在数字化时代&#xff0c;网络空间已成为各类活动的重要载体&#xff0c;无论是商业交易、信息交流还是远程办公&#xff0c;都离不开互联网的支撑。然而&#xff0c;网络环境的开放性与匿名性也带来了安全风险&#xff0c;如何确保网络交互中的身份真实可信&#xff0c;成为了…

C++中的面向对象到底是什么

C中的面向对象到底是什么 对象嘛&#xff0c;就和大家都有的对象一样&#xff0c;两只眼睛、一个嘴巴、两条腿…… 对不起跑题了&#xff0c;C的面向对象中的对象可不是显示中的对象哦&#xff0c;但是有一些相似之处&#xff0c;有对象的同学可以参考着去学习C面向对象的概念…

3. WiFi基本原理

1. WiFi简介 WiFi的全称是Wireless Fidelity。它是一种无线网络通信技术&#xff0c;由Wi-Fi联盟拥有&#xff0c;目的是改善基于IEEE 802.11标准的无线网络产品之间的互通性&#xff0c;允许电子设备在没有物理连接的情况下进行高速数据传输。此外&#xff0c;WiFi也被视为IE…

SpringCloudAlibaba服务消费者调用nacos服务报错:java.net.UnknownHostException: xxx

确保服务情况正常 通过服务名字调用(注意不需要添加端口号) RequestMapping("/add") public String add() {String url "http://stock-nacos/stock/reduce";String result restTemplate.getForObject(url, String.class);System.out.println("下单…