⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmd_load.c

📁 嵌入式试验箱S3C2410的bootloader源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
static int k_recv (void){    char new_char;    char k_state, k_state_saved;    int sum;    int done;    int length;    int n, last_n;    int z = 0;    int len_lo, len_hi;    /* initialize some protocol parameters */    his_eol = END_CHAR;     /* default end of line character */    his_pad_count = 0;    his_pad_char = '\0';    his_quote = K_ESCAPE;    /* initialize the k_recv and k_data state machine */    done = 0;    k_state = 0;    k_data_init ();    k_state_saved = k_state;    k_data_save ();    n = 0;              /* just to get rid of a warning */    last_n = -1;    /* expect this "type" sequence (but don't check):       S: send initiate       F: file header       D: data (multiple)       Z: end of file       B: break transmission     */    /* enter main loop */    while (!done) {        /* set the send packet pointer to begining of send packet parms */        send_ptr = send_parms;        /* With each packet, start summing the bytes starting with the length.           Save the current sequence number.           Note the type of the packet.           If a character less than SPACE (0x20) is received - error.         */#if 0        /* OLD CODE, Prior to checking sequence numbers */        /* first have all state machines save current states */        k_state_saved = k_state;        k_data_save ();#endif        /* get a packet */        /* wait for the starting character or ^C */        for (;;) {            switch (getc ()) {            case START_CHAR:    /* start packet */                goto START;            case ETX_CHAR:      /* ^C waiting for packet */                return (0);            default:                ;            }        }START:        /* get length of packet */        sum = 0;        new_char = getc ();        if ((new_char & 0xE0) == 0)            goto packet_error;        sum += new_char & 0xff;        length = untochar (new_char);        /* get sequence number */        new_char = getc ();        if ((new_char & 0xE0) == 0)            goto packet_error;        sum += new_char & 0xff;        n = untochar (new_char);        --length;        /* NEW CODE - check sequence numbers for retried packets */        /* Note - this new code assumes that the sequence number is correctly         * received.  Handling an invalid sequence number adds another layer         * of complexity that may not be needed - yet!  At this time, I'm hoping         * that I don't need to buffer the incoming data packets and can write         * the data into memory in real time.         */        if (n == last_n) {            /* same sequence number, restore the previous state */            k_state = k_state_saved;            k_data_restore ();        } else {            /* new sequence number, checkpoint the download */            last_n = n;            k_state_saved = k_state;            k_data_save ();        }        /* END NEW CODE */        /* get packet type */        new_char = getc ();        if ((new_char & 0xE0) == 0)            goto packet_error;        sum += new_char & 0xff;        k_state = new_char;        --length;        /* check for extended length */        if (length == -2) {            /* (length byte was 0, decremented twice) */            /* get the two length bytes */            new_char = getc ();            if ((new_char & 0xE0) == 0)                goto packet_error;            sum += new_char & 0xff;            len_hi = untochar (new_char);            new_char = getc ();            if ((new_char & 0xE0) == 0)                goto packet_error;            sum += new_char & 0xff;            len_lo = untochar (new_char);            length = len_hi * 95 + len_lo;            /* check header checksum */            new_char = getc ();            if ((new_char & 0xE0) == 0)                goto packet_error;            if (new_char != tochar ((sum + ((sum >> 6) & 0x03)) & 0x3f))                goto packet_error;            sum += new_char & 0xff;/* --length; */ /* new length includes only data and block check to come */        }        /* bring in rest of packet */        while (length > 1) {            new_char = getc ();            if ((new_char & 0xE0) == 0)                goto packet_error;            sum += new_char & 0xff;            --length;            if (k_state == DATA_TYPE) {                /* pass on the data if this is a data packet */                k_data_char (new_char);            } else if (k_state == SEND_TYPE) {                /* save send pack in buffer as is */                *send_ptr++ = new_char;                /* if too much data, back off the pointer */                if (send_ptr >= &send_parms[SEND_DATA_SIZE])                    --send_ptr;            }        }        /* get and validate checksum character */        new_char = getc ();        if ((new_char & 0xE0) == 0)            goto packet_error;        if (new_char != tochar ((sum + ((sum >> 6) & 0x03)) & 0x3f))            goto packet_error;        /* get END_CHAR */        new_char = getc ();        if (new_char != END_CHAR) {          packet_error:            /* restore state machines */            k_state = k_state_saved;            k_data_restore ();            /* send a negative acknowledge packet in */            send_nack (n);        } else if (k_state == SEND_TYPE) {            /* crack the protocol parms, build an appropriate ack packet */            handle_send_packet (n);        } else {            /* send simple acknowledge packet in */            send_ack (n);            /* quit if end of transmission */            if (k_state == BREAK_TYPE)                done = 1;        }        ++z;    }    return ((ulong) os_data_addr - (ulong) bin_start_address);}static int getcxmodem(void) {    if (tstc())        return (getc());    return -1;}/* support xmodem, www.arm9.net */static ulong load_serial_xmodem (ulong offset){    int size;    char buf[32];    int err;    int res;    connection_info_t info;    char xmodemBuf[1024];    ulong store_addr = ~0;    ulong addr = 0;    size = 0;    info.mode = xyzModem_xmodem;    res = xyzModem_stream_open (&info, &err);    if (!res) {        while ((res =            xyzModem_stream_read (xmodemBuf, 1024, &err)) > 0) {            store_addr = addr + offset;            size += res;            addr += res;#ifndef CFG_NO_FLASH            if (addr2info (store_addr)) {                int rc;                rc = flash_write ((char *) xmodemBuf,                          store_addr, res);                if (rc != 0) {                    flash_perror (rc);                    return (~0);                }            } else#endif            {                memcpy ((char *) (store_addr), xmodemBuf,                    res);            }        }    } else {        printf ("%s\n", xyzModem_error (err));    }    xyzModem_stream_close (&err);    xyzModem_stream_terminate (false, &getcxmodem);    flush_cache (offset, size);    printf ("## Total Size      = 0x%08x = %d Bytes\n", size, size);    sprintf (buf, "%X", size);    setenv ("filesize", buf);    return offset;}static ulong load_serial_ymodem (ulong offset){    int size;    char buf[32];    int err;    int res;    connection_info_t info;    char ymodemBuf[1024];    ulong store_addr = ~0;    ulong addr = 0;    size = 0;    info.mode = xyzModem_ymodem;    res = xyzModem_stream_open (&info, &err);    if (!res) {        while ((res =            xyzModem_stream_read (ymodemBuf, 1024, &err)) > 0) {            store_addr = addr + offset;            size += res;            addr += res;#ifndef CFG_NO_FLASH            if (addr2info (store_addr)) {                int rc;                rc = flash_write ((char *) ymodemBuf,                          store_addr, res);                if (rc != 0) {                    flash_perror (rc);                    return (~0);                }            } else#endif            {                memcpy ((char *) (store_addr), ymodemBuf,                    res);            }        }    } else {        printf ("%s\n", xyzModem_error (err));    }    xyzModem_stream_close (&err);    xyzModem_stream_terminate (false, &getcxmodem);    flush_cache (offset, size);    printf ("## Total Size      = 0x%08x = %d Bytes\n", size, size);    sprintf (buf, "%X", size);    setenv ("filesize", buf);    return offset;}#endif  /* CFG_CMD_LOADB *//* -------------------------------------------------------------------- */#if (CONFIG_COMMANDS & CFG_CMD_LOADS)#ifdef  CFG_LOADS_BAUD_CHANGEU_BOOT_CMD(    loads, 3, 0,    do_load_serial,    "loads   - load S-Record file over serial line\n",    "[ off ] [ baud ]\n"    "    - load S-Record file over serial line"    " with offset 'off' and baudrate 'baud'\n");#else   /* ! CFG_LOADS_BAUD_CHANGE */U_BOOT_CMD(    loads, 2, 0,    do_load_serial,    "loads   - load S-Record file over serial line\n",    "[ off ]\n"    "    - load S-Record file over serial line with offset 'off'\n");#endif  /* CFG_LOADS_BAUD_CHANGE *//* * SAVES always requires LOADS support, but not vice versa */#if (CONFIG_COMMANDS & CFG_CMD_SAVES)#ifdef  CFG_LOADS_BAUD_CHANGEU_BOOT_CMD(    saves, 4, 0,    do_save_serial,    "saves   - save S-Record file over serial line\n",    "[ off ] [size] [ baud ]\n"    "    - save S-Record file over serial line"    " with offset 'off', size 'size' and baudrate 'baud'\n");#else   /* ! CFG_LOADS_BAUD_CHANGE */U_BOOT_CMD(    saves, 3, 0,    do_save_serial,    "saves   - save S-Record file over serial line\n",    "[ off ] [size]\n"    "    - save S-Record file over serial line with offset 'off' and size 'size'\n");#endif  /* CFG_LOADS_BAUD_CHANGE */#endif  /* CFG_CMD_SAVES */#endif  /* CFG_CMD_LOADS */#if (CONFIG_COMMANDS & CFG_CMD_LOADB)U_BOOT_CMD(    loadb, 3, 0,    do_load_serial_bin,    "loadb   - load binary file over serial line (kermit mode)\n",    "[ off ] [ baud ]\n"    "    - load binary file over serial line"    " with offset 'off' and baudrate 'baud'\n");/* support xmodem, www.arm9.net */U_BOOT_CMD(    loadx, 3, 0,    do_load_serial_bin,    "loadx   - load binary file over serial line (xmodem mode)\n",    "[ off ] [ baud ]\n"    "    - load binary file over serial line"    " with offset 'off' and baudrate 'baud'\n");U_BOOT_CMD(    loady, 3, 0,    do_load_serial_bin,    "loady   - load binary file over serial line (ymodem mode)\n",    "[ off ] [ baud ]\n"    "    - load binary file over serial line"    " with offset 'off' and baudrate 'baud'\n");#endif  /* CFG_CMD_LOADB *//* -------------------------------------------------------------------- */#if (CONFIG_COMMANDS & CFG_CMD_HWFLOW)int do_hwflow (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){    extern int hwflow_onoff(int);    if (argc == 2) {        if (strcmp(argv[1], "off") == 0)            hwflow_onoff(-1);        else            if (strcmp(argv[1], "on") == 0)                hwflow_onoff(1);            else                printf("Usage: %s\n", cmdtp->usage);    }    printf("RTS/CTS hardware flow control: %s\n", hwflow_onoff(0) ? "on" : "off");    return 0;}/* -------------------------------------------------------------------- */U_BOOT_CMD(    hwflow, 2, 0,   do_hwflow,    "hwflow  - turn the harwdare flow control on/off\n",    "[on|off]\n - change RTS/CTS hardware flow control over serial line\n");#endif /* CFG_CMD_HWFLOW */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -