ARM裸机开发的一些基础知识,基于x210开发板
课没有认真听完,也没接触过裸机的项目可供上传,但是了解一下总是好的=v=

授课老师:朱有鹏
听课辣鸡:宕机酱

===========================================================
ARM裸机开发

一、ARM必须知道的事

1.1ARM的几种版本号
三个描述方法

ARM内核版本号 armv7
ARM SoC版本号 cortex-A8
芯片型号 S5PV210

1.3 SoC与CPU——我们现在所用的称为“CPU”的,其实都是SoC

外设 peripheral 包括GPIO串口等等等等

CPU是在一个PCB上的板级系统 走线连接 board
SoC是半导体发展继承的芯片级系统 内部总线 chip
总线的效率要比PCB上的外接走线快很多!
未来的趋势:单芯片

1.8单片机和嵌入式
单片机:就业在两年后达到瓶颈,6K-8K。学习路线短,活儿的产品很简单。
嵌入式:嵌入式可以走一辈子,薪资多年后能达到瓶颈,12K-15K。薪资差异比较大
单片机操控USB、单片机操控网卡,这都是扯淡的。现在上网都经过操作系统,借用网络协议栈。因为这都是现成的。
不要学听起来很牛逼,学完了没屁用的知识,嵌入式裸机教程是完全够用的

1.9交叉编译
交叉编译工具链。一般说的编译器是一个系列,实际上只有gcc是编译器,不包括GDB等
交叉编译:低性能设备需要在高性能设备上编译。如安卓手机本身不能写程序一样。包括裸机程序、系统级程序和应用级程序

1.10 程序在SoC运行
Flash相当于冰箱、仓库,充当存储器的作用
DDR相当于案板,即是工作台面,程序运行在这里
CPU由三部分组成:寄存器、运算器、控制器

将内容“137”放到&0x0007的方法:
1、地址总线传7
2、命令总线传“写入”权限
3、数据总线传137

实际上使用char去节省空间意义不大。因为一次处理还是32位的,这是地址总线所决定的
总线的速度决定CPU和外设交互的速度。
32位的单片机最多扩展到4G。32位是指数据总线,4G说的是32位地址总线
地址总线和数据总线可以不一样。代表:51单片机

====================================================================================–
二、ARM体系结构与汇编指令

2.1可编程器件的编程原理

电子器件的发展方向:
模拟器件 -> 数字器件
ASIC -> 可编程器件

2.2指令集
汇编的好处:
编程效率最高,比如移位操作等。用很多次、很频繁的操作比如中断就可以用汇编嵌入到C中处理。

程序语言的发展历程
低级语言:汇编,更接近机器的思维 就是1010101110这样指令的替代,机器语言的助记符。
CPU有自己不同设计的汇编指令集,移植到另一个CPU上要完全重写!
C 移植性好,到时候只需要Intel/ARM等不同的编译器,代码可以重复使用
C++ C语言还是很麻烦,实现面向对象先天不足。程序大而复杂就需要C++(30万以上吧)
高级语言:JAVA、C#,更接近人的思维
C++还是太难了……这么说是因为当今程序员门槛又变低了
脚本语言 还不够简单,程序员已经变得弱智了。。。1脚本语言 = 10Java =20C++ = 100C = 1000汇编语言(举例)

编程语言是发展的产物,每个语言都具有生命力。

=============================================================

2.3RISC 和 CISC的区别

CISC 复杂指令集
理念:用最少的指令集完成任务。如乘法MUL、乘加…CISC的CPU设计复杂。但容易设计编译器。
程序员本身不需要动太多脑子,设计CPU的时候就给程序员做好了,遇到哪个问题用哪个指令(200+个)
电路做的非常复杂,功耗也随之增大
Intel在使用

RISC 精简指令集
灵活,常用的就20-30个。学的非常快
ARM使用

===========================================================

2.7S5PV210的内存映射

ROM 只读存储器
RAM 随机存取存储器
IROM 内部ROM
IRAM 内部RAM
SRAM 静态RAM,小 优点是不需要软件初始化,直接上电就可以使用
单片机:内存需求小,而且希望开发尽量简单所以全部用SRAM
DRAM 动态RAM,大 缺点是需要上电后初始化
PC机:内存需求量大,不在乎DRAM的初始化开销,适合全部用DRAM
嵌入式系统:内存需求大,而且没有NorFlash等可启动介质
memoryMAP未来会经常去查这个表,要注意

