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

📄 ser_test_protocol.inl

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 INL
📖 第 1 页 / 共 3 页
字号:
//==========================================================================
//
//        ser_test_protocol.c
//
//        Serial device driver testing protocol
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s):     jskov
// Contributors:  jskov, gthomas
// 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/infra/cyg_ass.h>

#include <cyg/hal/hal_intr.h>           // for reclaiming interrupt vector

//----------------------------------------------------------------------------
// Definition of which device to run tests on on various platforms.

#define NA_MSG "No test device specified"

// Cleaned up drivers will export the testing parameters via CDL.
// When all drivers are changed, replace the TEST_ macros throughout
// with the CYGPRI_ equivalents.
#ifdef CYGPRI_SER_TEST_CRASH_ID
# define TEST_CRASH_ID CYGPRI_SER_TEST_CRASH_ID
# define TEST_SER_DEV  CYGPRI_SER_TEST_SER_DEV
# define TEST_TTY_DEV  CYGPRI_SER_TEST_TTY_DEV
#endif

// Note that CYGPRI_SER_TEST_OVERRIDE_INT_1 and CYGPRI_SER_TEST_OVERRIDE_INT_2
// may also be exported. These identify interrupts that should be reclaimed
// from the ROM monitor before the test is started.

#if defined(CYGPKG_HAL_POWERPC_MBX)                          \    && defined(CYGPKG_HAL_QUICC)                 \    && defined(CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC)                 \    && defined(CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC1)
# define TEST_CRASH_ID "ppcmbx"
# define TEST_SER_DEV CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_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_AM31_STDEVAL1)           \    && defined(CYGPKG_IO_SERIAL_MN10300)                \    && defined(CYGPKG_IO_SERIAL_MN10300_SERIAL2)
# define TEST_CRASH_ID "am31st"
# define TEST_SER_DEV CYGDAT_IO_SERIAL_MN10300_SERIAL2_NAME
# if defined(CYGPKG_IO_SERIAL_TTY_TTY2)
#  define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY1_DEV
# endif
#endif
#if defined(CYGPKG_HAL_MN10300_AM33_STB)                \    && defined(CYGPKG_IO_SERIAL_MN10300)                \    && defined(CYGPKG_IO_SERIAL_MN10300_SERIAL0)
# define TEST_CRASH_ID "am33st"
# define TEST_SER_DEV CYGDAT_IO_SERIAL_MN10300_SERIAL0_NAME
# 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

#ifndef TEST_CRASH_ID
#define TEST_CRASH_ID "......"
#endif

//----------------------------------------------------------------------------
// Crash types
// Eventually this will be moved into a separate header file so a script
// can read the definitions and use the output formats/codes to analyze
// test results. For now we just keep it here...

// FAILCODE:<tttttt:cccc:[optional data, separated by :]!>
//  tttttt: 6 letter target code
//  cccc:   crash code (16bit hex value)

#define TEST_CRASH(__h, __code, __msg, args...)                         \    CYG_MACRO_START                                                     \    int __len = 1;                                                      \    /* Try to flush remaining input */                                  \    cyg_thread_delay(50);                                               \    cyg_io_get_config(__h, CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH,        \                      0, &__len);                                       \    diag_printf("FAILCODE:<" TEST_CRASH_ID ":%04x:" __code, ## args);    \    diag_printf("!>\n");                                                \    CYG_FAIL(__msg);                                                    \    hang();                                                             \    CYG_MACRO_END

// Target IO
#define TEST_CRASH_IO                     0x0000
#define TEST_CRASH_IO_READ                "%d",            0x0001
#define TEST_CRASH_IO_WRITE               "%d",            0x0002
#define TEST_CRASH_IO_DRAIN               "%d",            0x0003
#define TEST_CRASH_IO_GET_CFG             "%d",            0x0004
#define TEST_CRASH_IO_SET_CFG             "%d",            0x0005

// Target
#define TEST_CRASH_CRC                    0x0010
#define TEST_CRASH_CRC_CHAR               "%02x",          0x0011
#define TEST_CRASH_CRC_BAD                "%08x:%08x",     0x0012
#define TEST_CRASH_CRC_HOST               "",              0x0013

// Protocol errors
#define TEST_CRASH_PROT                   0x1000
#define TEST_CRASH_PROT_BIN_MODE          "%d",            0x1080
#define TEST_CRASH_PROT_TEXT              "%d",            0x1100

#define TEST_CRASH_HOST_xx                0xf000
#define TEST_CRASH_HOST_TIMEOUT           "%d:%d:%d:%d",      0xf000
        // command#, read invocation#, expected, actual
#define TEST_CRASH_HOST_CRC_BAD           "%d:%08x:%08x:%d:%02x:%02x", 0xf010
        // command#, expected CRC, actual, index, expected char, actual
