diff -ruN -x 'Entries*' ecos_web_cvs/ecos/packages/io/can/current/ChangeLog ecos/ecos/packages/io/can/current/ChangeLog --- ecos_web_cvs/ecos/packages/io/can/current/ChangeLog 2007-01-02 23:35:42.000000000 +0100 +++ ecos/ecos/packages/io/can/current/ChangeLog 2007-03-23 11:26:43.000000000 +0100 @@ -1,3 +1,57 @@ +2007-03-23 Uwe Kindler + + * cdl/io_can.cdl: Added several interfaces for implementation by + device drivers. + Moved several configuration options from device drivers to the + generic CAN driver. With this design a device driver does not + need to provide all configuration options in its CDL file - it + simply needs to implement the provided interfaces. The drawback + of this decicsion is, that it is not possible to control these + options independently for several CAN devices. (But most platforms + will have only 1 channel) + Added configuration option CYGBLD_IO_CAN_EXTRA_TESTS. This option + enables the build of the interactive CAN tests. + + * test/can_filter: Added interactive message filtering test + + * test/can_hdi: Added interactive hardware description interface + test + + * test/can_load: Added interactive message handling (reception, + transmission) test. + + * test/can_remote: Added interactive remote response buffer test + + * test/can_tx: Added interactive basic TX test. All tests are not + part of the eCos test framework because they are interactive. That + means, they require interaction with another user controlled + CAN node. + + * include/can.h: Added identifier masks for standard and extended + identifiers. + Added the line #include CYGDAT_IO_CAN_DEVICE_INL. This enables a + device driver to provide an own device inline file. In this inline + file the driver may define own data types for CAN messages (for + internal storage of CAN messages (see AT91SAM7 CAN driver)) + + * include/canio.h: Added baudrate CYGNUM_CAN_KBAUD_AUTO - support of + automatic baudrate detection if a driver supports such a feature. + Added state CYGNUM_CAN_STATE_CONFIG and mode CYGNUM_CAN_MODE_CONFIG. + The application may use these identifiers to set the CAN device into + a state where it is safe to add/remove/configure message buffers. + Added union data type cyg_can_msg_data. With this data type a 4 byte + alignment of message data is guaranteed, an byte, word and dword + access to the data is possible and an assignment of two CAN datas are + possible now. + cyg_can_message now uses cyg_can_msg_data union for CAN data. + Replaced SW-Filt flag by autobaud flag in HDI. + Added CAN message access macros for read/write acces of CAN message + structures. These macros hide implementation of CAN message from + application. + + * src/can.c: Added support for device driver defined CAN message + data types + 2006-12-19 Sergei Gavrikov * doc/can.sgml: Correctly close para tag. diff -ruN -x 'Entries*' ecos_web_cvs/ecos/packages/io/can/current/cdl/io_can.cdl ecos/ecos/packages/io/can/current/cdl/io_can.cdl --- ecos_web_cvs/ecos/packages/io/can/current/cdl/io_can.cdl 2006-09-20 19:40:10.000000000 +0200 +++ ecos/ecos/packages/io/can/current/cdl/io_can.cdl 2007-03-22 11:21:01.000000000 +0100 @@ -70,14 +70,57 @@ puts $::cdl_header "#endif " puts $::cdl_header "/****** proc output end ******/" } - + + #----------------------------------------------------------------- + # Interfaces + # A hardware device driver should implement each interface it + # supports + # cdl_interface CYGINT_IO_CAN_TIMESTAMP { display "CAN driver supports timestamps" } + cdl_interface CYGINT_IO_CAN_STD_CAN_ID { + display "11 Bit standard CAN ID support" + } + + cdl_interface CYGINT_IO_CAN_EXT_CAN_ID { + display "29 Bit extended CAN ID support" + } + + cdl_interface CYGINT_IO_CAN_RUNTIME_MBOX_CFG { + display "CAN driver supports message box runtime configuration" + } + + cdl_interface CYGINT_IO_CAN_REMOTE_BUF { + display "CAN driver supports remote response buffers" + } + + cdl_interface CYGINT_IO_CAN_AUTOBAUD { + display "CAN driver supports automatic baudrate detection" + } + + cdl_interface CYGINT_IO_CAN_TX_EVENTS { + display "CAN driver supports TX events" + } + + + #----------------------------------------------------------------- + # Generic CAN driver configuration + # + cdl_component CYGPKG_IO_CAN_DEVICES { + display "Hardware CAN device drivers" + flavor bool + default_value 1 + description " + This option enables the hardware device drivers + for the current platform." + } + cdl_option CYGOPT_IO_CAN_SUPPORT_TIMESTAMP { display "Support CAN event timestamps" requires { CYGINT_IO_CAN_TIMESTAMP > 0 } + active_if { CYGINT_IO_CAN_TIMESTAMP > 0 } default_value 0 description " If the CAN hardware driver supports some kind of timestamps @@ -87,6 +130,8 @@ cdl_option CYGOPT_IO_CAN_TX_EVENT_SUPPORT { display "Support TX events" + requires { CYGINT_IO_CAN_TX_EVENTS > 0 } + active_if { CYGINT_IO_CAN_TX_EVENTS > 0 } default_value 0 description " This option enables support for TX events. If a CAN message is @@ -95,15 +140,66 @@ option is enabled the RX event queue will be filled faster." } - cdl_component CYGPKG_IO_CAN_DEVICES { - display "Hardware CAN device drivers" - flavor bool + cdl_option CYGOPT_IO_CAN_STD_CAN_ID { + display "11 Bit standard CAN ID support" + requires { CYGINT_IO_CAN_STD_CAN_ID > 0 } + active_if { CYGINT_IO_CAN_STD_CAN_ID > 0 } + default_value { CYGINT_IO_CAN_STD_CAN_ID > 0 ? 1 : 0 } + description " + This option enables support for 11 Bit standard CAN identifiers. + If the application deals only with 29 Bit extended CAN messages + then disabling this option may reduce codesize or increase + performance." + } + + cdl_option CYGOPT_IO_CAN_EXT_CAN_ID { + display "29 Bit extended CAN ID support" + requires { CYGINT_IO_CAN_EXT_CAN_ID > 0 } + active_if { CYGINT_IO_CAN_EXT_CAN_ID > 0 } + default_value { CYGINT_IO_CAN_EXT_CAN_ID > 0 ? 1 : 0 } + description " + This option enables support for 29 Bit extended CAN identifiers. + If the application deals only with 11 Bit standard CAN messages + then disabling this option may reduce codesize or increase + performance." + } + + cdl_option CYGOPT_IO_CAN_AUTOBAUD { + display "Support automatic baudrate detection." + requires { CYGINT_IO_CAN_AUTOBAUD > 0 } + active_if { CYGINT_IO_CAN_AUTOBAUD > 0 } + default_value 0 + description " + If the CAN hardware device driver supports any kind of automatic + baudrate detection then this option enables support for this feature. + If automatic baudrate detection is not required, then disabling this + option may reduce codesize." + } + + cdl_option CYGOPT_IO_CAN_RUNTIME_MBOX_CFG { + display "Message box runtime configuration support" + requires { CYGINT_IO_CAN_RUNTIME_MBOX_CFG > 0 } + active_if { CYGINT_IO_CAN_RUNTIME_MBOX_CFG > 0 } default_value 1 - description " - This option enables the hardware device drivers - for the current platform." + description " + Message box runtime configuration is required for for hardware message + filtering and for hardware remote response buffers. If no hardware + filtering is required and if the application does not need remote + response buffers this option can be disabled to decrease codesize." } + cdl_option CYGOPT_IO_CAN_REMOTE_BUF { + display "Remote response buffer support" + requires { CYGOPT_IO_CAN_RUNTIME_MBOX_CFG } + requires { CYGINT_IO_CAN_REMOTE_BUF > 0} + active_if { CYGINT_IO_CAN_REMOTE_BUF > 0 } + default_value 1 + description " + If the driver should handle remote requests automatically then remote + response buffers are required. Disabling this option may save some + bytes of ROM memory." + } + cdl_option CYGOPT_IO_CAN_SUPPORT_NONBLOCKING { display "Support non-blocking read and write calls" default_value 0 @@ -142,38 +238,78 @@ The initial timeout value in clock ticks for cyg_io_write() calls." } } - - cdl_component CYGPKG_IO_CAN_OPTIONS { - display "CAN device driver build options" - flavor none - description " - Package specific build options including control over - compiler flags used only in building this package, - and details of which tests are built." - - - cdl_option CYGPKG_IO_CAN_CFLAGS_ADD { - display "Additional compiler flags" - flavor data - no_define - default_value { "" } - description " - This option modifies the set of compiler flags for - building the CAN device drivers. These flags are used in addition - to the set of global flags." + + cdl_option CYGBLD_IO_CAN_EXTRA_TESTS { + display "Build extra CAN tests" + default_value 0 + no_define + description " + This option enables the building of some extra tests which + can be used when testing / debugging CAN drivers. These + are not built by default since they do not use the dedicated + testing infrastructure. All tests require a properly configured + CAN network with a second CAN node that can send and receive + CAN messages." + + make -priority 320 { + /bin/can_load : /tests/can_load.c + @sh -c "mkdir -p tests $(dir $@)" + $(CC) -c $(INCLUDE_PATH) -Wp,-MD,deps.tmp -I$(dir $<) $(CFLAGS) -o tests/can_load.o $< + @echo $@ ": \\" > $(notdir $@).deps + @echo $(wildcard $(PREFIX)/lib/*) " \\" >> $(notdir $@).deps + @tail -n +2 deps.tmp >> $(notdir $@).deps + @echo >> $(notdir $@).deps + @rm deps.tmp + $(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -o $@ tests/can_load.o } - - cdl_option CYGPKG_IO_CAN_CFLAGS_REMOVE { - display "Suppressed compiler flags" - flavor data - no_define - default_value { "" } - description " - This option modifies the set of compiler flags for - building the CAN device drivers. These flags are removed from - the set of global flags if present." + + make -priority 320 { + /bin/can_remote : /tests/can_remote.c + @sh -c "mkdir -p tests $(dir $@)" + $(CC) -c $(INCLUDE_PATH) -Wp,-MD,deps.tmp -I$(dir $<) $(CFLAGS) -o tests/can_remote.o $< + @echo $@ ": \\" > $(notdir $@).deps + @echo $(wildcard $(PREFIX)/lib/*) " \\" >> $(notdir $@).deps + @tail -n +2 deps.tmp >> $(notdir $@).deps + @echo >> $(notdir $@).deps + @rm deps.tmp + $(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -o $@ tests/can_remote.o + } + + make -priority 320 { + /bin/can_tx : /tests/can_tx.c + @sh -c "mkdir -p tests $(dir $@)" + $(CC) -c $(INCLUDE_PATH) -Wp,-MD,deps.tmp -I$(dir $<) $(CFLAGS) -o tests/can_tx.o $< + @echo $@ ": \\" > $(notdir $@).deps + @echo $(wildcard $(PREFIX)/lib/*) " \\" >> $(notdir $@).deps + @tail -n +2 deps.tmp >> $(notdir $@).deps + @echo >> $(notdir $@).deps + @rm deps.tmp + $(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -o $@ tests/can_tx.o + } + + make -priority 320 { + /bin/can_filter : /tests/can_filter.c + @sh -c "mkdir -p tests $(dir $@)" + $(CC) -c $(INCLUDE_PATH) -Wp,-MD,deps.tmp -I$(dir $<) $(CFLAGS) -o tests/can_filter.o $< + @echo $@ ": \\" > $(notdir $@).deps + @echo $(wildcard $(PREFIX)/lib/*) " \\" >> $(notdir $@).deps + @tail -n +2 deps.tmp >> $(notdir $@).deps + @echo >> $(notdir $@).deps + @rm deps.tmp + $(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -o $@ tests/can_filter.o + } + + make -priority 320 { + /bin/can_hdi : /tests/can_hdi.c + @sh -c "mkdir -p tests $(dir $@)" + $(CC) -c $(INCLUDE_PATH) -Wp,-MD,deps.tmp -I$(dir $<) $(CFLAGS) -o tests/can_hdi.o $< + @echo $@ ": \\" > $(notdir $@).deps + @echo $(wildcard $(PREFIX)/lib/*) " \\" >> $(notdir $@).deps + @tail -n +2 deps.tmp >> $(notdir $@).deps + @echo >> $(notdir $@).deps + @rm deps.tmp + $(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -o $@ tests/can_hdi.o } - } } diff -ruN -x 'Entries*' ecos_web_cvs/ecos/packages/io/can/current/include/can.h ecos/ecos/packages/io/can/current/include/can.h --- ecos_web_cvs/ecos/packages/io/can/current/include/can.h 2005-09-13 15:36:24.000000000 +0200 +++ ecos/ecos/packages/io/can/current/include/can.h 2007-02-20 21:24:24.000000000 +0100 @@ -66,6 +66,34 @@ #include +// define standard and extended id masks +#define CYG_CAN_STD_ID_MASK 0x7FF +#define CYG_CAN_EXT_ID_MASK 0x1FFFFFFF + +// +// include device header +// a device can define its own types of CAN messages and CAN events. It does this +// in the device header CYGDAT_IO_CAN_DEVICE_INL. Because this header is included +// here, the device header file can use all definitions in the files included +// in the include section above +// +#ifdef CYGDAT_IO_CAN_DEVICE_INL +#include CYGDAT_IO_CAN_DEVICE_INL // include device header +#endif + +// +// If the device did not define its own type of CAN message and CAN event, then +// we define standard types here and use the types cyg_can_message and cyg_can_event +// from CAN I/O layer +// +#ifndef CYG_CAN_MSG_T +#define CYG_CAN_MSG_T cyg_can_message +#define CYG_CAN_EVENT_T cyg_can_event +#define CYG_CAN_WRITE_MSG(_devmsg_ptr_, _iomsg_ptr_) (*(_devmsg_ptr_) = *(_iomsg_ptr_)) +#define CYG_CAN_READ_EVENT(_ioevent_ptr_, _devevent_ptr_) (*(_ioevent_ptr_) = *(_devevent_ptr_)) +#endif + + //=========================================================================== // FORWARD DECLARATIONS //=========================================================================== @@ -175,18 +203,18 @@ // struct can_lowlevel_funs { - bool (*putmsg)(can_channel *priv, cyg_can_message *pmsg, void *pdata); // send one can message - return true if consumed - bool (*getevent)(can_channel *priv, cyg_can_event *pevent, void *pdata); // fetch one CAN event from device - Cyg_ErrNo (*get_config)(can_channel *priv, // query hardware configuration (baud rate, etc) + bool (*putmsg)(can_channel *priv, CYG_CAN_MSG_T *pmsg, void *pdata); // send one can message - return true if consumed + bool (*getevent)(can_channel *priv, CYG_CAN_EVENT_T *pevent, void *pdata); // fetch one CAN event from device + Cyg_ErrNo (*get_config)(can_channel *priv, // query hardware configuration (baud rate, etc) cyg_uint32 key, const void *xbuf, cyg_uint32 *len); - Cyg_ErrNo (*set_config)(can_channel *priv, // Change hardware configuration (baud rate, etc) + Cyg_ErrNo (*set_config)(can_channel *priv, // Change hardware configuration (baud rate, etc) cyg_uint32 key, const void *xbuf, cyg_uint32 *len); - void (*start_xmit)(can_channel *priv); // Enable the transmit channel and turn on transmit interrupts - void (*stop_xmit)(can_channel *priv); // Disable the transmit channel and turn transmit interrupts off + void (*start_xmit)(can_channel *priv); // Enable the transmit channel and turn on transmit interrupts + void (*stop_xmit)(can_channel *priv); // Disable the transmit channel and turn transmit interrupts off }; #define CAN_LOWLEVEL_FUNS(_l,_putmsg,_getevent,_get_config,_set_config,_start_xmit,_stop_xmit) \ diff -ruN -x 'Entries*' ecos_web_cvs/ecos/packages/io/can/current/include/canio.h ecos/ecos/packages/io/can/current/include/canio.h --- ecos_web_cvs/ecos/packages/io/can/current/include/canio.h 2006-03-13 15:46:12.000000000 +0100 +++ ecos/ecos/packages/io/can/current/include/canio.h 2007-02-20 21:28:28.000000000 +0100 @@ -85,6 +85,7 @@ CYGNUM_CAN_KBAUD_500, CYGNUM_CAN_KBAUD_800, CYGNUM_CAN_KBAUD_1000, + CYGNUM_CAN_KBAUD_AUTO, // automatic detection of baudrate (if supported by hardware) } cyg_can_baud_rate_t; #define CYGNUM_CAN_KBAUD_MIN CYGNUM_CAN_KBAUD_10 #define CYGNUM_CAN_KBAUD_MAX CYGNUM_CAN_KBAUD_1000 @@ -133,6 +134,7 @@ CYGNUM_CAN_STATE_PHY_FAULT, // General failure of physical layer detected (if supported by hardware) CYGNUM_CAN_STATE_PHY_H, // Fault on CAN-H detected (Low Speed CAN) CYGNUM_CAN_STATE_PHY_L, // Fault on CAN-L detected (Low Speed CAN) + CYGNUM_CAN_STATE_CONFIG, // CAN controller is in configuration state } cyg_can_state; // @@ -142,7 +144,8 @@ { CYGNUM_CAN_MODE_STOP, // set controller into stop mode CYGNUM_CAN_MODE_START, // set controller into operational mode - CYGNUM_CAN_MODE_STANDBY // set controller into standby / sleep mode + CYGNUM_CAN_MODE_STANDBY,// set controller into standby / sleep mode + CYGNUM_CAN_MODE_CONFIG // set controller and driver into a state where it is safe to add/delete message buffers } cyg_can_mode; // @@ -174,13 +177,28 @@ #define CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD 3 // add new remote response buffer #define CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE 4 // store data into existing remote buffer (remote buf handle required) + +// +// CAN message data - this union is a container for the 8 data bytes of a can +// message and the union is alway part of a can message - no matter if this type +// is defined by generic CAN layer or by CAN hardware device driver +// +typedef union u_cyg_can_msg_data +{ + cyg_uint8 bytes[8]; // byte access (array of 8 bytes) + cyg_uint16 words[4]; // word access (array of 4 words) + cyg_uint32 dwords[2]; // double word access (array of 2 dwords) +} cyg_can_msg_data; + // // CAN message type for transport or transmit of CAN messages +// The message data is a union. This enables byte, word and dword access and +// also ensures a 4 byte alignment of the message data // typedef struct st_cyg_can_message { cyg_uint32 id; // 11 Bit or 29 Bit CAN identifier - cyg_can_id_type - cyg_uint8 data[8];// 8 data bytes + cyg_can_msg_data data; // CAN data (8 data bytes) cyg_can_id_type ext; // CYGNUM_CAN_ID_STD = 11 Bit CAN id, CYGNUM_CAN_ID_EXT = 29 Bit CAN id cyg_can_frame_type rtr; // CYGNUM_CAN_FRAME_DATA = data frame, CYGNUM_CAN_FRAME_RTR = remote transmission request cyg_uint8 dlc; // data length code (number of bytes (0 - 8) containing valid data @@ -287,9 +305,9 @@ // this purpose the following structure is defined: // // Support flags: -// | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | -// +-------+-------+-------+-------+-------+-------+-------+--------+ -// | res | res | res |timest.|SW-Filt|FullCAN| Frametype | +// | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | +// +-------+-------+-------+-------+--------+-------+-------+--------+ +// | res | res | res |timest.|autobaud|FullCAN| Frametype | // typedef struct cyg_can_hdi_st { @@ -304,20 +322,92 @@ #define CYGNUM_CAN_HDI_FRAMETYPE_STD 0x00 // standard frame (11-bit identifier), 2.0A #define CYGNUM_CAN_HDI_FRAMETYPE_EXT_PASSIVE 0x01 // extended frame (29-bit identifier), 2.0B passive #define CYGNUM_CAN_HDI_FRAMETYPE_EXT_ACTIVE 0x02 // extended frame (29-bit identifier), 2.0B active +#define CYGNUM_CAN_HDI_FULLCAN 0x04 // controller supports more than one receive and transmit buffer +#define CYGNUM_CAN_HDI_AUTBAUD 0x08 // driver supports automatic baudrate detection +#define CYGNUM_CAN_HDI_TIMESTAMP 0x10 // driver supports timestamps + +//=========================================================================== +// CAN MESSAGE ACCESS MACROS // -// If the flag "FullCAN" is set to "1", the CAN controller has more than one -// receive buffer and one transmit buffer. +// An application should not access a cyg_can_message directly instead it +// should use these macros for all manipulations to a CAN message. +//=========================================================================== + +//--------------------------------------------------------------------------- +// Frame type macros // -#define CYGNUM_CAN_HDI_FULLCAN 0x04 +#define CYG_CAN_MSG_SET_FRAME_TYPE(_msg_, _type_) ((_msg_).rtr = (_type_)) +#define CYG_CAN_MSG_GET_FRAME_TYPE(_msg_) ((_msg_).rtr) +#define CYG_CAN_MSG_SET_RTR(_msg_) ((_msg_).rtr = CYGNUM_CAN_FRAME_RTR) +#define CYG_CAN_MSG_IS_REMOTE(_msg_) ((_msg_).rtr == CYGNUM_CAN_FRAME_RTR) + +//--------------------------------------------------------------------------- +// ID type macros // -// If the flag "Software ID-Filter" is set to "1", the driver has implemented -// the software ID filter for standard frames. If the member is set to "0", the -// software filter is not available. +#define CYG_CAN_MSG_SET_ID_TYPE(_msg_, _type_) ((_msg_).ext = (_type_)) +#define CYG_CAN_MSG_GET_ID_TYPE(_msg_) ((_msg_).ext) +#define CYG_CAN_MSG_SET_EXT(_msg_) ((_msg_).ext = CYGNUM_CAN_ID_EXT) +#define CYG_CAN_MSG_SET_STD(_msg_) ((_msg_).ext = CYGNUM_CAN_ID_STD) +#define CYG_CAN_MSG_IS_EXT(_msg_) ((_msg_).ext == CYGNUM_CAN_ID_EXT) + + +//--------------------------------------------------------------------------- +// Identifier access macros // -#define CYGNUM_CAN_HDI_FILT_SW 0x08 -#define CYGNUM_CAN_HDI_TIMESTAMP 0x10 +#define CYG_CAN_MSG_GET_ID(_msg_) ((_msg_).id) +#define CYG_CAN_MSG_SET_ID(_msg_, _id_) ((_msg_).id = (_id_)) +#define CYG_CAN_MSG_SET_STD_ID(_msg_, _id_) \ +CYG_MACRO_START \ + CYG_CAN_MSG_SET_ID(_msg_, _id_); \ + CYG_CAN_MSG_SET_STD(_msg_); \ +CYG_MACRO_END + +#define CYG_CAN_MSG_SET_EXT_ID(_msg_, _id_) \ +CYG_MACRO_START \ + CYG_CAN_MSG_SET_ID(_msg_, _id_); \ + CYG_CAN_MSG_SET_EXT(_msg_); \ +CYG_MACRO_END + + +//--------------------------------------------------------------------------- +// DLC (data length code) access macros +// +#define CYG_CAN_MSG_GET_DATA_LEN(_msg_) ((_msg_).dlc) +#define CYG_CAN_MSG_SET_DATA_LEN(_msg_, _len_) ((_msg_).dlc = (_len_)) + + +//--------------------------------------------------------------------------- +// CAN message data access +// This macro returns a pointer to a cyg_can_msg_data union +// +#define CYG_CAN_MSG_DATA_PTR(_msg_) (&(_msg_).data) +#define CYG_CAN_MSG_GET_DATA(_msg_, _pos_) ((_msg_).data.bytes[_pos_]) +#define CYG_CAN_MSG_SET_DATA(_msg_, _pos_, _val_) ((_msg_).data.bytes[_pos_] = (_val_)) + + +//--------------------------------------------------------------------------- +// Access multiple parameters +// +#define CYG_CAN_MSG_SET_PARAM(_msg_, _id_, _ext_, _dlc_, _rtr_) \ +CYG_MACRO_START \ + CYG_CAN_MSG_SET_ID(_msg_, _id_); \ + CYG_CAN_MSG_SET_ID_TYPE(_msg_, _ext_); \ + CYG_CAN_MSG_SET_DATA_LEN(_msg_, _dlc_); \ + CYG_CAN_MSG_SET_FRAME_TYPE(_msg_, _rtr_); \ +CYG_MACRO_END + +#define CYG_CAN_MSG_INIT(_clabel_, _id_, _ext_, _dlc_, _rtr_) \ +cyg_can_message _clabel_ = \ +{ \ + id : _id_, \ + ext : _ext_, \ + rtr : _rtr_, \ + dlc : _dlc_, \ +} + + #ifdef __cplusplus } diff -ruN -x 'Entries*' ecos_web_cvs/ecos/packages/io/can/current/src/can.c ecos/ecos/packages/io/can/current/src/can.c --- ecos_web_cvs/ecos/packages/io/can/current/src/can.c 2006-08-01 08:02:28.000000000 +0200 +++ ecos/ecos/packages/io/can/current/src/can.c 2007-02-20 21:27:05.000000000 +0100 @@ -236,12 +236,12 @@ // // there is enougth space left so we can store additional data // - cyg_can_message *ptxbuf = (cyg_can_message *)cbuf->pdata; - cyg_can_message *pbuf_message = &ptxbuf[cbuf->put]; + CYG_CAN_MSG_T *ptxbuf = (CYG_CAN_MSG_T *)cbuf->pdata; + CYG_CAN_MSG_T *pbuf_message = &ptxbuf[cbuf->put]; cyg_can_message *pmessage = (cyg_can_message *)_buf; - *pbuf_message = *pmessage; // copy message - + CYG_CAN_WRITE_MSG(pbuf_message, pmessage); // copy message + cbuf->put = (cbuf->put + 1) % cbuf->len; cbuf->data_cnt++; size -= sizeof(cyg_can_message); @@ -286,11 +286,11 @@ // if (cbuf->data_cnt > 0) { - cyg_can_event *prxbuf = (cyg_can_event *)cbuf->pdata; - cyg_can_event *pbuf_event = &prxbuf[cbuf->get]; - cyg_can_event *pevent = (cyg_can_event *)_buf; - - *pevent = *pbuf_event; // copy event + CYG_CAN_EVENT_T *prxbuf = (CYG_CAN_EVENT_T *)cbuf->pdata; + CYG_CAN_EVENT_T *pbuf_event = &prxbuf[cbuf->get]; + cyg_can_event *pevent = (cyg_can_event *)_buf; + + CYG_CAN_READ_EVENT(pevent, pbuf_event); // copy event cbuf->get = (cbuf->get + 1) % cbuf->len; cbuf->data_cnt--; @@ -693,8 +693,8 @@ //=========================================================================== static void can_rcv_event(can_channel *chan, void *pdata) { - can_cbuf_t *cbuf = &chan->in_cbuf; - cyg_can_event *prxbuf = (cyg_can_event *)cbuf->pdata; + can_cbuf_t *cbuf = &chan->in_cbuf; + CYG_CAN_EVENT_T *prxbuf = (CYG_CAN_EVENT_T *)cbuf->pdata; // // cbuf is a ring buffer - if the buffer is full, then we overwrite the @@ -743,8 +743,8 @@ { can_cbuf_t *cbuf = &chan->out_cbuf; can_lowlevel_funs *funs = chan->funs; - cyg_can_message *ptxbuf = (cyg_can_message *)cbuf->pdata; - cyg_can_message *pbuf_txmsg; + CYG_CAN_MSG_T *ptxbuf = (CYG_CAN_MSG_T *)cbuf->pdata; + CYG_CAN_MSG_T *pbuf_txmsg; // // transmit messages as long as there are messages in the buffer diff -ruN -x 'Entries*' ecos_web_cvs/ecos/packages/io/can/current/tests/can_filter.c ecos/ecos/packages/io/can/current/tests/can_filter.c --- ecos_web_cvs/ecos/packages/io/can/current/tests/can_filter.c 1970-01-01 01:00:00.000000000 +0100 +++ ecos/ecos/packages/io/can/current/tests/can_filter.c 2007-03-23 09:38:01.000000000 +0100 @@ -0,0 +1,307 @@ +//========================================================================== +// +// can_filter.c +// +// CAN message filter 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): Uwe Kindler +// Contributors: Uwe Kindler +// Date: 2007-03-21 +// Description: CAN hardware filter test +//####DESCRIPTIONEND#### + + +//=========================================================================== +// INCLUDES +//=========================================================================== +#include + +#include // test macros +#include // assertion macros +#include + +// Package requirements +#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL) + +#include +#include +#include + +// Package option requirements +#if defined(CYGFUN_KERNEL_API_C) + +#include // CYGNUM_HAL_STACK_SIZE_TYPICAL +#include + +// Package option requirements +#if defined (CYGOPT_IO_CAN_STD_CAN_ID) + + +//=========================================================================== +// DATA TYPES +//=========================================================================== +typedef struct st_thread_data +{ + cyg_thread obj; + long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL]; + cyg_handle_t hdl; +} thread_data_t; + + +//=========================================================================== +// LOCAL DATA +//=========================================================================== +cyg_thread_entry_t can0_thread; +thread_data_t can0_thread_data; + + +cyg_io_handle_t hCAN0; + + +//=========================================================================== +// LOCAL FUNCTIONS +//=========================================================================== +#include "can_test_aux.inl" // include CAN test auxiliary functions + + +//=========================================================================== +// Main thread +//=========================================================================== +void can0_thread(cyg_addrword_t data) +{ + cyg_uint32 len; + cyg_can_event rx_event; + cyg_uint8 i; + cyg_can_hdi hdi; + cyg_can_msgbuf_info msgbox_info; + cyg_can_msgbuf_cfg msgbox_cfg; + + + len = sizeof(hdi); + if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_HDI ,&hdi, &len)) + { + CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0"); + } + + // + // Normally the CAN modul should support message filters. So the + // FULLCAN flag should be set - if it is not, we treat this as an error + // + if (!(hdi.support_flags & CYGNUM_CAN_HDI_FULLCAN)) + { + CYG_TEST_FAIL_FINISH("/dev/can0 does not support message buffers"); + } + + + // + // Now reset message buffer configuration - this is mandatory bevore starting + // message buffer runtime configuration + // + msgbox_cfg.cfg_id = CYGNUM_CAN_MSGBUF_RESET_ALL; + len = sizeof(msgbox_cfg); + if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&msgbox_cfg, &len)) + { + CYG_TEST_FAIL_FINISH("Error resetting message buffer configuration of /dev/can0"); + } + + // + // Now query number of available and free message boxes + // + len = sizeof(msgbox_info); + if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len)) + { + CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0"); + } + + // + // if there are no free message boxes available then this is a failure + // + if (!msgbox_info.free) + { + CYG_TEST_FAIL_FINISH("No free message boxes available for /dev/can0"); + } + + // + // We setup as many standard CAN message filters as there are free + // message buffers available. + // + for (i = 0; i < msgbox_info.free; ++i) + { + cyg_can_filter rx_filter; + + rx_filter.cfg_id = CYGNUM_CAN_MSGBUF_RX_FILTER_ADD; + rx_filter.msg.id = i; + rx_filter.msg.ext = CYGNUM_CAN_ID_STD; + + len = sizeof(rx_filter); + if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&rx_filter, &len)) + { + CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0"); + } + else if (CYGNUM_CAN_MSGBUF_NA == rx_filter.handle) + { + CYG_TEST_FAIL_FINISH("Error setting up message filter for /dev/can0"); + } + } + + + diag_printf("\n\nNow try to send CAN messages. The device should only\n" + "receive messages identifiers in the range of 0x00 to 0x%X.\n" + "As soon as a standard message with ID 0x000 arrives, all\n" + "message filters will be cleared\n\n", (msgbox_info.free - 1)); + + // + // Now receive messages until a message arrives with largest ID of all + // available message filters + // + rx_event.msg.id = 1; + while(rx_event.msg.id != 0) + { + len = sizeof(rx_event); + + if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len)) + { + CYG_TEST_FAIL_FINISH("Error reading from /dev/can0"); + } + else if (rx_event.flags & CYGNUM_CAN_EVENT_RX) + { + print_can_msg(&rx_event.msg, ""); + } // if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len)) + else + { + print_can_flags(rx_event.flags, ""); + rx_event.msg.id = 1; + } + } // while(1) + + + // + // Now enable reception of all available CAN messages + // + cyg_can_filter rx_filter; + rx_filter.cfg_id = CYGNUM_CAN_MSGBUF_RX_FILTER_ALL; + len = sizeof(rx_filter); + if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF , &rx_filter, &len)) + { + CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0"); + } + + + diag_printf("\n\nAll message filters have been cleared an now the device\n" + "will receive any available CAN message identifiers.\n" + "Send a CAN message with ID 0x100 to stop this test.\n\n"); + + // + // Now receive messages until a message arrives with largest ID of all + // available message filters + // + rx_event.msg.id = 1; + while(rx_event.msg.id != 0x100) + { + len = sizeof(rx_event); + + if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len)) + { + CYG_TEST_FAIL_FINISH("Error reading from /dev/can0"); + } + else if (rx_event.flags & CYGNUM_CAN_EVENT_RX) + { + print_can_msg(&rx_event.msg, ""); + } // if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len)) + } // while(1) + + CYG_TEST_PASS_FINISH("can_filter test OK"); +} + + +void +cyg_start(void) +{ + CYG_TEST_INIT(); + + // + // open CAN device driver + // + if (ENOERR != cyg_io_lookup("/dev/can0", &hCAN0)) + { + CYG_TEST_FAIL_FINISH("Error opening /dev/can0"); + } + + + // + // create the two threads which access the CAN device driver + // a reader thread with a higher priority and a writer thread + // with a lower priority + // + cyg_thread_create(4, can0_thread, + (cyg_addrword_t) 0, + "can0_thread", + (void *) can0_thread_data.stack, + 1024 * sizeof(long), + &can0_thread_data.hdl, + &can0_thread_data.obj); + + cyg_thread_resume(can0_thread_data.hdl); + + cyg_scheduler_start(); +} + +#else // CYGOPT_IO_CAN_STD_CAN_ID +#define N_A_MSG "Needs support for standard CAN identifiers" +#endif + +#else // CYGFUN_KERNEL_API_C +#define N_A_MSG "Needs kernel C API" +#endif + +#else // CYGPKG_IO_CAN && CYGPKG_KERNEL +#define N_A_MSG "Needs IO/CAN 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 can_filter.c diff -ruN -x 'Entries*' ecos_web_cvs/ecos/packages/io/can/current/tests/can_hdi.c ecos/ecos/packages/io/can/current/tests/can_hdi.c --- ecos_web_cvs/ecos/packages/io/can/current/tests/can_hdi.c 1970-01-01 01:00:00.000000000 +0100 +++ ecos/ecos/packages/io/can/current/tests/can_hdi.c 2007-03-23 09:37:42.000000000 +0100 @@ -0,0 +1,235 @@ +//========================================================================== +// +// can_hdi.c +// +// CAN hardware description information 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): Uwe Kindler +// Contributors: Uwe Kindler +// Date: 2007-03-22 +// Description: CAN hardware desciption information test +//####DESCRIPTIONEND#### + + +//=========================================================================== +// INCLUDES +//=========================================================================== +#include + +#include // test macros +#include // assertion macros +#include + +// Package requirements +#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL) + +#include +#include +#include + +// Package option requirements +#if defined(CYGFUN_KERNEL_API_C) + +#include // CYGNUM_HAL_STACK_SIZE_TYPICAL +#include + + +//=========================================================================== +// DATA TYPES +//=========================================================================== +typedef struct st_thread_data +{ + cyg_thread obj; + long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL]; + cyg_handle_t hdl; +} thread_data_t; + + +//=========================================================================== +// LOCAL DATA +//=========================================================================== +cyg_thread_entry_t can0_thread; +thread_data_t can0_thread_data; + + +cyg_io_handle_t hCAN0; + + +//=========================================================================== +// LOCAL FUNCTIONS +//=========================================================================== +#include "can_test_aux.inl" // include CAN test auxiliary functions + + +//=========================================================================== +// Main thread +//=========================================================================== +void can0_thread(cyg_addrword_t data) +{ + cyg_uint32 len; + cyg_can_hdi hdi; + cyg_can_msgbuf_info msgbox_info; + + + // + // Query information about hardware of CAN controller + // + len = sizeof(hdi); + if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_HDI ,&hdi, &len)) + { + CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0"); + } + + // + // Check type of CAN controller - type of supported CAN frames + // + diag_printf("\n\nSupported message formats:\n"); + if (hdi.support_flags & CYGNUM_CAN_HDI_FRAMETYPE_STD) + { + diag_printf(" Standard CAN (2.0A): yes\n"); + diag_printf(" Extended CAN (2.0B): no\n"); + } + else if (hdi.support_flags & CYGNUM_CAN_HDI_FRAMETYPE_EXT_PASSIVE) + { + diag_printf(" Standard CAN (2.0A): yes\n"); + diag_printf(" Extended CAN (2.0B): passive\n"); + } + else if (hdi.support_flags & CYGNUM_CAN_HDI_FRAMETYPE_EXT_ACTIVE) + { + diag_printf(" Standard CAN (2.0A): yes\n"); + diag_printf(" Extended CAN (2.0B): yes\n"); + } + + // + // Check if this is a FullCAN controller + // + diag_printf("\nController type: "); + if (hdi.support_flags & CYGNUM_CAN_HDI_FULLCAN) + { + diag_printf("FullCAN\n"); + // + // FullCAN means the controller supports a number of message buffers. + // Now query number of available and free message buffers + // + len = sizeof(msgbox_info); + if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len)) + { + CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0"); + } + + diag_printf(" Message buffers: %d\n", msgbox_info.count); + diag_printf(" Message buffers free: %d\n", msgbox_info.free); + } + else + { + diag_printf("BasicCAN\n"); + } + + // + // Check if automatic baudrate detection is supported + // + if (hdi.support_flags & CYGNUM_CAN_HDI_AUTBAUD) + { + diag_printf("\nAutomatic baudrate detection: supported\n"); + } + + // + // Check if driver supports timestamps + // + if (hdi.support_flags & CYGNUM_CAN_HDI_TIMESTAMP) + { + diag_printf("Timestamps: supported\n"); + } + + diag_printf("\n\n"); + CYG_TEST_PASS_FINISH("can_hdi test OK"); +} + + +void +cyg_start(void) +{ + CYG_TEST_INIT(); + + // + // open CAN device driver + // + if (ENOERR != cyg_io_lookup("/dev/can0", &hCAN0)) + { + CYG_TEST_FAIL_FINISH("Error opening /dev/can0"); + } + + + // + // create the two threads which access the CAN device driver + // a reader thread with a higher priority and a writer thread + // with a lower priority + // + cyg_thread_create(4, can0_thread, + (cyg_addrword_t) 0, + "can0_thread", + (void *) can0_thread_data.stack, + 1024 * sizeof(long), + &can0_thread_data.hdl, + &can0_thread_data.obj); + + cyg_thread_resume(can0_thread_data.hdl); + + cyg_scheduler_start(); +} + +#else // CYGFUN_KERNEL_API_C +#define N_A_MSG "Needs kernel C API" +#endif + +#else // CYGPKG_IO_CAN && CYGPKG_KERNEL +#define N_A_MSG "Needs IO/CAN 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 can_hdi.c diff -ruN -x 'Entries*' ecos_web_cvs/ecos/packages/io/can/current/tests/can_load.c ecos/ecos/packages/io/can/current/tests/can_load.c --- ecos_web_cvs/ecos/packages/io/can/current/tests/can_load.c 1970-01-01 01:00:00.000000000 +0100 +++ ecos/ecos/packages/io/can/current/tests/can_load.c 2007-03-23 09:37:28.000000000 +0100 @@ -0,0 +1,308 @@ +//========================================================================== +// +// can_load.c +// +// CAN load 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): Uwe Kindler +// Contributors: Uwe Kindler +// Date: 2005-08-14 +// Description: CAN load test +//####DESCRIPTIONEND#### + + +//=========================================================================== +// INCLUDES +//=========================================================================== +#include + +#include // test macros +#include // assertion macros +#include + +// Package requirements +#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL) + +#include +#include +#include + +// Package option requirements +#if defined(CYGFUN_KERNEL_API_C) + +#include // CYGNUM_HAL_STACK_SIZE_TYPICAL +#include + +// Package option requirements +#if defined(CYGOPT_IO_CAN_STD_CAN_ID) && defined(CYGOPT_IO_CAN_EXT_CAN_ID) + + +//=========================================================================== +// DATA TYPES +//=========================================================================== +typedef struct st_thread_data +{ + cyg_thread obj; + long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL]; + cyg_handle_t hdl; +} thread_data_t; + + +//=========================================================================== +// LOCAL DATA +//=========================================================================== +cyg_thread_entry_t can0_thread; +thread_data_t can0_thread_data; + +cyg_thread_entry_t can1_thread; +thread_data_t can1_thread_data; + +cyg_io_handle_t hCAN0; + + +//=========================================================================== +// LOCAL FUNCTIONS +//=========================================================================== +#include "can_test_aux.inl" // include CAN test auxiliary functions + + +//=========================================================================== +// Main thread +//=========================================================================== +void can0_thread(cyg_addrword_t data) +{ + cyg_uint32 len; + cyg_can_event rx_event; + cyg_can_timeout_info_t timeouts; + +#if defined(CYGOPT_IO_CAN_SUPPORT_TIMEOUTS) + // + // setup large timeout values because we do not need timeouts here + // + timeouts.rx_timeout = 100000; + timeouts.tx_timeout = 100000; + + len = sizeof(timeouts); + if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_TIMEOUT ,&timeouts, &len)) + { + CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0"); + } +#endif // defined(CYGOPT_IO_CAN_SUPPORT_TIMEOUTS) + + // + // This thread simply receives all CAN events and prints the event flags and the + // CAN message if it was a TX or RX event. You can use this test in order to check + // when a RX overrun occurs + // + while (1) + { + len = sizeof(rx_event); + + if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len)) + { + CYG_TEST_FAIL_FINISH("Error reading from /dev/can0"); + } + else + { + print_can_flags(rx_event.flags, ""); + + if ((rx_event.flags & CYGNUM_CAN_EVENT_RX) || (rx_event.flags & CYGNUM_CAN_EVENT_TX)) + { + print_can_msg(&rx_event.msg, ""); + } + } + } +} + + +//=========================================================================== +// WRITER THREAD +//=========================================================================== +void can1_thread(cyg_addrword_t data) +{ + cyg_uint16 i = 0; + cyg_uint32 len; + cyg_can_message tx_msg = + { + 0x000, // CAN identifier + data : + { + {0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 } // 8 data bytes + }, + CYGNUM_CAN_ID_STD, // standard frame + CYGNUM_CAN_FRAME_DATA, // data frame + 8, // data length code + }; + + // + // This thread simply sends CAN messages. It increments the ID for each new CAN messsage + // and sends a remote frame after seven data frames. In the first byte of each data frame + // the number (0 - 7) of the data frame is stored and the length of the data frame grows + // from 1 - 8 data bytes. + // + // The received pattern should look like this way: + // ID Length Data + // ---------------------------------------------- + // 000 1 00 + // 001 2 01 F1 + // 002 3 02 F1 F2 + // 003 4 03 F1 F2 F3 + // 004 5 04 F1 F2 F3 F4 + // 005 6 05 F1 F2 F3 F4 F5 + // 006 7 06 F1 F2 F3 F4 F5 F6 + // 007 8 Remote Request + // 008 1 00 + // 009 2 01 F1 + // 00A 3 02 F1 F2 + // ... + // + while (1) + { + tx_msg.id = i; + tx_msg.dlc = (i % 8) + 1; + tx_msg.data.bytes[0] = (i % 8); + i = (i + 1) % 0x7FF; + + // + // the 6th frame is a remote frame + // + if ((i % 8) == 6) + { + tx_msg.rtr = CYGNUM_CAN_FRAME_RTR; + tx_msg.ext = CYGNUM_CAN_ID_STD; + } + // + // the 7th frame is a extended frame + // + else if ((i % 8) == 7) + { + tx_msg.ext = CYGNUM_CAN_ID_EXT; + tx_msg.rtr = CYGNUM_CAN_FRAME_DATA; + } + // + // the 8th frame is a extended remote frame + // + else if (!(i % 8)) + { + tx_msg.ext = CYGNUM_CAN_ID_EXT; + tx_msg.rtr = CYGNUM_CAN_FRAME_RTR; + } + // + // all other frames are standard data frames + // + else + { + tx_msg.ext = CYGNUM_CAN_ID_STD; + tx_msg.rtr = CYGNUM_CAN_FRAME_DATA; + } + + len = sizeof(tx_msg); + if (ENOERR != cyg_io_write(hCAN0, &tx_msg, &len)) + { + CYG_TEST_FAIL_FINISH("Error writing to /dev/can0"); + } + + cyg_thread_delay(50); + } // while (1) +} + + + +void +cyg_start(void) +{ + CYG_TEST_INIT(); + + // + // open CAN device driver + // + if (ENOERR != cyg_io_lookup("/dev/can0", &hCAN0)) + { + CYG_TEST_FAIL_FINISH("Error opening /dev/can0"); + } + + // + // create the two threads which access the CAN device driver + // a reader thread with a higher priority and a writer thread + // with a lower priority + // + cyg_thread_create(4, can0_thread, + (cyg_addrword_t) 0, + "can0_thread", + (void *) can0_thread_data.stack, + 1024 * sizeof(long), + &can0_thread_data.hdl, + &can0_thread_data.obj); + + cyg_thread_create(5, can1_thread, + (cyg_addrword_t) can0_thread_data.hdl, + "can1_thread", + (void *) can1_thread_data.stack, + 1024 * sizeof(long), + &can1_thread_data.hdl, + &can1_thread_data.obj); + + cyg_thread_resume(can0_thread_data.hdl); + cyg_thread_resume(can1_thread_data.hdl); + + cyg_scheduler_start(); +} + +#else // defined(CYGOPT_IO_CAN_STD_CAN_ID) && defined(CYGOPT_IO_CAN_EXT_CAN_ID) +#define N_A_MSG "Needs support for standard and extended CAN identifiers" +#endif + +#else // CYGFUN_KERNEL_API_C +#define N_A_MSG "Needs kernel C API" +#endif + +#else // CYGPKG_IO_CAN && CYGPKG_KERNEL +#define N_A_MSG "Needs IO/CAN 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 can_load.c diff -ruN -x 'Entries*' ecos_web_cvs/ecos/packages/io/can/current/tests/can_remote.c ecos/ecos/packages/io/can/current/tests/can_remote.c --- ecos_web_cvs/ecos/packages/io/can/current/tests/can_remote.c 1970-01-01 01:00:00.000000000 +0100 +++ ecos/ecos/packages/io/can/current/tests/can_remote.c 2007-03-23 09:37:15.000000000 +0100 @@ -0,0 +1,312 @@ +//========================================================================== +// +// can_remote.c +// +// CAN remote response buffer 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): Uwe Kindler +// Contributors: Uwe Kindler +// Date: 2005-08-14 +// Description: CAN load test +//####DESCRIPTIONEND#### + + +//=========================================================================== +// INCLUDES +//=========================================================================== +#include + +#include // test macros +#include // assertion macros +#include + +// Package requirements +#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL) + +#include +#include +#include + +// Package option requirements +#if defined(CYGFUN_KERNEL_API_C) + +#include // CYGNUM_HAL_STACK_SIZE_TYPICAL +#include + +// Package option requirements +#if defined(CYGOPT_IO_CAN_RUNTIME_MBOX_CFG) + +// Package option requirements +#if defined(CYGOPT_IO_CAN_REMOTE_BUF) + + +//=========================================================================== +// DATA TYPES +//=========================================================================== +typedef struct st_thread_data +{ + cyg_thread obj; + long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL]; + cyg_handle_t hdl; +} thread_data_t; + + +//=========================================================================== +// LOCAL DATA +//=========================================================================== +cyg_thread_entry_t can0_thread; +thread_data_t can0_thread_data; +cyg_io_handle_t hCAN0; + + +//=========================================================================== +// LOCAL FUNCTIONS +//=========================================================================== +#include "can_test_aux.inl" // include CAN test auxiliary functions + + +//=========================================================================== +// Main thread +//=========================================================================== +void can0_thread(cyg_addrword_t data) +{ + cyg_uint32 len; + cyg_can_event rx_event; + cyg_can_remote_buf rtr_buf; + cyg_can_filter rx_filter; + cyg_can_msgbuf_info msgbox_info; + cyg_can_msgbuf_cfg msgbox_cfg; + + // + // We would like to setup 2 remote buffers - check if we have enough + // free message buffers + // + len = sizeof(msgbox_info); + if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len)) + { + CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0"); + } + else + { + diag_printf("\n\n\nMessage boxes available: %d free: %d\n", + msgbox_info.count, msgbox_info.free); + } + + // + // We have not enougth free message buffers, so we clear all message buffers now + // and try again + // + if (msgbox_info.free < 2) + { + msgbox_cfg.cfg_id = CYGNUM_CAN_MSGBUF_RESET_ALL; + len = sizeof(msgbox_cfg); + if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF, &msgbox_cfg, &len)) + { + CYG_TEST_FAIL_FINISH("Error clearing message buffers of /dev/can0"); + } + + // + // Now query number of free message boxes again. We need 3 free message boxes. + // 2 message boxes for setup of remote response buffers and 1 message box for + // setup of receive message box for CAN identifier 0x100 + // + len = sizeof(msgbox_info); + if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len)) + { + CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0"); + } + else + { + diag_printf("Message boxes available: %d free: %d\n", + msgbox_info.count, msgbox_info.free); + } + + if (msgbox_info.free < 3) + { + CYG_TEST_FAIL_FINISH("Not enough free message buffers available for /dev/can0"); + } + else + { + rx_filter.cfg_id = CYGNUM_CAN_MSGBUF_RX_FILTER_ADD; + CYG_CAN_MSG_SET_STD_ID(rx_filter.msg, 0x100); + + len = sizeof(rx_filter); + if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&rx_filter, &len)) + { + CYG_TEST_FAIL_FINISH("Error adding rx filter for CAN ID 0x100 for /dev/can0"); + } + } // if (msgbox_info.free < 3) + } // if (msgbox_info.free < 2) +#ifdef CYGOPT_IO_CAN_STD_CAN_ID + // + // Setup the first remote response buffer for resception of standard + // remote frames + // + rtr_buf.cfg_id = CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD; + CYG_CAN_MSG_SET_PARAM(rtr_buf.msg, 0x7FF, CYGNUM_CAN_ID_STD, 1, CYGNUM_CAN_FRAME_DATA); + CYG_CAN_MSG_SET_DATA(rtr_buf.msg, 0, 0xAB); + + len = sizeof(rtr_buf); + if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&rtr_buf, &len)) + { + CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0"); + } +#endif + +#ifdef CYGOPT_IO_CAN_EXT_CAN_ID + cyg_can_remote_buf rtr_buf2; + // + // setup the second remote response buffer for reception of extended + // remote frames + // + rtr_buf2.cfg_id = CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD; + CYG_CAN_MSG_SET_PARAM(rtr_buf2.msg, 0x800, CYGNUM_CAN_ID_EXT, 4, CYGNUM_CAN_FRAME_DATA); + CYG_CAN_MSG_SET_DATA(rtr_buf2.msg, 0, 0xCD); + + len = sizeof(rtr_buf2); + if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&rtr_buf2, &len)) + { + CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0"); + } + + if (rtr_buf.handle == CYGNUM_CAN_MSGBUF_NA) + { + CYG_TEST_FAIL_FINISH("No free message buffer available for /dev/can0"); + } +#endif + + diag_printf("\nTest of CAN remote response buffer configuration\n" + "If a CAN node sends a remote request with ID 0x7FF (std. ID)\n" + "or 0x800 (ext. ID) then the CAN driver should respond with\n" + "data frames.\n\n"); + diag_printf("!!! This test can be stopped by sending a data frame\n" + "with ID 0x100 !!!\n\n"); + + len = sizeof(msgbox_info); + if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len)) + { + CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0"); + } + else + { + diag_printf("Message boxes available: %d free: %d\n", + msgbox_info.count, msgbox_info.free); + } + + while (1) + { + len = sizeof(rx_event); + + if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len)) + { + CYG_TEST_FAIL_FINISH("Error reading from /dev/can0"); + } + + if (0x100 == rx_event.msg.id) + { + CYG_TEST_PASS_FINISH("can_remote test OK"); + } + else + { + print_can_flags(rx_event.flags, ""); + + if (rx_event.flags & CYGNUM_CAN_EVENT_RX) + { + print_can_msg(&rx_event.msg, ""); + } + } + } +} + + +void +cyg_start(void) +{ + CYG_TEST_INIT(); + + // + // open CAN device driver + // + if (ENOERR != cyg_io_lookup("/dev/can0", &hCAN0)) + { + CYG_TEST_FAIL_FINISH("Error opening /dev/can0"); + } + + // + // create the thread that accesses the CAN device driver + // + cyg_thread_create(4, can0_thread, + (cyg_addrword_t) 0, + "can0_thread", + (void *) can0_thread_data.stack, + 1024 * sizeof(long), + &can0_thread_data.hdl, + &can0_thread_data.obj); + + cyg_thread_resume(can0_thread_data.hdl); + + cyg_scheduler_start(); +} + +#else // CYGOPT_IO_CAN_REMOTE_BUF +#define N_A_MSG "Needs support for CAN remote response buffers" +#endif + +#else // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG +#define N_A_MSG "Needs support for CAN message buffer runtime configuration" +#endif + +#else // CYGFUN_KERNEL_API_C +#define N_A_MSG "Needs kernel C API" +#endif + +#else // CYGPKG_IO_CAN && CYGPKG_KERNEL +#define N_A_MSG "Needs IO/CAN 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 can_remote.c diff -ruN -x 'Entries*' ecos_web_cvs/ecos/packages/io/can/current/tests/can_test_aux.inl ecos/ecos/packages/io/can/current/tests/can_test_aux.inl --- ecos_web_cvs/ecos/packages/io/can/current/tests/can_test_aux.inl 1970-01-01 01:00:00.000000000 +0100 +++ ecos/ecos/packages/io/can/current/tests/can_test_aux.inl 2007-03-04 10:46:54.000000000 +0100 @@ -0,0 +1,148 @@ +//========================================================================== +// +// can_test_aux.inl +// +// CAN test auxiliary functions +// +//========================================================================== +//####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): Uwe Kindler +// Contributors: Uwe Kindler +// Date: 2005-08-07 +// Description: Auxiliary functions for CAN driver tests +//####DESCRIPTIONEND#### + + +//=========================================================================== +// PRINT CAN EVENT +//=========================================================================== +void print_can_msg(cyg_can_message *pmsg, char *pMsg) +{ + char *pmsg_str; + static char* msg_tbl[] = + { + "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:]\n", + "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X]\n", + "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X]\n", + "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X]\n", + "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X]\n", + "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X]\n", + "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X %02X]\n", + "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X %02X %02X]\n", + "%s [ID:%03X] [RTR:%d] [EXT:%d] [DATA:%02X %02X %02X %02X %02X %02X %02X %02X]\n" + }; + + if (pmsg->rtr) + { + diag_printf("%s [ID:%03X] [RTR:%d] [EXT:%d] [DLC:%d]\n", + pMsg, + pmsg->id, + pmsg->rtr, + pmsg->ext, + pmsg->dlc); + + return; + } + + if (pmsg->dlc > 8) + { + pmsg_str = msg_tbl[8]; + } + else + { + pmsg_str = msg_tbl[pmsg->dlc]; + } + + diag_printf(pmsg_str, + pMsg, + pmsg->id, + pmsg->rtr, + pmsg->ext, + pmsg->data.bytes[0], + pmsg->data.bytes[1], + pmsg->data.bytes[2], + pmsg->data.bytes[3], + pmsg->data.bytes[4], + pmsg->data.bytes[5], + pmsg->data.bytes[6], + pmsg->data.bytes[7]); +} + + +//=========================================================================== +// PRINT CAN EVENT FLAGS +//=========================================================================== +void print_can_flags(cyg_uint16 flags, char *pMsg) +{ + char *pmsg_str; + cyg_uint8 i ; + static char* msg_tbl[] = + { + "RX ", + "TX ", + "WRX ", + "WTX ", + "ERRP ", + "BOFF ", + "OVRX ", + "OVTX ", + "CERR ", + "LSTY ", + "ESTY ", + "ALOS ", + "DEVC ", + "PHYF ", + "PHYH ", + "PHYL " + }; + i = 0; + while (flags && (i < 16)) + { + if (flags & 0x0001) + { + pmsg_str = msg_tbl[i]; + diag_printf(pmsg_str); + } + flags >>=1; + i++; + } + + diag_printf("\n"); +} + +//--------------------------------------------------------------------------- +// end of can_test_aux.inl diff -ruN -x 'Entries*' ecos_web_cvs/ecos/packages/io/can/current/tests/can_tx.c ecos/ecos/packages/io/can/current/tests/can_tx.c --- ecos_web_cvs/ecos/packages/io/can/current/tests/can_tx.c 1970-01-01 01:00:00.000000000 +0100 +++ ecos/ecos/packages/io/can/current/tests/can_tx.c 2007-03-04 11:26:42.000000000 +0100 @@ -0,0 +1,230 @@ +//========================================================================== +// +// can_tx.c +// +// Simple CAN TX 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): Uwe Kindler +// Contributors: Uwe Kindler +// Date: 2007-01-08 +// Description: Simple write test of CAN driver +//####DESCRIPTIONEND#### + + +//=========================================================================== +// INCLUDES +//=========================================================================== +#include + +#include // test macros +#include // assertion macros +#include +#include + +// Package requirements +#if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL) + +#include +#include +#include + +// Package option requirements +#if defined(CYGFUN_KERNEL_API_C) + +#include // CYGNUM_HAL_STACK_SIZE_TYPICAL +#include + + +//=========================================================================== +// DATA TYPES +//=========================================================================== +typedef struct st_thread_data +{ + cyg_thread obj; + long stack[CYGNUM_HAL_STACK_SIZE_TYPICAL]; + cyg_handle_t hdl; +} thread_data_t; + + +//=========================================================================== +// LOCAL DATA +//=========================================================================== +cyg_thread_entry_t can0_thread; +thread_data_t can0_thread_data; + + +//=========================================================================== +// LOCAL FUNCTIONS +//=========================================================================== +#include "can_test_aux.inl" // include CAN test auxiliary functions + + +//=========================================================================== +// WRITER THREAD +//=========================================================================== +void can0_thread(cyg_addrword_t data) +{ + cyg_io_handle_t hCAN0; + cyg_uint32 i; + cyg_uint32 len; + CYG_CAN_MSG_INIT(tx_msg, 0x001, CYGNUM_CAN_ID_STD, 1, CYGNUM_CAN_FRAME_DATA); + + // + // Open device and check return value + // + if (ENOERR != cyg_io_lookup("/dev/can0", &hCAN0)) + { + CYG_TEST_FAIL_FINISH("Error opening /dev/can0"); + } + +#ifdef CYGOPT_IO_CAN_STD_CAN_ID + // + // Now send 1000 messages with standard identifier. + // Each message contains the message number in its identifier + // and in the first data byte + // + for (i = 0; i < 1000; ++i) + { + CYG_CAN_MSG_SET_STD_ID(tx_msg, i); + CYG_CAN_MSG_SET_DATA(tx_msg, 0, i); + len = sizeof(tx_msg); + + // + // Each message with an odd identifier should be a remote request message + // + if (i % 2) + { + CYG_CAN_MSG_SET_FRAME_TYPE(tx_msg, CYGNUM_CAN_FRAME_RTR); + } + else + { + CYG_CAN_MSG_SET_FRAME_TYPE(tx_msg, CYGNUM_CAN_FRAME_DATA); + } + + // + // Sending CAN messages is blocking so the thread waits until there is + // space in the tx queue + // + if (ENOERR != cyg_io_write(hCAN0, &tx_msg, &len)) + { + CYG_TEST_FAIL_FINISH("Error writing to /dev/can0"); + } + } +#endif + +#ifdef CYGOPT_IO_CAN_EXT_CAN_ID + // + // Now send 1000 messages with extended identifier. + // Each message contains the message number in its identifier + // and in the first data byte + // + for (i = 0; i < 1000; ++i) + { + CYG_CAN_MSG_SET_EXT_ID(tx_msg, i + 0x800); + CYG_CAN_MSG_SET_DATA(tx_msg, 0, i); + CYG_CAN_MSG_SET_DATA_LEN(tx_msg, 8); + len = sizeof(tx_msg); + + // + // Each message with an odd identifier should be a remote request message + // + if (i % 2) + { + CYG_CAN_MSG_SET_FRAME_TYPE(tx_msg, CYGNUM_CAN_FRAME_RTR); + } + else + { + CYG_CAN_MSG_SET_FRAME_TYPE(tx_msg, CYGNUM_CAN_FRAME_DATA); + } + + // + // Sending CAN messages is blocking so the thread waits until there is + // space in the tx queue + // + if (ENOERR != cyg_io_write(hCAN0, &tx_msg, &len)) + { + CYG_TEST_FAIL_FINISH("Error writing to /dev/can0"); + } + } +#endif + + + CYG_TEST_PASS_FINISH("CAN TX test OK"); +} + + +void +cyg_start(void) +{ + CYG_TEST_INIT(); + + // + // create the threads that access the CAN device driver + // + cyg_thread_create(4, can0_thread, + (cyg_addrword_t) 0, + "can0_thread", + (void *) can0_thread_data.stack, + 1024 * sizeof(long), + &can0_thread_data.hdl, + &can0_thread_data.obj); + + cyg_thread_resume(can0_thread_data.hdl); + + cyg_scheduler_start(); +} + +#else // CYGFUN_KERNEL_API_C +#define N_A_MSG "Needs kernel C API" +#endif + +#else // CYGPKG_IO_CAN && CYGPKG_KERNEL +#define N_A_MSG "Needs IO/CAN 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 can_tx.c