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

📄 ser_test_protocol.inl

📁 ecos为实时嵌入式操作系统
💻 INL
📖 第 1 页 / 共 2 页
字号:
//==========================================================================////        ser_test_protocol.c////        Serial device driver testing protocol////==========================================================================//####COPYRIGHTBEGIN####//// -------------------------------------------// The contents of this file are subject to the Cygnus eCos Public License// Version 1.0 (the "License"); you may not use this file except in// compliance with the License.  You may obtain a copy of the License at// http://sourceware.cygnus.com/ecos// // Software distributed under the License is distributed on an "AS IS"// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the// License for the specific language governing rights and limitations under// the License.// // The Original Code is eCos - Embedded Cygnus Operating System, released// September 30, 1998.// // The Initial Developer of the Original Code is Cygnus.  Portions created// by Cygnus are Copyright (C) 1998, 1999 Cygnus Solutions.  // All Rights Reserved.// -------------------------------------------////####COPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):     jskov// Contributors:  jskov// Date:          1999-03-17// Description:   Protocol implementation used to test eCos serial devices.//                Relies on ser_filter to be present on the host side to//                respond to test requests.// // To Do://  o Clean up.//  o Clean up config change magic.//  o Figure out how to handle kernel dependency//    : without kernel, no timeout. Without timeout, no filter auto detection.////####DESCRIPTIONEND#####include <pkgconf/system.h>#include <pkgconf/io.h>#include <pkgconf/io_serial.h>#include <cyg/io/io.h>#include <cyg/io/devtab.h>#include <cyg/io/ttyio.h>#include <cyg/infra/diag.h>#include <cyg/hal/hal_intr.h>           // for reclaiming interrup vector//----------------------------------------------------------------------------// Definition of which device to run tests on on various platforms.#if defined(CYGPKG_HAL_POWERPC_COGENT)                          \    && defined(CYGPKG_IO_SERIAL_POWERPC_COGENT)                 \    && defined(CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_B)# define TEST_SER_DEV CYGDAT_IO_SERIAL_POWERPC_COGENT_SERIAL_B_NAME# if defined(CYGPKG_IO_SERIAL_TTY_TTY2)#  define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY2_DEV# endif#endif#if defined(CYGPKG_HAL_ARM_PID)                         \    && defined(CYGPKG_IO_SERIAL_ARM_PID)                \    && defined(CYGPKG_IO_SERIAL_ARM_PID_SERIAL0)# define TEST_SER_DEV CYGDAT_IO_SERIAL_ARM_PID_SERIAL0_NAME# if defined(CYGPKG_IO_SERIAL_TTY_TTY0)#  define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY0_DEV# endif#endif#if defined(CYGPKG_HAL_ARM_AEB)                         \    && defined(CYGPKG_IO_SERIAL_ARM_AEB)                \    && defined(CYGPKG_IO_SERIAL_ARM_AEB_SERIAL1)# define TEST_SER_DEV CYGDAT_IO_SERIAL_ARM_AEB_SERIAL1_NAME# if defined(CYGPKG_IO_SERIAL_TTY_TTY1)#  define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY1_DEV# endif#endif#if defined(CYGPKG_HAL_TX39_JMR3904)                    \    && defined(CYGPKG_IO_SERIAL_TX39_JMR3904)           \    && defined(CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0)# define TEST_SER_DEV CYGDAT_IO_SERIAL_TX39_JMR3904_SERIAL0_NAME# if defined(CYGPKG_IO_SERIAL_TTY_TTY1)#  define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY1_DEV# endif#endif#if defined(CYGPKG_HAL_MN10300_STDEVAL1)                \    && defined(CYGPKG_IO_SERIAL_MN10300)                \    && defined(CYGPKG_IO_SERIAL_MN10300_SERIAL1)// Note: Serial1 is *not* the same port as GDB is using. It seems that// CygMon is interfering with the tests if run on the same port.// This configuration allows the serial driver to be tested using the// filter in stand alone mode (option -n).# define TEST_SER_DEV CYGDAT_IO_SERIAL_MN10300_SERIAL1_NAME# if defined(CYGPKG_IO_SERIAL_TTY_TTY1)#  define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY1_DEV# endif#endif#if defined(CYGPKG_HAL_SPARCLITE_SLEB)                    \    && defined(CYGPKG_IO_SERIAL_SPARCLITE_SLEB)           \    && defined(CYGPKG_IO_SERIAL_SPARCLITE_SLEB_CON1)# define TEST_SER_DEV CYGDAT_IO_SERIAL_SPARCLITE_SLEB_CON1_NAME# define SER_OVERRIDE_INT_1 CYGNUM_HAL_INTERRUPT_9# define SER_OVERRIDE_INT_2 CYGNUM_HAL_INTERRUPT_10# if defined(CYGPKG_IO_SERIAL_TTY_TTY0)#  define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY0_DEV# endif#endif// We can't rely on haldiag for ser_filter detection - it may not define// a working character reading function.#ifndef   TEST_SER_DEV# define  SER_NOP_TEST# define  TTY_NOP_TEST# define  TEST_SER_DEV "/dev/null"# define  TEST_TTY_DEV "/dev/null"#else# ifndef  TEST_TTY_DEV#  define TTY_NOP_TEST# define  TEST_TTY_DEV "/dev/null"# endif#endif//----------------------------------------------------------------------------// FIXME: The PPC sometimes sees a spurious byte. There is workaround code// that can be enabled here.#define HANDLE_SPURIOUS 1//----------------------------------------------------------------------------// The data in buffer and the cmd buffer#define IN_BUFFER_SIZE 1024cyg_uint8 in_buffer[IN_BUFFER_SIZE];cyg_int8 cmd_buffer[128];//----------------------------------------------------------------------------// Some types specific to the testing protocol.typedef enum {    MODE_NO_ECHO = 0,    MODE_EOP_ECHO,    MODE_DUPLEX_ECHO} cyg_mode_t;typedef enum {    TEST_RETURN_OK = ENOERR,    TEST_RETURN_NA} cyg_test_return_t;typedef struct ser_cfg {    cyg_serial_baud_rate_t   baud_rate;    cyg_serial_word_length_t data_bits;    cyg_serial_stop_bits_t   stop_bits;    cyg_serial_parity_t      parity;    // etc...} cyg_ser_cfg_t;//----------------------------------------------------------------------------// A few predefined configurations. These must all be valid for any// given target until change_config is behaving correctly.cyg_ser_cfg_t test_configs[] = {#if !defined(CYGPKG_HAL_TX39_JMR3904) &&        \    !defined(CYGPKG_HAL_ARM_PID) &&             \    !defined(CYGPKG_HAL_ARM_AEB) &&             \    !defined(CYGPKG_HAL_MN10300_STDEVAL1) &&    \    !defined(CYGPKG_HAL_SPARCLITE_SLEB)    { CYGNUM_SERIAL_BAUD_115200, CYGNUM_SERIAL_WORD_LENGTH_8,       CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE },#endif#if !defined(CYGPKG_HAL_TX39_JMR3904) &&        \    !defined(CYGPKG_HAL_ARM_AEB) &&             \    !defined(CYGPKG_HAL_SPARCLITE_SLEB)    { CYGNUM_SERIAL_BAUD_57600, CYGNUM_SERIAL_WORD_LENGTH_8,       CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE },#endif    { CYGNUM_SERIAL_BAUD_38400, CYGNUM_SERIAL_WORD_LENGTH_8,       CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE },    { CYGNUM_SERIAL_BAUD_19200, CYGNUM_SERIAL_WORD_LENGTH_8,       CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE },#if !defined(CYGPKG_HAL_TX39_JMR3904) && !defined(CYGPKG_HAL_ARM_PID)    { CYGNUM_SERIAL_BAUD_9600, CYGNUM_SERIAL_WORD_LENGTH_8,       CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE },#endif#if !defined(CYGPKG_HAL_TX39_JMR3904) &&        \    !defined(CYGPKG_HAL_ARM_AEB) &&             \    !defined(CYGPKG_HAL_ARM_PID)    // One stop bit, even parity    { CYGNUM_SERIAL_BAUD_19200, CYGNUM_SERIAL_WORD_LENGTH_8,       CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_EVEN },#endif#if !defined(CYGPKG_HAL_TX39_JMR3904) &&        \    !defined(CYGPKG_HAL_ARM_AEB) &&             \    !defined(CYGPKG_HAL_ARM_PID)    // Two stop bits, even parity    { CYGNUM_SERIAL_BAUD_19200, CYGNUM_SERIAL_WORD_LENGTH_8,       CYGNUM_SERIAL_STOP_2, CYGNUM_SERIAL_PARITY_EVEN },#endif#if !defined(CYGPKG_HAL_TX39_JMR3904)    // Two stop bits, no parity    { CYGNUM_SERIAL_BAUD_19200, CYGNUM_SERIAL_WORD_LENGTH_8,       CYGNUM_SERIAL_STOP_2, CYGNUM_SERIAL_PARITY_NONE },#endif};//----------------------------------------------------------------------------// Macros to help extract values from the argument string.// Note: This is probably not an ideal solution, but it was easy to make :)#define INIT_VALUE(__args)                      \    unsigned int v;                             \    char *__ptr1, *__ptr2 = (__args)#define SET_VALUE(__slot)                       \do {                                            \    __ptr1 = index(__ptr2, (int) ':');          \    if (__ptr1)                                 \        *__ptr1 = 0;                            \    v = atoi(__ptr2);                           \    __ptr2 = __ptr1+1;                          \    (__slot) = v;                               \} while (0)//----------------------------------------------------------------------------// CRC magic - it's a bit of a hack for now.// FIXME: standard definition?#define ADD_CRC_BYTE(__crc, __c)                \    CYG_MACRO_START                             \    (__crc) = ((__crc) << 1) ^ (__c);           \    CYG_MACRO_END// FIXME: Hack to allow easy ASCII transfer.#define FIX_CRC(__crc, __icrc)                  \    CYG_MACRO_START                             \    __icrc = (int) (__crc);                     \    if (__icrc < 0)                             \        __icrc = -__icrc;                       \    CYG_MACRO_END//----------------------------------------------------------------------------// Macros for read/write to serial with error cheking.cyg_uint32 r_stamp;// 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);}#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));                                 \    CYG_TEST_CHECK((ENOERR == __res || -EINTR == __res),"cyg_io_read failed");\    *(__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));               \    CYG_TEST_CHECK(ENOERR == __res, "cyg_io_read failed");      \    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));                          \    CYG_TEST_CHECK(ENOERR == __res, "cyg_io_write failed");             \    __res = cyg_io_get_config((__h),                                    \                              CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN,    \                              0, &__len);                               \    CYG_TEST_CHECK(ENOERR == __res, "DRAIN failed");                    \    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.// FIXME: This is still slightly bogus in that it doesn't check for target//        capabilities. Correct way is;//            o try setting new cfg//            o restore//            o if OK://               o send cfg to target//               o if reply OK://                  o change to new cfg//// Host&protocol currently only supports://  - no/even parityintchange_config(cyg_io_handle_t handle, cyg_ser_cfg_t* cfg){    const char cmd[] = "@CONFIG:";    char reply[2];    int msglen;    int res;    cyg_uint8 *p1;        // Prepare and send 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++ = 0;    CYG_TEST_INFO(&cmd_buffer[1]);    msglen = strlen(&cmd_buffer[0]);    Tcyg_io_write(handle, &cmd_buffer[0], &msglen);    msglen = 2;    Tcyg_io_read(handle, &reply[0], &msglen);    if (reply[0] == 'O') {        // Change config        cyg_serial_info_t serial_info;        int len = sizeof(serial_info);        res = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_SERIAL_INFO, &serial_info, &len);        if (res != ENOERR) {            diag_printf("Can't get serial config - DEVIO error: %d\n", res);            hang();        }        serial_info.baud = cfg->baud_rate;        serial_info.word_length = cfg->data_bits;        serial_info.stop = cfg->stop_bits;        serial_info.parity = cfg->parity;        res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO, &serial_info, &len);        if (res != ENOERR) {            diag_printf("Can't set serial config - DEVIO error: %d\n", res);            hang();        }        res = ENOERR;    } else {        res = ENOSUPP;#ifdef __DEVELOPER__        diag_printf("Host didn't accept config (%02x, %02x).\n",                    reply[0], reply[1]);

⌨️ 快捷键说明

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