ARM裸机编程需要知道的知识3--寄存器
ARM裸机编程需要知道的知识3--寄存器
---参考朱有鹏ARM裸机课程
1、为什么软件可以操作硬件?
数电中以前可以通过一些IC,的引脚来形成一个个的计数器。可以做一个时钟。
单片机和嵌入式也可以做一个时钟,但不是通过硬件电路的改变,而是通过软件的编程。
寄存器属于CPU外设的硬件组成部分。
CPU可以像访问内存一样的访问寄存器。
寄存器是CPU的硬件设计者制定的,目的是外设被编程控制的“活动开关。
朱老师打了一个比方:
正如汇编指令集是CPU的编程接口API一样,寄存器是外设硬件的软件编程接口API,
使用软件编程控制某一个硬件,其实就是编程读写该硬件的寄存器。
因为内存用不完,一般是32位的,所以有4G的内存
前面说过寄存器和IO和内存都是统一编址的,所以使用的方法都是一样的
(1)编程操作寄存器的时候,类似于访问内存。
(2)寄存器中每一个bit位都有特定的含义,因此编程操作时需要位操作。
(3)单个寄存器的位宽一般和CPU的位宽一样,以实现最佳的访问效率
2、两类寄存器
(1)SOC中2类寄存器:通用寄存器和SFR通用寄存器(ARM中有37个)是CPU的组成部分,CPU的很多活动都需要通用寄存器的支持和参与。
一般是可读可写的,功能是没有定的,你可以人为的规定。
(2)SFR(Special function register,特殊功能寄存器)不在CPU中,而存在于CPU的外设中,我们通过访问外设的SFR来编程操作这个外设,这就是硬件编程控制的方法。
为什么把这种寄存器叫做特殊功能寄存器:()
(1)功能是订好的,不能改变的
(2)他不是通用的,给别人某个功能定制化使用的
(3)跟某个外设绑定的。
每一个外设都有一堆特殊功能寄存器。
用汇编编程访问寄存器的方法:
Ldr r1, = 0xE0200280 ; 读取你地址,然后放进R1寄存器里面
Str r0,[r1] ; 使用间接寻址,类似于C语言的指针寻址一样
Mov r0,#0 ;把0的值写入r1指向的内存的那个值
Int *p = (int *)0x30008000; //C语言就更加容易理解了,就是把16的值写入一个0x30008000的地址中
*p = 16;
3、简单的总结ARM 的体系结构的特点:
ARM的CPU的总结:
ARM是RISC架构:
1、常用的ARM汇编指令只有20~30条
2、ARM是低功耗CPU
3、ARM的架构非常适合单片机,嵌入式,尤其是物联网领域;而服务器等高性能领域目前主导还是Intel。
ARM也在努力在往服务器的方面发展。
ARM是统一编址的
ARM是32位架构的
32位ARM的CPU支持的内存少于4G,通过CPU地址总线来访问。
SOC中的各种内部外设通过各自的SFR编程访问,这些SFR的访问方式类似于访问普通的内存,这就叫做IO与内存的统一编址。
ARM是哈弗结构的
把代码和数据是分开存储的。
使用实际的地址即是物理地址(链接比较麻烦)必须使用复杂的链接脚本告知链接器如何组织程序;对于OS之上的应用(工作在虚拟地址之中)则不需要考虑这么多。
裸机程序使用了实际的物理地址,所以需要写链接脚本。
4、S5PV210的地址映射详解
S5PV210的地址的映射关系;
0xE000 0000 ~ 0xFFFF FFFF :这里主要是外设的特殊功能寄存器
0xD000 0000 ~ 0xDFFF FFFF :这里主要是DMZ_ROM(只读)
:IROM和IRAM内部的只读寄存器和内部的随机寄存器
0xC000 0000 ~ 0xCFFF FFFF :放在低功耗的声卡
0xB000 0000 ~ 0xBFFF FFFF :ONENAND和NAND中NANDFLASH,本身是是只 读的,所以放代码的(哈弗结构)
0x2000 0000 ~ 0x6000 0000 :DRAM,就是用来存放内存的
0x0000 0000 ~ 0x1FFF FFFF :IROM & IRAM 内部的寄存器
这里分为一个表:
0x2000 0000 0x3fff ffff : 512MB DRAM0
0x4000 0000 0x5fff ffff : 512MB DRAM1
这里我觉得是十分重要的,因为后面裸机启动的地址为什么是在那个位置都需要根据
这个表格来填写,嵌入式的芯片跟单片机的芯片是不一样的,我们需要编写链接地址。
为什么我们需要在嵌入式的芯片中编写链接地址,而不需要在window的桌面程序中编写
链接地址。
一个很重要的原因是WINDOW的桌面程序的Intel是基于冯诺依曼结构的
而嵌入式的ARM是基于哈弗结构的,他们的代码个数据是分开的放置的。
所以需要在程序调用的时候,分段处理。
如下表格: