您尚未登录。

楼主 #1 2020-05-09 20:59:33

缥缈九哥
会员
注册时间: 2020-05-09
已发帖子: 93
积分: 96

添加XMODEM下载协议到基于u-boot-1.3.4的9G9260开发板 --缥缈九哥

添加XMODEM下载协议到基于u-boot-1.3.4的9G9260开发板

1,下载解压源码:
root@yuanxh-desktop:/home/yuanxh/sam9260# wget ftp://ftp.denx.de/pub/u-boot/u-boot-1.3.4.tar.bz2
root@yuanxh-desktop:/home/yuanxh/sam9260# wget ftp://www.linux4sam.org/pub/uboot/u-boot-1.3.4-exp/u-boot-1.3.4-exp.diff
root@yuanxh-desktop:/home/yuanxh/sam9260# tar xjvf u-boot-1.3.4.tar.bz2
root@yuanxh-desktop:/home/yuanxh/sam9260# mv u-boot-1.3.4 u-boot-1.3.4-9g9260
root@yuanxh-desktop:/home/yuanxh/sam9260# mv u-boot-1.3.4-exp.diff u-boot-1.3.4-9g9260/

2,打补丁:
root@yuanxh-desktop:/home/yuanxh/sam9260# cd u-boot-1.3.4-9g9260
root@yuanxh-desktop:/home/yuanxh/sam9260/u-boot-1.3.4-9g9260# patch -p1 < ./u-boot-1.3.4-exp.diff

3,默认配置:
root@yuanxh-desktop:/home/yuanxh/sam9260/u-boot-1.3.4-9g9260# make at91sam9260ek_dataflash_cs0_config
root@yuanxh-desktop:/home/yuanxh/sam9260/u-boot-1.3.4-9g9260# make at91sam9260ek_dataflash_cs1_config
root@yuanxh-desktop:/home/yuanxh/sam9260/u-boot-1.3.4-9g9260# make at91sam9260ek_nandflash_config
(选择对应的一项,区分NANDFLASH和DATAFLASH的CS0,CS1)

4,添加XMODEM下载协议
在\common\Makefile的147行添加 COBJS-y += cmd_xmodem.o xmodem.o
root@yuanxh-desktop:/home/yuanxh/sam9260/u-boot-1.3.4-9g9260# vi common/Makefile
在\common\中增加源文件  xmodem.c cmd_xmodem.c
root@yuanxh-desktop:/home/yuanxh/sam9260/u-boot-1.3.4-9g9260# rz
root@yuanxh-desktop:/home/yuanxh/sam9260/u-boot-1.3.4-9g9260# mv xmodem.c cmd_xmodem.c common/

5,编译发布:
root@yuanxh-desktop:/home/yuanxh/sam9260/u-boot-1.3.4-9g9260# make
root@yuanxh-desktop:/home/yuanxh/sam9260/u-boot-1.3.4-9g9260# mv u-boot.bin u-boot-1.3.4-9g9260.bin
root@yuanxh-desktop:/home/yuanxh/sam9260/u-boot-1.3.4-9g9260# sz u-boot-1.3.4-9g9260.bin

6, 清除配置
root@yuanxh-desktop:/home/yuanxh/sam9260/u-boot-1.3.4-9g9260# make distclean

附件:xmodem.c文件

/*******************************************************************************
 *
 * Filename: xmodem.c
 *
 * change from KB9202 , yuanxihua@21cn.com
 ******************************************************************************/

#include <common.h>

extern int xmodem_rx(char *dest);

/* Line control codes */
#define SOH   0x01 /* start of header for Xmodem protocol  */
#define STX   0x02 /* start of header for 1K xmodem protocol*/
#define ACK   0x06 /* Acknowledge */
#define NAK   0x15 /* Negative acknowledge */
#define CAN   0x18 /* Cancel */
#define EOT   0x04 /* end of text */
#define TIMEOUT 2
#define TIMEOUT_LONG 10
#define XMODEM_DATA_SIZE_SOH 128  /* for Xmodem protocol */
#define XMODEM_DATA_SIZE_STX 1024 /* for 1K xmodem protocol */

enum {
 INVALID_STATE = 0,
 WAITING_START,
 WAIT_HEAD,
 RX_PACKET,
 RX_EOT,
 SEND_NAK
};

static char packetNumber;
static int PACKET_SIZE;
static char HEAD;

#define TransitionState(x, y) (x = y)

void DebugPutc(char cValue)
{
 putc (cValue & 0x1FF);
}
int WaitForChar(char *cPtr, int seconds)
{
   unsigned long counter = 0;
   
   seconds = seconds * 1000 ;  /* delay 1000 * 50 * 20us */
   
   while (!tstc () && (counter < seconds * 50 ))
    {
      udelay (20);
      counter++;
    }
  if (tstc ())
    {
      *cPtr = getc ();
      return 1;
    }
  return 0;
}
static int GetRecord(char blocknum, char *dest) {
 int  size;
 char  nextChar;
 unsigned chk, j;

 chk = 0;

 if (!WaitForChar(&nextChar, TIMEOUT)) {
  return (0);
 }

 if ((char)nextChar != (char)~blocknum) {
  return (0);
 }

 for (size = 0; size < PACKET_SIZE; ++size) {
  if (!WaitForChar(&nextChar, TIMEOUT)) {
   return (0);
  }
  chk = chk ^(int)nextChar << 8;
  for (j = 0; j < 8; ++j) {
   if (chk & 0x8000)
    chk = chk << 1 ^ 0x1021;
   else
    chk = chk << 1;
  }
  *dest++ = nextChar;
 }

 chk &= 0xFFFF;

 if ((!WaitForChar(&nextChar, TIMEOUT)) || (nextChar != ((chk >> 8) & 0xFF))) {
  return (0);
 }

 if ((!WaitForChar(&nextChar, TIMEOUT)) || (nextChar != (chk & 0xFF))) {
  return (0);
 }

 DebugPutc(ACK);

 return (1);
}
int xmodem_rx(char *dest) {

 int  state;
 char  nextChar, *startAddress = dest;

 packetNumber = 1;
 state = WAITING_START;
 PACKET_SIZE = XMODEM_DATA_SIZE_SOH;
 HEAD = SOH;
      
 while (1) {

  if (state == WAITING_START) {
   DebugPutc('C');
   if (WaitForChar(&nextChar, TIMEOUT)) {
    if (nextChar == SOH)
    {
      PACKET_SIZE = XMODEM_DATA_SIZE_SOH;
      HEAD = SOH;
      TransitionState(state, RX_PACKET);
    }
    else
    if (nextChar == STX)
    {
      PACKET_SIZE = XMODEM_DATA_SIZE_STX;
      HEAD = STX;
      TransitionState(state, RX_PACKET);
    }
   }
  }

  if (state == WAIT_HEAD) {
   if (!WaitForChar(&nextChar, TIMEOUT_LONG)) {
    return (-1);
   }

/*   if (nextChar == HEAD) {
    TransitionState(state, RX_PACKET);
   }
*/
    if (nextChar == SOH)
    {
      PACKET_SIZE = XMODEM_DATA_SIZE_SOH;
      HEAD = SOH;
      TransitionState(state, RX_PACKET);
    }
    else
    if (nextChar == STX)
    {
      PACKET_SIZE = XMODEM_DATA_SIZE_STX;
      HEAD = STX;
      TransitionState(state, RX_PACKET);
    }
    
   if (nextChar == EOT) {
    // TransitionState(state, RX_EOT);
    DebugPutc(ACK);
    return (dest - startAddress);
   }
  }

  if (state == RX_PACKET) {
   if (!WaitForChar(&nextChar, TIMEOUT)) {
    return (-1);
   }

   if (nextChar != packetNumber) {
    // TransitionState(state, SEND_NAK);
    DebugPutc(NAK);
    return (-1);
   }

   if (GetRecord(packetNumber, dest)) {
    dest += PACKET_SIZE;
    ++packetNumber;
    TransitionState(state, WAIT_HEAD);
   } else {
    return (-1);
   }
  }
 }

 // the loop above should return in all cases
 return (-1);
}

附件:cmd_xmodem.c文件

#include <common.h>
#include <command.h>
#include <asm/io.h>
#include <asm/arch/hardware.h>

static ulong load_xmodem_bin(ulong *);
static char *bin_start_address;

int do_xmodem(cmd_tbl_t *cmdtp,int flag,int argc, char *argv[])
{
 DECLARE_GLOBAL_DATA_PTR;

 ulong offset = 0;
 ulong addr;
 int load_baudrate, current_baudrate;
 int rcode = 0;
 char *s;

 /* pre-set offset from CFG_LOAD_ADDR */
 offset = CFG_LOAD_ADDR;

 /* pre-set offset from $loadaddr */
 if ((s = getenv("loadaddr")) != NULL) {
  offset = simple_strtoul(s, NULL, 16);
 }

 load_baudrate = current_baudrate = gd->baudrate;

 if (argc >= 2) {
  offset = simple_strtoul(argv[1], NULL, 16);
 }
 if (argc == 3) {
  load_baudrate = (int)simple_strtoul(argv[2], NULL, 10);

  /* default to current baudrate */
  if (load_baudrate == 0)
   load_baudrate = current_baudrate;
 }

 if (load_baudrate != current_baudrate) {
  printf ("## Switch baudrate to %d bps and press ENTER ...\n",
   load_baudrate);
  udelay(50000);
  gd->baudrate = load_baudrate;
  serial_setbrg ();
  udelay(50000);
  for (;;) {
   if (getc() == '\r')
    break;
  }
 }

 printf ("## Ready for binary (xmodem) download "
  "to 0x%08lX at %d bps...\n",
  offset,
  load_baudrate);

 addr = load_xmodem_bin((ulong *) offset);
 
 if (addr == ~0) {
  load_addr = 0;
  printf ("## Binary (xmodem) download aborted\n");
  rcode = 1;
 } else {
  printf ("## Start Addr      = 0x%08lX\n", addr);
  load_addr = addr;
 }

 if (load_baudrate != current_baudrate) {
  printf ("## Switch baudrate to %d bps and press ESC ...\n",
   current_baudrate);
  udelay (50000);
  gd->baudrate = current_baudrate;
  serial_setbrg ();
  udelay (50000);
  for (;;) {
   if (getc() == 0x1B) /* ESC */
    break;
  }
 }

#ifdef CONFIG_AUTOSCRIPT
 if (load_addr) {
  char *s;

  if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) {
   printf("Running autoscript at addr 0x%08lX ...\n", load_addr);
   rcode = autoscript (load_addr);
  }
 }
#endif
 return rcode;
}

static ulong load_xmodem_bin(unsigned long *addr)
{
 int size, i;
 char buf[32];
 ulong offset;
 
// set_kerm_bin_mode ((ulong *) offset);
// size = k_recv ();
  offset = addr;
  bin_start_address = (char *) addr;
  size = xmodem_rx(bin_start_address);

 /*
  * Gather any trailing characters (for instance, the ^D which
  * is sent by 'cu' after sending a file), and give the
  * box some time (100 * 1 ms)
  */
 for (i=0; i<100; ++i) {
  if (tstc()) {
   (void) getc();
  }
  udelay(1000);
 }

 flush_cache (offset, size);

 printf("## Total Size      = 0x%08x = %d Bytes\n", size, size);
 sprintf(buf, "%X", size);
 setenv("filesize", buf);

 return offset;
}

U_BOOT_CMD(
  rx,    3,    0,     do_xmodem,
 "rx      - load binary file over serial line (xmodem)\n",
 "[ off ] [ baud ]\n"
 "    - load binary file over serial line"
 " with offset 'off' and baudrate 'baud'\n"
);

 

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn