]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/io/can/v2_0/tests/can_remote.c
Initial revision
[karo-tx-redboot.git] / packages / io / can / v2_0 / tests / can_remote.c
1 //==========================================================================
2 //
3 //        can_remote.c
4 //
5 //        CAN remote response buffer test
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
42 //
43 // Author(s):     Uwe Kindler
44 // Contributors:  Uwe Kindler
45 // Date:          2005-08-14
46 // Description:   CAN load test
47 //####DESCRIPTIONEND####
48
49
50 //===========================================================================
51 //                                INCLUDES
52 //===========================================================================
53 #include <pkgconf/system.h>
54
55 #include <cyg/infra/testcase.h>         // test macros
56 #include <cyg/infra/cyg_ass.h>          // assertion macros
57 #include <cyg/infra/diag.h>
58
59 // Package requirements
60 #if defined(CYGPKG_IO_CAN) && defined(CYGPKG_KERNEL)
61
62 #include <pkgconf/kernel.h>
63 #include <cyg/io/io.h>
64 #include <cyg/io/canio.h>
65
66 // Package option requirements
67 #if defined(CYGFUN_KERNEL_API_C)
68
69 #include <cyg/hal/hal_arch.h>           // CYGNUM_HAL_STACK_SIZE_TYPICAL
70 #include <cyg/kernel/kapi.h>
71
72 // Package option requirements
73 #if defined(CYGOPT_IO_CAN_RUNTIME_MBOX_CFG)
74
75 // Package option requirements
76 #if defined(CYGOPT_IO_CAN_REMOTE_BUF)
77
78
79 //===========================================================================
80 //                               DATA TYPES
81 //===========================================================================
82 typedef struct st_thread_data
83 {
84     cyg_thread   obj;
85     long         stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
86     cyg_handle_t hdl;
87 } thread_data_t;
88
89
90 //===========================================================================
91 //                              LOCAL DATA
92 //===========================================================================
93 cyg_thread_entry_t can0_thread;
94 thread_data_t      can0_thread_data;
95 cyg_io_handle_t    hCAN0;
96
97
98 //===========================================================================
99 //                          LOCAL FUNCTIONS
100 //===========================================================================
101 #include "can_test_aux.inl" // include CAN test auxiliary functions
102
103
104 //===========================================================================
105 // Main thread
106 //===========================================================================
107 void can0_thread(cyg_addrword_t data)
108 {
109     cyg_uint32             len;
110     cyg_can_event          rx_event;
111     cyg_can_remote_buf     rtr_buf;
112     cyg_can_filter         rx_filter;
113     cyg_can_msgbuf_info    msgbox_info; 
114     cyg_can_msgbuf_cfg     msgbox_cfg;
115
116     //
117     // We would like to setup 2 remote buffers - check if we have enough
118     // free message buffers
119     //
120     len = sizeof(msgbox_info);
121     if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len))
122     {
123         CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0");
124     } 
125     else
126     {
127         diag_printf("\n\n\nMessage boxes available: %d    free: %d\n", 
128                     msgbox_info.count, msgbox_info.free);
129     }
130     
131     //
132     // We have not enougth free message buffers, so we clear all message buffers now
133     // and try again
134     //
135     if (msgbox_info.free < 2)
136     {
137         msgbox_cfg.cfg_id = CYGNUM_CAN_MSGBUF_RESET_ALL;
138         len = sizeof(msgbox_cfg);
139         if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF, &msgbox_cfg, &len))
140         {
141             CYG_TEST_FAIL_FINISH("Error clearing message buffers of /dev/can0");    
142         }
143         
144         //
145         // Now query number of free message boxes again. We need 3 free message boxes.
146         // 2 message boxes for setup of remote response buffers and 1 message box for
147         // setup of receive message box for CAN identifier 0x100
148         //
149         len = sizeof(msgbox_info);
150         if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len))
151         {
152             CYG_TEST_FAIL_FINISH("Error reading config of /dev/can0");
153         } 
154         else
155         {
156             diag_printf("Message boxes available: %d    free: %d\n", 
157                         msgbox_info.count, msgbox_info.free);    
158         }
159         
160         if (msgbox_info.free < 3)
161         {
162             CYG_TEST_FAIL_FINISH("Not enough free message buffers available for /dev/can0");    
163         }
164         else
165         {
166             rx_filter.cfg_id = CYGNUM_CAN_MSGBUF_RX_FILTER_ADD;
167             CYG_CAN_MSG_SET_STD_ID(rx_filter.msg, 0x100);
168             
169             len = sizeof(rx_filter);
170             if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&rx_filter, &len))
171             {
172                 CYG_TEST_FAIL_FINISH("Error adding rx filter for CAN ID 0x100 for /dev/can0");
173             } 
174         } // if (msgbox_info.free < 3)
175     } // if (msgbox_info.free < 2)
176 #ifdef CYGOPT_IO_CAN_STD_CAN_ID
177     //
178     // Setup the first remote response buffer for resception of standard
179     // remote frames
180     //
181     rtr_buf.cfg_id      = CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD;
182     CYG_CAN_MSG_SET_PARAM(rtr_buf.msg, 0x7FF, CYGNUM_CAN_ID_STD, 1, CYGNUM_CAN_FRAME_DATA);
183     CYG_CAN_MSG_SET_DATA(rtr_buf.msg, 0, 0xAB);
184    
185     len = sizeof(rtr_buf);
186     if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&rtr_buf, &len))
187     {
188         CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
189     } 
190 #endif
191
192 #ifdef CYGOPT_IO_CAN_EXT_CAN_ID
193     cyg_can_remote_buf     rtr_buf2;
194     //
195     // setup the second remote response buffer for reception of extended
196     // remote frames
197     // 
198     rtr_buf2.cfg_id      = CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD;
199     CYG_CAN_MSG_SET_PARAM(rtr_buf2.msg, 0x800, CYGNUM_CAN_ID_EXT, 4, CYGNUM_CAN_FRAME_DATA);
200     CYG_CAN_MSG_SET_DATA(rtr_buf2.msg, 0, 0xCD);
201    
202     len = sizeof(rtr_buf2);
203     if (ENOERR != cyg_io_set_config(hCAN0, CYG_IO_SET_CONFIG_CAN_MSGBUF ,&rtr_buf2, &len))
204     {
205         CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
206     } 
207     
208     if (rtr_buf.handle == CYGNUM_CAN_MSGBUF_NA)
209     {
210         CYG_TEST_FAIL_FINISH("No free message buffer available for /dev/can0");
211     }
212 #endif
213       
214     diag_printf("\nTest of CAN remote response buffer configuration\n"
215                 "If a CAN node sends a remote request with ID 0x7FF (std. ID)\n"
216                 "or 0x800 (ext. ID) then the CAN driver should respond with\n"
217                 "data frames.\n\n");
218     diag_printf("!!! This test can be stopped by sending a data frame\n"
219                 "with ID 0x100 !!!\n\n");
220     
221     len = sizeof(msgbox_info);
222     if (ENOERR != cyg_io_get_config(hCAN0, CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO ,&msgbox_info, &len))
223     {
224         CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
225     } 
226     else
227     {
228         diag_printf("Message boxes available: %d    free: %d\n", 
229                     msgbox_info.count, msgbox_info.free);
230     }
231     
232     while (1)
233     {
234         len = sizeof(rx_event); 
235             
236         if (ENOERR != cyg_io_read(hCAN0, &rx_event, &len))
237         {
238             CYG_TEST_FAIL_FINISH("Error reading from /dev/can0");
239         }
240         
241         if (0x100 == rx_event.msg.id)
242         {
243             CYG_TEST_PASS_FINISH("can_remote test OK"); 
244         }
245         else
246         {
247             print_can_flags(rx_event.flags, "");
248             
249             if (rx_event.flags & CYGNUM_CAN_EVENT_RX)
250             {
251                 print_can_msg(&rx_event.msg, "");   
252             }
253         }
254     }         
255 }
256
257
258 void
259 cyg_start(void)
260 {
261     CYG_TEST_INIT();
262     
263     //
264     // open CAN device driver
265     //
266     if (ENOERR != cyg_io_lookup("/dev/can0", &hCAN0)) 
267     {
268         CYG_TEST_FAIL_FINISH("Error opening /dev/can0");
269     }
270     
271     //
272     // create the thread that accesses the CAN device driver
273     //
274     cyg_thread_create(4, can0_thread, 
275                         (cyg_addrword_t) 0,
276                                 "can0_thread", 
277                                 (void *) can0_thread_data.stack, 
278                                 1024 * sizeof(long),
279                                 &can0_thread_data.hdl, 
280                                 &can0_thread_data.obj);
281                                 
282     cyg_thread_resume(can0_thread_data.hdl);
283     
284     cyg_scheduler_start();
285 }
286
287 #else // CYGOPT_IO_CAN_REMOTE_BUF
288 #define N_A_MSG "Needs support for CAN remote response buffers"
289 #endif
290
291 #else // CYGOPT_IO_CAN_RUNTIME_MBOX_CFG
292 #define N_A_MSG "Needs support for CAN message buffer runtime configuration"
293 #endif
294
295 #else // CYGFUN_KERNEL_API_C
296 #define N_A_MSG "Needs kernel C API"
297 #endif
298
299 #else // CYGPKG_IO_CAN && CYGPKG_KERNEL
300 #define N_A_MSG "Needs IO/CAN and Kernel"
301 #endif
302
303 #ifdef N_A_MSG
304 void
305 cyg_start( void )
306 {
307     CYG_TEST_INIT();
308     CYG_TEST_NA( N_A_MSG);
309 }
310 #endif // N_A_MSG
311
312 // EOF can_remote.c