第一个ARM裸板程序及引申
1、点亮LED(怎么做)
1)看原理图确定控制LED的引脚。
2)看主芯片手册,确定如何设置/控制引脚。 3)写程序。 注意:
a)LED导通电阻很小,为防止回路电流过大,需串联一电阻。 b)引脚驱动能力不足一般指输出电流或电压过小,无法驱动负载正常工 作。(采用三极管-->开关作用,基极电压控制e、c间通断)
c)电子系统中,我们不关心引脚输出电压具体多少,只关心输出为高电 平还是低电平(如我们不关心输出3.3v还是1.2v,只关心输出了高 电平),即输出1/0(逻辑1/逻辑0)
d)同名net表示引脚连接在一起。
e)nLED_1:n表示低电平有效。(如低电平灯亮,在这里有效即指灯亮)
2、GPF4输出1/0(怎么做)
1)配置为输出引脚。(GPFCON)
2)设置它的状态(pin states,配置GPFDAT寄存器)。
3、S3C2440框架与启动过程
SOC(System On Chip):CPU+GPIO控制器+4K SRAM(4K内存)+Nand Flash控 制器
注:GPIO:General Purpose Input/Output
启动过程:
1)NOR启动:NOR Flash 基地址为0,片内SRAM地址为0x4000,0000,CPU 读出NOR上第一个指令(前4字节),执行。CPU继续读出其他指令执行。
2)Nand启动:片内4K SRAM基地址为0,NOR Flash不可访问(即设为Nand 启动时,就无法使用NOR Flash)。S3C2440的硬件把Nand前4K内容复制到 片内内存(SRAM),然后CPU从0地址(SRAM内)取出第一条指令执行。
注:NOR与Nand区别:CPU可直接读取NOR Flash内的数据;CPU读取Nand Flash中数据时,需先将代码复制到SRAM(内存)中,再从SRAM中读取 Nand Flash的数据(即CPU不能直接读取Nand Flash中的数据)。
参考资料:链接库\\001_LED原理图及S3C2440启动流程.jpg
4、点亮LED程序
寄存器:
1)CPU寄存器:R1、R2、R3、...(可使用R1、R2等直接访问)
2)GPIO寄存器:GPFCON、GPFDAT、GPFUP、...(仅能通过寄存器地址进行访 问)
注:1)访问即指对寄存器的操作,修改、设置寄存器中各个位的值。
2)ARM9为32位处理器,所有寄存器都为32位(4字节-->一个指令长度)
3)处理器中所有的内存或者寄存器都是编址的,即每个地址都对应一 块特定的空间(1个字节),可能是内存,也可能是寄存器。
几条汇编:
1)LDR(load):读内存命令
如:LDR R0,[R1] ,假设R1值为x,读取地址x(实际上是地址x所对应 的那块区域,可能是内存,也可能是寄存器)上的数据(4字节,因 为是32位处理器),保存到R0中。
注: a)计算机是按字节存储数据,一个字节对应一个地址。32位处 理器一次处理4字节数据(32位),所以地址按4依次增加。 32位处理器的寄存器大小也为32位,所以寄存器地址也按4依 次增加。
b)设x、y为十进制数x-y=a,证明两数据差值为a 设x、y位十六进制数x-y=a,证明两数据差值为a
即,两个数据间差值即为两数据之差,与进制无关系。如:寄存 器GPFCON地址为0x56000050,GPFDAT地址为0x56000054,两 寄存器地址相差4,因为其差值为4,与其是几进制数据无关。 又如0b1011与0b1010差值为1,因为0b1011-0b1010=1,或者 0b1011=0d11,0b1010=0d10,0d11-0d10=1。由上分析可知,数据 运算结果与其进制形式无关,进制形式仅是数据的表现形式(书 写形式)不同而已,数据的本质--大小是保持不变的,采用不同 的进制形式是为了方便数据的书写、表达和分析、处理,或者在 某些专业领域某些进制形式更符合物理实际,更利于观察规律、 解决问题。总之采用不同的进制形式是为了在数据使用操作过程 中更加方便,而数据的本质属性--大小是不发生改变的。
2)STR(store):写内存命令
如:STR R0,[R1] ,假设R1值为x,把R0的值写到地址x(实际上是地 址x所对应的那块区域,可能是内存,也可能是寄存器)上去(4字节, 因为是32位处理器)。 3) B:跳转
4)MOV(move)
如:MOV R0,R1 把R1的值赋给R0,即R0=R1
MOV R0,#0x100 即,R0=0x100
5)LDR R0,=0x12345678 (伪指令:并不存在这样一条指令,它最终会被拆 分成几条真正的ARM指令)最终所得结果为:R0=0x12345678
注:R0=0x12345678如果使用MOV指令完成,即,MOV R0,#0x12345678,
则
会被报告为错误指令,原因如下:
一条ARM指令有32位,其中某些为表示MOV指令本身和R0,剩下不足32位来存放数据,如果该数据过大(超过32位或者等于32位),则该指令会报错。即,MOV指令不能处理任意值,只能处理简单值(又被称为立即数)。所以引入伪指令:LDR R0,=任意值(与之前读内存指令区别在于多了一个“=”)
注:关于配置Linux服务器,进行linux与Windows直接文件传输与
共享的教程(链接库\\Ubuntu16.04如何使用samba服务器.pdf)
注:关于arm-linux-gcc 安装配置的一系列问题参考。(链接库
\\Ubuntu 16.04[64bit]嵌入式交叉编译环境arm-linux-gcc搭建过程图解.pdf)
5、.S(汇编文件)文件编译成.bin(二进制流--机器码)文件
1)arm-linux-gcc -c -o led_on.o led_on.S(编译:汇编-->机器码--0/1代码)
2)arm-linux-ld -Ttext 0 led_on.o -o led_on.elf(链接:机器码-->机器码--增加了链接库代码)
3)arm-linux-objcopy -O binary -S led_on.elf led_on.bin(链接文件-->bin文件,都是机器码;注意大写O、S)
4)arm-linux-objdump -D led_on.elf > led_on.dis(反汇编指令:机器码-->汇编代码)
6、CPU寄存器
CPU内部有15个寄存器:R1--R15,每个寄存器都有对应的别名(代表其各自的功能),如:R15-->pc、R14-->lr、R13-->sp等。
PC:程序计数器(program Counter=当前指令+8)
CPU工作模式为流水线:当前执行地址A的指令,已经在对地址A+4的指令进行译码,已经在读取地址A+8的指令。(注:一个字节对应一个地址