URL
https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk
Subversion Repositories openrisc_me
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/rtos/ecos-2.0/packages/io/serial/v2_0/tests
- from Rev 27 to Rev 174
- ↔ Reverse comparison
Rev 27 → Rev 174
/serial1.c
0,0 → 1,154
//========================================================================== |
// |
// serial1.c |
// |
// Test serial driver API |
// |
//========================================================================== |
//####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 |
// Date: 1999-03-17 |
// Description: Test the serial driver API. |
// |
//####DESCRIPTIONEND#### |
|
#include <pkgconf/system.h> |
|
#include <cyg/infra/testcase.h> // test macros |
#include <cyg/infra/cyg_ass.h> // assertion macros |
|
// Package requirements |
#if defined(CYGPKG_IO_SERIAL) && defined(CYGPKG_KERNEL) |
|
#include <pkgconf/kernel.h> |
|
// Package option requirements |
#if defined(CYGFUN_KERNEL_API_C) |
|
#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL |
#include <cyg/kernel/kapi.h> |
unsigned char stack[CYGNUM_HAL_STACK_SIZE_TYPICAL]; |
cyg_thread thread_data; |
cyg_handle_t thread_handle; |
|
#include "ser_test_protocol.inl" |
|
//--------------------------------------------------------------------------- |
// Serial test main function. |
|
|
void |
serial_api_test(int dummy) |
{ |
cyg_io_handle_t handle; |
int res, len; |
unsigned char buffer[16]; |
|
// Always return... |
if (dummy) |
return; |
|
CYG_TEST_FAIL_FINISH("Not reached"); |
|
test_open_ser(&handle); |
|
// read & write |
res = cyg_io_read(handle, &buffer[0], &len); |
res = cyg_io_write(handle, &buffer[0], &len); |
|
// cyg_io_get_config |
cyg_io_get_config(handle, |
CYG_IO_GET_CONFIG_SERIAL_INFO, &buffer[0], &len); |
cyg_io_get_config(handle, |
CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN, &buffer[0], &len); |
cyg_io_get_config(handle, |
CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH, &buffer[0], &len); |
cyg_io_get_config(handle, |
CYG_IO_GET_CONFIG_SERIAL_ABORT, &buffer[0], &len); |
cyg_io_get_config(handle, |
CYG_IO_GET_CONFIG_SERIAL_OUTPUT_FLUSH, &buffer[0], &len); |
|
// cyg_io_set_config |
cyg_io_set_config(handle, |
CYG_IO_SET_CONFIG_SERIAL_INFO, &buffer[0], &len); |
} |
|
|
void |
serial_test( void ) |
{ |
serial_api_test(1); |
|
CYG_TEST_PASS_FINISH("serial1 test OK"); |
} |
|
void |
cyg_start(void) |
{ |
CYG_TEST_INIT(); |
cyg_thread_create(10, // Priority - just a number |
(cyg_thread_entry_t*)serial_test, // entry |
0, // |
"serial_thread", // Name |
&stack[0], // Stack |
CYGNUM_HAL_STACK_SIZE_TYPICAL, // Size |
&thread_handle, // Handle |
&thread_data // Thread data structure |
); |
cyg_thread_resume(thread_handle); |
cyg_scheduler_start(); |
} |
|
#else // CYGFUN_KERNEL_API_C |
#define N_A_MSG "Needs kernel C API" |
#endif |
|
#else // CYGPKG_IO_SERIAL && CYGPKG_KERNEL |
#define N_A_MSG "Needs IO/serial and Kernel" |
#endif |
|
#ifdef N_A_MSG |
void |
cyg_start( void ) |
{ |
CYG_TEST_INIT(); |
CYG_TEST_NA( N_A_MSG); |
} |
#endif // N_A_MSG |
|
// EOF serial1.c |
/serial2.c
0,0 → 1,127
//========================================================================== |
// |
// serial2.c |
// |
// Test simple string output. |
// |
//========================================================================== |
//####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 |
// Date: 1999-03-17 |
// Description: Test simple string output. |
// |
//####DESCRIPTIONEND#### |
|
#include <pkgconf/system.h> |
|
#include <cyg/infra/testcase.h> // test macros |
#include <cyg/infra/cyg_ass.h> // assertion macros |
|
#if defined(CYGPKG_IO_SERIAL) && defined(CYGPKG_KERNEL) |
|
#include <pkgconf/kernel.h> |
|
// Package option requirements |
#if defined(CYGFUN_KERNEL_API_C) |
|
#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL |
#include <cyg/kernel/kapi.h> |
unsigned char stack[CYGNUM_HAL_STACK_SIZE_TYPICAL]; |
cyg_thread thread_data; |
cyg_handle_t thread_handle; |
|
#include "ser_test_protocol.inl" |
|
//--------------------------------------------------------------------------- |
// Serial test main function. |
void |
serial_test( void ) |
{ |
char test_msg1[]="This is a test message!\n"; |
char test_msg2[]="$O5468697320697320612074657374206d657373616765210d0a#12"; |
int msglen; |
cyg_io_handle_t ser_handle; |
|
test_open_ser(&ser_handle); |
|
CYG_TEST_INFO("Writing a raw string to the serial device..."); |
msglen = strlen(&test_msg1[0]); |
Tcyg_io_write(ser_handle, &test_msg1[0], &msglen); |
|
CYG_TEST_INFO("Writing a GDB encoded string to the serial device..."); |
msglen = strlen(&test_msg2[0]); |
Tcyg_io_write(ser_handle, &test_msg2[0], &msglen); |
|
CYG_TEST_PASS_FINISH("serial2 test OK"); |
} |
|
void |
cyg_start(void) |
{ |
CYG_TEST_INIT(); |
cyg_thread_create(10, // Priority - just a number |
(cyg_thread_entry_t*)serial_test, // entry |
0, // |
"serial_thread", // Name |
&stack[0], // Stack |
CYGNUM_HAL_STACK_SIZE_TYPICAL, // Size |
&thread_handle, // Handle |
&thread_data // Thread data structure |
); |
cyg_thread_resume(thread_handle); |
cyg_scheduler_start(); |
} |
|
#else // CYGFUN_KERNEL_API_C |
#define N_A_MSG "Needs kernel C API" |
#endif |
|
#else // CYGPKG_IO_SERIAL && CYGPKG_KERNEL |
#define N_A_MSG "Needs IO/serial and Kernel" |
#endif |
|
#ifdef N_A_MSG |
void |
cyg_start( void ) |
{ |
CYG_TEST_INIT(); |
CYG_TEST_NA( N_A_MSG); |
} |
#endif // N_A_MSG |
|
// EOF serial2.c |
/tty1.c
0,0 → 1,162
//========================================================================== |
// |
// tty.c |
// |
// Test TTY driver API |
// |
//========================================================================== |
//####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 |
// Date: 1999-04-08 |
// Description: Test the TTY driver API. |
// |
//####DESCRIPTIONEND#### |
|
#include <pkgconf/system.h> |
|
#include <cyg/infra/testcase.h> // test macros |
#include <cyg/infra/cyg_ass.h> // assertion macros |
|
// Package requirements |
#if defined(CYGPKG_IO_SERIAL) && defined(CYGPKG_KERNEL) |
|
#include <pkgconf/kernel.h> |
|
// Package option requirements |
#if defined(CYGFUN_KERNEL_API_C) |
|
#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL |
#include <cyg/kernel/kapi.h> |
unsigned char stack[CYGNUM_HAL_STACK_SIZE_TYPICAL]; |
cyg_thread thread_data; |
cyg_handle_t thread_handle; |
|
#include "ser_test_protocol.inl" |
|
//--------------------------------------------------------------------------- |
// TTY test main function. |
|
|
void |
tty_api_test(cyg_io_handle_t* handle) |
{ |
int res, len; |
unsigned char buffer[16]; |
|
// Always return... |
if (handle) |
return; |
|
CYG_TEST_FAIL_FINISH("Not reached"); |
|
// read & write |
res = cyg_io_read(handle, &buffer[0], &len); |
res = cyg_io_write(handle, &buffer[0], &len); |
|
// cyg_io_get_config |
// TTY layer |
cyg_io_get_config(handle, |
CYG_IO_GET_CONFIG_TTY_INFO, &buffer[0], &len); |
// Call-throughs to serial layer. |
cyg_io_get_config(handle, |
CYG_IO_GET_CONFIG_SERIAL_INFO, &buffer[0], &len); |
cyg_io_get_config(handle, |
CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN, &buffer[0], &len); |
cyg_io_get_config(handle, |
CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH, &buffer[0], &len); |
cyg_io_get_config(handle, |
CYG_IO_GET_CONFIG_SERIAL_ABORT, &buffer[0], &len); |
cyg_io_get_config(handle, |
CYG_IO_GET_CONFIG_SERIAL_OUTPUT_FLUSH, &buffer[0], &len); |
|
// cyg_io_set_config |
// TTY layer. |
cyg_io_set_config(handle, |
CYG_IO_SET_CONFIG_TTY_INFO, &buffer[0], &len); |
// Call-throughs to serial layer. |
cyg_io_set_config(handle, |
CYG_IO_SET_CONFIG_SERIAL_INFO, &buffer[0], &len); |
} |
|
|
void |
tty_test( void ) |
{ |
cyg_io_handle_t tty_handle; |
|
test_open_tty(&tty_handle); |
|
tty_api_test(&tty_handle); |
|
CYG_TEST_PASS_FINISH("tty1 test OK"); |
} |
|
void |
cyg_start(void) |
{ |
CYG_TEST_INIT(); |
cyg_thread_create(10, // Priority - just a number |
(cyg_thread_entry_t*)tty_test, // entry |
0, // |
"tty_thread", // Name |
&stack[0], // Stack |
CYGNUM_HAL_STACK_SIZE_TYPICAL, // Size |
&thread_handle, // Handle |
&thread_data // Thread data structure |
); |
cyg_thread_resume(thread_handle); |
cyg_scheduler_start(); |
} |
|
#else // CYGFUN_KERNEL_API_C |
#define N_A_MSG "Needs kernel C API" |
#endif |
|
#else // CYGPKG_IO_SERIAL && CYGPKG_KERNEL |
#define N_A_MSG "Needs IO/serial and Kernel" |
#endif |
|
#ifdef N_A_MSG |
void |
cyg_start( void ) |
{ |
CYG_TEST_INIT(); |
CYG_TEST_NA( N_A_MSG); |
} |
#endif // N_A_MSG |
// EOF tty1.c |
/serial3.c
0,0 → 1,166
//========================================================================== |
// |
// serial3.c |
// |
// Test data half-duplex receive and send. |
// |
//========================================================================== |
//####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 |
// Date: 1999-03-17 |
// Description: Test the half-duplex receive and send capabilities of |
// the serial driver. |
// Requirements: This test requires the ser_filter on the host side. |
// |
//####DESCRIPTIONEND#### |
|
#include <pkgconf/system.h> |
|
#include <cyg/infra/testcase.h> // test macros |
#include <cyg/infra/cyg_ass.h> // assertion macros |
|
// Package requirements |
#if defined(CYGPKG_IO_SERIAL) && defined(CYGPKG_KERNEL) |
|
#include <pkgconf/kernel.h> |
|
// Package option requirements |
#if defined(CYGFUN_KERNEL_API_C) |
|
#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL |
#include <cyg/kernel/kapi.h> |
unsigned char stack[CYGNUM_HAL_STACK_SIZE_TYPICAL]; |
cyg_thread thread_data; |
cyg_handle_t thread_handle; |
|
#include "ser_test_protocol.inl" |
|
//--------------------------------------------------------------------------- |
// Serial test main function. |
void |
serial_test( void ) |
{ |
cyg_io_handle_t ser_handle; |
|
test_open_ser(&ser_handle); |
|
// We need the filter for this test. |
test_ping(ser_handle); |
|
#if (CYGINT_IO_SERIAL_TEST_SKIP_38400 > 0) |
{ |
// The board is too slow to run the driver in interrupt mode |
// at the default 38400 baud when doing this test, so run it |
// at a slower rate. |
cyg_ser_cfg_t slow_cfg = { |
CYGNUM_SERIAL_BAUD_19200, CYGNUM_SERIAL_WORD_LENGTH_8, |
CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE, |
CYGNUM_SERIAL_FLOW_NONE }; |
|
CYG_TEST_INFO("Reducing baud rate to 19200"); |
change_config(ser_handle, &slow_cfg); |
} |
#endif |
|
// Start slowly, then go for max size. |
{ |
test_binary(ser_handle, 16, MODE_EOP_ECHO); |
test_binary(ser_handle, 128, MODE_EOP_ECHO); |
test_binary(ser_handle, 256, MODE_EOP_ECHO); |
test_binary(ser_handle, IN_BUFFER_SIZE, MODE_EOP_ECHO); |
} |
|
// Write some varying length packets. |
{ |
int i; |
for(i = 0; i < 8; i++) { |
// No echo. |
test_binary(ser_handle, 256 + 42*i, MODE_NO_ECHO); |
test_binary(ser_handle, 64 + 7*i, MODE_NO_ECHO); |
// Echo. |
test_binary(ser_handle, 256 + 42*i, MODE_EOP_ECHO); |
test_binary(ser_handle, 64 + 7*i, MODE_EOP_ECHO); |
} |
} |
|
#if 0 // Disable this for now. |
// End with some long packets. |
{ |
test_binary(ser_handle, 2048, MODE_NO_ECHO); |
test_binary(ser_handle, 16384, MODE_NO_ECHO); |
test_binary(ser_handle, 65536, MODE_NO_ECHO); |
} |
#endif |
|
CYG_TEST_PASS_FINISH("serial3 test OK"); |
} |
|
void |
cyg_start(void) |
{ |
CYG_TEST_INIT(); |
cyg_thread_create(10, // Priority - just a number |
(cyg_thread_entry_t*)serial_test, // entry |
0, // |
"serial_thread", // Name |
&stack[0], // Stack |
CYGNUM_HAL_STACK_SIZE_TYPICAL, // Size |
&thread_handle, // Handle |
&thread_data // Thread data structure |
); |
cyg_thread_resume(thread_handle); |
cyg_scheduler_start(); |
} |
|
#else // CYGFUN_KERNEL_API_C |
#define N_A_MSG "Needs kernel C API" |
#endif |
|
#else // CYGPKG_IO_SERIAL && CYGPKG_KERNEL |
#define N_A_MSG "Needs IO/serial and Kernel" |
#endif |
|
#ifdef N_A_MSG |
void |
cyg_start( void ) |
{ |
CYG_TEST_INIT(); |
CYG_TEST_NA( N_A_MSG); |
} |
#endif // N_A_MSG |
// EOF serial3.c |
/tty2.c
0,0 → 1,128
//========================================================================== |
// |
// tty2.c |
// |
// Test simple string output. |
// |
//========================================================================== |
//####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 |
// Date: 1999-03-17 |
// Description: Test simple string output. |
// |
//####DESCRIPTIONEND#### |
|
#include <pkgconf/system.h> |
|
#include <cyg/infra/testcase.h> // test macros |
#include <cyg/infra/cyg_ass.h> // assertion macros |
|
// Package requirements |
#if defined(CYGPKG_IO_SERIAL) && defined(CYGPKG_KERNEL) |
|
#include <pkgconf/kernel.h> |
|
// Package option requirements |
#if defined(CYGFUN_KERNEL_API_C) |
|
#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL |
#include <cyg/kernel/kapi.h> |
unsigned char stack[CYGNUM_HAL_STACK_SIZE_TYPICAL]; |
cyg_thread thread_data; |
cyg_handle_t thread_handle; |
|
#include "ser_test_protocol.inl" |
|
//--------------------------------------------------------------------------- |
// TTY test main function. |
void |
tty_test( void ) |
{ |
char test_msg1[]="This is a test message!\n"; |
char test_msg2[]="$O5468697320697320612074657374206d657373616765210d0a#12"; |
int msglen; |
cyg_io_handle_t tty_handle; |
|
test_open_tty(&tty_handle); |
|
CYG_TEST_INFO("Writing a raw string to the TTY device..."); |
msglen = strlen(&test_msg1[0]); |
Tcyg_io_write(tty_handle, &test_msg1[0], &msglen); |
|
CYG_TEST_INFO("Writing a GDB encoded string to the TTY device..."); |
msglen = strlen(&test_msg2[0]); |
Tcyg_io_write(tty_handle, &test_msg2[0], &msglen); |
|
CYG_TEST_PASS_FINISH("tty2 test OK"); |
} |
|
void |
cyg_start(void) |
{ |
CYG_TEST_INIT(); |
cyg_thread_create(10, // Priority - just a number |
(cyg_thread_entry_t*)tty_test, // entry |
0, // |
"tty_thread", // Name |
&stack[0], // Stack |
CYGNUM_HAL_STACK_SIZE_TYPICAL, // Size |
&thread_handle, // Handle |
&thread_data // Thread data structure |
); |
cyg_thread_resume(thread_handle); |
cyg_scheduler_start(); |
} |
|
|
#else // CYGFUN_KERNEL_API_C |
#define N_A_MSG "Needs kernel C API" |
#endif |
|
#else // CYGPKG_IO_SERIAL && CYGPKG_KERNEL |
#define N_A_MSG "Needs IO/serial and Kernel" |
#endif |
|
#ifdef N_A_MSG |
void |
cyg_start( void ) |
{ |
CYG_TEST_INIT(); |
CYG_TEST_NA( N_A_MSG); |
} |
#endif // N_A_MSG |
// EOF tty2.c |
/serial4.c
0,0 → 1,143
//========================================================================== |
// |
// serial4.c |
// |
// Test serial configuration changing |
// |
//========================================================================== |
//####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 |
// Date: 1999-03-17 |
// Description: Test the configuration capabilities of the serial driver. |
// Requirements: This test requires the ser_filter on the host side. |
// |
// To Do: |
// This test should do a full test of the configuration combinations. |
// This will get possible with proper test_change_config protocol |
// implementation. |
//####DESCRIPTIONEND#### |
|
#include <pkgconf/system.h> |
|
#include <cyg/infra/testcase.h> // test macros |
#include <cyg/infra/cyg_ass.h> // assertion macros |
|
// Package requirements |
#if defined(CYGPKG_IO_SERIAL) && defined(CYGPKG_KERNEL) |
|
#include <pkgconf/kernel.h> |
|
// Package option requirements |
#if defined(CYGFUN_KERNEL_API_C) |
|
#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL |
#include <cyg/kernel/kapi.h> |
unsigned char stack[CYGNUM_HAL_STACK_SIZE_TYPICAL]; |
cyg_thread thread_data; |
cyg_handle_t thread_handle; |
|
#include "ser_test_protocol.inl" |
|
//--------------------------------------------------------------------------- |
// Serial test main function. |
void |
serial_test( void ) |
{ |
cyg_io_handle_t ser_handle; |
|
test_open_ser(&ser_handle); |
|
// We need the filter for this test. |
test_ping(ser_handle); |
|
// Test multiple configurations (defined in the protocol file). |
// FIXME: This will get replaced with a test over the full configuration |
// permutation space. |
{ |
int i; |
int count = sizeof(test_configs) / sizeof(cyg_ser_cfg_t); |
char msg[] = "This is a test\n"; |
int msglen = strlen(msg); |
|
for (i = 0; i < count; i++){ |
if (ENOERR == change_config(ser_handle, &test_configs[i])) { |
test_binary(ser_handle, 128, MODE_EOP_ECHO); |
test_binary(ser_handle, 256, MODE_NO_ECHO); |
Tcyg_io_write(ser_handle, msg, &msglen); |
} |
} |
} |
|
CYG_TEST_PASS_FINISH("serial4 test OK"); |
} |
|
void |
cyg_start(void) |
{ |
CYG_TEST_INIT(); |
cyg_thread_create(10, // Priority - just a number |
(cyg_thread_entry_t*)serial_test, // entry |
0, // |
"serial_thread", // Name |
&stack[0], // Stack |
CYGNUM_HAL_STACK_SIZE_TYPICAL, // Size |
&thread_handle, // Handle |
&thread_data // Thread data structure |
); |
cyg_thread_resume(thread_handle); |
cyg_scheduler_start(); |
} |
|
#else // CYGFUN_KERNEL_API_C |
#define N_A_MSG "Needs kernel C API" |
#endif |
|
#else // CYGPKG_IO_SERIAL && CYGPKG_KERNEL |
#define N_A_MSG "Needs IO/serial and Kernel" |
#endif |
|
#ifdef N_A_MSG |
void |
cyg_start( void ) |
{ |
CYG_TEST_INIT(); |
CYG_TEST_NA( N_A_MSG); |
} |
#endif // N_A_MSG |
|
// EOF serial4.c |
/serial5.c
0,0 → 1,148
//========================================================================== |
// |
// serial5.c |
// |
// Test data duplex receive and send. |
// |
//========================================================================== |
//####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 |
// Date: 1999-03-19 |
// Description: Test the duplex receive and send capabilities of |
// the serial driver. |
// Requirements: This test requires the ser_filter on the host side. |
//####DESCRIPTIONEND#### |
|
#include <pkgconf/system.h> |
|
#include <cyg/infra/testcase.h> // test macros |
#include <cyg/infra/cyg_ass.h> // assertion macros |
|
// Package requirements |
#if defined(CYGPKG_IO_SERIAL) && defined(CYGPKG_KERNEL) |
|
#include <pkgconf/kernel.h> |
|
// Package option requirements |
#if defined(CYGFUN_KERNEL_API_C) |
|
#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL |
#include <cyg/kernel/kapi.h> |
unsigned char stack[CYGNUM_HAL_STACK_SIZE_TYPICAL]; |
cyg_thread thread_data; |
cyg_handle_t thread_handle; |
|
#include "ser_test_protocol.inl" |
|
//--------------------------------------------------------------------------- |
// Serial test main function. |
void |
serial_test( void ) |
{ |
cyg_io_handle_t ser_handle; |
|
test_open_ser(&ser_handle); |
|
// We need the filter for this test. |
test_ping(ser_handle); |
|
|
#if (CYGINT_IO_SERIAL_TEST_SKIP_38400 > 0) |
{ |
// The board is too slow to run the driver in interrupt mode |
// at the default 38400 baud when doing this test, so run it |
// at a slower rate. |
cyg_ser_cfg_t slow_cfg = { |
CYGNUM_SERIAL_BAUD_19200, CYGNUM_SERIAL_WORD_LENGTH_8, |
CYGNUM_SERIAL_STOP_1, CYGNUM_SERIAL_PARITY_NONE, |
CYGNUM_SERIAL_FLOW_NONE }; |
|
CYG_TEST_INFO("Reducing baud rate to 19200"); |
change_config(ser_handle, &slow_cfg); |
} |
#endif |
|
// Start out slow, then go for many tests. Each cycle causes |
// 512 bytes to be sent over the wire. |
test_binary(ser_handle, 1, MODE_DUPLEX_ECHO); |
test_binary(ser_handle, 2, MODE_DUPLEX_ECHO); |
test_binary(ser_handle, 5, MODE_DUPLEX_ECHO); |
|
#if 0 // Disable these until the ser_filter produces status output. |
test_binary(ser_handle, 128, MODE_DUPLEX_ECHO); |
test_binary(ser_handle, 512, MODE_DUPLEX_ECHO); |
test_binary(ser_handle, 1024, MODE_DUPLEX_ECHO); |
#endif |
|
CYG_TEST_PASS_FINISH("serial5 test OK"); |
} |
|
void |
cyg_start(void) |
{ |
CYG_TEST_INIT(); |
cyg_thread_create(10, // Priority - just a number |
(cyg_thread_entry_t*)serial_test, // entry |
0, // |
"serial_thread", // Name |
&stack[0], // Stack |
CYGNUM_HAL_STACK_SIZE_TYPICAL, // Size |
&thread_handle, // Handle |
&thread_data // Thread data structure |
); |
cyg_thread_resume(thread_handle); |
cyg_scheduler_start(); |
} |
|
#else // CYGFUN_KERNEL_API_C |
#define N_A_MSG "Needs kernel C API" |
#endif |
|
#else // CYGPKG_IO_SERIAL && CYGPKG_KERNEL |
#define N_A_MSG "Needs IO/serial and Kernel" |
#endif |
|
#ifdef N_A_MSG |
void |
cyg_start( void ) |
{ |
CYG_TEST_INIT(); |
CYG_TEST_NA( N_A_MSG); |
} |
#endif // N_A_MSG |
// EOF serial5.c |
/timeout.inl
0,0 → 1,143
#ifndef CYGONCE_IO_SERIAL_MISC_TIMEOUT_INL |
#define CYGONCE_IO_SERIAL_MISC_TIMEOUT_INL |
//========================================================================== |
// |
// timeout.inl |
// |
// Simple timeout support for serial I/O testing. |
// |
//========================================================================== |
//####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): gthomas |
// Contributors: gthomas |
// Date: 1999-02-05 |
// Description: Simple timeout functions |
//####DESCRIPTIONEND#### |
|
// Timeout support |
|
typedef void (timeout_fun)(void *); |
#ifndef NTIMEOUTS |
#define NTIMEOUTS 8 |
#endif |
typedef struct { |
cyg_int32 delta; // Number of "ticks" in the future for this timeout |
timeout_fun *fun; // Function to execute when it expires |
void *arg; // Argument to pass when it does |
} timeout_entry; |
static timeout_entry timeouts[NTIMEOUTS]; |
static cyg_handle_t timeout_alarm_handle; |
static cyg_alarm timeout_alarm; |
static cyg_int32 last_delta; |
|
static void |
do_timeout(cyg_handle_t alarm, cyg_addrword_t data) |
{ |
int i; |
cyg_int32 min_delta; |
timeout_entry *e = timeouts; |
min_delta = 0x7FFFFFFF; // Maxint |
for (i = 0; i < NTIMEOUTS; i++, e++) { |
if (e->delta) { |
e->delta -= last_delta; |
if (e->delta == 0) { |
// Time for this item to 'fire' |
(e->fun)(e->arg); |
} else { |
if (e->delta < min_delta) min_delta = e->delta; |
} |
} |
} |
if (min_delta != 0x7FFFFFFF) { |
// Still something to do, schedule it |
cyg_alarm_initialize(timeout_alarm_handle, cyg_current_time()+min_delta, 0); |
last_delta = min_delta; |
} |
} |
|
static cyg_uint32 |
timeout(cyg_int32 delta, timeout_fun *fun, void *arg) |
{ |
int i; |
cyg_int32 min_delta; |
static bool init = false; |
timeout_entry *e = timeouts; |
cyg_uint32 stamp; |
if (!init) { |
cyg_handle_t h; |
cyg_clock_to_counter(cyg_real_time_clock(), &h); |
cyg_alarm_create(h, do_timeout, 0, &timeout_alarm_handle, &timeout_alarm); |
init = true; |
} |
stamp = 0; // Assume no slots available |
for (i = 0; i < NTIMEOUTS; i++, e++) { |
if ((e->delta == 0) && (e->fun == 0)) { |
// Free entry |
e->delta = delta; |
e->fun = fun; |
e->arg = arg; |
stamp = (cyg_uint32)e; |
break; |
} |
} |
e = timeouts; |
min_delta = 0x7FFFFFFF; |
for (i = 0; i < NTIMEOUTS; i++, e++) { |
if (e->delta && (e->delta < min_delta)) min_delta = e->delta; |
} |
if (min_delta != 0x7FFFFFFF) { |
// Still something to do, schedule it |
cyg_alarm_initialize(timeout_alarm_handle, cyg_current_time()+min_delta, 0); |
last_delta = min_delta; |
} |
return stamp; |
} |
|
static void |
untimeout(cyg_uint32 stamp) |
{ |
if (stamp != 0) { |
timeout_entry *e = (timeout_entry *)stamp; |
if (e->fun != 0) { |
e->delta = 0; |
e->fun = 0; |
e->arg = 0; |
} |
} |
} |
|
#endif // CYGONCE_IO_SERIAL_MISC_TIMEOUT_INL |
/flow1.c
0,0 → 1,209
//========================================================================== |
// |
// flow1.c |
// |
// Test data half-duplex receive and send with flow control. |
// |
//========================================================================== |
//####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,jlarmour |
// Contributors: |
// Date: 2000-07-27 |
// Description: Test the half-duplex receive and send capabilities of |
// the serial driver with flow control. |
// Requirements: This test requires the ser_filter on the host side. |
// |
//####DESCRIPTIONEND#### |
|
#include <pkgconf/system.h> |
|
#include <cyg/infra/testcase.h> // test macros |
#include <cyg/infra/cyg_ass.h> // assertion macros |
|
#ifdef CYGPKG_KERNEL |
# include <pkgconf/kernel.h> |
#endif |
#ifdef CYGPKG_IO_SERIAL |
# include <pkgconf/io_serial.h> |
#endif |
|
// Package requirements |
#ifndef CYGPKG_IO_SERIAL |
# define NA_MSG "Requires I/O serial package" |
#elif !defined(CYGFUN_KERNEL_API_C) |
# define NA_MSG "Requires kernel C API" |
#elif !defined(CYGPKG_IO_SERIAL_FLOW_CONTROL) |
# define NA_MSG "Requires serial flow control" |
#endif |
|
#ifdef NA_MSG |
void |
cyg_start( void ) |
{ |
CYG_TEST_INIT(); |
CYG_TEST_NA( NA_MSG); |
} |
#else |
|
#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL |
#include <cyg/kernel/kapi.h> |
unsigned char stack[CYGNUM_HAL_STACK_SIZE_TYPICAL]; |
cyg_thread thread_data; |
cyg_handle_t thread_handle; |
|
// redefine buffer size for large transfer tests |
#ifndef CYGPKG_HAL_ARM_AEB |
# define IN_BUFFER_SIZE 65536 |
#endif |
|
#include "ser_test_protocol.inl" |
|
|
//--------------------------------------------------------------------------- |
// run the tests |
|
static void |
run_tests( cyg_io_handle_t ser_handle ) |
{ |
|
|
// Start slowly, then go for max size. |
{ |
test_binary(ser_handle, 16, MODE_EOP_ECHO); |
test_binary(ser_handle, 128, MODE_EOP_ECHO); |
test_binary(ser_handle, 256, MODE_EOP_ECHO); |
test_binary(ser_handle, IN_BUFFER_SIZE, MODE_EOP_ECHO); |
} |
|
// Write some varying length packets. |
{ |
int i; |
for(i = 0; i < 8; i++) { |
// No echo. |
test_binary(ser_handle, 256 + 42*i, MODE_NO_ECHO); |
test_binary(ser_handle, 64 + 7*i, MODE_NO_ECHO); |
// Echo. |
test_binary(ser_handle, 256 + 42*i, MODE_EOP_ECHO); |
test_binary(ser_handle, 64 + 7*i, MODE_EOP_ECHO); |
} |
} |
|
// End with some long packets. |
{ |
test_binary(ser_handle, 2048, MODE_NO_ECHO); |
test_binary(ser_handle, 16384, MODE_NO_ECHO); |
test_binary(ser_handle, 65536, MODE_NO_ECHO); |
} |
} |
|
//--------------------------------------------------------------------------- |
// Serial test main function. |
|
void |
serial_test( void ) |
{ |
cyg_io_handle_t ser_handle; |
cyg_ser_cfg_t *cfg=&test_configs[0]; |
cyg_ser_cfg_t new_cfg; |
int count = sizeof(test_configs) / sizeof(cyg_ser_cfg_t); |
int i; |
|
test_open_ser(&ser_handle); |
|
// We need the filter for this test. |
test_ping(ser_handle); |
|
// Choose the configuration with the fastest baud rate, to be most |
// provocative. Start at 1 coz cfg already points at 0 |
for (i=1; i<count; i++) { |
if (cfg->baud_rate < test_configs[i].baud_rate) |
cfg=&test_configs[i]; |
} |
|
// Set flow control from configuration |
// Choose software first |
|
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_SOFTWARE |
CYG_TEST_INFO("Setting software flow control"); |
|
new_cfg = *cfg; |
new_cfg.flags |= CYGNUM_SERIAL_FLOW_XONXOFF_RX | |
CYGNUM_SERIAL_FLOW_XONXOFF_TX; |
if (ENOERR == change_config(ser_handle, &new_cfg)) |
run_tests( ser_handle ); |
#endif |
|
// hardware flow control |
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_HW |
CYG_TEST_INFO("Setting hardware flow control"); |
|
new_cfg = *cfg; |
new_cfg.flags |= CYGNUM_SERIAL_FLOW_RTSCTS_RX|CYGNUM_SERIAL_FLOW_RTSCTS_TX; |
if (ENOERR == change_config(ser_handle, &new_cfg)) |
run_tests( ser_handle ); |
|
CYG_TEST_INFO("Setting DSR/DTR hardware flow control"); |
|
new_cfg = *cfg; |
new_cfg.flags |= CYGNUM_SERIAL_FLOW_DSRDTR_RX|CYGNUM_SERIAL_FLOW_DSRDTR_TX; |
if (ENOERR == change_config(ser_handle, &new_cfg)) |
run_tests( ser_handle ); |
#endif |
|
CYG_TEST_PASS_FINISH("flow1 test OK"); |
} |
|
void |
cyg_start(void) |
{ |
CYG_TEST_INIT(); |
cyg_thread_create(10, // Priority - just a number |
(cyg_thread_entry_t*)serial_test, // entry |
0, // |
"serial_thread", // Name |
&stack[0], // Stack |
CYGNUM_HAL_STACK_SIZE_TYPICAL, // Size |
&thread_handle, // Handle |
&thread_data // Thread data structure |
); |
cyg_thread_resume(thread_handle); |
cyg_scheduler_start(); |
} |
|
#endif // ifndef NA_MSG |
|
// EOF flow1.c |
/flow2.c
0,0 → 1,182
//========================================================================== |
// |
// flow2.c |
// |
// Test duplex receive and send with flow control. |
// |
//========================================================================== |
//####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,jlarmour |
// Contributors: |
// Date: 2000-07-27 |
// Description: Test the duplex receive and send capabilities of |
// the serial driver with flow control. |
// Requirements: This test requires the ser_filter on the host side. |
// |
//####DESCRIPTIONEND#### |
|
#include <pkgconf/system.h> |
|
#include <cyg/infra/testcase.h> // test macros |
#include <cyg/infra/cyg_ass.h> // assertion macros |
|
#ifdef CYGPKG_KERNEL |
# include <pkgconf/kernel.h> |
#endif |
#ifdef CYGPKG_IO_SERIAL |
# include <pkgconf/io_serial.h> |
#endif |
|
// Package requirements |
#ifndef CYGPKG_IO_SERIAL |
# define NA_MSG "Requires I/O serial package" |
#elif !defined(CYGFUN_KERNEL_API_C) |
# define NA_MSG "Requires kernel C API" |
#elif !defined(CYGPKG_IO_SERIAL_FLOW_CONTROL) |
# define NA_MSG "Requires serial flow control" |
#endif |
|
#ifdef NA_MSG |
void |
cyg_start( void ) |
{ |
CYG_TEST_INIT(); |
CYG_TEST_NA( NA_MSG); |
} |
#else |
|
#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL |
#include <cyg/kernel/kapi.h> |
unsigned char stack[CYGNUM_HAL_STACK_SIZE_TYPICAL]; |
cyg_thread thread_data; |
cyg_handle_t thread_handle; |
|
#include "ser_test_protocol.inl" |
|
|
//--------------------------------------------------------------------------- |
// run the tests |
|
static void |
run_tests( cyg_io_handle_t ser_handle ) |
{ |
// Start slowly, then go for max size. |
{ |
test_binary(ser_handle, 16, MODE_DUPLEX_ECHO); |
test_binary(ser_handle, 128, MODE_DUPLEX_ECHO); |
test_binary(ser_handle, 256, MODE_DUPLEX_ECHO); |
test_binary(ser_handle, 1024, MODE_DUPLEX_ECHO); |
} |
} |
|
//--------------------------------------------------------------------------- |
// Serial test main function. |
|
void |
serial_test( void ) |
{ |
cyg_io_handle_t ser_handle; |
cyg_ser_cfg_t *cfg=&test_configs[0]; |
cyg_ser_cfg_t new_cfg; |
int count = sizeof(test_configs) / sizeof(cyg_ser_cfg_t); |
int i; |
|
test_open_ser(&ser_handle); |
|
// We need the filter for this test. |
test_ping(ser_handle); |
|
// Choose the configuration with the fastest baud rate, to be most |
// provocative. Start at 1 coz cfg already points at 0 |
for (i=1; i<count; i++) { |
if (cfg->baud_rate < test_configs[i].baud_rate) |
cfg=&test_configs[i]; |
} |
|
// Set flow control from configuration |
// Choose software first |
|
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_SOFTWARE |
CYG_TEST_INFO("Setting software flow control"); |
|
new_cfg = *cfg; |
new_cfg.flags |= CYGNUM_SERIAL_FLOW_XONXOFF_RX | |
CYGNUM_SERIAL_FLOW_XONXOFF_TX; |
if (ENOERR == change_config(ser_handle, &new_cfg)) |
run_tests( ser_handle ); |
#endif |
|
// hardware flow control |
#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_HW |
CYG_TEST_INFO("Setting RTS/CTS hardware flow control"); |
|
new_cfg = *cfg; |
new_cfg.flags |= CYGNUM_SERIAL_FLOW_RTSCTS_RX|CYGNUM_SERIAL_FLOW_RTSCTS_TX; |
if (ENOERR == change_config(ser_handle, &new_cfg)) |
run_tests( ser_handle ); |
|
CYG_TEST_INFO("Setting DSR/DTR hardware flow control"); |
|
new_cfg = *cfg; |
new_cfg.flags |= CYGNUM_SERIAL_FLOW_DSRDTR_RX|CYGNUM_SERIAL_FLOW_DSRDTR_TX; |
if (ENOERR == change_config(ser_handle, &new_cfg)) |
run_tests( ser_handle ); |
#endif |
|
CYG_TEST_PASS_FINISH("flow2 test OK"); |
} |
|
void |
cyg_start(void) |
{ |
CYG_TEST_INIT(); |
cyg_thread_create(10, // Priority - just a number |
(cyg_thread_entry_t*)serial_test, // entry |
0, // |
"serial_thread", // Name |
&stack[0], // Stack |
CYGNUM_HAL_STACK_SIZE_TYPICAL, // Size |
&thread_handle, // Handle |
&thread_data // Thread data structure |
); |
cyg_thread_resume(thread_handle); |
cyg_scheduler_start(); |
} |
|
#endif // ifndef NA_MSG |
|
// EOF flow2.c |
/ser_test_protocol.inl
0,0 → 1,1071
//========================================================================== |
// |
// 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; \ |
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 void |
do_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 int |
strlen(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) |
|
void |
hang(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 parity |
int |
change_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 ! |
int |
read_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: |
// OK/ER |
// Format out: |
// DONE |
// |
// The last DONE allows the host to eat bytes if target is sending too many. |
// |
// Mode: |
// MODE_NO_ECHO: |
// Just receive data and verify CRC. |
// MODE_EOP_ECHO: |
// Receive data, verify CRC, resend data. |
// Expect OK/ER reply from host when done. |
// MODE_DUPLEX_ECHO: |
// Receive data, echo data, verify CRC. |
// Expect OK/ER reply from host when done. |
// |
// Note: |
// Using diag_printf while talking with the host may cause some funky |
// errors (bytes from the host side being lost!?!?) |
// |
// To Do: |
// MODE_DUPLEX_ECHO: |
// The current implementation is simple and may not stress the |
// driver enough. Also, it's command packet format doesn't match |
// that of the other modes. |
|
cyg_test_return_t |
test_binary(cyg_io_handle_t handle, int size, cyg_mode_t mode) |
{ |
const char cmd[] = "@BINARY:"; |
int msglen; |
cyg_uint32 xcrc; |
int icrc, host_crc; |
cyg_uint8 *p1; |
cyg_int8 host_status = 'O'; // host is happy by default |
|
// Verify that the test can be run with available ressources. |
if (MODE_EOP_ECHO == mode && size > IN_BUFFER_SIZE) |
return TEST_RETURN_NA; |
|
// Prepare and send the command. |
p1 = &cmd_buffer[0]; |
p1 = strcpy(p1, &cmd[0]); |
p1 = itoa(p1, size); |
*p1++ = ':'; |
p1 = itoa(p1, mode); |
*p1++ = '!'; |
*p1++ = 0; |
|
CYG_TEST_INFO(&cmd_buffer[1]); |
|
msglen = strlen(&cmd_buffer[0]); |
Tcyg_io_write(handle, &cmd_buffer[0], &msglen); |
|
// Get CRC back. |
host_crc = read_host_crc(handle); |
|
// Depending on mode, start reading data. |
xcrc = 0; |
switch (mode) { |
case MODE_NO_ECHO: |
{ |
// Break transfers into chunks no larger than the buffer size. |
int tx_len, chunk_len, i; |
while (size > 0) { |
chunk_len = min(IN_BUFFER_SIZE, size); |
tx_len = chunk_len; |
size -= chunk_len; |
|
Tcyg_io_read(handle, &in_buffer[0], &chunk_len); |
|
for (i = 0; i < tx_len; i++) { |
ADD_CRC_BYTE(xcrc, in_buffer[i]); |
} |
} |
|
// Reply that we have completed the test. |
{ |
const char msg_done[] = "DONE"; |
|
chunk_len = strlen(&msg_done[0]); |
Tcyg_io_write(handle, &msg_done[0], &chunk_len); |
} |
|
} |
break; |
case MODE_EOP_ECHO: |
{ |
// We have already checked that the in buffer is large enough. |
int i, tx_len, chunk_len; |
chunk_len = tx_len = size; |
Tcyg_io_read(handle, &in_buffer[0], &chunk_len); |
|
for (i = 0; i < tx_len; i++) { |
ADD_CRC_BYTE(xcrc, in_buffer[i]); |
} |
|
// Echo data back. |
chunk_len = size; |
Tcyg_io_write(handle, &in_buffer[0], &chunk_len); |
|
// Now read host side's status |
chunk_len = 2; |
Tcyg_io_read(handle, &in_buffer[0], &chunk_len); |
host_status = in_buffer[0]; |
|
// Reply that we have completed the test. |
{ |
const char msg_done[] = "DONE"; |
|
chunk_len = strlen(&msg_done[0]); |
Tcyg_io_write(handle, &msg_done[0], &chunk_len); |
} |
} |
break; |
case MODE_DUPLEX_ECHO: |
{ |
int chunk_len; |
int block_size = 64; |
|
// This is a simple implementation (maybe too simple). |
// Host sends 4 packets with the same size (64 bytes atm). |
// Target echoes in this way: |
// packet1 -> packet1 |
// packet2 -> packet2, packet2 |
// packet3 -> packet3 |
// packet4 -> /dev/null |
// |
// The reads/writes are interleaved in a way that should ensure |
// the target out buffer to be full before the target starts to read |
// packet3. That is, the target should be both receiving (packet3) |
// and sending (packet2) at the same time. |
|
while (size--) { |
// block_size -> block_size |
chunk_len = block_size; |
Tcyg_io_read(handle, &in_buffer[0], &chunk_len); |
chunk_len = block_size; |
Tcyg_io_write(handle, &in_buffer[0], &chunk_len); |
|
// block_size -> 2 x block_size |
chunk_len = block_size; |
Tcyg_io_read(handle, &in_buffer[0], &chunk_len); |
chunk_len = block_size; |
Tcyg_io_write(handle, &in_buffer[0], &chunk_len); |
chunk_len = block_size; |
Tcyg_io_write(handle, &in_buffer[0], &chunk_len); |
|
// block_size -> block_size |
chunk_len = block_size; |
Tcyg_io_read(handle, &in_buffer[0], &chunk_len); |
chunk_len = block_size; |
Tcyg_io_write(handle, &in_buffer[0], &chunk_len); |
|
// block_size -> 0 |
chunk_len = block_size; |
Tcyg_io_read(handle, &in_buffer[0], &chunk_len); |
} |
|
// Kill the CRC. Leave packet verification to the host for now. |
xcrc = host_crc = 0; |
|
// Now read host side's status |
chunk_len = 2; |
Tcyg_io_read(handle, &in_buffer[0], &chunk_len); |
host_status = in_buffer[0]; |
|
// Reply that we have completed the test. |
{ |
const char msg_done[] = "DONE"; |
|
chunk_len = strlen(&msg_done[0]); |
Tcyg_io_write(handle, &msg_done[0], &chunk_len); |
} |
} |
break; |
default: |
TEST_CRASH(handle, TEST_CRASH_PROT_BIN_MODE, |
"Unknown mode", mode); |
break; |
} |
|
|
// Verify that the CRC matches the one from the host. |
FIX_CRC(xcrc, icrc); |
if (host_crc != icrc) { |
TEST_CRASH(handle, TEST_CRASH_CRC_BAD, |
"Input CRC failed", icrc, host_crc); |
} |
|
// Verify that the host is happy with the data we echoed. |
if ('O' != host_status) { |
TEST_CRASH(handle, TEST_CRASH_CRC_HOST, |
"Output CRC failed"); |
} |
|
CYG_TEST_PASS("Binary test completed"); |
return TEST_RETURN_OK; |
} |
|
//--------------------------------------------------------------------------- |
// Test transformations on text transmissions |
// Format out: |
// "@TEXT:<mode>!<4 bytes binary checksum><C string>" |
// Format in: |
// "<C string>" |
// OK/ER |
// |
// Mode: |
// MODE_EOP_ECHO: |
// Receive data, verify CRC, resend data. |
// Expect OK/ER reply from host when done. |
// MODE_DUPLEX_ECHO: |
// Receive data, echo data, verify CRC. |
// Expect OK/ER reply from host when done. |
// |
cyg_test_return_t |
test_text(cyg_io_handle_t handle, cyg_mode_t mode, const char* s_base, |
const char* s_out, const char* s_in) |
{ |
return TEST_RETURN_NA; |
} |
|
//--------------------------------------------------------------------------- |
// Send PING to host, verifying the filter's presence. |
// Format out: |
// "@PING:<crash id>!" |
// Format in: |
// "OK" |
// or |
// No response if directly connected to GDB. |
// |
// This call only returns if the ser_filter is listening. Otherwise it |
// sends N/A and hangs. |
void |
test_ping(cyg_io_handle_t handle) |
{ |
char msg[] = "@PING:" TEST_CRASH_ID "!"; |
char msg2[] = "\n"; |
int msglen = strlen(msg); |
int res; |
|
msglen = strlen(msg); |
Tcyg_io_write(handle, msg, &msglen); |
|
// Now read host side's status |
msglen = 2; |
Tcyg_io_read_timeout(handle, &in_buffer[0], &msglen, 100, &res); |
if (ENOERR == res && 'O' == in_buffer[0] && 'K' == in_buffer[1]) |
return; |
|
msglen = strlen(msg2); |
Tcyg_io_write(handle, msg2, &msglen); |
|
CYG_TEST_NA("No host side testing harness detected."); |
} |
|
|
//--------------------------------------------------------------------------- |
// Send OPT to host, setting options in the filter. |
// Format out: |
// "@OPT:option1,value1:...:optionN,valueN!" |
// Format in: |
// "OK" |
// |
// Only integer values can be used. Any option not recognized by the |
// filter will be silently ignored. |
void |
test_options(cyg_io_handle_t handle, int count, cyg_uint32* options) |
{ |
const char cmd[] = "@OPT:"; |
int msglen; |
cyg_uint8 *p1; |
|
// Prepare and send the command. |
p1 = &cmd_buffer[0]; |
p1 = strcpy(p1, &cmd[0]); |
while(count--) { |
p1 = itoa(p1, *options++); // option |
*p1++ = ':'; |
p1 = itoa(p1, *options++); // value |
*p1++ = ':'; |
} |
*(p1-1) = '!'; |
*p1++ = 0; |
|
CYG_TEST_INFO(&cmd_buffer[1]); |
|
msglen = strlen(&cmd_buffer[0]); |
Tcyg_io_write(handle, &cmd_buffer[0], &msglen); |
|
// Now read host side's status |
msglen = 2; |
Tcyg_io_read(handle, &in_buffer[0], &msglen); |
} |
|
|
//--------------------------------------------------------------------------- |
// Some helper functions to get a test started. |
void |
test_open_ser( cyg_io_handle_t* handle ) |
{ |
#if defined(CYGPKG_IO_SERIAL_DEVICES) && !defined(SER_NOP_TEST) |
Cyg_ErrNo res; |
|
if (cyg_test_is_simulator) |
CYG_TEST_NA("Cannot run from simulator"); |
|
#if defined(HAL_VSR_SET_TO_ECOS_HANDLER) |
# if defined(CYGPRI_SER_TEST_OVERRIDE_INT_1) |
HAL_VSR_SET_TO_ECOS_HANDLER(CYGPRI_SER_TEST_OVERRIDE_INT_1, NULL); |
# endif |
# if defined(CYGPRI_SER_TEST_OVERRIDE_INT_2) |
HAL_VSR_SET_TO_ECOS_HANDLER(CYGPRI_SER_TEST_OVERRIDE_INT_2, NULL); |
# endif |
#endif |
|
res = cyg_io_lookup(TEST_SER_DEV, handle); |
if (res != ENOERR) { |
CYG_TEST_FAIL_FINISH("Can't lookup " TEST_SER_DEV); |
} |
#else |
CYG_TEST_NA(NA_MSG); |
#endif |
} |
|
void |
test_open_tty( cyg_io_handle_t* handle ) |
{ |
#if defined(CYGPKG_IO_SERIAL_TTY) && !defined(TTY_NOP_TEST) |
Cyg_ErrNo res; |
|
if (cyg_test_is_simulator) |
CYG_TEST_NA("Cannot run from simulator"); |
|
#if defined(HAL_VSR_SET_TO_ECOS_HANDLER) |
# if defined(CYGPRI_SER_TEST_OVERRIDE_INT_1) |
HAL_VSR_SET_TO_ECOS_HANDLER(CYGPRI_SER_TEST_OVERRIDE_INT_1, NULL); |
# endif |
# if defined(CYGPRI_SER_TEST_OVERRIDE_INT_2) |
HAL_VSR_SET_TO_ECOS_HANDLER(CYGPRI_SER_TEST_OVERRIDE_INT_2, NULL); |
# endif |
#endif |
|
res = cyg_io_lookup(TEST_TTY_DEV, handle); |
if (res != ENOERR) { |
CYG_TEST_FAIL_FINISH("Can't lookup " TEST_TTY_DEV); |
} |
#else |
CYG_TEST_NA(NA_MSG); |
#endif |
} |
|
//--------------------------------------------------------------------------- |
// end of ser_test_protocol.inl |
/README
0,0 → 1,285
Serial Testing with ser_filter |
|
Rationale |
~~~~~~~~~ |
Since some targets only have one serial connection, a serial testing |
harness needs to be able to share the connection with GDB (however, |
the test and GDB can also run on separate lines). |
|
The serial filter (ser_filter) sits between the serial port and GDB |
and monitors the exchange of data between GDB and the |
target. Normally, no changes are made to the data. |
|
When a test request packet is sent from the test on the target, it is |
intercepted by the filter. The filter and target then enter a loop, |
exchanging protocol data between them which GDB never sees. |
|
In the event of a timeout, or a crash on the target, the filter falls |
back into its pass-through mode. If this happens due to a crash it |
should be possible to start regular debugging with GDB. The filter |
will then stay in the pass-though mode until GDB disconnects. |
|
|
Adding A New Platform |
~~~~~~~~~~~~~~~~~~~~~ |
The file ser_test_protocol.inl contains information about how to run |
the serial tests on supported platforms. When adding a new serial |
driver to eCos, ser_test_protocol.inl should be updated accordingly |
so the driver can be tested. |
|
The definitions TEST_SER_DEV and TEST_TTY_DEV are set according to |
platform: |
|
TEST_SER_DEV is the name of the serial device over which the serial |
test protocol runs. The definition should be conditional on all |
required configuration options. |
|
TEST_TTY_DEV is the name of the TTY device over which the TTY test |
protocol runs. The definition should be conditional on all required |
configuration options. Note that this device is layered on top of a |
serial device and must be conditional on that device's config |
options as well as its own. |
|
Here's an example for the PowerPC/Cogent where GDB is connected via |
serial connector B: |
|
#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 |
|
|
On some targets it may also be necessary to intialize interrupt |
vectors which are otherwise used by CygMon or an eCos GDB stub to |
monitor characters from the host (looking for Control-C): |
|
# define SER_OVERRIDE_INT_1 CYGNUM_HAL_INTERRUPT_9 |
# define SER_OVERRIDE_INT_2 CYGNUM_HAL_INTERRUPT_10 |
|
These definitions cause the serial test to restore the eCos handler |
on the specified vectors before opening the serial device. |
|
|
The file ser_test_protocol.inl also contains an array of serial |
configurations (test_configs). It may be necessary to comment some of |
these out for the platform if the driver or hardware cannot handle |
all the given serial configurations. |
|
|
The Protocol |
~~~~~~~~~~~~ |
The protocol commands are prefixed with an @-character which the |
serial filter is looking for. The protocol commands include: |
|
PING |
Allows the test on the target to probe for the filter. The filter |
responds with OK, while GDB would just ignore the command. This |
allows the tests to do nothing if they require the filter and it is |
not present. |
|
CONFIG |
Requests a change of serial line configuration. Arguments of the |
command specify baud rate, data bits, stop bits, and parity. |
|
OPT |
Requests changes in the filter's options. This allows various |
amounts of tracing to be recorded when running tests without |
requiring the filter to be restarted. |
|
BINARY |
Requests data to be sent from the filter to the target. The data is |
checksummed, allowing errors in the transfer to be detected. |
Sub-options of this command control how the data transfer is made: |
|
NO_ECHO (serial driver receive test) |
Just send data from the filter to the target. The test verifies |
the checksum and PASS/FAIL depending on the result. |
|
EOP_ECHO (serial driver half-duplex receive and send test) |
As NO_ECHO but the test echoes back the data to the filter. The |
filter does a checksum on the received data and sends the result |
to the target. The test PASS/FAIL depending on the result of both |
checksum verifications. |
|
DUPLEX_ECHO (serial driver duplex receive and send test) |
Smaller packets of data are sent back and forth in a pattern that |
ensures that the serial driver will be both sending and receiving |
at the same time. Again, checksums are computed and verified |
resulting in PASS/FAIL. |
|
TEXT |
This is a test of the text translations in the TTY layer. |
Requests a transfer of text data from the target to the filter and |
possibly back again. The filter treats this as a binary transfer, |
while the target may be doing translations on the data. The target |
provides the filter with checksums for what it should expect to |
see. |
[This test is not implemented yet] |
|
The above commands may be extended, and new commands added, as |
required to test (new) parts of the serial drivers in eCos. |
|
See ser_test_protocol.inl for further details on the protocols. |
|
|
The Serial Tests |
~~~~~~~~~~~~~~~~ |
The serial tests are built as any other eCos test. After running the |
'make tests' command, the tests can be found in: |
|
install/tests/io_serial/ |
|
serial1 |
A simple API test. |
|
serial2 |
A simple serial send test. It writes out two strings, one raw and |
one encoded as a GDB O-packet. |
|
serial3 [requires the serial filter] |
This tests the half-duplex send and receive capabilities of the |
serial driver. |
|
serial4 [requires the serial filter] |
This test attempts to use a few different serial configurations, |
testing the driver's configuration/setup functionality. |
|
serial5 [requires the serial filter] |
This tests the duplex send and receive capabilities of the serial |
driver. |
|
All tests should complete in less than 30 seconds. |
|
|
Serial Filter Usage |
~~~~~~~~~~~~~~~~~~~ |
Running the ser_filter program with no (or wrong) arguments results |
in the below output: |
|
Usage: ser_filter [-t -c -g -S] TcpIPport SerialPort BaudRate |
or: ser_filter -n [-t -c -g -S] SerialPort BaudRate |
-t: Enable tracing. |
-f: Enable filter output tracing. |
-g: Enable GDB tracing. |
-S: Output data read from serial line. |
-c: Output data on console instead of via GDB. |
-n: No GDB. |
|
The normal way to use it with GDB is to start the filter: |
|
ser_filter -t 9000 com1 38400 |
|
In this case, the filter will be listening on port 9000 and connect |
to the target via the serial port COM1 at 38400 baud. On a UNIX host, |
replace "com1" with a device such as "/dev/ttyS0". |
|
The '-t' option enables tracing which will cause the filter to |
describe its actions on the console. |
|
Now start GDB with one of the tests as an argument: |
|
$ mips-tx39-elf-gdb -nw install/tests/io_serial/serial3 |
|
Then connect to the filter: |
|
(gdb) target remote localhost:9000 |
|
This should result in a connection in exactly the same way as if you |
had connected directly to the target on the serial line. |
|
(gdb) load |
... |
(gdb) cont |
|
Which should result in output similar to the below: |
|
Continuing. |
INFO:<BINARY:16:1!> |
PASS:<Binary test completed> |
INFO:<BINARY:128:1!> |
PASS:<Binary test completed> |
INFO:<BINARY:256:1!> |
PASS:<Binary test completed> |
INFO:<BINARY:1024:1!> |
PASS:<Binary test completed> |
INFO:<BINARY:512:0!> |
PASS:<Binary test completed> |
... |
PASS:<Binary test completed> |
INFO:<BINARY:16384:0!> |
PASS:<Binary test completed> |
PASS:<serial3 test OK> |
EXIT:<done> |
|
If any of the individual tests fail the testing will terminate with |
a FAIL. |
|
With tracing enabled, you would also see the filter's status output: |
|
The PING command sent from the target to determine the presence of |
the filter: |
[400 11:35:16] Dispatching command PING |
[400 11:35:16] Responding with status OK |
|
Each of the binary commands result in output similar to: |
[400 11:35:16] Dispatching command BINARY |
[400 11:35:16] Binary data (Size:16, Flags:1). |
[400 11:35:16] Sending CRC: '170231!', len: 7. |
[400 11:35:16] Reading 16 bytes from target. |
[400 11:35:16] Done. in_crc 170231, out_crc 170231. |
[400 11:35:16] Responding with status OK |
[400 11:35:16] Received DONE from target. |
|
This tracing output is normally sent as O-packets to GDB which will |
display the tracing text. By using the -c option, the tracing text |
can be redirected to the console from which ser_filter was started. |
|
|
The trace options -f, -g, and -S cause data sent from filter, GDB or |
target to be output in hexadecimal form. |
|
|
A Note on Failures |
~~~~~~~~~~~~~~~~~~ |
A serial connection (especially when driven at a high baud rate) can |
garble the transmitted data because of noise from the environment. It |
is not the job of the serial driver to ensure data integrity - that |
is the job of protocols layering on top of the serial driver. |
|
In the current implementation the serial tests and the serial filter |
are not resilient to such data errors. This means that the test may |
crash or hang (possibly without reporting a FAIL). It also means that |
you should be aware of random errors - a FAIL is not necessarily |
caused by a bug in the serial driver. |
|
Ideally, the serial testing infrastructure should be able to |
distinguish random errors from consistent errors - the former are |
most likely due to noise in the transfer medium, while the latter are |
more likely to be caused by faulty drivers. The current |
implementation of the infrastructure does not have this capability. |
|
|
Debugging |
~~~~~~~~~ |
If a test fails, the serial filter's output may provide some hints |
about what the problem is. If the option '-S' is used when starting |
the filter, data received from the target is printed out: |
|
[400 11:35:16] 0000 50 41 53 53 3a 3c 42 69 'PASS:<Bi' |
[400 11:35:16] 0008 6e 61 72 79 20 74 65 73 'nary.tes' |
[400 11:35:16] 0010 74 20 63 6f 6d 70 6c 65 't.comple' |
[400 11:35:16] 0018 74 65 64 3e 0d 0a 49 4e 'ted>..IN' |
[400 11:35:16] 0020 46 4f 3a 3c 42 49 4e 41 'FO:<BINA' |
[400 11:35:16] 0028 52 59 3a 31 32 38 3a 31 'RY:128:1' |
[400 11:35:16] 0030 21 3e 0d 0a 40 42 49 4e '!>..@BIN' |
[400 11:35:16] 0038 41 52 59 3a 31 32 38 3a 'ARY:128:' |
[400 11:35:16] 0040 31 21 .. .. .. .. .. .. '1!' |
|
In the case of an error during a testing command the data received by |
the filter will be printed out, as will the data that was |
expected. This allows the two data sets to be compared which may give |
some idea of what the problem is. |
/serial_echo.c
0,0 → 1,127
//========================================================================== |
// |
// serial_echo.c |
// |
// Simple interactive echo test. |
// |
//========================================================================== |
//####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 |
// Date: 2000-04-11 |
// Description: Simple echo test. |
// |
//####DESCRIPTIONEND#### |
|
#include <pkgconf/system.h> |
|
#include <cyg/infra/testcase.h> // test macros |
#include <cyg/infra/cyg_ass.h> // assertion macros |
|
// Package requirements |
#if defined(CYGPKG_IO_SERIAL) && defined(CYGPKG_KERNEL) |
|
#include <pkgconf/kernel.h> |
|
// Package option requirements |
#if defined(CYGFUN_KERNEL_API_C) |
|
#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL |
#include <cyg/kernel/kapi.h> |
unsigned char stack[CYGNUM_HAL_STACK_SIZE_TYPICAL]; |
cyg_thread thread_data; |
cyg_handle_t thread_handle; |
|
#include "ser_test_protocol.inl" |
|
//--------------------------------------------------------------------------- |
// Serial test main function. |
void |
serial_test( void ) |
{ |
cyg_io_handle_t ser_handle; |
cyg_uint8 in_buffer[1]; |
int len = 1; |
|
test_open_ser(&ser_handle); |
|
CYG_TEST_INFO("Kill GDB and open a terminal emulator."); |
CYG_TEST_INFO("This test will echo all data."); |
|
while (1) { |
len = 1; |
Tcyg_io_read(ser_handle, in_buffer, &len); |
len = 1; |
Tcyg_io_write(ser_handle, in_buffer, &len); |
} |
|
} |
|
void |
cyg_start(void) |
{ |
CYG_TEST_INIT(); |
cyg_thread_create(10, // Priority - just a number |
(cyg_thread_entry_t*)serial_test, // entry |
0, // |
"serial_thread", // Name |
&stack[0], // Stack |
CYGNUM_HAL_STACK_SIZE_TYPICAL, // Size |
&thread_handle, // Handle |
&thread_data // Thread data structure |
); |
cyg_thread_resume(thread_handle); |
cyg_scheduler_start(); |
} |
|
#else // CYGFUN_KERNEL_API_C |
#define N_A_MSG "Needs kernel C API" |
#endif |
|
#else // CYGPKG_IO_SERIAL && CYGPKG_KERNEL |
#define N_A_MSG "Needs IO/serial and Kernel" |
#endif |
|
#ifdef N_A_MSG |
void |
cyg_start( void ) |
{ |
CYG_TEST_INIT(); |
CYG_TEST_NA( N_A_MSG); |
} |
#endif // N_A_MSG |
// EOF serial3.c |