新手發帖,很多方面都是剛入門,有錯誤的地方請大家見諒,歡迎批評指正
????我用的飛淩ok6410開發板,DNW下載程序太易容出問題了,于是買了個openjtag,買回來才發明暫不支撐MLC NAND。我下決心寫個有下載程序功能的裸板程序update.
????再也用不忍耐DNW了,并且還分析一種SD卡下載方法。先用飛淩供給的一鍵燒寫具工,寫mmc.bin到sd卡,再把自己要下載的程序以u-boot.bin定名,也拷到sd卡,
????mmc.bin會動自幫你把程序燒寫到NAND,再從NAND動啟就運行你的程序了。后以這片sd卡就相當于你的下載器,要需跑什么程序拷到sd卡就OK了。
????詳細作操過程見前面,在現開始寫update程序。
????系統:ubuntu 10.04.4
單板:ok6410
編譯器:arm-linux-gcc-4.3.2
搭建開發環境詳見ubuntu 10.04.4開發環境置配。
????標目:串口輸出菜單,有以下·功能供選擇
????
*********************************
update program with serial port
The board:witech(ok6410)
The NAND:K9GAG08U0D 2048MB
The DDR:K4X1G163PCX2 256MB
The NET:DM9000AEP
? ? ? ? ? ? ? ? ?date: 2013.4.26
***********************************
the menu of the update programe:
[w] write the nand flash
[r] read the nand flash
[e] erase the nand flash
[g] get file, and write to nand flash 0 block
[x] get file to ddr(0x57e00000), run it
[s] reset the programe
Please enter the chose:
????即現實讀寫nand,通過V2.2.exe/gtkterm發送文件到內存,再寫到NADN flash 0地址,以及重啟update程序。
????改程序主要功能是現實新更程序,以及把程序放到內存運行·。
????一、編寫源代碼
????根據s5pc100手冊編寫代碼,包含源文件start.S clock.S ?sdram.c init.c main.c boot.lds Makefile
????文件start.S:
.text
.global _start
_start:
/*0. 硬件關相的置設 */
/* Peri port setup */
ldr r0, =0x70000000
orr r0, r0, #0x13
mcr p15,0,r0,c15,c2,4 @ 256M(0x70000000-0x7fffffff)
/*1.關看門狗*/
ldr r0, =0x7E004000
mov r1, #0
str r1, [r0]
ldr sp, =8*1024
/*2.置設時鐘*/
bl clock_init
/*3.初始化SDRAM DDR*/
bl ddr_init
/*4.重定位:把代碼從flash復制到他的鏈接地址*/
ldr sp, =0x58000000
bl nand_init
mov r0, #0
ldr r1, =_start
ldr r2, =__bss_start
sub r2, r2, r1
bl copy_code_to_sdram
bl clear_bss
/*5.行執main*/
ldr lr, =halt
ldr pc, =main
halt:
b halt
????文件clock.S:
.globl clock_init
clock_init:
/* 1.置設LOCK_TIME */
ldr r0, =0x7E00F000 /* APLL_LOCK */
ldr r1, =0x0000FFFF
str r1, [r0]
str r1, [r0, #4] /* MPLL_LOCK */
str r1, [r0, #8] /* EPLL_LOCK */
#define OTHERS 0x7e00f900
@ set async mode /* 當CPU時鐘 != HCLK時,要設為異步模式 */
ldr r0, =OTHERS
ldr r1, [r0]
bic r1, r1, #0xc0 /* 1100,0000 */
str r1, [r0]
loop1: /* 待等,直到CPU進入異步模式 */
ldr r0, =OTHERS
ldr r1, [r0]
and r1, r1, #0xf00
cmp r1, #0
bne loop1
/* SYNC667 */
/* MISC_CON[19] = 0 */
#define ARM_RATIO 0 /* ARMCLK = DOUTAPLL / (ARM_RATIO + 1) */
#define HCLKX2_RATIO 1 /* HCLKX2 = HCLKX2IN / (HCLKX2_RATIO + 1) */
#define HCLK_RATIO 1 /* HCLK = HCLKX2 / (HCLK_RATIO + 1) */
#define PCLK_RATIO 3 /* PCLK = HCLKX2 / (PCLK_RATIO + 1) */
#define MPLL_RATIO 0 /* DOUTMPLL = MOUTMPLL / (MPLL_RATIO + 1) */
ldr r0, =0x7E00F020 /* CLK_DIV0 */
ldr r1, =(ARM_RATIO) | (MPLL_RATIO << 4) | (HCLK_RATIO << 8) | (HCLKX2_RATIO << 9) | (PCLK_RATIO << 12)
str r1, [r0]
/* 2.置配時鐘 */
/* 2.1 置配APLL */
/* 2.1.1 置設APLL
* 2.1.2 MUXAPLL
* 2.1.3 SYNC667
* 2.1.4 DIVAPLL
*/
#define APLL_CON_VAL ((1<<31) | (266 << 16) | (3 << 8) | (1))
ldr r0, =0x7E00F00C
ldr r1, =APLL_CON_VAL
str r1, [r0] /* APLL_CON, FOUTAPL = MDIV * Fin / (PDIV*2^SDIV) = 266*12/(3*2^1) = 532MHz */
/* 2.2 置配MPLL */
/* 2.2.1 置設MPLL
* 2.2.2 MUXMPLL
* 2.2.3 SYNCMUX
* 2.2.4 SYNC667
* 2.2.5 HCLKX2_RATIO
* 2.2.6 PCLK_RATIO
*/
#define MPLL_CON_VAL ((1<<31) | (266 << 16) | (3 << 8) | (1))
ldr r0, =0x7E00F010
ldr r1, =MPLL_CON_VAL
str r1, [r0] /* MPLL_CON, FOUTMPL = MDIV * Fin / (PDIV*2^SDIV) = 266*12/(3*2^1) = 532MHz */
/* 3.選擇PLL的輸出作為時鐘源 */
ldr r0, =0x7E00F01C
ldr r1, =0x03
str r1, [r0]
mov pc, lr
????文件sdram.c:
//#include <common.h>
#define MEMCCMD 0x7e001004
#define P1REFRESH 0x7e001010
#define P1CASLAT 0x7e001014
#define MEM_SYS_CFG 0x7e00f120
#define P1MEMCFG 0x7e00100c
#define P1T_DQSS 0x7e001018
#define P1T_MRD 0x7e00101c
#define P1T_RAS 0x7e001020
#define P1T_RC 0x7e001024
#define P1T_RCD 0x7e001028
#define P1T_RFC 0x7e00102c
#define P1T_RP 0x7e001030
#define P1T_RRD 0x7e001034
#define P1T_WR 0x7e001038
#define P1T_WTR 0x7e00103c
#define P1T_XP 0x7e001040
#define P1T_XSR 0x7e001044
#define P1T_ESR 0x7e001048
#define P1MEMCFG2 0X7e00104c
#define P1_chip_0_cfg 0x7e001200
#define P1MEMSTAT 0x7e001000
#define P1MEMCCMD 0x7e001004
#define P1DIRECTCMD 0x7e001008
#define HCLK 133000000
#define nstoclk(ns) (ns/( 1000000000/HCLK)+1)
#define vi *( volatile unsigned int * )
#define set_zero( addr, bit ) ( (vi addr) &= ( ~ ( 1 << (bit) ) ) )
#define set_one( addr, bit ) ( (vi addr) |= ( 1 << ( bit ) ) )
#define set_bit( addr, bit, val ) ( (vi addr) = (( vi addr)&=(~(1<<(bit))) ) | ( (val)<<(bit) ) )
#define set_2bit( addr, bit, val ) ( (vi addr) = (( vi addr)&(~(3<<(bit))) ) | ( (val)<<(bit) ) )
#define set_nbit( addr, bit, len, val ) \
( (vi addr) = ((( vi addr)&(~(( ((1<<(len))-1) )<<(bit)))) | ( (val)<<(bit) ) ))
#define get_bit( addr, bit ) ( (( vi addr ) & ( 1 << (bit) )) > 0 )
#define get_val( addr, val ) ( (val) = vi addr )
#define read_val( addr ) ( vi ( addr ) )
#define set_val( addr, val ) ( (vi addr) = (val) )
#define or_val( addr, val ) ( (vi addr) |= (val) )
void ddr_init( void )
{
// tell dramc to configure
set_val( MEMCCMD, 0x4 );
// set refresh period
set_val( P1REFRESH, nstoclk(7800) );
// set timing para
set_val( P1CASLAT, ( 3 << 1 ) );
set_val( P1T_DQSS, 0x1 ); // 0.75 - 1.25
set_val( P1T_MRD, 0x2 );
set_val( P1T_RAS, nstoclk(45) );
set_val( P1T_RC, nstoclk(68) );
unsigned int trcd = nstoclk( 23 );
set_val( P1T_RCD, trcd | (( trcd - 3 ) << 3 ) );
unsigned int trfc = nstoclk( 80 );
set_val( P1T_RFC, trfc | ( ( trfc-3 ) << 5 ) );
unsigned int trp = nstoclk( 23 );
set_val( P1T_RP, trp | ( ( trp - 3 ) << 3 ) );
set_val( P1T_RRD, nstoclk(15) );
set_val( P1T_WR, nstoclk(15) );
set_val( P1T_WTR, 0x7 );
set_val( P1T_XP, 0x2 );
set_val( P1T_XSR, nstoclk(120) );
set_val( P1T_ESR, nstoclk(120) );
// set mem cfg
set_nbit( P1MEMCFG, 0, 3, 0x2 ); /* 10 column address */
/* set_nbit: 把從第bit位開始的一共len位零消,然后把這幾位設為val */
set_nbit( P1MEMCFG, 3, 3, 0x2 ); /* 13 row address */
set_zero( P1MEMCFG, 6 ); /* A10/AP */
set_nbit( P1MEMCFG, 15, 3, 0x2 ); /* Burst 4 */
set_nbit( P1MEMCFG2, 0, 4, 0x5 );
set_2bit( P1MEMCFG2, 6, 0x1 ); /* 32 bit */
set_nbit( P1MEMCFG2, 8, 3, 0x3 ); /* Mobile DDR SDRAM */
set_2bit( P1MEMCFG2, 11, 0x1 );
set_one( P1_chip_0_cfg, 16 ); /* Bank-Row-Column organization */
// memory init
set_val( P1DIRECTCMD, 0xc0000 ); // NOP
set_val( P1DIRECTCMD, 0x000 ); // precharge
set_val( P1DIRECTCMD, 0x40000 );// auto refresh
set_val( P1DIRECTCMD, 0x40000 );// auto refresh
set_val( P1DIRECTCMD, 0xa0000 ); // EMRS
set_val( P1DIRECTCMD, 0x80032 ); // MRS
set_val( MEM_SYS_CFG, 0x0 );
// set dramc to "go" status
set_val( P1MEMCCMD, 0x000 );
// wait ready
while( !(( read_val( P1MEMSTAT ) & 0x3 ) == 0x1));
}
????文件init.c:
#define MEM_SYS_CFG (*((volatile unsigned long *)0x7E00F120))
#define NFCONF (*((volatile unsigned long *)0x70200000))
#define NFCONT (*((volatile unsigned long *)0x70200004))
#define NFCMMD (*((volatile unsigned long *)0x70200008))
#define NFADDR (*((volatile unsigned long *)0x7020000C))
#define NFDATA (*((volatile unsigned char *)0x70200010))
#define NFSTAT (*((volatile unsigned long *)0x70200028))
void nand_read(unsigned int nand_start, unsigned int ddr_start, unsigned int len);
int isBootFromNorFlash(void)
{
volatile int *p = (volatile int *)0;
int val;
val = *p;
*p = 0x12345678;
if (*p == 0x12345678)
{
/*寫勝利,是nand動啟*/
*p = val;
return 0;
}
else
{
/*Nor不能像內存一樣寫*/
return 1;
}
}
void copy_code_to_sdram(unsigned int src, unsigned int dest, unsigned int len)
{
int i = 0;
/*如果是Nor動啟*/
unsigned char *src_start = (unsigned char *)src;
unsigned char *dest_start = (unsigned char *)dest;
if(isBootFromNorFlash())
{
while (i < len)
{
dest_start[i] = src_start[i];
i++;
}
}
else
{
//nand_init();
//nand_resd(src, dest, len)
nand_read(src, dest, len);
}
}
void nand_select(void)
{
NFCONT &= ~(1<<1);
}
void nand_deselect(void)
{
NFCONT |= (1<<1);
}
void nand_cmd(unsigned char cmd)
{
NFCMMD = cmd;
}
void nand_addr(unsigned char addr)
{
NFADDR = addr;
}
unsigned char nand_get_data(void)
{
return NFDATA;
}
void nand_send_data(unsigned char data)
{
NFDATA = data;
}
void wait_ready(void)
{
while ((NFSTAT & 0x1) == 0);
}
void nand_reset(void)
{
/* 中選 */
nand_select();
/* 收回0xff命令 */
nand_cmd(0xff);
/* 待等就緒 */
wait_ready();
/* 取消中選 */
nand_deselect();
}
void clear_bss(void)
{
extern int __bss_start, __bss_end;
int *p = &__bss_start;
for (; p < &__bss_end; p++)
*p = 0;
}
void nand_init(void)
{
/* 讓xm0csn2用作nand flash cs0 片選引腳 */
MEM_SYS_CFG &= ~(1<<1);
/* 置設間時參數 */
#define TACLS 0
#define TWRPH0 2
#define TWRPH1 1
NFCONF &= ~((1<<30) | (7<<12) | (7<<8) | (7<<4));
NFCONF |= ((TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4));
/* 使能nand flash controller */
NFCONT |= 1;
NFCONT &= ~(1<<16); /* 森止soft lock */
nand_reset();
}
void nand_send_addr(unsigned int addr)
{
#if 1
unsigned int page = addr / 4096;
unsigned int colunm = addr & (4096 - 1);
/* 這兩個地址示表從頁內哪里開始 */
nand_addr(colunm & 0xff);
nand_addr((colunm >> 8) & 0xff);
/* 面下三個地址示表哪一頁 */
nand_addr(page & 0xff);
nand_addr((page >> 8) & 0xff);
nand_addr((page >> 16) & 0xff);
#else
nand_addr(addr & 0xff); /* a0~a7 */
nand_addr((addr >> 8) & 0x1f); /* 程序的角度: a8~a12 */
nand_addr((addr >> 13) & 0xff); /* 程序的角度: a13~a20 */
nand_addr((addr >> 21) & 0xff); /* 程序的角度: a21~a28 */
nand_addr((addr >> 29) & 0x7); /* 程序的角度: a29 ~ */
#endif
}
void nand_read(unsigned int nand_start, unsigned int ddr_start, unsigned int len)
{
unsigned int addr = nand_start;
int i = nand_start % 4096;
int left = i;
int count = 0;
unsigned char *dest = (unsigned char *)ddr_start;
unsigned char data = 0;
/* 中選片芯 */
nand_select();
while (count < len)
{
/* 收回命令0x00 */
nand_cmd(0x00);
/* 收回地址 */
nand_send_addr(addr);
/* 收回命令0x30 */
nand_cmd(0x30);
/* 待等就緒 */
wait_ready();
/* 讀數據 */
for (; i < (4096-left) && count < len; i++)//從某頁的i處開始讀
{
data = nand_get_data();
if(addr<16384)//前4頁每次只能寫2K
{
if(i<(2048-left))
{
dest[count++] = data;
}
}
else
{
dest[count++] = data;
}
//dest[count++] = nand_get_data();
addr++;
}
i = 0;
left = i;
}
/* 取消片選 */
nand_deselect();
// return 0;
}
void nand_erase_block(unsigned long addr)
{
int page = addr / 4096;
nand_select();
nand_cmd(0x60);
nand_addr(page & 0xff);
nand_addr((page >> 8) & 0xff);
nand_addr((page >> 16) & 0xff);
nand_cmd(0xd0);
wait_ready();
nand_deselect();
}
void nand_write(unsigned int nand_start, unsigned char * buf, unsigned int len)
{
unsigned long count = 0;
unsigned long addr = nand_start;
int i = nand_start % 4096;
int left = i;
nand_select();
while (count < len)
{
nand_cmd(0x80);
nand_send_addr(addr);
for (; i < (4096-left) && count < len; i++)
{
if(addr<16384)//寫前2K
{
if(i<(2048-left))//前2頁每頁只能寫2K
{
nand_send_data(buf[count++]);
}
}
else
{
nand_send_data(buf[count++]);
}
//nand_send_data(buf[count++]);
addr++;
}
nand_cmd(0x10);
wait_ready();
i = 0;
left = i;
}
nand_deselect();
}
#define ULCON0 (*((volatile unsigned long *)0x7F005000))
#define UCON0 (*((volatile unsigned long *)0x7F005004))
#define UFCON0 (*((volatile unsigned long *)0x7F005008))
#define UMCON0 (*((volatile unsigned long *)0x7F00500C))
#define UTRSTAT0 (*((volatile unsigned long *)0x7F005010))
#define UFSTAT0 (*((volatile unsigned long *)0x7F005018))
#define UTXH0 (*((volatile unsigned char *)0x7F005020))
#define URXH0 (*((volatile unsigned char *)0x7F005024))
#define UBRDIV0 (*((volatile unsigned short *)0x7F005028))
#define UDIVSLOT0 (*((volatile unsigned short *)0x7F00502C))
#define GPACON (*((volatile unsigned long *)0x7F008000))
#define ENABLE_FIFO
static void delay(void)
{
volatile int i = 10;
while (i--);
}
void init_uart(void)
{
GPACON &= ~0xff;
GPACON |= 0x22;
/* ULCON0 */
ULCON0 = 0x3; /* 數據位:8, 無較驗, 停止位: 1, 8n1 */
UCON0 = 0x5; /* 使能UART發送、收接 */
#ifdef ENABLE_FIFO
UFCON0 = 0x07; /* FIFO enable */
#else
UFCON0 = 0x00; /* FIFO disable */
#endif
UMCON0 = 0;
/* 波特率 */
/* DIV_VAL = (PCLK / (bps x 16 ) ) - 1
* bps = 115200
* DIV_VAL = (66500000 / (115200 x 16 ) ) - 1
* = 35.08
*/
UBRDIV0 = 35;
/* x/16 = 0.08
* x = 1
*/
UDIVSLOT0 = 0x1;
}
unsigned char getc(void)
{
#ifdef ENABLE_FIFO
while ((UFSTAT0 & (1<<6)) == 0 && (UFSTAT0 & 0x3f) == 0)delay();
#else
while ((UTRSTAT0 & (1<<0)) == 0);
#endif
return URXH0;
}
int getc_nowait(unsigned char *pChar)
{
#ifdef ENABLE_FIFO
if ((UFSTAT0 & (1<<6)) == 0 && (UFSTAT0 & 0x3f) == 0)
#else
if ((UTRSTAT0 & (1<<0)) == 0)
#endif
{
return -1;
}
else
{
*pChar = URXH0;
return 0;
}
}
void putc(char c)
{
#ifdef ENABLE_FIFO
while (UFSTAT0 & (1<<14))delay();
#else
while ((UTRSTAT0 & (1<<2)) == 0);
#endif
UTXH0 = c;
}
void puts(char *str)
{
int i = 0;
while (str[i])
{
putc(str[i]);
i++;
}
}
void puthex(unsigned int val)
{
/* 0x1234abcd */
int i;
int j;
puts("0x");
for (i = 0; i < 8; i++)
{
j = (val >> ((7-i)*4)) & 0xf;
if ((j >= 0) && (j <= 9))
putc('0' + j);
else
putc('A' + j - 0xa);
}
}
void putbyte(unsigned char val)
{
/* 0x1234abcd */
int i;
int j;
puts("0x");
for (i = 0; i < 2; i++)
{
j = (val >> ((1-i)*4)) & 0xf;
if ((j >= 0) && (j <= 9))
putc('0' + j);
else
putc('A' + j - 0xa);
}
}
????文件main.c:
extern void init_uart(void);
extern void nand_read(unsigned int nand_start, unsigned int ddr_start, unsigned int len);
extern void putc(char c);
extern void puts(char *str);
extern void puthex(unsigned int val);
extern unsigned char getc(void);
extern int getc_nowait(unsigned char *pChar);
extern void putbyte(unsigned char val);
extern void nand_erase_block(unsigned long addr);
extern void nand_write(unsigned int nand_start, unsigned char * buf, unsigned int len);
int strlen(char *str)
{
int i = 0;
while (str[i])
{
i++;
}
return i;
}
void nand_read_test(void)
{
int i;
char buf[100];
unsigned long addr;
unsigned long size;
puts("enter the start address: 0x80000");
//scanf("%s", buf);
//addr = strtoul(buf, NULL, 0);
addr = 0x80000;
//puts("read addr = 0x%x\n\r", addr);
puts("enter the size: 0x60");
//scanf("%s", buf);
//size = strtoul(buf, NULL, 0);
size = 0x60;
if (size > 100)
{
puts("the max size is 100\n\r");
size = 100;
}
nand_read(addr, buf, size);
puts("datas: \n\r");
for (i = 0; i < size; i++)
{
// printf("%02x ", buf[i]);
putbyte(buf[i]);
puts("\t");
if ((i+1) % 8 == 0)
{
puts("\n\r");
}
}
puts("\n\r");
}
void nand_erase_test(void)
{
//char buf[100];
unsigned long addr;
puts("enter the start address: ");
//scanf("%s", buf);
//addr = strtoul(buf, NULL, 0);
addr = 0x80000;
puts("erase addr = ");
puthex(addr);
puts("\n\r");
nand_erase_block(addr);
}
void nand_write_test(void)
{
char buf[20] = {"abcd1234ABCD"};
unsigned long addr;
unsigned long size;
puts("enter the start address:0x80000 ");
//scanf("%s", buf);
//addr = strtoul(buf, NULL, 0);
addr = 0x80000;
puts("enter the string:abcd1234ABCD ");
//scanf("%s", buf);
size = strlen(buf) + 1;
puts(" size= ");
puthex(size);
puts("\n\r");
nand_write(addr, buf, size);
}
void update_program(void)
{
unsigned char *buf = (unsigned char *)0x52000000;
unsigned long len = 0;
int have_begin = 0;
int nodata_time = 0;
unsigned long erase_addr;
char c;
int i;
/* 璇諱覆鍙h幏寰楁暟鎹?*/
puts("\n\ruse V2.2.exe/gtkterm to send file\n\r");
while (1)
{
if (getc_nowait(&buf[len]) == 0)
{
have_begin = 1;
nodata_time = 0;
len++;
}
else
{
if (have_begin)
{
nodata_time++;
}
}
if (nodata_time == 1000)
{
break;
}
}
puts("\n\rhave get data:");
puthex(len);
puts(" bytes\n\r");
puts("the first 16 bytes data: \n\r");
for (i = 0; i < 16; i++)
{
// put("%02x ", buf[i]);
putbyte(buf[i]);
puts("\t");
}
puts("\n\r");
puts("Press Y to program the flash: \n\r");
c = getc();
putc(c);
puts("\n\r");
if (c == 'y' || c == 'Y')
{
/* 鐑у啓鍒皀and flash block 0 */
for (erase_addr = 0; erase_addr < ((len + 0x1FFFF) & ~0x1FFFF); erase_addr += 0x20000)
{
nand_erase_block(erase_addr);
}
nand_write(0, buf, len);
puts("update program successful\n\r");
}
else
{
puts("Cancel program!\n\r");
}
}
void run_program(void)
{
unsigned char *buf = (unsigned char *)0x57e00000;
unsigned long len = 0;
int have_begin = 0;
int nodata_time = 0;
void (*theProgram)(void);
int i;
puts("\n\r use gtkterm to send file\n\r");
while (1)
{
if (getc_nowait(&buf[len]) == 0)
{
have_begin = 1;
nodata_time = 0;
len++;
}
else
{
if (have_begin)
{
nodata_time++;
}
}
if (nodata_time == 1000)
{
break;
}
}
//printf("have get %d bytes data\n\r", len);
puts("\n\r have get data:");
puthex(len);
puts(" bytes\n\r");
puts("the first 16 bytes data: \n\r");
for (i = 0; i < 16; i++)
{
// put("%02x ", buf[i]);
putbyte(buf[i]);
puts("\t");
//putc('\0');
}
puts("\n\r");
puts("jump to 0x57e00000 to run it\n\r");
theProgram = (void (*)(void))0x57e00000;
theProgram();
}
int main(void)
{
char c;
init_uart();
puts("\n\r*********************************\n\r");
puts("update program with serial port\n\r");
puts("The board:witech(ok6410)\n\r");
puts("The NAND:K9GAG08U0D 2048MB\n\r");
puts("The DDR:K4X1G163PCX2 256MB\n\r");
puts("The NET:DM9000AEP\n\r");
puts(" date: 2013.4.26\n\r");
puts("***********************************\n\r");
while (1)
{
puts("the menu of the update programe:\n\r");
puts("[w] write the nand flash\n\r");
puts("[r] read the nand flash\n\r");
puts("[e] erase the nand flash\n\r");
puts("[g] get file, and write to nand flash 0 block\n\r");
puts("[x] get file to ddr(0x57e00000), run it\n\r");
puts("[s] reset the programe\n\r");
puts("Please enter the chose:\n\r");
do {
c = getc();
if (c == '\n' || c == '\r')
{
puts("\n\r");
}
else
{
putc(c);
}
} while (c == '\n' || c == '\r');
switch (c)
{
case 'w':
case 'W':
{
nand_write_test();
break;
}
case 'r':
case 'R':
{
nand_read_test();
break;
}
case 'e':
case 'E':
{
nand_erase_test();
break;
}
case 'g':
case 'G':
{
update_program();
break;
}
case 'x':
case 'X':
{
run_program();
break;
}
case 's':
case 'S':
{
void (*theProgram)(void);
theProgram = (void (*)(void))0x57e00000;
theProgram();
break;
}
}
}
return 0;
}
????文件boot.lds:
SECTIONS {
. = 0x57e00000;
.text : { *(.text) }
. = ALIGN(4);
.rodata : {*(.rodata*)}
. = ALIGN(4);
.data : { *(.data) }
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss) *(COMMON) }
__bss_end = .;
}
????文件Makefile:
CC = arm-linux-gcc
LD = arm-linux-ld
AR = arm-linux-ar
OBJCOPY = arm-linux-objcopy
OBJDUMP = arm-linux-objdump
CFLAGS := -Wall -O2
CPPFLAGS := -nostdinc -nostdlib -fno-builtin
objs := start.o clock.o sdram.o init.o main.o
update.bin: $(objs)
${LD} -Tboot.lds -o boot.elf $^
${OBJCOPY} -O binary -S boot.elf $@
${OBJDUMP} -D -m arm boot.elf > boot.dis
%.o:%.c
${CC} $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
%.o:%.S
${CC} $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
clean:
rm -f *.o *.bin *.elf *.dis
????二、編譯源程序
????
change@change:~/Si/OK6410/update$
cd /home/change/
change@change:~$
cd Si/OK6410/update/
change@change:~/Si/OK6410/update$
make clean
rm -f *.o *.bin *.elf *.dis
change@change:~/Si/OK6410/update$
make
arm-linux-gcc -nostdinc -nostdlib -fno-builtin -Wall -O2 -c -o start.o start.S
arm-linux-gcc -nostdinc -nostdlib -fno-builtin -Wall -O2 -c -o clock.o clock.S
arm-linux-gcc -nostdinc -nostdlib -fno-builtin -Wall -O2 -c -o sdram.o sdram.c
arm-linux-gcc -nostdinc -nostdlib -fno-builtin -Wall -O2 -c -o init.o init.c
arm-linux-gcc -nostdinc -nostdlib -fno-builtin -Wall -O2 -c -o main.o main.c
main.c: In function 'nand_read_test':
main.c:50: warning: passing argument 2 of 'nand_read' makes integer from pointer without a cast
main.c: In function 'nand_write_test':
main.c:98: warning: pointer targets in passing argument 2 of 'nand_write' differ in signedness
arm-linux-ld ?-Tboot.lds -o boot.elf start.o clock.o sdram.o init.o main.o
arm-linux-objcopy -O binary -S boot.elf update.bin
arm-linux-objdump -D -m arm boot.elf > boot.dis
change@change:~/Si/OK6410/update$?
????這都是經過修改后的終究編譯結果,所以沒有錯誤。
????三、燒寫、試測
????用新想到的方法燒寫程序,用不面前說的u-boot下載程序。先用飛淩供給的一鍵燒寫具工,寫mmc.bin到sd卡,再把面下編譯成生的update.bin以u-boot.bin定名,并拷到sd卡,接著把單板撥到sd卡動啟。我的OK6410在NAND動啟的情況下直接把6、7撥到on就成變SD動啟了。單板SD卡動啟上電,串口(115200 8 n 1)輸出如下:
????
K
U-Boot 1.1.6 (Dec 15 2010 - 09:02:39) for SMDK6410
****************************************
** ? ?u-boot 1.1.6 ? ? ? ? ? ? ? ? ? ?**
** ? ?Updated for TE6410 Board ? ? ? ?**
** ? ?Version 1.0 (10-01-15) ? ? ? ? ?**
** ? ?OEM: Forlinx Embedded ? ? ? ? ? **
** ? ?Web: http://www.witech.com.cn ? **
****************************************
CPU: ? ? S3C6410 @532MHz
? ? ? ? ?Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz, Serial = CLKUART (SYNC Mode)?
Board: ? SMDK6410
DRAM: ? ?128 MB
Flash: ? 0 kB
NAND: ? ?tmp = 29
select s3c_nand_oob_mlc_128
2048 MB?
SD/MMC: ?1877 MB?
*** Warning - bad CRC or moviNAND, using default environment
In: ? ? ?serial
Out: ? ? serial
Err: ? ? serial
Hit any key to stop autoboot: ?0?
NAND erase: device 0 whole chip
Skipping bad block at ?0x00800000 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
Skipping bad block at ?0x0e400000 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
Skipping bad block at ?0x0e780000 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
Skipping bad block at ?0x13b80000 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
Skipping bad block at ?0x27a80000 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
Skipping bad block at ?0x7e280000 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
Erasing at 0x7ff80000 -- 100% complete.
OK
reading u-boot.bin
5228 bytes read
NAND write: device 0 offset 0x0, size 0x100000
?1032192 bytes written: OK
reading zImage
** Unable to read "zImage" from mmc 0:1 **
????明說u-boot燒寫畢完。燒寫mmc.bin的SD卡,會動自幫你把程序燒寫到NAND。接著斷電下取SD卡,單板撥到NAND動啟,串口輸出如下:
????
*********************************
update program with serial port
The board:witech(ok6410)
The NAND:K9GAG08U0D 2048MB
The DDR:K4X1G163PCX2 256MB
The NET:DM9000AEP
? ? ? ? ? ? ? ? ?date: 2013.4.26
***********************************
the menu of the update programe:
[w] write the nand flash
[r] read the nand flash
[e] erase the nand flash
[g] get file, and write to nand flash 0 block
[x] get file to ddr(0x57e00000), run it
[s] reset the programe
Please enter the chose:
????用串口具工v2.2.exe,演示update程序功能如下:
????
*********************************
update program with serial port
The board:witech(ok6410)
The NAND:K9GAG08U0D 2048MB
The DDR:K4X1G163PCX2 256MB
The NET:DM9000AEP
? ? ? ? ? ? ? ? ?date: 2013.4.26
***********************************
the menu of the update programe:
[w] write the nand flash
[r] read the nand flash
[e] erase the nand flash
[g] get file, and write to nand flash 0 block
[x] get file to ddr(0x57e00000), run it
[s] reset the programe
Please enter the chose:
????
g
use V2.2.exe/gtkterm to send file
????
接著選要擇發送的文件eg:u-boot.bin,并發送文件,發送畢完輸出如下:
have get data:0x0003A6BC bytes
the first 16 bytes data:?
0x150x00 0x000xEA 0x140xF0 0x9F0xE5 0x140xF0 0x9F0xE5 0x140xF0 0x9F0xE5
Press Y to program the flash:?
????接著手動發送y,這里要慎謹作操,因為一旦入輸y,程序就會擦除之前的程序。串口輸出如下:
????
update program successful
the menu of the update programe:
[w] write the nand flash
[r] read the nand flash
[e] erase the nand flash
[g] get file, and write to nand flash 0 block
[x] get file to ddr(0x57e00000), run it
[s] reset the programe
Please enter the chose:
????看到update program successful面下程序新更畢完。面下來驗證,斷電重啟,串口輸出如下:
????
U-Boot 2012.04.01 (Nov 25 2012 - 21:01:21) for SMDK6410
CPU: ? ? S3C6400@532MHz
? ? ? ? ?Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz (ASYNC Mode)?
Board: ? SMDK6410
DRAM: ?128 MiB
WARNING: Caches not enabled
Flash: 0 KB
NAND: ?select s3c_nand_oob_mlc_64
id_data[0] = 0xec id_data[1] = 0xd5 id_data[2] = 0x94 id_data[3] = 0x29 id_data[4] = 0x34 id_data[5] = 0x41 id_data[6] = 0xec id_data[7] = 0xd5 NAND_ECC_NONE selected by board driver. This is not recommended !!
2048 MiB
realpage value:255
page value:255
ret value:0
*** Warning - bad CRC, using default environment
In: ? ?serial
Out: ? serial
Err: ? serial
Net: ? dm9000
Hit any key to stop autoboot: ?0?
##### 100ask Bootloader for OpenJTAG #####
[n] Download u-boot to Nand Flash
[k] Download Linux kernel uImage
[j] Download root_jffs2 image
[y] Download root_yaffs image
[d] Download to SDRAM & Run
[z] Download zImage into RAM
[g] get file, and write to nand flash 0 block
[f] Format the Nand Flash
[s] Set the boot parameters
[b] Boot the system
[r] Reboot u-boot
[q] Quit from menu
Enter your selection: q
SMDK6410 #
????明說u-boot經已下載畢完,當然之前的程序也就擦掉了。經過試測基本OK,可能還存在bug,橫豎人多力量大,可以提出一同處理。
文章結束給大家分享下程序員的一些笑話語錄: 剎車失靈
有一個物理學家,工程師和一個程序員駕駛著一輛汽車行駛在阿爾卑斯山脈 上,在下山的時候,忽然,汽車的剎車失靈了,汽車無法控制地向下沖去, 眼看前面就是一個懸崖峭壁,但是很幸運的是在這個懸崖的前面有一些小樹 讓他們的汽車停了下來, 而沒有掉下山去。 三個驚魂未定地從車里爬了出來。
物理學家說, “我覺得我們應該建立一個模型來模擬在下山過程中剎車片在高 溫情況下失靈的情形”。
工程師說, “我在車的后備廂來有個扳手, 要不我們把車拆開看看到底是什么 原因”。
程序員說,“為什么我們不找個相同的車再來一次以重現這個問題呢?”
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