内存映射基本就是地址映射,叫法不同而已
我们写硬盘(ROM)不是通过地址总线去读写,而是通过特定IO接口去访问。RAM是通过地址总线
随机访问 比如访问第500个字节,就直接去访问了
顺序访问 访问从头开始 FLASH
IROM 、IRAM 内部ROM、内部RAM,集成到了SoC
NAND 即是NANDFLASH
SFR 特殊功能寄存器 外设的接口
S5PV210理论上最多4G内存,实际上只有1.5G。如果CPU的档次使用最多1G,那么配置1.5G就足够了,配多了也没用

SROM_BANK 后面网卡会用到,以后再说了

三星的CPU有一个非常标志性的设计:内存中IRAM&IROM是映射的。 在memory中有两个IRAM/IROM,实际上只有一个
另一个(0x0起始)是镜像(必要时查数据手册),并非真的重复。像是有两个门,地址不一样实际进的都是一个地方

IROM存放代码
IRAM存放数据
中间隔开了一层Not Aviliable 是为了防止代码段溢出,导致数据被冲了,也就是防止越界。最安全,真是煞费苦心

DRAM0 地址: 0x2000 0000 — 0x3FFF FFFF
DRAM1 地址: 0x4000 0000 — 0x7FFF FFFF

=============================================================

2.8CPU和外部存储器的接口

内存:SRAM DRAM DDR
外存:ROM(NANDFLASH iNAND SSD U盘)

设备连接方式 :
1、总线连接。RAM和CPU是这样连接的,因为需要直接地址访问,利用地址总线、数据总线。
好处:直接访问、随机访问 坏处:占用CPU地址空间,大小受限
2、非总线连接。外存和CPU是通过外存接口来连接的
好处:不占用CPU地址空间 坏处:比如总线式反应快

外存分为两大类:一种是FLASH,一种是硬盘
FLASH:是一种电学设备
NorFlash 特点:可以总线式访问,也就是可以接到地址空间来(一般接SROM_BANK)
一般专门用来启动。很多年前嵌入式设备都要NorFlash启动,但是比较贵,可靠
NandFlash 特点:通过时序去访问。最初是不支持NandFlash去启动,后来就可以了,廉价易出问题
三星公司首创了用NandFlash启动设备。
分为SLC和MLC SLC问题少,存储小 MLC不稳定,容易出现坏块,容量大。
eMMC/iNand
SSD
SD卡/TF卡/MMC卡:都是SD卡,SD卡的标准很多,不需要太纠结。
硬盘:是一种机械设备,通过磁存储,容量比较大

将来的趋势就是都用FLASH,因为FLASH速度快体积小,造价也会慢慢变低
目前的 嵌入式设备全部是使用FLASH的

=============================================================

2.9 S5PV210的 启动过程

【S5PV210的 启动过程】
第一步:上电后先从IROM读取到预先设置的代码,执行,做基本的系统初始化
//但初始化不了外接的DRAM,因为三星不知道是什么样的DRAM。
//这里的预先设置的代码就是 【BL0】
第二步:使用IROM的代码(64KB BL0)根据OM_PIN选择启动方式,读取启动代码到SRAM
第三步:执行启动代码,初始化Nand、DRAM、板卡、从Nand调取OS到DRAM运行,启动结束

这个启动过程对,但是有些问题,我们的SRAM应该只有96KB,但是UBOOT至少也要100+KB
这样一来不就不能启动了吗?所以210设计的要比上述过程复杂一点点

【关键是第二步】
第二步:读取启动代码到SRAM,关键是读取多少
先读取第一部分启动代码:BL1,大小为16Kb,初始化NandFlash
然后是BL2,初始化DRAM,执行操作系统

关于BL1和BL2:两者是协同工作的
BL1负责初始化DRAM和NandFlash,然后将BL2读取到

做单片机不需要硬件初始化,因为用的都是硬件上电就能用的东西。(很小容量NorFlash+SRAM)
PC机: BIOS(NOR)+NAND
嵌入式系统: NAND+DRAM+SoC内置的SRAM (NOR很贵 于是不用)
(没有SRAM那么前两者全部都启动不起来)

S5pv210 :内置了96KB大小的IRAM(内置SRAM)+64KB大小的IROM(NorFlash)

iRAM —> BL1 –>BL2 –> DRAM
从iRAM调取的代码,执行BL1,BL2

到uboot会依次实现这些步骤,是iROM_Application…整张图的实现过程

==============================================================

2.10
一般的SOC只支持一种启动方式,但X210有两次,分为1st boot,2nd boot
2nd boot相当于备用的启动,所有的备用通道都是SD2通道。
正常是SD0启动的,但第一次启动如果失败,那么就会尝试从SD2通道启动

设计IRAM/ IROM的原因:为了支持多种外部设备启动设备。

