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

📄 ser_test_protocol.inl

📁 eCos操作系统源码
💻 INL
📖 第 1 页 / 共 3 页
字号:
    CYG_MACRO_END//----------------------------------------------------------------------------// Macros for read/write to serial with error cheking.static volatile cyg_uint32 r_stamp;static volatile int aborted;// This routine will be called if the read "times out"static voiddo_abort(void *handle){    cyg_io_handle_t io_handle = (cyg_io_handle_t)handle;    cyg_int32 len = 1;  // Need something here    cyg_io_get_config(io_handle, CYG_IO_GET_CONFIG_SERIAL_ABORT, 0, &len);    aborted = 1;}#include "timeout.inl"// Read with timeout (__t = timeout in ticks, int* __r = result)#define Tcyg_io_read_timeout(__h, __d, __l, __t, __r)           \    CYG_MACRO_START                                             \    int __res;                                                  \    r_stamp = timeout((__t), do_abort, (__h));                  \    __res = cyg_io_read((__h), (__d), (__l));                   \    if (ENOERR != __res && -EINTR != __res) {                   \        TEST_CRASH(__h, TEST_CRASH_IO_READ,                     \                   "cyg_io_read/timeout failed", __res);        \    }                                                           \    *(__r) = __res;                                             \    untimeout(r_stamp);                                         \    CYG_MACRO_END#define Tcyg_io_read(__h, __d, __l)                     \    CYG_MACRO_START                                     \    int __res = cyg_io_read((__h), (__d), (__l));       \    if (ENOERR != __res) {                              \        TEST_CRASH(__h, TEST_CRASH_IO_READ,             \                   "cyg_io_read failed", __res);        \    }                                                   \    CYG_MACRO_END#define Tcyg_io_write(__h, __d, __l)                                    \    CYG_MACRO_START                                                     \    int __res;                                                          \    cyg_uint32 __len = 1;                                               \    __res = cyg_io_write((__h), (__d), (__l));                          \    if (ENOERR != __res) {                                              \        TEST_CRASH(__h, TEST_CRASH_IO_WRITE,                            \                   "cyg_io_write failed", __res);                       \    }                                                                   \    __res = cyg_io_get_config((__h),                                    \                              CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN,    \                              0, &__len);                               \    if (ENOERR != __res) {                                              \        TEST_CRASH(__h, TEST_CRASH_IO_DRAIN,                            \                   "DRAIN failed", __res);                              \    }                                                                   \    CYG_MACRO_END//----------------------------------------------------------------------------// Some libc like functions that are handy to have around.static intstrlen(const char *c){    int l = 0;    while (*c++) l++;    return l;}static char*strcpy(char* dest, const char* src){    char c;    while ((c = *src++)) {        *dest++ = c;    }    *dest = c;    return dest;}static char*itoa(char* dest, int v){    char b[16];    char* p = &b[16];    *--p = 0;    if (v) {        while (v){            *--p = (v % 10) + '0';            v = v / 10;        }    } else        *--p = '0';    return strcpy(dest, p);}#define min(_a, _b) ((_a) < (_b)) ? (_a) : (_b)voidhang(void){    while (1);}//-----------------------------------------------------------------------------// Configuration changing function.//// First change to the new config and back again to determine if the driver// can handle the config.// If not, return error.//// Then query the host for its capability to use the config:// Format out://  "@CONFIG:<baud rate code>:<#data bits>:<#stop bits>:<parity on/off>:<flow control code>!"// Format in://  OK/ER//// On ER, return error.//// On OK, change to the new configuration. Resynchronize with the host://  Target waits for host to send S(ync) //     [host will delay at least .1 secs after changing baud rate so the //      line has time to settle.]////  When receiving S(ync), target replies OK to the host which then//  acknowledges with D(one).////  Host can also send R(esync) which means it didn't receieve the OK. If//  so the target resends its S(ync) message.//// If the synchronization has not succeeded within 1 second// (configurable in the protocol), both host and target will revert to// the previous configuration and attempt to synchronize again. If// this fails, this call will hang and the host will consider the test// a failure.//// To Do://  Host&protocol currently only supports://   - no/even parityintchange_config(cyg_io_handle_t handle, cyg_ser_cfg_t* cfg){    cyg_serial_info_t old_cfg, new_cfg;    const char cmd[] = "@CONFIG:";    char reply[2];    int msglen;    int res, len;    cyg_uint8 *p1;    // Prepare the command.    p1 = &cmd_buffer[0];    p1 = strcpy(p1, &cmd[0]);    p1 = itoa(p1, cfg->baud_rate);    *p1++ = ':';    p1 = itoa(p1, cfg->data_bits);    *p1++ = ':';    p1 = itoa(p1, cfg->stop_bits);    *p1++ = ':';    p1 = itoa(p1, cfg->parity);    *p1++ = ':';    p1 = itoa(p1, cfg->flags);    *p1++ = '!';    *p1 = 0;                            // note: we may append to this later    // Tell user what we're up to.    CYG_TEST_INFO(&cmd_buffer[1]);    // Change to new config and then back to determine if the driver likes it.    len = sizeof(old_cfg);    res = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_SERIAL_INFO,                             &old_cfg, &len);    res = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_SERIAL_INFO,                             &new_cfg, &len);    if (res != ENOERR) {        TEST_CRASH(handle, TEST_CRASH_IO_GET_CFG,                    "Can't get serial config", res);    }    new_cfg.baud = cfg->baud_rate;    new_cfg.word_length = cfg->data_bits;    new_cfg.stop = cfg->stop_bits;    new_cfg.parity = cfg->parity;    new_cfg.flags = cfg->flags;    res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO,                             &new_cfg, &len);    cyg_thread_delay(10);  // Some chips don't like changes to happen to fast...    // Driver didn't like it. It will not have changed anything, so it's    // safe to return now.    if (ENOERR != res) {        // Let user know that the config was skipped due to the target.        const char txt_tskipped[] = "- skipped by target!";        p1 = strcpy(p1, txt_tskipped);        *p1 = 0;        CYG_TEST_INFO(&cmd_buffer[1]);        return res;    }    // Succeeded. Change back to the original config so we can communicate    // with the host.    res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO,                             &old_cfg, &len);    cyg_thread_delay(10); // Some chips don't like changes to happen to fast...    if (res != ENOERR) {        TEST_CRASH(handle, TEST_CRASH_IO_SET_CFG,                    "Can't set serial config", res);    }    // Send command to host and read host's reply.    msglen = strlen(&cmd_buffer[0]);    Tcyg_io_write(handle, &cmd_buffer[0], &msglen);    msglen = 2;    Tcyg_io_read(handle, &reply[0], &msglen);    // Did host accept configuration?    if ('O' != reply[0] || 'K' != reply[1]) {        // Let user know that the config was skipped due to the host.        const char txt_hskipped[] = "- skipped by host!";        p1 = strcpy(p1, txt_hskipped);        *p1 = 0;        CYG_TEST_INFO(&cmd_buffer[1]);        diag_printf("Host didn't accept config (%02x, %02x).\n",                    reply[0], reply[1]);        res = ENOSUPP;        return res;    }    // Now change config and wait for host to send us a S(ync)    // character.      // Loop until protocol exchange completed. This may hang (as seen    // from the host), but only when we get totally lost, in which    // case there's not much else to do really. In this case the host    // will consider the test a FAIL.    len = sizeof(new_cfg);    res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO,                             &new_cfg, &len);    cyg_thread_delay(10);  // Some chips don't like changes to happen to fast...    if (res != ENOERR) {        TEST_CRASH(handle, TEST_CRASH_IO_SET_CFG,                    "Can't set serial config/2", res);    }    {        int change_succeeded = 0;        int using_old_config = 0;        char in_buf[1];        int len;        int saw_host_sync;        for (;;) {            aborted = 0;                    // global abort flag            // FIXME: Timeout time needs to be configurable, and needs to            // be sent to the host before getting here. That would allow            // changing the timeout by just rebuilding the test - without            // changing the host software.            saw_host_sync = 0;            r_stamp = timeout(100, do_abort, handle);            while(!aborted) {                len = 1;                in_buf[0] = 0;                res = cyg_io_read(handle, in_buf, &len);                if (ENOERR != res && -EINTR != res) {                    // We may have to reset the driver here if the fail                    // was due to a framing or parity error.                    break;                }                if ('R' == in_buf[0]) {                    // Resync - host didn't see our message. Try again.                    saw_host_sync = 0;                } else if ('S' == in_buf[0] && !saw_host_sync) {                    // In sync - reply to host if we haven't already                    char ok_msg[2] = "OK";                    int ok_len = 2;                    Tcyg_io_write(handle, ok_msg, &ok_len);                    saw_host_sync = 1;                } else if ('D' == in_buf[0] && saw_host_sync) {                    // Done - exchange completed.                    change_succeeded = 1;                    break;                }            }            untimeout(r_stamp);            if (change_succeeded) {                // If we had to revert to the old configuration, return error.                if (using_old_config)                    return -EIO;                else                    return ENOERR;            }            // We didn't synchronize with the host. Due to an IO error?            if (ENOERR != res && -EINTR != res) {                // We may have to reset the driver if the fail was due to                // a framing or parity error.            }            // Revert to the old configuration and try again.            len = sizeof(old_cfg);            res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO,                                     &old_cfg, &len);            cyg_thread_delay(10);  // Some chips don't like changes to happen to fast...            if (res != ENOERR) {                TEST_CRASH(handle, TEST_CRASH_IO_SET_CFG,                           "Can't set serial config/3", res);            }            using_old_config = 1;        }    }}//-----------------------------------------------------------------------------// Host sends CRC in decimal ASCII, terminated with !intread_host_crc(cyg_io_handle_t handle){    int crc, len;    cyg_uint8 ch;    crc = 0;    while (1) {        len = 1;        Tcyg_io_read(handle, &ch, &len);        if ('!' == ch)            break;        if (!((ch >= '0' && ch <= '9'))){            TEST_CRASH(handle, TEST_CRASH_CRC_CHAR,                       "Illegal CRC format from host", ch);        }        crc = crc*10 + (ch - '0');    }    return crc;}//---------------------------------------------------------------------------// Test binary data transmission.// Format out://  "@BINARY:<byte size>:<mode>!"// Format in://  <checksum>!<#size bytes data>// For echo modes, also://     Format out://      <#size bytes data>//     Format in:

⌨️ 快捷键说明

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