原创作品:http://write.blog.csdn.net/postedit/7956383
欢迎大家一起交流学习,知识在与分享。
希望结交一些志同道和之士
QQ: 474530676
longguopeng168@163.com
开发板下载程序
启动uboot 拨码开关往上(SD卡启动)
程序下载到nand flash 里 启动 拨码开关往下(nand启动)
将程序通过u-boot烧写到硬盘nand-flash,然后通过nand-flash(拨码开关往下)启动,直接运行程序
程序编写步骤如下:
第一步:
告诉cpu外部设备的起始地址。
因为是在硬盘启动,cpu并不知道,所给的地址对应的是什么设备,所以一开始,必须要告诉cpu所给地址对应的究竟是什么设备。
一开始上电时,ARM11内核里的cpu(smdk6410,并不能说成是纯意义上的cpu,
因为它里面还包括了,ARM11的内核,而ARM11里面仍然包括了很多的寄存器,和协处理器,
所以ARM11也仍然不能说成是纯意义的cpu,只有ARM11里的中心处理器,才能说是纯意义的cpu)
会自动的到nand-flash硬盘里的0地址开始,读前8k的程序到RAM11里的SRAM内存(不是芯片外部的内存)执行,
所以在这8k的程序里必须要初始化外部内存和设备
又因为cpu访问内存和访问外部设备的方式时不一样的,所以在这里要告诉cpu外部设备的起始地址:
0x70000000 - 0x800000000
ARM11里面有一个专门的寄存器p15里的c15,就是用来确定寄存器地址的。
查看内核手册arm1176jzfs.pdf ,第三章3.2.49 342页
c15寄存器的高20位,是用来确定起始地址的,
低4位是用来确定范围的,取值在343页有详细的介绍。设置格式如下:
ldr r0, =0x70000013
mcr p15,0,r0,c15,c2,4 //设置格式是确定的,在344有说明
第二步:
关闭看门狗
芯片上电时,看门狗,和cpu一样,是同时开始同步运行的。看门狗的作用就是,当芯片崩溃时,重新初始化芯片。
当芯片上电时看门狗对一个确定的变量自动减1,当该变量减到0时,就会重新初始化芯片。
所以cpu正常运行时会定时的给改变量赋值,防止看门狗初始化芯片,这个过程就叫作“喂狗”。
在这里为了简单,为了避免看门狗复位芯片,所以需要将看门狗关闭。
查看芯片手册S3C6410X.pdf 第34章,1137页
找到看门狗控制寄存器WTCON 1138页
将寄存器的所有位设置为0,就可以关闭看门狗了
ldr r0, =WTCON
mov r1, #0
str r1, [r0]
下面是一个硬盘启动时,不通过u-boot直接运行的蜂鸣器的程序例子:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//buzzer.S(蜂鸣器)
#define WTCON 0x7E004000
#define GPFCON 0x7F0080A0
#define GPFDAT 0x7F0080A4
.text
.align 2
.global _start @因为直接在裸板上运行的,所以不需要保存环境
_start:
bl set_port @设置寄存器
bl close_wtd @关闭看门狗
ldr r0, =GPFCON @这是初始话蜂鸣器控制器的
ldr r1, [r0]
ldr r2, =(3 << 30)
bic r1, r1, r2
mov r2, #0x40000000
orr r1, r1, r2
str r1, [r0]
mov r4, #10
loop:
ldr r0, =GPFDAT
ldr r1, [r0]
mov r2, #(1<<15)
orr r1, r1, r2
str r1, [r0]
ldr r0, =100000
bl delay
ldr r0, =GPFDAT
ldr r1, [r0]
mov r2, #(1<<15)
bic r1, r1, r2
str r1, [r0]
ldr r0, =100000
bl delay
subs r4, #1
bne loop
l:
b l
.align 2
delay:
subs r0, #1 @s --> cpsr Z beq
bne delay
mov pc, lr
.align 2
set_port:
ldr r0, =0x70000013 @设置寄存起器地址
mcr p15, 0, r0, c15, c2, 4
mov pc, lr
.align 2
close_wtd: @关闭看门狗
ldr r0, =WTCON
mov r1, #0
str r1, [r0]
mov pc, lr
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
第三步:
程序编译步骤:(在虚拟机下)
[root@longguopeng 蜂鸣器]# arm-linux-gcc -c buzzer.S
[root@longguopeng 蜂鸣器]# arm-linux-ld buzzer.o -o buzzer
[root@longguopeng 蜂鸣器]# arm-linux-objcopy -O binary buzzer buzzer.bin
[root@longguopeng 蜂鸣器]# arm-linux-objdump -d buzzer > buzzer.dis
[root@longguopeng 蜂鸣器]# rm -rf buzzer.o buzzer
[root@longguopeng 蜂鸣器]# mv buzzer.bin /tftpboot
第四步:
通过u-boot烧写程序(在uboot下)
1:进到u-boot界面
2:清空从0地址开始,8kb的空间,清空的大小是4kb对齐的
[uplooking]# nand erase 0 0x2000
3:下载程序到开发板的内存的0x50000000
[uplooking]# tftp 0x50000000 buzzer.bin
4:将程序写到nand-flash
[uplooking]# nand write 0x50000000 0 0x2000
5:把拨码开关往下(nand flash启动) 按下复位键
(注:程序运行时,效果是不对的,在u-boot下运行时,是响一下,停一下,
在nand-boot下运行时,一直响着,所以还需要进行下面的设置)
每次都要打这3个命令,显的很麻烦,可以用u-boot的run命令,直接完成这三个步骤
1):查看u-boot是否有run 这个命令,可以用help run
若能找出来,则,证明当前u-boot下已经有了这个命令了
2):若没有则需要重新编译u-boot将run命令打开
vim up6410/src/u-boot-1.1.6/include/configs/smdk6410.h
到(大概)170行 找到 CFG_CMD_RUN 变量
将该变量移到& ~(CFG_CMD_AUTOSCRIPT | \ 的上面
然后重新编译u-boot下就行了
3):确定有run命令后,设置环境变量,加一行:
setenv wstart nand erase 0 0x2000 \; tftp 0x50000000 start.bin \;
nand write 0x50000000 0 0x2000
4):保存环境变量
5):输出 run wstart 命令就可以把程序自动烧写到硬盘了
===================================================================================
显示如下:
/
[root@longguopeng /]# cd home
[root@longguopeng home]# ls
[root@longguopeng home]# cd 蜂鸣器
[root@longguopeng 蜂鸣器]# arm-linux-gcc -c buzzer.S
[root@longguopeng 蜂鸣器]# arm-linux-ld buzzer.o -o buzzer
[root@longguopeng 蜂鸣器]# arm-linux-objcopy -O binary buzzer buzzer.bin
[root@longguopeng 蜂鸣器]# arm-linux-objdump -d buzzer > buzzer.dis
[root@longguopeng 蜂鸣器]# rm -rf buzzer.o buzzer
[root@longguopeng 蜂鸣器]# mv buzzer.bin /tftpboot
=========================================================================
U-Boot 1.1.6 (Jun 8 2012 - 21:54:34) for SMDK6410
****************************************
** UT-S3C6410 Nand boot v0.18 **
** ShenZhen Urbetter Technology **
** Http://www.urbetter.com **
****************************************
CPU: S3C6410@532MHz
Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz, Serial = CLKUART (SYNC Mod
Board: SMDK6410
DRAM: 128 MB
Flash: 0 kB
NAND: 256 MB
SD/MMC: 1880 MB
In: serial
Out: serial
Err: serial
dm9000 i/o: 0x18000300, id: 0x90000a46
MAC: 11:22:33:44:55:66
operating at unknown: 15 mode
Hit any key to stop autoboot: 0
[uplooking]# nand erase 0 0x2000
NAND erase: device 0 offset 0x0, size 0x2000
Erasing at 0x0 -- 1600% complete.
OK
[uplooking]# tftp 0x50000000 buzzer.bin
dm9000 i/o: 0x18000300, id: 0x90000a46
MAC: 11:22:33:44:55:66
operating at 100M full duplex mode
TFTP from server 192.168.1.254; our IP address is 192.168.1.253
Filename 'buzzer.bin'.
Load address: 0x50000000
Loading: #
done
Bytes transferred = 168 (a8 hex)
[uplooking]# nand write 0x50000000 0 0x2000
NAND write: device 0 offset 0x0, size 0x2000
8192 bytes written: OK
[uplooking]#
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\