使用IROM启动的好处:
1、降低成本,少了一颗NorFlash,不用BIOS;
2、其次 支持各种校验类型的Nand;
3、量产方便,比如客户要刷机,拿SD卡一插就好了。

=============================================================

2.11通过OMpin选择不同的启动方式

硬件手册和iROM_application.pdf里面是有的

SD卡、Nand启动等
开发板的拨码开关,在蜂鸣器的旁边,向板子里是vcc,外面是gnd,需要镊子
具体参考他的课件吧
eg:从SD0的eMMC启动 101100 [om0到om5] //预先烧录了andriod
从SD2的eMMC启动,但如果SD0有系统允许启动,那么就会SD0启动,只有校验和(checksum)不通过的时候才会试图从SD2启动,也就是说SD0的出厂bootloader破坏掉才能从SD2启动。
USB启动,1xxxx1

101100 SD
101101 USB(优先级高于SD卡)

现在用JTAG、JLink调试已经不再普遍了,调试用USB,量产用SD

2.12 ARM的编程模式和7种工作模式

3种指令集:大部分ARM Core提供ARM/Thumb/Thumb2指令集
Thumb (16bit) 每条指令16个位,是不健全的(比如一个异常处理事件要用两个16位指令)
Thumb2 (16 & 32 bit)
前辈的年代:ARM和THumb来回切换的年代
朱的年代:ARM指令集,纯32位的年代,讲求效率,牺牲一些内存
我们的年代:Thumb2是ARMv7之后才出来的产物,代表16和32加和的年代

Jazelle支持Java bytecode,为JAVA做了优化,支持java快速运行

ARM的7种工作模式
非特权模式:
-User:大部分任务执行的模式

特权模式:
异常模式:
-FIQ:快中断模式 Fast interrupt //中断
-IRQ:普通中断模式 //中断
-SVC:复位或软中断后进入该模式 Supervisor //引导内核的
-Abort:存取异常模式
-Undef:未定义指令
系统模式:
-System:寄存器集和USER模式相同 //OS内核专用的

在做裸机实验的时候这是没有意义的
区分这些模式是为了安全级别要求,设计多种模式是未了方便OS的多种角色安全等级需要。
硬件和软件是互相考虑的关系,而不是对立的关系。ARM的CPU出来肯定是要跑操作系统的
Linux诞生于1991年,设计出的操作系统肯定是接受前面OS的约束,从而让CPU的编程可以移植

2.13 ARM的37个寄存器详解
37个通用寄存器,可以看做ARM CPU的特殊功能寄存器
每一个特殊功能寄存器靠特定的地址进行访问
通用型寄存器没有特定地址,每个通用寄存器有一个名字 ——”r0 - r15“

[下图就是ARM所有的37个寄存器了]

√当前可见寄存器(18个)
r0 - r12
r13 (sp) 堆栈指针。比如中断来了,需要保护程序上下文转到中断。堆栈是程序的工作现场,每种模式下都有不同的现场,万一中断的程序崩了,整个系统还能用(狡兔三窟么)
r14 (lr ) 存储返回地址的。IRQ工作完回到User的时候,直接 BL lr 可以回到User模式。也可以做函数调用,所以每种模式下也都有lr
r15 (pc) 程序计数器,当前程序执行到哪儿了,所以只有一个

cpsr    程序状态寄存器,记录CPU当前所处的状态
spsr    用来保存cpsr的

备用寄存器(模式名是举个栗子用的,使用的时候和visble同名寄存器相互替换)
User r13 - r14

FIQ r8 - r14 + spsr

IRQ r13 - r14 + spsr

SVC r13 - r14 + spsr

Undef r13 - r14 + spsr

名字重复:看处理器的模式了。
ARM总共有37个寄存器 但是每种模式下最多看到18个寄存器!不同模式下的r13是不同的寄存器
在每种特定模式下,只有一个r13是当前可见的,其他的r13必须切换到他的对应模式下才能看到。
上述设计称为影子寄存器 (banked register)

[CPSR] 中断禁止位:-I =1:禁止IRQ
    -F=1:禁止FIQ
           NZCV条件位:(重要,平时是0,运算发生了什么就会置1)-N = Negative result from ALU    //运算获得负结果
    -Z = Zero result from ALU        //运算得0
    -C = ALU operation Carried out   //进位标志位
    -V = ALU operation oVerflowed    //溢出

[PC_r15]程序控制寄存器:也叫做程序指针
非常重要的一个寄存器,想执行那一段代码就把指针放到那个地方。

ARM指令举例:
BLE 若相等(上一句)跳转 // branch lr equal
这里看是不是相等就是用的 Z位,我们不会直接接触他们。

