让LED程序在片外SDRAM中运行

一、引子

在前一篇文章中,我们已经成功点亮过LED了,为什么还要再重复一次呢?

我们已经知道,Mini2440开发板有两种启动模式:从NorFlash启动和从NandFlash启动。

这里着重说明一下从NandFlash启动的过程。

在S3C2440片内有一块被称为SteppingStone的片内SRAM,它的大小为4K。将开发板设置为从NandFlash启动之后,SteppingStone会被映射成为0地址,并且在上电后,NandFlash前4K的数据会被自动拷贝至SteppingStone中。然后,系统从地址0处开始执行。

上一篇文章中的LED程序很小,所以它在大小仅为4K的SteppingStone中运行是可行的。但是如果我们编写的应用程序超过了4K,那该怎么办?

答案就是,利用SteppingStone,将NandFlash中的应用程序拷贝至片外SDRAM中去运行。当然,对于大小没有超过4K的程序,我们同样也能这样做。

接下来,我们就来实现LED程序在片外SDRAM中运行。

二、代码

1. led.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

以上代码依次做了以下几件事情:

  1. 关闭看门狗
  2. 配置存储控制器,以便接下来读写SDRAM
  3. 将SteppingStoen中所有内容拷贝至片外SDRAM中
  4. 设置SP
  5. 跳至Main函数,控制LED

需要说明的是“ ldr pc, =on_sdram ”这一句,为什么执行这一句代码后,PC指针就跳到了sdram,以及ldr与同样做为跳转指令的bl的区别,可以参考如下两篇文章:

2. led.c


#define GPBCON (*(volatile unsigned long *)0x56000010)
#define GPBDAT (*(volatile unsigned long *)0x56000014) #define GPB5_out (1<<(5*2))
#define GPB6_out (1<<(6*2))
#define GPB7_out (1<<(7*2))
#define GPB8_out (1<<(8*2)) void wait(unsigned long dly)
{
for(; dly > 0; dly--);
} int main(void)
{
unsigned long i = 5; GPBCON = GPB5_out|GPB6_out|GPB7_out|GPB8_out; // 将LED1-4对应的GPB5/6/7/8四个引脚设为输出 while(1){
wait(30000);
GPBDAT = (~(1<<i)) & 0xFFFFFFFF; // 根据i的值,点亮LED1-4
if(++i == 9)
i = 5;
} return 0;
}

以上的main函数,即为led.S中调用的main。其作用为依次点亮4个LED。

3. makefile

sdram.bin : head.S  leds.c
arm-linux-gcc -c -o head.o head.S
arm-linux-gcc -c -o leds.o leds.c
arm-linux-ld -Ttext 0x30000000 head.o leds.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

以上是makefile的内容,需要注意的一点是,程序的链接地址被指定为0x30000000,它与led.S中的SDRAM_BASE值应一致。

三、烧录

将Mini2440通过串口线、USB线与电脑连接,设置为从NandFlash启动(假定NandFlash中已经烧录了supervivi),按住开发板上任意一个按键,然后上电,这时串口会打印出以下信息,提示你输入指令:

##### FriendlyARM BIOS for 2440 #####
[x] bon part 0 320k 2368k
[v] Download vivi
[k] Download linux kernel
[y] Download root_yaffs image
[a] Absolute User Application
[n] Download Nboot
[l] Download WinCE boot-logo
[w] Download WinCE NK.bin
[d] Download & Run
[z] Download zImage into RAM
[g] Boot linux from RAM
[f] Format the nand flash
[b] Boot the system
[s] Set the boot parameters
[u] Backup NAND Flash to HOST through USB(upload)
[r] Restore NAND Flash from HOST through USB
[q] Goto shell of vivi
[i] Version: 1026-12
Enter your selection:

在电脑键盘上敲击a,在dnw中选择由以上3个文件make生成的sdram.bin文件,将其烧录至NandFlash中。

烧录完成后,重新给开发板上电,可以看到4个LED灯被依次点亮。

烧录过程中需要注意的是,指令a是将bin文件烧录至Nandflash中,此时dnw中的Download Address是没有作用的。而指令d则是将bin文件烧录至SDRAM中,此时设置的Download Address才起作用。

如果使用指令d将生成的sdram.bin烧录至sdram中,有可能达不到实验效果。因为在烧录完成后,sdram.bin被执行,它会将0地址即steppingstone处的4K内容拷贝至0x30000000处,而要知道,被拷贝的steppingstone中的4K数据,并不是我们的sdram.bin,而是本次上电时NandFlash前4K的数据。

施主,能让我尝尝通过写博客赚到一分钱的甜头吗?