#define TEST_CRASH_HOST_DUPLEX_BAD        "%d:%d:%02x:%02x",     0xf020
        // command#, index, expected char, actual

//----------------------------------------------------------------------------
// The data in buffer and the cmd buffer
#ifndef IN_BUFFER_SIZE
# define IN_BUFFER_SIZE 1024
#endif
cyg_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;
    cyg_uint32                flags;
    // etc...
} cyg_ser_cfg_t;

typedef enum {
    OPT_SERIAL_DEBUG = 0,
    OPT_VERBOSE_LEVEL
} cyg_option_t;

typedef enum {
    _NONE = 0,
    PROTOCOL_PROGRESS,
    PROTOCOL_DATA,
} cyg_verbosity_level_t;


// A few predifined option macros. Use after test_ping().
#define TEST_OPTIONS(__handle, __array) \  test_options(__handle, sizeof(__array)/8, __array)

#define TEST_HOST_DEBUG(__handle)                               \    CYG_MACRO_START                                             \    cyg_uint32 __options[] = {OPT_SERIAL_DEBUG, 1};             \    test_options((__handle), sizeof(__options)/8,               \                 __options);                                    \    CYG_MACRO_END

#define TEST_HOST_PROGRESS(__handle)                            \    CYG_MACRO_START                                             \    cyg_uint32 __options[] =                                    \        {OPT_SERIAL_DEBUG, 1,                                   \         OPT_VERBOSE_LEVEL, PROTOCOL_PROGRESS};                 \    test_options((__handle), sizeof(__options)/8,               \                 __options);                                    \    CYG_MACRO_END

#define TEST_HOST_DATA(__handle)                                \    CYG_MACRO_START                                             \    cyg_uint32 __options[] =                                    \        {OPT_SERIAL_DEBUG, 1,                                   \         OPT_VERBOSE_LEVEL, PROTOCOL_DATA};                     \    test_options((__handle), sizeof(__options)/8,               \                 __options);                                    \    CYG_MACRO_END

//----------------------------------------------------------------------------
// 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 (0 == CYGINT_IO_SERIAL_TEST_SKIP_9600)
    { CYGNUM_SERIAL_BAUD_9600, CYGNUM_SERIAL_WORD_LENGTH_8, 
      CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE,
      CYGNUM_SERIAL_FLOW_NONE },
#endif

#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_14400)
#if !defined(CYGPKG_HAL_MN10300_AM31) &&    \    !defined(CYGPKG_HAL_MN10300_AM33)
    { CYGNUM_SERIAL_BAUD_14400, CYGNUM_SERIAL_WORD_LENGTH_8, 
      CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE,
      CYGNUM_SERIAL_FLOW_NONE },
#endif
#endif

    { CYGNUM_SERIAL_BAUD_19200, CYGNUM_SERIAL_WORD_LENGTH_8, 
      CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE,
      CYGNUM_SERIAL_FLOW_NONE },

#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_38400)
    { CYGNUM_SERIAL_BAUD_38400, CYGNUM_SERIAL_WORD_LENGTH_8, 
      CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE,
      CYGNUM_SERIAL_FLOW_NONE },
#endif

#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_57600)
#if !defined(CYGPKG_HAL_MN10300_AM33)
    { CYGNUM_SERIAL_BAUD_57600, CYGNUM_SERIAL_WORD_LENGTH_8, 
      CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE,
      CYGNUM_SERIAL_FLOW_NONE },
#endif
#endif

#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_115200)
#if !defined(CYGPKG_HAL_MN10300_STDEVAL1)
    { CYGNUM_SERIAL_BAUD_115200, CYGNUM_SERIAL_WORD_LENGTH_8, 
      CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE,
      CYGNUM_SERIAL_FLOW_NONE },
#endif
#endif

#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_PARITY_EVEN)
    // One stop bit, even parity
    { CYGNUM_SERIAL_BAUD_19200, CYGNUM_SERIAL_WORD_LENGTH_8, 
      CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_EVEN,
      CYGNUM_SERIAL_FLOW_NONE },
#endif

#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_PARITY_EVEN)
#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_STOP_2)
    // Two stop bits, even parity
    { CYGNUM_SERIAL_BAUD_19200, CYGNUM_SERIAL_WORD_LENGTH_8, 
      CYGNUM_SERIAL_STOP_2, CYGNUM_SERIAL_PARITY_EVEN,
      CYGNUM_SERIAL_FLOW_NONE },
#endif
#endif

#if (0 == CYGINT_IO_SERIAL_TEST_SKIP_STOP_2)
    // Two stop bits, no parity
    { CYGNUM_SERIAL_BAUD_19200, CYGNUM_SERIAL_WORD_LENGTH_8, 
      CYGNUM_SERIAL_STOP_2, CYGNUM_SERIAL_PARITY_NONE,
      CYGNUM_SERIAL_FLOW_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;                       \

⌨️ 快捷键说明

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