2.14—ARM的异常处理方式

预料之中的异常:FIQ 、IRQ、 SVC (中断也是一种异常)
预料之外的、真正的异常:Abort(收到干扰了/CPU不知所措了)、Undef

CPU是不知道什么时候中断的,对此完全无法预测。我们点鼠标对于写程序的人来说就是一个异常,他永远也不会预测到我们什么时候点鼠标从而发生中断。

处理机制:现场保护
异常向量表
所有CPU都有,是硬件决定的。是硬件向软件提供的处理异常的支持。
当异常发生时,CPU会自动动作(PC跳转到异常向量处,处理异常)

异常发生时,
1、拷贝CPSR到SPSR,
2、设置CPSR(改变处理器状态至ARM状态,进入相应异常模式)
3、保存返回地址到LR

返回时,
1、通过SPSR至CPSR
2、从LR恢复PC
(上述操作只能在ARM态执行,Thumb指令不完整)

2.15ARM汇编指令与伪指令
共同组成可执行程序,伪指令在编译后不生成机器码,是编译环境提供的,是一种工具

两种风格:
ARM风格:多在win下IDE种出现 LDR R0,[R1]
GNU风格:多在linux环境下使用 ldr r0,[r1]

指令不可能有很大差别。不同编译器的伪指令之间的差异非常大。
我们的汇编都围绕GNU汇编,后面的工作都是在GNU下进行
[插] Git:linux程序的衍生物,版本管理工具

LDR/STR架构 (load register/store register)
ARM采用RISC架构,CPU本身是不能读取内存的,必须将内存的内容转入寄存器中才能处理
[ARM架构 中 CPU只能操作寄存器而不是内存]
ldr 指令将内存内容加载入通用寄存器
str 指令将寄存器内容存入内存
LDR/STR实现CPU与内存之间的数据交换

ARM的8种寻址方式(注意地址的寻址方式)

