1、从led切入
问题:
有些芯片输出的电流非常弱 ------> 引脚驱动能力不足?
解决:使用三极管来进行放大:
分析:同名的称之为网络, 同名的网络是连在一起的。
2、S3C2440的框架和启动过程
启动过程:
1、设置为norflash启动:
cpu直接从norflash 读取指令执行。
注:设置为谁启动,谁的基地址就是 0, norflash启动的时候,片内SRAM 还可以进行访问,他的地址为 0x4000 0000;
2、设置为nandflash启动:
cpu不可以直接从 nandflash 读取数据。
但是我们硬件,会自动复制nandflash 的前4K 内存 到片内RAM。
然后cpu ,再从片内 RAM 执行代码。
注:nandflash 启动的时候,norflash 不可以进行访问。
3、soc的一些概念
1、cpu 有自己的通用寄存器:R0 — R15。
2、各个外设有自己的 SFR :专用寄存器。
区别:
1、cpu可以通过 R0 寄存器的名称,直接访问。
2、但是 cpu 访问 SFR ,必须通过对应的地址来进行访问。
4、编程实践
1、逻辑操作:
缺点:
这些直接操作,虽然我们将我们需要的位置1,但是我们同时也清除了其他位。
(影响了其他位。)
2、一些基本的arm汇编指令:
LDR RO [R1] :假设R1的值是X,读取地址X上的数据,保存到 R0 寄存器当中
load :加载到寄存器。 []: 对寄存器里面值的取值
STR RO [R1] :假设R1的值是X,把R0 的值,写入到地址 X 当中。
store :写内存。 []: 对寄存器里面值的取值
MOV RO R1 :将 R1 的值赋值给 R0
MOV R0 #100 : 将100赋值给 R0
注:
1、非法立即数
MOV R0 #123456789
这个指令是错误的(后面汇编与指令码中讲解)
初步解析:ARM的一条指令最终会被编译成 32 的机器指令,如果是一个非常大的数放不下。
2、引入伪指令:就是不是真实的汇编指令, 在被编译的时候,会被改成真正的汇编指令。
伪指令:就是加一个 ”=“ 等于号
LDR R0 =0X12345678
3、汇编和机器码
解释汇编伪指令
通用寄存器的别名:
注:
1、pc(program count ) 程序计数器是什么东西?
其实是 通用 R15寄存器的别名。
2、流水线 — arm为三级流水线(为了节省cpu的时间)
假设当前在执行 A 地址处的机器指令,
那么当前就在对 A+4 地址处的机器指令进行译码。
最后 PC指针正在读取 A+8 地址处的机器指令。
4、真正了解 mov 指令转化为机器指令
mov r0 #0x100 ;
转为了机器码为: e3a00c01
mov 机器码格式
5、进制
1、计算:
2、八进制和十六进制 与二进制的关系。
3、二进制,八进制,十六进制如何快速转换
6、字节序(大小端)模式
7、c语言编写led
1、普通变量,指针变量, 任何一个变量,在内存中都占有一块区域。
2、如何操控内存。
- 直接通过变量名
int a;
a = 123;
解析: 就是从 变量a 地址处开始,往后面延续 4个字节的大小,然后写入 123。
两个要点:
(1)往后延续多长:由变量名的类型决定, int
(2)写入多少: 由赋值决定。
- 通过指针来操控内存
int *p1;
p1 = &a;
*p1 = 234;
三个要点:
(1)从哪个地址开始: &a
(2)延续多长:int * (4个字节)
(3)写入多少: 234
总结:使用指针来写入寄存器
这里有一个错误: unsigned int * 的指针 不可以直接赋值 int类型的数字。 要加上强制转化(骗过编译器)。
5、c语言内部机制
1、main 函数在哪里被调用?main 函数的变量(局部变量)保存在哪块内存?
在我们的逻辑程序当中, main函数在启动代码(汇编文件)当中调用。
要明白,局部变量被保存在 栈当中。
2、c语言 -----> 汇编指令
引入新的汇编指令:
- sub,add
想要分清楚,最后是改变谁。---- 最终改变的是目的操作数。
add r0, r1, #4 r0 = r1 + 4
sub r0, r1, #4 r0 = r1 - 4
sub r0, r1,r2 r0 = r1 - r2
- b 和 bl 指令
bl :brarch and link。
(1) 跳转到 XXX
(2) 将返回地址保存在 lr 寄存器当中。 返回地址 : 下一条指令的地址。
- ldm 和 stm指令
ldm:load many ,读内存,写入多个寄存器
stm :store many ,把多个寄存器的值写入内存,
ldmia:
stmdb:
后缀: ia ,ib ,da , db 的含义
举例:
stmdb sp!, {
fp,ip,lr,pc}
db : 就是先减后存的意思。
注: { }里面的寄存器,怎么排序无所谓, 存放规则: 高编号寄存器存在高地址处。
ldmia sp, {
fp,sp,pc}
ia :先读取后增加。
没有 ! :意思就是 sp 虽然移动但是不改变自己本身的值。
理解:就是将 sp 指针指向内存的值, 读取到寄存器当中。 ---- 本质就是恢复原来函数的现场。
3、c语言内部机制
1、整体浏览程序框架
问题:
我们代码和局部变量怎么存放?
代码–机器指令 (放到内存中----称之为代码段)
变量–变量的值 (放到内存中----称之为栈)
1、调用 “main” 函数时候,保存一个地址到 lr 寄存器当中, 返回什么地址?
2、在 C语言函数的开头,汇编帮我们做了些什么?
将fp ,lr ,ip ,pc 寄存器压入栈: