小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

vivi中的xmodem代碼部分的注釋

 苦修茶館 2015-11-04
/*
 * vivi/deriver/serialxmodem.c:
 * - an implementation of the xmodem protocol from the spec.
 *
 * Based on bootldr/xmodem.c (C) 2000 Compaq Computer Coporation.
 *
 * Copyright (C) 2001 MIZI Research, Inc.
 *
 *
 * 1999-01-xx: Edwin Foo
 * - Initial code
 *
 * 2001-10-04: Janghoon Lyu
 * - Modified a little bit.
 *
 * 2002-07-04: Janghoon Lyu
 */


#include "config.h"
#include "machine.h"
#include "serial.h"
#include "priv_data.h"
#include <types.h>

/* XMODEM parameters */
#define BLOCK_SIZE    128    /* size of transmit blocks */
#define RETRIES        20    /* maximum number of RETRIES */

/* Line control codes */
#define SOH        0x01    /* start of header */
#define ACK        0x06    /* Acknowledge */
#define NAK        0x15    /* Negative acknowledge */
#define CAN        0x18    /* Cancel */
#define EOT        0x04    /* end of text */

#define GET_BYTE_TIMEOUT 10000000

/* global error variable */
char *xmodem_errtxt = NULL;
int get_byte_err = 0;
__u8 volatile rbuffer[BLOCK_SIZE];

/* prototypes of helper functions */
int get_record(void);
__u8 get_byte(void);

enum
{
    SAC_SEND_NAK = 0,
    SAC_SENT_NAK = 1,
    SAC_PAST_START_NAK = 2
};

static volatile int seen_a_char = SAC_SEND_NAK;

static int one_nak = 0;
static unsigned long xmodem_timeout = GET_BYTE_TIMEOUT;

char debugbuf[4096];
int db_idx = 0;

void bufputs(char *s)
{
    size_t len = strlen(s) + 1;

    if (len + db_idx > sizeof(debugbuf))
        len = sizeof(debugbuf) - db_idx;

    if (len) {
        memcpy(&debugbuf[db_idx], s, len);
        db_idx += len;
    }
}

void reset_debugbuf(void)
{
    memset(debugbuf, 0x2a, sizeof(debugbuf));
    db_idx = 0;
}

__u32 xmodem_receive(char *dldaddr, size_t len)
{
    char ochr;
    int r = 0, rx_block_num = 0, error_count = 0;
    __u32 foffset = 0;
    int i;
    int ret;

    xmodem_errtxt = NULL;
    seen_a_char = 0;

    one_nak = get_param_value("xmodem_one_nak", &ret);
    if (ret) one_nak = 0;

    xmodem_timeout = get_param_value("xmodem_initial_timeout", &ret);
    if (ret) xmodem_timeout = GET_BYTE_TIMEOUT;

    rx_block_num = 1; // 一共接收到了多少個包

    error_count = RETRIES; // 重試次數(shù) 20次


    do {
        // rx_block_num & 255 的意思是求出當(dāng)前的包的編號,因為每次最多

        // 是 256個包而已0-255,并且 rx_block_num 應(yīng)該是指向下一個應(yīng)該

        // 接收到的正確的包的編號,如果相等,表示今次接收的包是正確的

        if ((r = get_record()) == (rx_block_num & 255)) {
            error_count = RETRIES; // 重置重試次數(shù)

            for (i = 0; i <BLOCK_SIZE; i++) // 將一個包復(fù)制到指定的地址

                *(__u8 *)(dldaddr+foffset+i) = rbuffer[i];
            xmodem_errtxt = "RX PACKET"; // 錯誤信息,沒有錯誤,接收一個包完畢

            rx_block_num++; // 接收到的總包數(shù)加1

            ochr = ACK; // 回應(yīng) ACK 信號

            foffset += BLOCK_SIZE; // 寫入的目標地址的偏移,相應(yīng)加上一個block

        } else {
            switch (r) { // 否則,處理錯誤代碼

                // NAK 信號的意思是請求發(fā)送方重新發(fā)一個包

                // ACK 信號解釋為正確接收

                // 下面可以看出,超時,錯誤的checksum

            case -1: /* TIMEOUT */
                xmodem_errtxt = "TIMEOUT";
                ochr = NAK;
                break;
            case -2: /* Bad block */
                xmodem_errtxt = "BAD BLOCK#";
                /* eat teh rest of the block */
                get_byte_err = 0;
                while (get_byte_err != -1) get_byte();
                ochr = NAK;
                break;
            case -3: /* Bad checksum */
                xmodem_errtxt = "BAD CHKSUM";
                ochr = NAK;
                break;
            case -4: /* End of file */
                xmodem_errtxt = "DONE";
                ochr = ACK;
                break;
            case -5: /* Cancel */
                xmodem_errtxt = "ABORTED";
                ochr = ACK;
                break;
            default: /* Block out of sequence */
                xmodem_errtxt = "WRONG BLK";
                ochr = NAK;
            }
            error_count--; // 錯誤加一

        }
        putc(ochr); // 發(fā)送應(yīng)答信號,很簡單,putc就是接收-->發(fā)送端的信號了

    } while ((r > -3) && error_count);
    // r>-3表示 DONE 和 ABORTED 之外的情況,也就是說,沒有完成或者沒有中途退出

    // 的話就一直循環(huán),但是如果錯誤技術(shù)過多的話也停止傳輸。


    if ((!error_count) || (r != -4)) { // 表示出錯了

        foffset = 0;    /* indicate failure to caller */
        /*printk("x-modem error: %s\n", xmodem_errtxt); */
    }

    return foffset; // 返回最后指向的指針,應(yīng)該是文件的結(jié)尾處表示正確,0表示錯誤

}

