《tiny6410裸机程序》第六章:myled通过usb下载至nandflash不能运行
2014-05-12 14:20
357 查看
====================================================================================================================================
一、前期准备
1.开发板必须在SD卡启动模式!
2.安装usb下载驱动,安装rs232 to usb驱动。
3.安装dns,并打开dns。
二、烧写《tiny6410裸机程序》第五章:汇编与C混合编程-LED跑马灯最终说明、myled再次精简bin至nandflash。
三、不能运行原因分析
1.之前文章分析的:《micro2440开发》第七章:micro2440从NAND FLASH启动原理分析
因为nandflash上本身不能运行代码(因为它不像norflash是随机存储的),解决这个问题的方法是:硬件设计中选择从nandflash启动时、CPU自动会搬移nandflash前4KB至SRAM运行;其二,要访问nandflash,必须首先初始化nandflash控制器,解决方法是:上述4KB部分代码必须实现nandflash的初始化工作。
但是,本程序不存在问题;是因为本bin只有2KB<4KB,不存在代码搬移问题,也就没必要初始化nandflash控制器寄存器。
2.真正原因
ADS调试时MMU是关闭的,实际bin中MMU没有关闭。所以,加入LED相关GPIO地址映射代码即可。
四、解决方法
该bin的前4KB必须首先完成nandflash控制器寄存器的初始化功能;并且设置外设IO的基地址及地址空间、或关闭mmu和cache。
====================================================================================================================================
改编后程序(主要是在Startup.s中添加对CP15协处理器操作,设置外设IO的基地址和地址空间;因为6410的内存和IO空间是分开的):
1.Startup.s
[plain] view
plaincopy
preserve8
IMPORT main ; 声明C程序中的Main()函数
AREA Start,CODE,READONLY ; 声明代码段Start
ENTRY ; 标识程序入口
CODE32 ; 声明32位ARM指令
ldr r0, =0x70000000
orr r0, r0, #0x13
mcr p15,0,r0,c15,c2,4 ;256M(0x70000 0000~0x7FFF FFFF)ARM协处理器相关 告诉协处理器外设寄存器的基地址和地址空间
ldr r0, =0x7E004000
mov r1, #0
str r1, [r0] ;关闭看门狗
ldr sp, =8*1024 ;设置C堆栈
bl main
2.led.c
[cpp] view
plaincopy
#define LED1_ON ~(1<<4) //1111 1111 1111 1111 1111 1111 1110 1111 GPKDAT31~GPKDAT0
#define LED2_ON ~(1<<5)
#define LED3_ON ~(1<<6)
#define LED4_ON ~(1<<7)
#define LED1_OFF (1<<4) //0000 0000 0000 0000 0000 0000 0001 0000
#define LED2_OFF (1<<5)
#define LED3_OFF (1<<6)
#define LED4_OFF (1<<7)
#define LEDALL_OFF (0xf<<4) //0000 0000 0000 0000 0000 0000 1111 0000
typedef unsigned long u32;
typedef unsigned short u16;
typedef unsigned char u8;
#define rGPIOKCON0 (*(volatile u32 *)0x7f008800)
#define rGPIOKDAT (*(volatile u32 *)0x7f008808)
int main(void){
u32 uConValue;
u32 i;
uConValue = rGPIOKCON0;
uConValue &= ~(0xffff<<16); //0000 0000 0000 0000 1111 1111 1111 1111 GPKCON7~GPKCON0
uConValue |= 0x1111<<16; //0001 0001 0001 0001 0000 0000 0000 0000 //0001 0001 0001 0001 1111 1111 1111 1111
rGPIOKCON0 = uConValue;
rGPIOKDAT |= LEDALL_OFF;
while(1){
rGPIOKDAT &= LED1_ON;
for(i=0;i<3000*100;i++);
rGPIOKDAT |= LEDALL_OFF;
rGPIOKDAT &= LED2_ON;
for(i=0;i<3000*100;i++);
rGPIOKDAT |= LEDALL_OFF;
rGPIOKDAT &= LED3_ON;
for(i=0;i<3000*100;i++);
rGPIOKDAT |= LEDALL_OFF;
rGPIOKDAT &= LED4_ON;
for(i=0;i<3000*100;i++);
rGPIOKDAT |= LEDALL_OFF;
}
}
3.以下是基于Window下armcc编译器的Makefile
[plain] view
plaincopy
all:
armasm -o Startup.o Startup.s --debug --keep --cpu=ARM1176JZF-S
armcc -c led.o led.c --debug --cpu=ARM1176JZF-S -O0
armlink -o myled.axf Startup.o led.o --ro_base=0x50200000 --rw_base=0x50203000 --first=Startup.o(start) --entry=0x50200000
fromelf -o myled.bin --bin myled.axf
clean:
del *.o *.axf *.bin
====================================================================================================================================
补充:
u-boot-mini6410/cpu/s3c64xx/start.S
[plain] view
plaincopy
/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
cpu_init_crit:
/*
* flush v4 I/D caches
*/
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
/*
* disable MMU stuff and caches
*/
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
orr r0, r0, #0x00000002 @ set bit 2 (A) Align
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
mcr p15, 0, r0, c1, c0, 0
/* Peri port setup */
ldr r0, =0x70000000
orr r0, r0, #0x13
mcr p15,0,r0,c15,c2,4 @ 256M(0x70000000-0x7fffffff)
分析:该程序烧录至nand flash或nor flash时,其实并没有在连接器指定的0x50200000处的SDRAM中运行;而是在0x00000000处运行,整个代码也体现了PIC、ARM位置无关代码设计的思想。
一、前期准备
1.开发板必须在SD卡启动模式!
2.安装usb下载驱动,安装rs232 to usb驱动。
3.安装dns,并打开dns。
二、烧写《tiny6410裸机程序》第五章:汇编与C混合编程-LED跑马灯最终说明、myled再次精简bin至nandflash。
三、不能运行原因分析
1.之前文章分析的:《micro2440开发》第七章:micro2440从NAND FLASH启动原理分析
因为nandflash上本身不能运行代码(因为它不像norflash是随机存储的),解决这个问题的方法是:硬件设计中选择从nandflash启动时、CPU自动会搬移nandflash前4KB至SRAM运行;其二,要访问nandflash,必须首先初始化nandflash控制器,解决方法是:上述4KB部分代码必须实现nandflash的初始化工作。
但是,本程序不存在问题;是因为本bin只有2KB<4KB,不存在代码搬移问题,也就没必要初始化nandflash控制器寄存器。
2.真正原因
ADS调试时MMU是关闭的,实际bin中MMU没有关闭。所以,加入LED相关GPIO地址映射代码即可。
四、解决方法
该bin的前4KB必须首先完成nandflash控制器寄存器的初始化功能;并且设置外设IO的基地址及地址空间、或关闭mmu和cache。
====================================================================================================================================
改编后程序(主要是在Startup.s中添加对CP15协处理器操作,设置外设IO的基地址和地址空间;因为6410的内存和IO空间是分开的):
1.Startup.s
[plain] view
plaincopy
preserve8
IMPORT main ; 声明C程序中的Main()函数
AREA Start,CODE,READONLY ; 声明代码段Start
ENTRY ; 标识程序入口
CODE32 ; 声明32位ARM指令
ldr r0, =0x70000000
orr r0, r0, #0x13
mcr p15,0,r0,c15,c2,4 ;256M(0x70000 0000~0x7FFF FFFF)ARM协处理器相关 告诉协处理器外设寄存器的基地址和地址空间
ldr r0, =0x7E004000
mov r1, #0
str r1, [r0] ;关闭看门狗
ldr sp, =8*1024 ;设置C堆栈
bl main
2.led.c
[cpp] view
plaincopy
#define LED1_ON ~(1<<4) //1111 1111 1111 1111 1111 1111 1110 1111 GPKDAT31~GPKDAT0
#define LED2_ON ~(1<<5)
#define LED3_ON ~(1<<6)
#define LED4_ON ~(1<<7)
#define LED1_OFF (1<<4) //0000 0000 0000 0000 0000 0000 0001 0000
#define LED2_OFF (1<<5)
#define LED3_OFF (1<<6)
#define LED4_OFF (1<<7)
#define LEDALL_OFF (0xf<<4) //0000 0000 0000 0000 0000 0000 1111 0000
typedef unsigned long u32;
typedef unsigned short u16;
typedef unsigned char u8;
#define rGPIOKCON0 (*(volatile u32 *)0x7f008800)
#define rGPIOKDAT (*(volatile u32 *)0x7f008808)
int main(void){
u32 uConValue;
u32 i;
uConValue = rGPIOKCON0;
uConValue &= ~(0xffff<<16); //0000 0000 0000 0000 1111 1111 1111 1111 GPKCON7~GPKCON0
uConValue |= 0x1111<<16; //0001 0001 0001 0001 0000 0000 0000 0000 //0001 0001 0001 0001 1111 1111 1111 1111
rGPIOKCON0 = uConValue;
rGPIOKDAT |= LEDALL_OFF;
while(1){
rGPIOKDAT &= LED1_ON;
for(i=0;i<3000*100;i++);
rGPIOKDAT |= LEDALL_OFF;
rGPIOKDAT &= LED2_ON;
for(i=0;i<3000*100;i++);
rGPIOKDAT |= LEDALL_OFF;
rGPIOKDAT &= LED3_ON;
for(i=0;i<3000*100;i++);
rGPIOKDAT |= LEDALL_OFF;
rGPIOKDAT &= LED4_ON;
for(i=0;i<3000*100;i++);
rGPIOKDAT |= LEDALL_OFF;
}
}
3.以下是基于Window下armcc编译器的Makefile
[plain] view
plaincopy
all:
armasm -o Startup.o Startup.s --debug --keep --cpu=ARM1176JZF-S
armcc -c led.o led.c --debug --cpu=ARM1176JZF-S -O0
armlink -o myled.axf Startup.o led.o --ro_base=0x50200000 --rw_base=0x50203000 --first=Startup.o(start) --entry=0x50200000
fromelf -o myled.bin --bin myled.axf
clean:
del *.o *.axf *.bin
====================================================================================================================================
补充:
u-boot-mini6410/cpu/s3c64xx/start.S
[plain] view
plaincopy
/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
cpu_init_crit:
/*
* flush v4 I/D caches
*/
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
/*
* disable MMU stuff and caches
*/
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
orr r0, r0, #0x00000002 @ set bit 2 (A) Align
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
mcr p15, 0, r0, c1, c0, 0
/* Peri port setup */
ldr r0, =0x70000000
orr r0, r0, #0x13
mcr p15,0,r0,c15,c2,4 @ 256M(0x70000000-0x7fffffff)
分析:该程序烧录至nand flash或nor flash时,其实并没有在连接器指定的0x50200000处的SDRAM中运行;而是在0x00000000处运行,整个代码也体现了PIC、ARM位置无关代码设计的思想。
相关文章推荐
- 《tiny6410裸机程序》第六章:myled通过usb下载至nandflash不能运行
- U-boot 2011.06 smdk6410的移植(转载-测试通过-修改)--下载后还不能运行......
- MDK生成的BIN文件用DNW通过USB下载RAM中运行的问题
- 基于WINCE6.0+S3C6410通过USB下载stepldr
- 通过修改程序的代码使程序能够下载并运行指定程序
- Imote2平台,通过ARM-USB-TINY-H下载TINYOS程序
- WinCE开机Logo的实现(USB下载图片到nandflash)
- Windows程序运行不能通过的解决方案
- homestead虚拟机,通过npm下载依赖包和解决运行gulp报错问题 yarn出错问题
- 下载的Demo不能使用真机运行
- 通过serverlet方式下载文件,不能显示中文的解决方法
- 基于WINCE6.0+S3C6410通过USB下载stepldr
- 解决Poser Pro 2014 不能运行问题(附下载地址)
- WinCE开机Logo的实现(USB下载图片到nandflash)
- 如果在PC机上安装了S3C2440驱动但是通过虚拟机不能用DNW下载程序
- Maven私服不能自动通过内部nexus下载远程仓库的jar
- ESP8266可以让LED发光,通过运行网络服务器驱动继电器检测按钮状态
- 定时器中断程序下: 下载到NAND不能运行,,只能下载到内存中运行~~
- 由于google被墙, 一些go语言包不能下载, 可以通过Chome浏览器到这个网址下载
- 关于 通过jlink使用jtag(或swd)下载程序成功后,keil4 uversion停止运行 的解决方法