寄存器寻址 mov r1 , r2 //R1 = R2,通过寄存器找到寄存器
立即寻址 mov r0 , #0xFF00 //r0 = 0xff00;
寄存器移位寻址 mov r0,r1, lsl #3 //r1左移3位,把这个数赋值给r0(本例乘以8)
寄存器间接寻址 ldr r1 , [r2] //[r2]表示内存,r2本身是一个地址,这类似指针
//把内存地址里的值赋给r1(C的指针也是这么来的)
基址变址寻址 ldr r1,[r2,#4] //(r2+4)这个地址代表的内存
多寄存器寻址 ldmia r1!,{r2-r7,r12} //一次访问7个寄存器,
//r1是起始,依次往后访问,然后读出来放到后面的寄存器
//ld就是load,加载的意思,加载肯定是从内存到寄存器
//寄存器到寄存器不叫加载,而是mov
//ld或者st的指令肯定一个是内存,另一个是寄存器
//相当于一个r1数组,依次读出来丢到寄存器里去
堆栈寻址 stmfd sp!,{r2-r7,lr} //不操作寄存器,而是操作堆栈的多寄存器寻址(道理同上)
相对寻址 beq flag //以PC为参考,加一个偏移量。PC放要执行的程序代码
//可以实现跳转多少个字节执行代码

标号“:”标号代表类似函数名的存在,c语言也是有标号的
eg: b reset
reset:
语句/指令……

ARM汇编的指令后缀
同一个指令加不同的后缀可以衍生出不同的指令族,常用的有
B(byte) 功能不变,操作长度变为8位
H(half word) 操作长度变为16位
S(signed) 操作变为有符号
以上三个后缀使用例如:ldr ldrb ldrsb ldrsh(一般是用ldr,即32位。个别情况下不能读某些位才用ldrb等)

S(s标志) 影响CPSR标志位(默认操作数是不会影响CPSR中的nzcv位的)
如 mov movs
举个例子:减法:5-5=0,默认z位是不会改变的
mov r0,#0 //r0=0,不会影响CPSR里面的位,因为没有s后缀
movs r0,#0 //r0最后的值为0,又有s标志,会影响CPSR里面的Z位,Z=1

ARM的条件执行后缀
是ARM特有的一种特性。ARM的每一条指令都可以带一条条件执行后缀,决定当前指令执行,还是不执行
eg: mov r0, r1 @r0 = r1
moveq r0, r1 @若eq条件成立则执行mov r0, r1,不成立则不执行
@类似于c语言 if(eq) {r0 =r1;}
eq是前一句指令决定的。上一行代码eq成立,则执行moveq
条件后缀决定本句代码是否执行,对前后代码是否执行无影响
后缀名(助记符) 标志

eq(重要)Z=1相等equal
ne(重要)Z=0unequal
cs/hs(重要)C=1无符号数大于或等于
cc/lo(重要)C=0
miN=1负数minus/negative不应该简写成ne
plN=0plus,非负数
vsV=1溢出
vcV=0
hi(重要)C=1,Z=0
lsC=0,Z=1
geN=V有符号数大于或等于greater/equal
ltN=!V有符号数小于less than
gt(重要)N=V有符号数大于greater than
leN=V
AL无条件执行
NV从不执行

以前讲过,nvcz四位记录着指令执行的结果,但不会直接用。现在知道了,包括在后缀名里

ARM的多级指令流水线:三级:取指-解码-执行
流水线越多,运行速度就更快。但如果流水线被打断,那么回复过程就越复杂(例如CPU跳转,需要置空流水线,重新填充。CPU跳转是可以被预测的,ARM的CPU预测成功率有60%左右)
ARM11为8级流水线,210使用13级流水线
编程中的流水线:(以ARM状态举例,Thumb状态分别为pc,pc-2,pc-4)
PC -> 指令 【pc所指的是正在被取指的指令,而不是被执行的指令】
pc-4 -> 解码指令中用到的寄存器
pc-8 ->执行 寄存器读,移位/ALU操作,寄存器写
中断返回会遇到 ”-8“操作,以后会用到的喂!.

2.17ARM汇编数据处理指令
算数传输指令 mov(move,两个[寄存器,或是立即数]之数据传递)
寄存器寻址 mov r1 , r2 //R1 = R2,通过寄存器找到寄存器
立即寻址 mov r0 , #0xFF00 //r0 = 0xff00;

    mvn(mvn是按位取反之后传递)

算数指令 add sub rsb adc sbc rsc
逻辑指令 and orr eor
bic(位清除指令)
bic r0,r1,#0x1f
将r1中的数的bit0到bit4清零后,赋值给r0
比较指令 cmp(比较两数是否相等)
cmp r0,r1 //内部是sub r0,r1,但sub本身不能这么用,正确:sub r2,r0,r1
//减出来的结果不要了,直接影响CPSR的标志位

    cmn     //内部是add r0,r1,看两数是否为相反数tst     //测试某一位是否为0tst r0, #0x08   //测试bit3是否为0,下一句可以是:XXXNE ...teq     //测试等价,进行EOR,异或teq{条件}   op1,op2

【注意:比较指令不需+s就可以影响CPSR标志位】
乘法指令 mul mla umull umlal smull smlal
前导零计数 clz

移位指令
LSL 逻辑左移
LSR 逻辑右移
ASL 算术左移
ASR 算术右移
ROR 循环右移

CPSR访问指令
不能用mov去读写它,比较敏感所以专门去设定了指令
mrs:用来读cpsr/spsr
mrs r0,cpsr

msr:用来写cpsr/spsr
msr cpsr,r0

eg:

mrs     r0, cpsr
bic     r0, r0, #0x1f
orr r0, r0, #0xd3
msr cpsr,r0
//set CPU to SVC32 mode and     FIQ & IRQ Disabled(仔细揣摩一下)msr cpsr_c, #0xd3
//cpsr_c指的是cpsr中的某控制位,而不影响其他位,具体看cpsr的详细资料。

ARM跳转指令
执行子函数、中断等等
b branch 直接跳转
bl branch and link 跳转前把返回地址放入lr寄存器以便返回,用于函数调用返回
bx 跳转同时切换到ARM模式,用于异常处理的跳转(现在基本不用)

ARM访问内存指令
ldr读
str写
多字批量访问:ldm/stm m:multiple 一次读取16个内存内容放到4个寄存器
内存和寄存器互换指令:swp 一边读一边写
swp r1, r2 ,[r0] c: r1 = *r0 r0 = r2 互相转了一下,做交换
swp r1, r1 ,[r0] 一条指令完成r1和[r0]内容交换

ARM中的立即数
合法立即数:立即数的数量是有限的,满足数量限制而且 任意移位后非零部分可以用8位表示
合法立即数举例: 0xff 0x00ff0000也合法,移位之后可以用8位表示
非法立即数: 0xf000000f

软中断指令
swi software interrupt
实现操作系统中系统调用

2.18 ARM汇编与协处理器指令
opcode:操作数
rd:通用寄存器

mcr 读取cp15 cp就是协处理器的意思:coproccessor
mrc 写cp15

协处理器:用来协助主处理器来处理的。是SoC另一处理核心。ARM支持多达16个协处理器,但一般只实现一个
这一个即是cp15
协处理器与MMU、cache、TLB有关。比如MMU启动,清除cache等

示例代码:

mcr {<cond>}  p15 ,0 , {<crn>}, {<crm>}, <opcode>   主要是用来控制c1的
mrc p15, 0(恒定), r0, c1, c0, 0       //将cp15的寄存器c1的值读到r0中
bic r0, r0, #0x00002000     @clear bits 13 (--V-)
bic r0, r0, #0x00000007     @clear bits 0,1,2 (-CAM),禁止MMU或PU,禁止对齐检查、禁止cache
orr r0, r0, #0x00000002     @set bit 1(--A-)使能地址对齐检查,是不是4字节对齐
orr r0, r0, #0x00000800     @set bit 11(Z===)使能跳转预测指令,与流水线是有关的
mcr p15, 0(恒定), r0, c1, c0, 0       //将r0的值写到cp15的寄存器c1

再举例:打开MMU

mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #0x01;
mcr p15, 0, r0, c1, c0, 0

之后的地址全部当做虚拟地址映射了,这部分以后再说了嘿!

三星原厂的代码也是很多错误的,在此时发现了一个bug喂
这些地方是不需要自己去搞的很明白的,业界接触的机会不多,除非原厂设计或者问题非常诡谲

cpu里面的寄存器都是r0,r1,r2
协处理器里面的寄存器以c开头:c0,c1,c2
~~~~查找:arm cp15

2.19 ldm/stm指令批处理和栈
可以看成并行的多个ldr/str,为了提高访问大量数据的效率
ldm(load regisrer multiple)

举例 from uboot

stmia sp , {r0 - r12}       @ia:每次传送后地址+4,即一个寄存器,32位    increase after@ib:先地址+4然后再传送          increase before@Save user registers。从r0-r12写到sp指向的内存处@过程:r0存入sp指向内存(假设0x30001000),地址+4,将r1存入(0x30001004)……直到r12存入@理解:空增栈

关于ia系列其他后缀:
da
db decrease
四种堆栈:
fd full decrease 满递减堆栈
ed empty decrease 空递减堆栈
fa full add 满递减堆栈
ea empty add 空递增堆栈

堆栈的概念:堆栈是大家这么认为的,最早期的时候胡乱翻译造成的。堆栈其实就是栈
空栈:栈指针指向空位,每次存入可以直接存入并且向后一格(+4),取出时需要先移动才可以取出
满栈:由于sp指向的是最后一个元素,不能直接存,不然把最后一位冲掉了,所以需要先移动一格然后再存入
增栈:栈指针移动时向地址增加的方向 0x00 to 0x04
减栈:栈指针移动时向地址减小的方向 0x08 to 0x04

================================================-

三、开发板、原理图和数据手册
–Attention: OTG-USB3.0 UART左 - USB2.0↑
开发板刷机
0、前置工作:安装串口监视器secureCRT、绿联 USBto串口驱动

1、清除inand原有的bootloader试图从SD2启动
UserManual 的x210v3开发板SD卡烧写教程。
进入android系统控制台,打开SecureCRT连接device串口,开始进行监视。开机后,显示开机信息
执行如下指令:

busybox dd if=/dev/zero of=/dev/block/mmcblk0 bs=512 seek=1 count=1 conv=sync
sync
回执显示; 1+0record in;1+0recode out;证明成功

dd命令:是用来读写磁盘的指令 if=input file of=output file

破坏的是磁盘的第一个扇区,自然会启动andriod失败,从而试图从SD2启动
此时SD2缺少启动代码,启动失败(CheckSum ERROR)

2、SD卡烧写:x210Fusing Tools,烧写uboot_iNand.bin文件
插入SD卡,打开解压好的 x210Fusing Tools
打开image文件夹,选择uboot_iNand.bin,大小大概为300K,START。
取出SD卡,就可以把SD塞到板子里,现在可以进入uboot(3210那个倒计时)

开机后会开始倒数,3,2,1.如果没按回车键,uboot会自动启动。终止启动进入uboot模式

3、fastboot(开始前需要连接USB线 )
在磁盘根目录下创建配置fastboot文件夹,在 /#210(secureCRT下 uboot模式下),输入fastboot指令
secureCRT下 进入#210,fastboot,进fastboot模式
运行cmd
cmd下:
d:
dir // = linux ls
cd fastboot //进入D:/fastboot 文件夹,才能使用cmd下fastboot系列指令

先 fastboot devices看看在不在

fastboot flash bootloader linuxqt4.8/uboot_inand.bin 烧uboot
fastboot flash kernel linuxqt4.8/zImage-qt 烧linux kernel
fastboot flash system linuxqt4.8/rootfs_qt4.ext3 烧android rom,也就是操作系统

fastboot flash [分区] [目录/文件] 这里的分区有6个,进去fastboot 的时候会说

烧写完成后就可以重启了。
方法一:reset
方法二:拔电源
方法三:(专业方法)cmd下输入指令 fastboot reboot

SD卡刷机较为简单,DNW刷机较为困难

=============================================================

3.8原理图导读

》———— 《————
网络,同名网络实际上是相互连接的

CPU原理图有好多张,其实都是s5pv210,因为有三五百个引脚,区分成模块就比较好看

若要知道s5pv210【原理图】上某个模块的引脚怎么使用怎么编程,就要去查【数据手册】,再看【CPU里面的定义】
看英文的数据手册这个是躲不过的QAQ

=============================================================

3.9 dnw烧机(不一定需要,SD卡能用就用SD卡)

这个过程参考光盘X210_dnw刷机.txt,九鼎官方所写。
通过usb直接到iROM中运行。
两个刷机文件:x210_usb.bin uboot.bin

===========================================================

3.10 Linux下dd命令刷机

1、SD卡连接入linux
注意:一个SD卡或者U盘是不能同时连接进windows和linux中的
需要在VMware,“虚拟机→可移动设备“菜单中,点选我们要连接的移动设备。
插入SD卡之后,在linux的 ls /dev/sd*命令后查看SD卡设备
我们的SD卡是sdb(自己有时候是mmcblk0)

2、刷卡
用SecureCRT将nand_fusing.sh放到linux下,这是个刷卡用的脚本
./nand_fusing.sh /dev/sdb

===========================================================

12.1 I2C
I2C: 物理结构非常简单,只有两根线。SCL+SDA
SCL是时钟线,传输CLK信号,一般是I2C的主设备向从属设备提供时钟的通道
(serial clock 串行时钟)

SDA是数据线,通信数据通过SDA传输
(serial data    串行数据)

通信特征:串行、同步、非差分、低速率
同步:工作在同一个时钟。一般是方通过一根CLK信号线传输A自己的时钟给B,B在A传输的时钟下工作
同步通信的显著特征就是有CLK线
非差分:即是电平信号。只有高速的通信(如USB)才会使用差分信号抗干扰。通信双方距离近,干扰本来就少
低速率:I2C一般是用一个板子上两个IC之间的通信,用来传输的数据量不大,一般只有几百K/s

每个I2C设备都有一个从地址,该地址是唯一的,是设备本身固有的设备,在通信中通过地址来甄别各个I2C设备。

电平通信:绝对的电压是没有意的,电压差是真正的意义。电平信号的传输线中有一个参考电平线(一般是GND)
容易受到干扰,届时传输失败
8位二进制并行通信时:需要9根线(1参考GND+8数据线)
差分信号:也是两条线,但是没有1和0,通过高电平减去其对称的低电平(详情1.7.1 37分钟),可能有9V-0.6V
最显著的特征就是抗干扰能力比较强,传输质量比较稳定,现代通信一般使用差分信号,电平信号很少。
而且电压整体上移或者下移没有影响。
8位二进制并行通信时:需要16根线(8x2数据线)

串行通信和并行通信:看起来并行通信快一些,但是串行通信才是王道,因为省信号线,速度可以由通讯提高。

经过发展,最终胜出的通信:异步、串行、差分(USB和网络)

=============================================================

十四、LCD显示器

14.1显示器
LED:特点是背光强、廉价,多用于街道显示屏
OLED:新型的显示器件,用于穿戴设备,很可能成为下一代主流显示器
LCD液晶显示器:目前的主流显示器,轻小且薄。在电的驱动下选择,从而改变其透光性,背后加一个白光即在面显示颜色。
电阻屏:早期触摸屏手机的配备输入输出设备,已经淘汰。
共阴极射线管(CRT显示器):大屁股电视电脑,日本掌握其核心科技,已经淘汰
等离子显示器:10年前后风行的数字电视技术

======================================================

十五、触摸屏

15.1输入设备简介
IO:input/output 输入输出,计算机 与 外部设备的交互接口
触摸屏和显示屏的区别:两者一般放在一起。其实我们的常说的触摸屏其实是两层的。一层用来显示(LCD),上面的是触摸屏
LCD本身是显示图像的,触摸是没有效果的
触摸屏是透明的一层屏幕,只是提供输入操作。制作工艺上要求透光性(>98%)
LCD显示屏和触摸屏两者完全不同,是完全分开的。

【笔记】ARM裸机程序开发_part1相关推荐

  1. 【笔记】ARM裸机程序开发_part2

    四.GPIO和LED 4.1usb配置DNW启动 DNW驱动安装需要数字签名,我们装好驱动后,连接USB线,配置DNW 下载地址是0xd0020010(这个地址是BL1的地址,约定好辣~) 按住pow ...

  2. aiku基于mini2440下裸机程序开发《概述与SDRAM运行》

    大家好,我是aiku,今天主要跟大家介绍一些 基于mini2440下裸机程序开发<概述与SDRAM运行> 有什么问题:都可以联系我们,谢谢! 我是aiku,本博客主要写一些我们的项目经验与 ...

  3. arm裸机程序启动流程

    Linux系统的引导: 一个SOC拿过来,它是有内部BROM和SRAM的,这个BROM中会固化芯片厂商的最初引导代码,我们叫它RBL(ROM boot loader),它是SOC上电后开始运行的地方, ...

  4. Java学习笔记——实现国际化程序开发 附:不同的国家/地区与语言缩写代码

    Locale类 要想实现国家化程序开发:首先需要解决的是不同国家用户的区域和语言编码问题,在java.util包里面提供有一个专门描述区域和语言编码的类,Local类,主要使用两个构造方法进行实例化: ...

  5. Keil5 平台 S3C2440裸机程序开发-----中断系统/UART

    目录 前言 一.启动文件 二.代码 main.c uart.c uart.h led.c led.h S3C2440.h 三.编译,烧录,打开串口助手,接收到数据. 前言 本博文介绍mini2440开 ...

  6. ARM 裸机程序学习 03 - 发送SOS信号(汇编 + C)

    之前的两个示例程序都是完全由汇编编写的,而这次的示例程序由汇编和C语言写成并编译. 汇编自有汇编的优点,比如你可以非常清楚地知道CPU在执行每条指令时到底做了什么,怎么做的,数据到底保存在哪儿等等,但 ...

  7. Keil5 平台 S3C2440裸机程序开发-----UART

    目录 前言 一.时钟频率 二.代码 main.c uart.c uart.h led.c led.h S3C2440.h 三.编译,烧录,打开串口助手,接收到数据. 前言 本博文介绍mini2440开 ...

  8. Keil5 平台 S3C2440裸机程序开发-----定时器中断

    前言 本博文介绍mini2440开发板,在keil5平台上进行定时器中断开发的一些基本配置. 一.定时器配置 ​ #include "S3C2440.h" #include &qu ...

  9. Keil5 平台 S3C2440裸机程序开发-----看门狗定时器

    目录 前言 一.看门狗定时器配置 二.源码 前言 本博文介绍mini2440开发板,在keil5平台上进行外部中断开发的一些基本配置. 一.看门狗定时器配置 PCLK=50MHz,预分频值设置为249 ...

最新文章

  1. python urllib.request 爬虫 数据处理-python 爬虫之 urllib库
  2. 6 有序集合ZSet(Sorted Set)
  3. OllyDbg 使用笔记 (十二)
  4. Django(part13)--过滤器
  5. 百度SEO Typecho仿Win95怀旧主题
  6. JavaScript 压缩 加密 解密
  7. Ontology与OO作为一种需求分析或软件构建方法的存在意义
  8. 随想录(octave软件)
  9. Maven搭建webService (一) 创建服务端---使用main函数发布服务
  10. 苏宁收购天天快递,海航哭晕,申通老板怒赚20亿
  11. linux应用程序开发指南-开发工具介绍
  12. 科学计算机怎么用10次方,一个数怎么用计算器开10次方
  13. 会声会影2020迅雷磁力链接bt搜索种子百度云网盘下载及有效序列号
  14. windows黑客编程系列(六):进程遍历之查询系统是否运行杀软
  15. Kerberos认证协议
  16. mysql数据写入磁盘的原理_WAL(Write Ahead Log)机制解析
  17. html显示latex公式,wordpress显示数学公式插件【LaTeX转HTML】
  18. 挖到这个高危SSRF漏洞,我和我的小伙伴们都惊呆了!
  19. 大型分布式网站架构设计与实践3
  20. 案例-站狼云品智美站助力必信空调中国制造领先品牌...

热门文章

  1. 顾城其实很可怜 舒婷回忆:他一辈子都在为钱发愁
  2. 利用eda函数对文本数据进行增强
  3. Google advertiser api开发概述——最佳做法建议
  4. Contiki开发1:Contiki与8位MCU
  5. node.js里的天龙八部
  6. stm32外设-DMA
  7. python英文分句_教你如何对英文段落进行分句
  8. 常见面试题(无答案)
  9. 推荐的几本数学书【by DaHua Lin】
  10. 用apline-linux创建的tomcat容器中查看catalina.out日志中文乱码问题解决