亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

程序卡OK6410裸板更新程序_update

系統 1843 0

新手發帖,很多方面都是剛入門,有錯誤的地方請大家見諒,歡迎批評指正

????我用的飛淩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,橫豎人多力量大,可以提出一同處理。

文章結束給大家分享下程序員的一些笑話語錄: 剎車失靈
有一個物理學家,工程師和一個程序員駕駛著一輛汽車行駛在阿爾卑斯山脈 上,在下山的時候,忽然,汽車的剎車失靈了,汽車無法控制地向下沖去, 眼看前面就是一個懸崖峭壁,但是很幸運的是在這個懸崖的前面有一些小樹 讓他們的汽車停了下來, 而沒有掉下山去。 三個驚魂未定地從車里爬了出來。
物理學家說, “我覺得我們應該建立一個模型來模擬在下山過程中剎車片在高 溫情況下失靈的情形”。
工程師說, “我在車的后備廂來有個扳手, 要不我們把車拆開看看到底是什么 原因”。
程序員說,“為什么我們不找個相同的車再來一次以重現這個問題呢?”

程序卡OK6410裸板更新程序_update


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 四虎国产一区 | 久久99国产亚洲高清观看首页 | 99国产精品免费视频观看 | 不卡影院在线观看 | 国产精品午夜性视频 | 99精品国产高清自在线看超 | 国产片91人成在线观看 | 四虎免费在线观看视频 | 日韩久久视频 | 久草首页在线观看 | 国产精品网站 夜色 | 99精品网站| 免费爱爱小视频 | 奇米视频在线观看 | 高清一级毛片一本到免费观看 | 国产精品视_精品国产免费 国产精品视频2021 | 久久99亚洲精品久久久久99 | 97国产在线公开免费观看 | 在线观看 一区 | 久久精品无码一区二区日韩av | 911国产在线观看精品 | 日本人xx视频免费视频 | 尤物视频在线观看 | 精品国产欧美一区二区三区成人 | 色精品视频 | 波多野吉衣一区二区三区在线观看 | 日韩色区| 91av爱爱| 精品久久久久久久久久久久久久久 | 国产91在线播放边 | 护士一级毛片 | 亚洲视频播放 | 久久福利免费视频 | 青青久久国产成人免费网站 | 97av在线视频| 久久996国产精品免费 | 国产探花在线观看 | 中文字幕高清免费不卡视频 | 久久精品入口麻豆 | 久热这里有精品 | 久久国产精品免费 |