让LED程序在片外SDRAM中运行的更多相关文章

  1. 用UBOOT自带loadb命令加载应用程序到SDRAM中运行的方法

    S3C44B0开发板中,用UBOOT自带loadb命令加载应用程序到SDRAM中运行的方法    1.开发板说明:  开发板上已有移植好的UBOOT运行.   2.交叉编译工具链为arm-linu-g ...

  2. 下载uboot的调试版本到开发板的sdram中运行

    开发环境:开发板:FriendlyARM Tiny6410 主机:CentOS release 6.4 (Final) 开发板与主机通过串口线连接 调试用的uboot源码为开发板光盘提供的u-boot ...

  3. Windows2008安装WebSphere 6.1提示此安装程序不能在图形方式中运行

    推荐的解决方式:http://blog.sina.com.cn/s/blog_4b010fb50100n1mk.html 在一般情况下,安装Websphere是直接运行launchpad.exe,然后 ...

  4. pycharm中可以运行的程序,在命令行中运行提示模块不存在的问题

    运行模块(包含main函数的模块),在模块开头添加以下代码,原因是pycharm运行python脚本时,会自动添加以下代码,将当前库加入到系统库目录集合中,在命令行中运行需要手动添加import os ...

  5. 将Winform程序快速转换为在浏览器中运行的程序

    http://www.codeproject.com/Articles/31429/Embedding-a-NET-WinForms-Application-in-an-Interne 详见以上文章. ...

  6. mini2440 裸机程序下载到 sdram 不能运行。

    今天在 写了个简单的 led 的汇编程序,下载到 mini2440 的 nand flash 里面可以正常运行,但是下载到 sdram 里面不能运行. 后来发现有几个注意点, 要在 sdram 中运行 ...

  7. S3C2440—9.复制程序到SDRAM中执行

    文章目录 一.S3C2440的启动方式 二.代码 一.S3C2440的启动方式 S3C2440的MMU有一种"steppingstone".技术,是协助MCU从无法执行程序的NAN ...

  8. 在docker中运行ASP.NET Core Web API应用程序

    本文是一篇指导快速演练的文章,将介绍在docker中运行一个ASP.NET Core Web API应用程序的基本步骤,在介绍的过程中,也会对docker的使用进行一些简单的描述.对于.NET Cor ...

  9. 在Linux和Windows的Docker容器中运行ASP.NET Core

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 译者序:其实过去这周我都在研究这方面的内容,结果周末有事没有来得及总结为文章,Scott H ...

随机推荐

  1. 苏浪浪 201771010120 第三周 Java基本程序设计总结

    理论知识: Java有五种语句: (1)方法调用语句(2)表达式语句(3)复合语句(4)控制语句(5)package.import语句 3.8控制流程 3.9大数值 *如果基本的整型和浮点型数据无法达 ...

  2. 仙人掌图判定及求直径HDU3594 BZOJ1023

    https://wenku.baidu.com/view/ce296043192e45361066f575.html   //仙人掌图基础知识3个判定条件 http://blog.csdn.net/y ...

  3. CF832C

    题目链接:http://codeforces.com/contest/832/problem/C 题目大意: n个人,面向左或者右站在同一条轴上,每个人在轴上的坐标为x,速度为v.请你在某个位置放置一 ...

  4. Map.Entry的作用

    一般情况下,要输出Map中的key 和 value 是先得到key的集合,然后再迭代(循环)由每个key得到每个value 而Entry可以一次性获得这两个值 Set set = map.keySet ...

  5. android小Demo--七彩霓虹灯效果

    七彩霓虹灯效果,基于网上的小Demo进行修改. 在android项目values文件夹下创建文件colors.xml,配置七种颜色: <?xml version="1.0" ...

  6. [JavaWeb基础] 011.Struts2 配置拦截器

    在网页开发中有一个很重要的东西就是拦截器,就是在请求接收到的时候先到拦截器中进行一些逻辑处理,例如会话是否过期的验证等.在Struts2中我们可以编写一个拦截器的类,然后在struts.xml中简单配 ...

  7. 附021.Traefik-ingress部署及使用

    一 Helm部署 1.1 获取资源 [root@master01 ~]# mkdir ingress [root@master01 ~]# cd ingress/ [root@master01 ing ...

  8. Rocket - debug - TLDebugModuleInner - Abstract Command Decoding & Generation

    https://mp.weixin.qq.com/s/0zKSTktxgzo5uCUphqaWSQ 介绍抽象命令的解码和生成. 1. accessRegisterCommandReg accessRe ...

  9. Rocket - diplomacy - AddressAdjuster

    https://mp.weixin.qq.com/s/X0s5CWN84GEiwpNR7tiRgA 基于AddressAdjuster介绍LazyModule的实现.   参考链接:https://g ...

  10. Chisel3 - bind - Op, ReadOnly, 左值

    https://mp.weixin.qq.com/s/F_08jKFMoX9Gf_J_YpsDpg   两个数据变量进行某个操作(op),产生一个输出,这个输出存在一个匿名变量中.这个匿名变量就是以O ...