点亮LED:
GPIO:控制寄存器 数据寄存器
Ds: 2.2.2 prot group GPA0 control register
正常状态下,6个寄存器
1、原理图查找LED对应引脚
2、开发板图对应引脚
3、代码编写
GPBCON(控制寄存器) GPBDTA(输出寄存器)
a) 设置引脚模式为输出
b) 设置引脚为高电平
210需要在BIN文件前加一个头mkv210_image.c文件编译
在关闭cache的步骤中,注意210和6410 2440不同,注意查看cortex-A8手册
mcr p15, 0, r0, c7, c5, 0 invalidate instruction cache
mcr p15, 0, r0, c7, c6, 1 invalidate data or unified cache
时钟初始化:
时钟体系(clock):
1、晶振频率。
2、PLL有多少个
3、每个PLL产生多少时钟
4、时钟用于做什么
2440 :(7 clock) 晶振(12MHz)
6410 :晶振(12MHz)
210 : 晶振(24MHz)
配置过程:
1、配置lock time
2、设置分频系数
3、设置fclok
4、设置cpu到异步模式(HDIVN)
Datasheet:
Clock time:
HDIVN 和 PDIVN位的设置
6410:
u-boot代码的Lowlevel_init.s文件中 查看分频系数
210:
Section2 3 clock 设置分频系数3.3
1、搜索lock time(使用默认值)
2、设置分频系数(uboot代码-> lowlevel_init.s -> sys_clock_init -> CLK_DIV0_VAL)
a) CLK_DIV0设置分频
b) 3.7.1 register map -> APLL_CON0设置分频系数
c)MPLL_CON0设置分频系数
d)CLK_SRC0源选择
3、内存
DRAM:需要定期刷新
SRAM:不需刷新,功耗大,价格高,速度快(多用于stepping stone)
SDRAM:同步动态随机存储器(2440)
DDR: 双倍速率同步动态随机存储器(6410)
DDR2: 四倍速率同步动态随机存储器(210)
Logical bank (L-bank)表结构 内存结构AR(行地址)CR(列地址)
容量 =块数* 每块单元格数* 单元字节数
初始化存储控制器
Datasheet: HY75V561620(内存手册210 6410) 查看规格 (4 * 4M * 16bit)
1、地址空间:4GB
2、存储区域DRAM0: 0x20000000->0x3fffffff
DRAM1: 0x40000000->0x7fffffff
3、硬件连接:8片8位内存连接
Section5 1、DRAM CONTROLE
1.2.1.3 DDR2 初始化过程
寄存器设置过程中细节:
列地址线数:10 bit
行地址线数:13 bit
Bank数 :8
循环赋值方法(用于大量寄存器的赋值):
#define mem_control 0x48000000 @首个寄存器地址
Init_sdram:
ldr r0, =mem_control
Add r3, r0, #4*3
Adrl r1, mem_data
0:
ldr r2, [r1], #4 @【r1】的值赋值给r2,并且r1 += 4
Str r2, [r0], #4 @r2的值赋给【r0】,并且r0 += 4
cmd r0, r3 @比较r0与r3
bne 0b @不等则跳转到0处,b:before
Mov pc, lr
Mem_data: @存放寄存器值
.long 0x22000000
.long 0x00007000
.long 0x54008900
。global mem_init @声明mem_init为全局函数
代码搬移:
将NAND flash内的程序代码拷贝进入内存
SRAM地址 :2440 -> 0x00000000
6410 -> 0x0c000000
(iram)210 -> 0xd0020000
链接地址
1、绝对跳转 pc =值
2、相对跳转 pc = pc +差值
C语言环境初始化:
1、栈初始化:
a) 空栈:sp指向下一个存放地址 满栈:指向最后一次放入数据的地址
b) arm系统:满降栈
c) 栈:一个进程拥有一个栈
一个函数拥有一个栈帧(栈的一部分)
栈保存的数据:
a) 保存局部变量
B) 传递参数
C) 保存寄存器的值
Fp:指向栈帧头
Sp:指向栈帧尾
感叹号的作用
@Sp = 8
Str fp, [sp, #-4]! @Sp = 4
Str fp, [sp, #-4] @sp = 8
函数参数小于4个时,使用r1 r2 r3 r4保存参数,大于时则保存在栈中
初始化步骤:
Sp = 内存开始64M后的地址空间
初始化bss段:
全局变量:数据段
局部: 栈
Malloc: 堆
未初始化全局变量: bss段
查看变量储存位置
编译生成elf文件:
Arm-linux-gcc xxx.c -o ccc
查看elf文件,输出到vvv文件中:
Arm-linux-readelf -a ccc >vvv
查看反汇编文件
编译C代码xxx.c
arm-linux-gcc -g xxx.c -o xxx1
反汇编xxx1输出到dump中:
Arm-linux-objdump -D -S xxx1 >dump
步骤:
对bss段清零,在编译脚本中定义了bss起始地址:bss_start和bss结束地址bss_end,初始化时将其存储区域全都赋值为0
moveq pc, lr @如相等的话执行返回,用于检测到bss段为零(bss_start = bss_end)
使用C:
相对跳转: b bl
绝对跳转: ldr pc, =0x00003000
控制台上复制文件夹:
cp dirt1/* dirt2/ dirt1目录下所有文件赋值到dirt2下
C语言与汇编混合编程
1、汇编语言信用C语言函数
ld pc, 函数名
2、c语言调用汇编函数
汇编标号:light_init
必须全局声明标号:
。global light_init
C语言调用:
light_init();
3、C内嵌汇编
_asm_(
汇编语句部分
:输出部分
:输入部分
:破坏描述
);
Void write_p15_c1(unsigned long value)
{
_asm_(
“mcr p15, 0, %0, c1, ,0, 0\n” @0:0号参数
:
:”r”(value) @编译器自动获取一个r*寄存器
:
);
}
Unsigned long read_p15_c1(void)
{
Unsigned long value;
_asm_(
“mrc p15, 0, %0, c1, c0, 0\n”
:”=r”(value) @’=’表示只写操作数,用于输出部分
:
:”memory”
);
Return value;
}
_asm_volatile( @告诉编译器,不要优化此函数
...
);