使用jlink下载程序到nandflash中
这次实验只是下载一个点灯的程序到nandflash中,因为该程序很小,不到4k,所以只拷贝前4k的代码,文章最后说明了通过这种方式下载uboot的步骤
准备知识:
了解s3c2440的启动过程,s3c2440的启动可以分为从nandflash启动和norflash启动。
nandflash启动过程:
注意: 以s3c2440进行开发时,一般在nandflash中“执行启动代码”(其实是存储启动代码),在sdram中执行主要的用户代码,因为nandflash和sdram相对于norflash而言更加便宜。
a. 启动代码搬运:在系统上电时,硬件会自动将nandflash的前4k内存的内容搬运到s3c2440中的SRAM前4k位置(该4k内存空间称为SteppingStone)运行。
b. 硬件初始化:nandflash中的前4k代码主要对s3c2440进行一些初始化操作——关看门狗,初始化SDRAM的硬件寄存器
c. 拷贝代码
第一种情况:如果你的代码很小,小于4k,那么可以直接将s3c2440中SRAM的前4k代码(SteppingStone)拷贝到SDRAM中,因为硬件在上电的时候直接将nandflash中的前4k代码拷贝到了s3c2440的SRAM中,所以SRAM中的前4k代码相当于是nandflash中的前4k代码。(这种情况一般只在做实验时使用)。
第二种情况:如果你的应用代码很大,有几百KB,那么你编写的启动代码就不是从S3C2440的SRAM中拷贝前4k代码到SDRAM中了,而是直接从nandflash中将整个应用代码直接拷贝到SDRAM中去,然后从SDRAM中继续执行。
d. 跳转到应用代码处执行
工具:FL2440开发板(该开发板带有64M的nandflash),jlink调试器,安装jlink 4.08(本次实验使用的版本),串口线
执行步骤
将FL2440通过jlink、串口线连接电脑
找到jlink安装下的J-link Commander打开,如下:
Paste_Image.png
J-link Commander显示如下,说明连接上了:
执行命令
r -- reset, 复位命令
h -- halt, 停机,也有暂停的功能
loadbin
-- 下载filename文件到地址上address
setpc
-- 设置PC的值
g -- 程序运行
对应这几个命令我的操作如下:
r 复位:
复位操作.png
h-停止/暂停:
停止/暂停
loadbin-下载程序到指定的位置:
loadbin下载程序
setpc-设置PC地址,表示从该地址运行
setpc命令,表示从改地址运行
g-运行
g-运行
可以看到开发板上led灯被点亮
注意:如果需要下载的是uboot,则上面的sdram.init功能应该换成是——搬运nandflash中整个应用代码到SDRAM,下载uboot的操作如下, 接上面的g-运行步骤后:
执行:
下载特制的uboot:
h-停止/暂停命令
loadbin e:\u-boot.bin 0x33f80000 下载uboot到0x33f80000地址位置,该地址请根据实际情况进行调整
setpc 0x33f80000 设置PC地址
4 . g 运行
5.结束
如果一切正常,则现在,u-boot已经启动了,在串口调试工具上可以看到相应的界面(在开始连接串口线时,要打开串口调试工具,并保证FL2440与电脑是稳定相连的),以后就可以通过网络、串口下载文件,然后使用u-boot里的命令进行烧写。
以上是针对nandflash启动的,其实norflash启动只需要更改相应的下载地址。
代码如下:
head.S文件内容
@*************************************************************************
@ File:head.S
@ 功能:设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行
@*************************************************************************
.equ MEM_CTL_BASE, 0x48000000
.equ SDRAM_BASE, 0x30000000
.text
.global _start
_start:
bl disable_watch_dog @ 关闭WATCHDOG,否则CPU会不断重启
bl memsetup @ 设置存储控制器
bl copy_steppingstone_to_sdram @ 复制代码到SDRAM中
ldr pc, =on_sdram @ 跳到SDRAM中继续执行
on_sdram:
ldr sp, =0x34000000 @ 设置堆栈
bl main
halt_loop:
b halt_loop
disable_watch_dog:
@ 往WATCHDOG寄存器写0即可
mov r1, #0x53000000
mov r2, #0x0
str r2, [r1]
mov pc, lr @ 返回
copy_steppingstone_to_sdram:
@ 将Steppingstone的4K数据全部复制到SDRAM中去
@ Steppingstone起始地址为0x00000000,SDRAM中起始地址为0x30000000
mov r1, #0
ldr r2, =SDRAM_BASE
mov r3, #4*1024
1:
ldr r4, [r1],#4 @ 从Steppingstone读取4字节的数据,并让源地址加4
str r4, [r2],#4 @ 将此4字节的数据复制到SDRAM中,并让目地地址加4
cmp r1, r3 @ 判断是否完成:源地址等于Steppingstone的未地址?
bne 1b @ 若没有复制完,继续
mov pc, lr @ 返回
memsetup:
@ 设置存储控制器以便使用SDRAM等外设
mov r1, #MEM_CTL_BASE @ 存储控制器的13个寄存器的开始地址
adrl r2, mem_cfg_val @ 这13个值的起始存储地址
add r3, r1, #52 @ 13*4 = 54
1:
ldr r4, [r2], #4 @ 读取设置值,并让r2加4
str r4, [r1], #4 @ 将此值写入寄存器,并让r1加4
cmp r1, r3 @ 判断是否设置完所有13个寄存器
bne 1b @ 若没有写成,继续
mov pc, lr @ 返回
.align 4
mem_cfg_val:
@ 存储控制器13个寄存器的设置值
.long 0x22011110 @ BWSCON
.long 0x00000700 @ BANKCON0
.long 0x00000700 @ BANKCON1
.long 0x00000700 @ BANKCON2
.long 0x00000700 @ BANKCON3
.long 0x00000700 @ BANKCON4
.long 0x00000700 @ BANKCON5
.long 0x00018005 @ BANKCON6
.long 0x00018005 @ BANKCON7
.long 0x008C07A3 @ REFRESH
.long 0x000000B1 @ BANKSIZE
.long 0x00000030 @ MRSRB6
.long 0x00000030 @ MRSRB7
led.c文件内容
#define GPBCON (*(volatile unsigned long *)0x56000010)
#define GPBDAT (*(volatile unsigned long *)0x56000014)
int main()
{
GPBCON = 0x55555;
GPBDAT = 0x00000000;
return 0;
}
Makefile文件内容
sdram.bin : head.S led.c
arm-linux-gcc -c -o head.o head.S
arm-linux-gcc -c -o led.o led.c
arm-linux-ld -Ttext 0x30000000 head.o led.o -o sdram_elf
arm-linux-objcopy -O binary -S sdram_elf sdram.bin
arm-linux-objdump -D -m arm sdram_elf > sdram.dis
clean:
rm -f sdram.dis sdram.bin sdram_elf *.o
注意:我们这个代码是最终效果是将生成的sdram.bin文件烧写到nandflash的0地址,然后通过将该程序搬运到SDRAM中去运行,所以Makefile中的连接地址是0x30000000。