/*
 * Read a record in the XMODEM protocol, return the block number
 * (0-255) if successful, or one of the following return codes:
 *     -1 = Bad byte
 *     -2 = Bad block number
 *     -3 = Bad block checksum
 *     -4 = End of file
 *     -5 = Canceled by remote
 *
 * 讀取一個塊,每個塊的格式為(根據(jù) xmodem協(xié)議)
 *
 *  | | | | | |
 *  | SOH | 信息包序號 | 信息包序號的補碼 | 數(shù)據(jù)區(qū)段 | 算術(shù)校驗和 |
 *  |_____|________ _ |________________ |________ |__________ |
 *
 *
 */

int get_record(void)
{
    int c, block_num = 0;
    int i;
    __u32 check_sum;

    /* clear the buffer,接收緩沖,存128字節(jié)的數(shù)據(jù)區(qū)段 */
    for (i = 0; i < BLOCK_SIZE; i++)
        rbuffer[i] = 0x00;

    check_sum = 0;
    i = -2;
    // 首先讀一個字節(jié),判斷是否有出錯

    c = get_byte();
    if (get_byte_err)
        return -1;

    switch (c) {
    case SOH:    /* 如果接收的是頭信號的話 Receive packet */
        for (;;) { // 一直循環(huán)到 128字節(jié)讀取完畢

            c = get_byte(); // 讀一個字節(jié)判斷有沒有錯誤

            if (get_byte_err)
                return -1;

            switch (i) {
            case -2: // 如果 i 為 -2 表示現(xiàn)在接收的是信息包的序號

                block_num = c; // 保存起來以便返回

                break;
            case -1:
#if 0
#ifdef CHECK_NEGATED_SECTNUM
                if (c != (-block_num -1))
                    return -2;
#endif
#endif
                break;
            case BLOCK_SIZE: // 如果現(xiàn)在計數(shù)到達 128表示這是一個CHECKSUM

                // 因為包的編號是 0-127一共128個,那么128編號的包為校驗和

                if ((check_sum & 0xff) != c) // 將接收到的校驗和和自己計算的比較

                    return -3; // 不對就返回錯誤

                else
                    return block_num; // 正確,返回包的編號

                break;
            default: // 默認的話就是一個塊里面的每個字節(jié)

                rbuffer[i] = c; // 存放數(shù)據(jù)

                check_sum += c; // checksum只是很簡單的相加

            }
            i++;
        }
    case EOT:    /* end of file encountered */
        return -4;
    case CAN:    /* cancel protocol */
        return -5;
    default:
        return -5;
    }
}

/* get_byte should use one of the timer's for a CPU clock independent timeout */
__u8 get_byte()
{
    int c, ret;

again:
    c = 0;
    get_byte_err = 0; /* reset errno */
    c = awaitkey(xmodem_timeout, &get_byte_err); // 從UART讀取一個字節(jié),超時時間為 xmodem_timeout


    if (get_byte_err) {
        if (seen_a_char == SAC_SEND_NAK || !one_nak) {
            bufputs("timeout nak");
            putc(NAK);    /* make the sender go */
        }

        if (seen_a_char < SAC_PAST_START_NAK) {
            bufputs("goto again");
            seen_a_char = SAC_SENT_NAK;

            xmodem_timeout = get_param_value("xmodem_timeout", &ret);
            if (ret) xmodem_timeout = GET_BYTE_TIMEOUT;
            goto again;
        }
    }

    if (get_byte_err == 0)
        seen_a_char = SAC_PAST_START_NAK;

    return (c);
}

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多