socan 1.2.1
Linux SocketCAN higher level library
Loading...
Searching...
No Matches
sotest.c
1
23/* sotest
24
25command line test program for socan
26*/
27
28#include <stdio.h>
29#include <limits.h>
30#include <stdbool.h>
31#include <stdlib.h>
32#include <string.h>
33
34#include <socan.h>
35
36#include <socan_util.h>
37
38/* ----------------------------------------------
39 * constants
40 * ---------------------------------------------- */
41
42#define VERSION "1.0"
43
44/* ----------------------------------------------
45 * types
46 * ---------------------------------------------- */
47
48typedef enum { T_CHECK=2, T_REMOTE=4,
49 T_TIMESTAMP=8,
50 T_STATS=16,
51 T_CONSISTENCE=32,
52 T_IGNORE_OLD=64
53 } testflags;
54
55enum options {
56 HELP,
57 INTERFACE,
58 LEAVE,
59 RWTEST,
60 WRITE,
61 WRITE_LATER,
62 WRITE_LATER_W,
63 WRITE_INHIBIT,
64 WRITE_RTR,
65 READ,
66 READ_NOW,
67 QUEUE_READ,
68 TRACE,
69 ERRPRINTLEVEL,
70 REALTIME,
71 BITRATE,
72 LOOP,
73 LOOPDELAY,
74 SLEEP,
75 QUIET,
76 TIMESTAMP,
77 STATS,
78 MAXLOSSRATE,
79 SIZE,
80 COUNT,
81 CHECK,
82 REMOTE,
83 CONSISTENCE,
84 IGNORE_OLD,
85 };
86
87enum commands {
88 CMD_NOTHING,
89 CMD_RWTEST,
90 CMD_BITRATE,
91 CMD_WRITE,
92 CMD_WRITE_LATER,
93 CMD_WRITE_LATER_W,
94 CMD_WRITE_INHIBIT,
95 CMD_WRITE_RTR,
96 CMD_READ,
97 CMD_READ_NOW,
98 CMD_QUEUE_READ,
99 };
100
101/* ----------------------------------------------
102 * tests
103 * ---------------------------------------------- */
104
105static void test_bitrate(int port)
106 {
107 socan_rc rc;
108 unsigned int bitrate;
109
110 rc= socan_port_bitrate((unsigned char) port, &bitrate);
111 if (socan_rc_is_error(rc))
112 {
113 printf("sotest.c line %d: socan_port_bitrate returned an error: %d (%s)\n",
114 __LINE__, rc, socan_str_rc(rc));
115 printf("test-abort!\n");
116 return;
117 }
118 printf("bitrate of port %d is %u\n", port, bitrate);
119 }
120
121
122static void test_simple_rw(int object1, int port1, int object2, int port2,
123 int w_timeout, int r_timeout,
124 int flag)
125 {
126 socan_hdl hdl;
127 socan_rc rc;
128 unsigned char wbuf[8];
129 unsigned char rbuf[8];
130 unsigned long ts;
131 int i;
132
133 printf("opening driver :\n");
134 hdl= socan_open();
135
136 if (hdl==NULL)
137 {
138 printf("opening of driver failed\n");
139 return;
140 };
141
142 printf("8 bytes will be written, content of these 8 bytes:\n");
143 printf("1 2 3 4 5 6 7 8\n");
144
145 printf("set write-mode for object %d, port %d ...",object1, port1);
146 printf("(timeout %d)\n", w_timeout);
147
148 rc= socan_add_obj(hdl, port1, object1, 8, w_timeout, SOCAN_WRITE);
149 if (socan_rc_is_error(rc))
150 {
151 printf("sotest.c line %d: socan_add_obj returned an error: %d (%s)\n",
152 __LINE__, rc, socan_str_rc(rc));
153 printf("test-abort!\n");
154 socan_close(hdl);
155 return;
156 }
157 else
158 printf("done\n");
159
160 printf("set read-mode for object %d, port %d ...",object2, port2);
161 printf("(timeout %d)\n", r_timeout);
162
163 rc= socan_add_obj(hdl, port2, object2, 8, r_timeout, SOCAN_READ);
164 if (socan_rc_is_error(rc))
165 {
166 printf("sotest.c line %d: socan_add_obj returned an error: %d (%s)\n",
167 __LINE__, rc, socan_str_rc(rc));
168 printf("test-abort!\n");
169 socan_close(hdl);
170 return;
171 }
172 else
173 printf("done\n");
174
175 for (i=1; i<=8; i++)
176 wbuf[i-1]=i;
177
178 if (flag & T_TIMESTAMP)
179 {
180 printf("time now : %lu\n", timestamp_us());
181 }
182
183 printf("now writing the data...");
184 rc= socan_write(hdl, port1, object1, wbuf);
185 if (rc!=SOCAN_OK)
186 {
187 printf("sotest.c line %d: socan_write returned %d (%s)\n",
188 __LINE__, rc, socan_str_rc(rc));
189 }
190 printf("done\n");
191 if (flag & T_TIMESTAMP)
192 {
193 rc= socan_obj_ts(port1, object1, &ts);
194 if (rc!=SOCAN_OK)
195 {
196 printf("sotest.c line %d: socan_obj_ts returned %d (%s)\n",
197 __LINE__, rc, socan_str_rc(rc));
198 }
199 printf("timestamp: %lu\n", ts);
200 }
201
202 printf("now reading the data...");
203 rc= socan_read(hdl, port2, object2, rbuf);
204 if (rc!=SOCAN_OK)
205 {
206 printf("sotest.c line %d: socan_read returned %d (%s)\n",
207 __LINE__, rc, socan_str_rc(rc));
208 }
209 printf("done\n");
210 if (flag & T_TIMESTAMP)
211 {
212 rc= socan_obj_ts(port2, object2, &ts);
213 if (rc!=SOCAN_OK)
214 {
215 printf("sotest.c line %d: socan_obj_ts returned %d (%s)\n",
216 __LINE__, rc, socan_str_rc(rc));
217 }
218 printf("timestamp: %lu\n", ts);
219 }
220
221 printf("message-content:\n");
222 nice_dump(rbuf, 8, 0);
223
224 printf("closing driver...\n");
225 if (!socan_close(hdl))
226 {
227 printf("closing failed !\n");
228 return;
229 };
230 }
231
232/* the usage of the counter is adjusted to a little-endian machine ! */
233static void test_write(int object, int port, unsigned int timeout,
234 unsigned long inhibit_tm,
235 int loops,
236 double loopdelay,
237 double sleep,
238 double leave,
239 int quietlevel,
240 int write_cmd,
241 int countsize, int countstart,
242 int flag)
243 {
244 socan_hdl hdl;
245 unsigned long counter;
246 char cbuf[8]= {0, 0, 0, 0, 0, 0, 0, 0}; /* counter is at byte 4 ! */
247 socan_obj_type objtype;
248 long loopdelay_long= (loopdelay==0) ? 0 : (long)(loopdelay*1000+0.5);
249
250 int i;
251 int l;
252 char ch;
253 int scale;
254 bool timed= (write_cmd==CMD_WRITE_INHIBIT);
255 bool busy_wait= (write_cmd==CMD_WRITE_LATER_W);
256 bool write_rtr_frame= (write_cmd==CMD_WRITE_RTR);
257 unsigned long timeval;
258 socan_rc rc;
259 const char *func_name;
260 int waitcount=0;
261 int errcount=0;
262 int loops_got= loops;
263 unsigned long start_time_ms, end_time_ms;
264
265 switch (write_cmd)
266 {
267 case CMD_WRITE_INHIBIT:
268 func_name= "socan_write_inhibit";
269 break;
270 case CMD_WRITE_LATER:
271 case CMD_WRITE_LATER_W:
272 case CMD_WRITE_RTR:
273 func_name= "socan_writelater";
274 break;
275 case CMD_WRITE:
276 func_name= "socan_write";
277 break;
278 default:
279 printf("internal error line %d\n", __LINE__);
280 return;
281 }
282
283 counter=countstart;
284
285 if (sleep!=0)
286 {
287 printf("sleeping %f seconds...\n", sleep);
288 mldelay((long)(sleep*1000+0.5));
289 }
290 printf("opening driver :\n");
291 hdl= socan_open();
292 if (hdl==NULL)
293 {
294 printf("opening of driver failed\n");
295 return;
296 };
297
298 printf("defining write-object...\n");
299 if (write_rtr_frame)
300 objtype= SOCAN_READ_RTR;
301 else
302 {
303 if (flag & T_REMOTE)
304 objtype= SOCAN_WRITE_RTR;
305 else
306 objtype= SOCAN_WRITE;
307 }
308 rc= socan_add_obj(hdl, port, object, countsize, timeout, objtype);
309 if (socan_rc_is_error(rc))
310 {
311 printf("sotest.c line %d: socan_add_obj returned an error: %d (%s)\n",
312 __LINE__, rc, socan_str_rc(rc));
313 printf("test-abort!\n");
314 socan_close(hdl);
315 return;
316 }
317 else
318 printf("done\n");
319 if (timed)
320 {
321 rc= socan_set_inhibit(port, object, inhibit_tm);
322 if (socan_rc_is_error(rc))
323 {
324 printf("sotest.c line %d: socan_set_inhibit returned "
325 "an error: %d (%s)\n", __LINE__, rc, socan_str_rc(rc));
326 printf("test-abort!\n");
327 socan_close(hdl);
328 return;
329 }
330 }
331
332 /* supported write functions here:
333 * CMD_WRITE_ : socan_write
334 * CMD_WRITE_LATER: socan_writelater
335 * CMD_WRITE_INHIBIT: socan_write_inhibit
336 * CMD_WRITE_RTR: socan_writelater
337 */
338 eval_quietlevel(quietlevel, &scale, &ch, &l);
339
340 start_time_ms= timestamp_ms();
341 for(; loops>0; loops--)
342 {
343 if (loopdelay_long)
344 mldelay(loopdelay_long);
345 if (flag & T_CONSISTENCE)
346 {
347 unsigned char b= (unsigned char) counter;
348 for(i=0; i<countsize; cbuf[i++]= b);
349 /* int converted to byte ^^^^ !*/
350 }
351 else
352 {
353 /* native endianess: */
354 memcpy(cbuf, &counter, countsize);
355 };
356 if (quietlevel>=0)
357 { if (quietlevel > 0)
358 if ((--l)<=0)
359 { l= scale; putchar(ch); fflush(stdout); };
360 }
361 else
362 { if (flag & T_CONSISTENCE)
363 printf("consistency test with byte %lu\n", counter & 0xFF);
364 else
365 { printf("writing %lu, %d bytes on %d\n",
366 counter, countsize, object);
367 };
368 };
369 w_again:
370 switch (write_cmd)
371 {
372 case CMD_WRITE_INHIBIT:
373 timeval= inhibit_tm; /* reset the inhibit-time parameter*/
374 rc= socan_write_inhibit(hdl, port, object, cbuf, &timeval);
375 break;
376 case CMD_WRITE_LATER:
377 case CMD_WRITE_LATER_W:
378 case CMD_WRITE_RTR:
379 rc= socan_writelater(hdl, port, object, cbuf);
380 break;
381 case CMD_WRITE:
382 rc= socan_write(hdl, port, object, cbuf);
383 break;
384 }
385 if (rc!= SOCAN_OK)
386 {
387 if (busy_wait)
388 if (rc == SOCAN_WAIT) /* we have to busy-wait... */
389 {
390 waitcount++;
391 goto w_again;
392 }
393
394 if (timed)
395 if (rc == SOCAN_WAIT) /* we have to wait... */
396 {
397 waitcount++;
398 micdelay(timeval);
399 goto w_again;
400 };
401 if (socan_rc_is_error(rc))
402 {
403 errcount++;
404 printf("sotest.c line %d: %s returned an error: %d (%s)\n",
405 __LINE__, func_name, rc, socan_str_rc(rc));
406 }
407 else
408 printf("%s return code: %d (%s)\n", func_name,
409 rc, socan_str_rc(rc));
410 };
411 counter++;
412 };
413 end_time_ms= timestamp_ms();
414 if (quietlevel>0)
415 printf("\n");
416
417 if (flag & T_STATS)
418 {
419 double dt= (end_time_ms-start_time_ms)/1000.0;
420 double wait_rate= ((double)waitcount) / loops_got;
421 printf("dt: %f loops_got: %d\n",dt, loops_got); /*@@@*/
422 printf("statistic:\n");
423 printf("sent: %d\n", loops_got);
424 printf("run-time: %.2f s\n", dt);
425 printf("objects / s : %.1f\n", loops_got/dt);
426 printf("ms / object : %.3f\n", 1000*dt/loops_got);
427 printf("wait-rate: %.3f %%\n", wait_rate*100);
428 printf("errors: %d\n", errcount);
429 }
430
431 if (leave!=0)
432 {
433 printf("sleeping %f seconds...\n", leave);
434 mldelay((long)(leave*1000+0.5));
435 }
436
437 printf("\nclosing driver...\n");
438 if (!socan_close(hdl))
439 {
440 printf("closing failed !\n");
441 return;
442 };
443 }
444
445static void test_read(int object, int port, unsigned int timeout,
446 int loops,
447 double loopdelay,
448 double sleep,
449 double leave,
450 double maxlossrate,
451 int quietlevel, bool readnow,
452 int countsize, int flag)
453 {
454 socan_hdl hdl;
455 socan_obj_type objtype;
456 long loopdelay_long= (loopdelay==0) ? 0 : (long)(loopdelay*1000+0.5);
457 int rc;
458 int mask;
459 int scale, i, l;
460 unsigned long c,count= 0;
461 char ch;
462 char cbuf[8]= {0, 0, 0, 0, 0, 0, 0, 0}; /* counter is at byte 4 ! */
463 int lostcount=0;
464 int errcount=0;
465 int loops_got= loops;
466 double loss_rate;
467 unsigned long start_time_ms, end_time_ms;
468 bool started= false;
469
470 if (countsize>=sizeof(int))
471 mask= 0xFFFFFFFF;
472 else
473 mask= 0xFFFFFFFF >> ((sizeof(int)-countsize)*8);
474 if (sleep!=0)
475 {
476 printf("sleeping %f seconds...\n", sleep);
477 mldelay((long)(sleep*1000+0.5));
478 }
479 printf("opening driver :\n");
480 hdl= socan_open();
481 if (hdl==NULL)
482 {
483 printf("opening of driver failed\n");
484 return;
485 };
486
487 printf("defining read-object...\n");
488 if (flag & T_REMOTE)
489 objtype= SOCAN_READ_RTR;
490 else
491 objtype= SOCAN_READ;
492 rc= socan_add_obj(hdl, port, object, countsize, timeout, objtype);
493 if (socan_rc_is_error(rc))
494 {
495 printf("sotest.c line %d: socan_add_obj returned an error: %d (%s)\n",
496 __LINE__, rc, socan_str_rc(rc));
497 printf("test-abort!\n");
498 socan_close(hdl);
499 return;
500 }
501 else
502 printf("done\n");
503
504 eval_quietlevel(quietlevel, &scale, &ch, &l);
505
506 for(; loops>0; loops--)
507 {
508 if (loopdelay_long)
509 mldelay(loopdelay_long);
510 if (readnow)
511 rc= socan_readnow(hdl, port, object, cbuf);
512 else
513 rc= socan_read(hdl, port, object, cbuf);
514 if (!started)
515 {
516 start_time_ms= timestamp_ms();
517 started= true;
518 }
519 if (quietlevel>=0)
520 { if (quietlevel>0)
521 if ((--l)<=0)
522 { l= scale; putchar(ch); fflush(stdout); };
523 }
524 else
525 { printf("received data:\n");
526 nice_dump(cbuf, countsize, 0);
527 };
528 if (rc != SOCAN_OK)
529 {
530 switch(rc)
531 {
532 case SOCAN_OLD:
533 if (!(flag & T_IGNORE_OLD))
534 printf("\nread return-code: %d (%s)\n",
535 rc, socan_str_rc(rc));
536 break;
537 case SOCAN_LOST:
538 lostcount+=1;
539 if (quietlevel>=0)
540 {
541 if (quietlevel>0)
542 {
543 putchar('L');
544 fflush(stdout);
545 }
546 }
547 else
548 printf("\nread return-code: %d (%s)\n",
549 rc, socan_str_rc(rc));
550 break;
551 default:
552 errcount+=1;
553 printf("\nread error-code: %d (%s)\n",
554 rc, socan_str_rc(rc));
555 break;
556 }
557 };
558 if (flag & T_CHECK)
559 {
560 if (flag & T_CONSISTENCE)
561 {
562 c= cbuf[0];
563 for (i=1; i<countsize; i++)
564 if (c!= cbuf[i])
565 {
566 printf("INCONSISTENT DATA!\n");
567 printf("received data:\n");
568 nice_dump(cbuf, countsize, 0);
569 break;
570 };
571 }
572 else
573 {
574 c=0;
575 memcpy(&c, cbuf, countsize);
576 if (c != count)
577 {
578 if ((c>count) || (countsize>1))
579 {
580 if (quietlevel>=0)
581 printf("[%lx,%lx]",c,count);
582 else
583 printf("%lu messages missed, got:%lu expected:%lu\n",
584 c-count, c, count);
585 }
586 else
587 printf("messages repeated, got:%lu, expected:%lu\n",
588 c, count);
589 count=c;
590 };
591 count++;
592 count&= mask;
593 };
594 };
595 } /* for */
596 end_time_ms= timestamp_ms();
597 if (quietlevel>0)
598 printf("\n");
599
600 loss_rate= ((double)lostcount) / loops_got;
601 if (flag & T_STATS)
602 {
603 double dt= (end_time_ms-start_time_ms)/1000.0;
604 printf("statistic:\n");
605 printf("received: %d\n", loops_got);
606 printf("run-time: %.1f s\n", dt);
607 printf("objects / s : %.1f\n", loops_got/dt);
608 printf("ms / object : %.2f\n", 1000*dt/loops_got);
609 if (maxlossrate<0)
610 {
611 printf("lost: %d\n", lostcount);
612 printf("loss-rate: %.4f\n", loss_rate);
613 }
614 else
615 {
616 if (loss_rate <= maxlossrate)
617 printf("loss-rate <= %.4f\n", maxlossrate);
618 else
619 {
620 printf("lost: %d\n", lostcount);
621 printf("loss-rate %.4f > %.4f\n",
622 loss_rate, maxlossrate);
623 }
624 }
625 printf("errors: %d\n", errcount);
626 }
627 else
628 if ((loss_rate > maxlossrate) && (maxlossrate>=0))
629 printf("loss-rate %.4f > %.4f\n",
630 loss_rate, maxlossrate);
631
632 if (leave!=0)
633 {
634 printf("sleeping %f seconds...\n", leave);
635 mldelay((long)(leave*1000+0.5));
636 }
637
638 printf("closing driver...\n");
639 if (!socan_close(hdl))
640 {
641 printf("closing failed !\n");
642 return;
643 };
644 }
645
646static void test_queue_read(int port_, unsigned int timeout, int *ids, int id_no,
647 int loops,
648 double loopdelay,
649 double sleep,
650 double leave,
651 double maxlossrate,
652 int quietlevel,
653 int countsize, int flag)
654 {
655 socan_hdl hdl;
656
657 char cbuf[8]= {0, 0, 0, 0, 0, 0, 0, 0}; /* counter is at byte 4 ! */
658 int rc, i;
659 int mask;
660
661 unsigned long c;
662 char ch;
663 int scale;
664 int l;
665 unsigned char port;
666 unsigned short cob;
667 unsigned long *count= NULL;
668 long loopdelay_long= (loopdelay==0) ? 0 : (long)(loopdelay*1000+0.5);
669 int *receivecount=NULL;
670 int *lostcount=NULL;
671 int *errcount=NULL;
672 double loss_rate;
673 unsigned long start_time_ms, end_time_ms;
674 bool started= false;
675 int *iptr;
676
677 if (id_no <=0)
678 {
679 printf("wrong id_no: %d\n", id_no);
680 return;
681 }
682 count= calloc(id_no, sizeof(unsigned long));
683 receivecount= calloc(id_no, sizeof(unsigned long));
684 lostcount= calloc(id_no, sizeof(unsigned long));
685 errcount= calloc(id_no, sizeof(unsigned long));
686
687 if (countsize>=sizeof(int))
688 mask= 0xFFFFFFFF;
689 else
690 mask= 0xFFFFFFFF >> ((sizeof(int)-countsize)*8);
691
692 if (sleep!=0)
693 {
694 printf("sleeping %f seconds...\n", sleep);
695 mldelay((long)(sleep*1000+0.5));
696 }
697
698 printf("opening driver :\n");
699 hdl= socan_open();
700 if (hdl==NULL)
701 {
702 printf("opening of driver failed\n");
703 return;
704 };
705
706 printf("defining read-objects...\n");
707
708 for(i=0; i<id_no; i++)
709 {
710 /* for now, no support for RTR objects here: */
711 rc= socan_add_obj(hdl, port_, ids[i], countsize, timeout, SOCAN_READ);
712 if (socan_rc_is_error(rc))
713 {
714 printf("sotest.c line %d: socan_add_obj returned an error: %d (%s)\n",
715 __LINE__, rc, socan_str_rc(rc));
716 printf("test-abort!\n");
717 socan_close(hdl);
718 return;
719 }
720 rc= socan_use_queue(port_, ids[i]);
721 if (socan_rc_is_error(rc))
722 {
723 printf("sotest.c line %d: socan_use_queue returned "
724 "an error: %d (%s)\n",
725 __LINE__, rc, socan_str_rc(rc));
726 printf("test-abort!\n");
727 socan_close(hdl);
728 return;
729 }
730 rc= socan_new_user_area(port_, ids[i], sizeof(i), (void*)(&iptr));
731 if (socan_rc_is_error(rc))
732 {
733 printf("sotest.c line %d: socan_new_user_area returned "
734 "an error: %d (%s)\n",
735 __LINE__, rc, socan_str_rc(rc));
736 printf("test-abort!\n");
737 socan_close(hdl);
738 return;
739 }
740 *iptr= i;
741 }
742
743 scale=0;
744 eval_quietlevel(quietlevel, &scale, &ch, &l);
745
746 start_time_ms= timestamp_ms();
747 for(; loops>0; loops--)
748 {
749 if (loopdelay_long)
750 mldelay(loopdelay_long);
751 rc= socan_queue_read(hdl, &port, &cob, cbuf);
752 if (!started)
753 {
754 start_time_ms= timestamp_ms();
755 started= true;
756 }
757 if (SOCAN_OK!= socan_user_area(port, cob, (void*)(&iptr)))
758 {
759 printf("sotest.c line %d: socan_user_area returned "
760 "an error: %d (%s)\n",
761 __LINE__, rc, socan_str_rc(rc));
762 printf("test-abort!\n");
763 socan_close(hdl);
764 return;
765 }
766 /* *iptr is now the object index */
767
768 receivecount[*iptr]++;
769
770 if (quietlevel>=0)
771 {
772 if (quietlevel>0)
773 if ((--l)<=0)
774 if (ch)
775 { l= scale; putchar(ch); fflush(stdout); };
776 }
777 else
778 {
779 printf("received on %d: data:\n", cob);
780 nice_dump(cbuf, countsize, 0);
781 };
782 if (rc != SOCAN_OK)
783 {
784 switch(rc)
785 {
786 case SOCAN_LOST:
787 lostcount[*iptr]+=1;
788 if (quietlevel>=0)
789 {
790 if (quietlevel>0)
791 {
792 putchar('L');
793 fflush(stdout);
794 }
795 }
796 else
797 printf("\nread return-code: %d (%s)\n",
798 rc, socan_str_rc(rc));
799 break;
800 default:
801 errcount[*iptr]+=1;
802 printf("\nread error-code: %d (%s)\n",
803 rc, socan_str_rc(rc));
804 break;
805 }
806 };
807
808 if (flag & T_CHECK)
809 {
810 if (flag & T_CONSISTENCE)
811 {
812 c= cbuf[0];
813 for (i=1; i<countsize; i++)
814 if (c!= cbuf[i])
815 {
816 printf("INCONSISTENT DATA!\n");
817 printf("received data:\n");
818 nice_dump(cbuf, countsize, 0);
819 break;
820 };
821 }
822 else
823 {
824 c=0;
825 memcpy(&c, cbuf, countsize);
826 if (c != count[*iptr])
827 {
828 if ((c>count[*iptr]) || (countsize>1))
829 {
830 if (quietlevel>=0)
831 printf("[%d:%lx,%lx]",cob,c,count[*iptr]);
832 else
833 printf("cob %d: %lu messages missed, "
834 "got:%lu expected:%lu\n",
835 cob, c-count[*iptr], c, count[*iptr]);
836 }
837 else
838 printf("cob %d: messages repeated, "
839 "got:%lu, expected:%lu\n",
840 cob, c, count[*iptr]);
841 count[*iptr]=c;
842 };
843 count[*iptr]++;
844 count[*iptr]&= mask;
845 };
846 };
847
848 }; /* for */
849 end_time_ms= timestamp_ms();
850
851 if (quietlevel>0)
852 printf("\n");
853
854 double dt= (end_time_ms-start_time_ms)/1000.0;
855 for(i=0; i<id_no; i++)
856 {
857 if (flag & T_STATS)
858 {
859 loss_rate= ((double)lostcount[i]) / receivecount[i];
860 printf("\nstatistic cob %d:\n", ids[i]);
861 printf("received: %d\n", receivecount[i]);
862 printf("run-time: %.1f s\n", dt);
863 printf("objects / s : %.1f\n", receivecount[i]/dt);
864 printf("ms / object : %.2f\n", 1000*dt/receivecount[i]);
865 if (maxlossrate<0)
866 {
867 printf("lost: %d\n", lostcount[i]);
868 printf("loss-rate: %.4f\n", loss_rate);
869 }
870 else
871 {
872 if (loss_rate <= maxlossrate)
873 printf("loss-rate <= %.4f\n", maxlossrate);
874 else
875 {
876 printf("lost: %d\n", lostcount[i]);
877 printf("loss-rate %.4f > %.4f\n",
878 loss_rate, maxlossrate);
879 }
880 }
881 printf("errors: %d\n", errcount[i]);
882 }
883 else
884 if ((loss_rate > maxlossrate) && (maxlossrate>=0))
885 printf("loss-rate %.4f > %.4f\n",
886 loss_rate, maxlossrate);
887 }
888
889 free(count);
890 free(errcount);
891 free(lostcount);
892
893 if (leave!=0)
894 {
895 printf("sleeping %f seconds...\n", leave);
896 mldelay((long)(leave*1000+0.5));
897 }
898
899 printf("\nclosing driver...\n");
900 if (!socan_close(hdl))
901 {
902 printf("closing failed !\n");
903 return;
904 };
905 }
906
907/* ----------------------------------------------
908 * main
909 * ---------------------------------------------- */
910
911void print_help(void)
912 {
913 printf(" **** sotest %s ****\n", VERSION);
914 printf("the socan test program\n"
915 "usage:\n"
916 "sotest {options}\n"
917 "options:\n"
918 " **************** Configuration*****************\n"
919 " --interface,-i INTERFACE \n"
920 " Use INTERFACE for CAN communication, this option\n"
921 " can be given more than once to use more than one\n"
922 " interface.\n"
923 " --realtime READER-PRIORITY WRITER-PRIORITY\n"
924 " Use given realtime priorities for reader and writer\n"
925 " thread.\n"
926 " --leave [SECONDS]\n"
927 " for all functions that define CAN-objects, hold the\n"
928 " program just before close() is performed. All CAN\n"
929 " objects remain defined. End the program with CRTL-C in\n"
930 " this case\n"
931 " --trace,-t LEVEL\n"
932 " set trace level, LEVEL is an integer 0..2 (default 0)\n"
933 " --errprintlevel,-E LEVEL\n"
934 " set errprint level, LEVEL is an integer 0..3 (default 1)\n"
935 " *************** command options ***************\n"
936 " --loop {no of loops}\n"
937 " run read, write, readnow or readmany in loop-mode\n"
938 " --loopdelay {delay}\n"
939 " delay each loop by the given number of seconds.\n"
940 " seconds may be a floating point number.\n"
941 " --sleep {seconds}\n"
942 " sleep a number of seconds before starting the test.\n"
943 " seconds may be a floating point number.\n"
944 " --quiet,-q {level}\n"
945 " Run read, write, readnow or readmany in quiet-mode\n"
946 " level may be 1 .. 5, meaning that each 10**(level-1)\n"
947 " events print a single character on the screen.\n"
948 " Level 0 means no printing at all.\n"
949 " --timestamp\n"
950 " Print a the timestamp for each sent or received\n"
951 " CAN object."
952 " --stats\n"
953 " run read, readnow or readmany in statistic mode.\n"
954 " Print number of transmits and errors.\n"
955 " --maxlossrate [number]\n"
956 " print a warning when the ratio of lost CAN objects for\n"
957 " read functions is bigger than [number].\n"
958 " --check\n"
959 " check sequence in --read, (must be used together with\n"
960 " --write in another sotest-task\n"
961 " --size,-s [bytes]\n"
962 " use [bytes] bytes to transfer and receive data\n"
963 " --count [number]\n"
964 " use [number] as initial number to write with -w\n"
965 " --consistence\n"
966 " send alternating 8 bytes of 0xFF or 0x00 to test data\n"
967 " consistence\n"
968 " --remote \n"
969 " do remote-read or remote-write, implemented for\n"
970 " --write and --read\n"
971 " --ignore_old \n"
972 " ignore the SOCAN_OLD-flag \n"
973 "\n");
974 printf(" ***************data transmission commands****************\n"
975 " --rwtest [object1] [port1] [object2] [port2] "
976 "[write-timeout] [read-timeout]\n"
977 " make a write-object (object1,port1) and a read-object\n"
978 " (object2,port2) with a timeout set for the 2nd object\n"
979 " then write 8 bytes (values 1 to 8) and read the 2nd\n"
980 " object (read immediately) and return the results\n"
981 " --write,-w [object] [port] [timeout]\n"
982 " write data (a running counter)\n"
983 " --writelater [object] [port] [timeout]\n"
984 " similar to write, but writelater returns immediately,\n"
985 " without waiting for the actual access of the CAN-bus.\n"
986 " Note: writelater returns only errors that are valid for\n"
987 " the PREVIOUS writelater !!!\n"
988 " --writelater-w [object] [port] [timeout]\n"
989 " the same as --writelater but do silently retry to write\n"
990 " when the driver returns a SOCAN_WAIT status.\n"
991 " --writeinhibit [object] [port] [timeout] [inhibit-time]\n"
992 " similar to writelater, but the CAN-object gets a timestamp\n"
993 " when it is transmitted. Inhibit-time is the minumum\n"
994 " time that has to pass before a new object is sent. This\n"
995 " concerns only writeinhibit combined with the loop-command.\n"
996 " In this case only about every [inhibit-time]\n"
997 " microseconds new data will be sent (note that the unit\n"
998 " for this parameter is microseconds, not milliseconds\n"
999 " --writertr [object] [port] [timeout]\n"
1000 " Just write an RTR frame on a CAN object.\n"
1001 " --read,-r [object] [port] [timeout]\n"
1002 " read data from an object (blocking).\n"
1003 " --readnow [object] [port] [timeout]\n"
1004 " read data from an object (immediately).\n"
1005 " --queue-read [port] [timeout] [object] {[object]}\n"
1006 " read more than one object via the signal-function in \n"
1007 " conjunction with the new queue-read operation\n"
1008 " together with --remote, all objects will be remote-read\n"
1009 " objects\n"
1010 "\n");
1011 printf(" ******************** miscellaneous tests ****************\n"
1012 " --bitrate [port]\n"
1013 " get bitrate of a port\n");
1014 }
1015
1016
1017#define MAX_INTERFACES 4
1018
1019int main( int argc, char *argv[])
1020
1021 {
1022 static option options[]=
1023 {
1024 { "-h" , HELP },
1025 { "--help" , HELP },
1026 { "-i" , INTERFACE },
1027 { "--interface" , INTERFACE },
1028 { "--leave" , LEAVE},
1029 { "--realtime" , REALTIME},
1030 { "--bitrate" , BITRATE},
1031 { "--rwtest" , RWTEST},
1032 { "-w" , WRITE},
1033 { "--write" , WRITE},
1034 { "--writelater" , WRITE_LATER},
1035 { "--writelater-w", WRITE_LATER_W},
1036 { "--writeinhibit", WRITE_INHIBIT},
1037 { "--writertr" , WRITE_RTR},
1038 { "-r" , READ},
1039 { "--read" , READ},
1040 { "--readnow" , READ_NOW},
1041 { "--queue-read" , QUEUE_READ},
1042 { "--loop" , LOOP},
1043 { "--loopdelay" , LOOPDELAY},
1044 { "--sleep" , SLEEP},
1045 { "-q" , QUIET},
1046 { "--quiet" , QUIET},
1047 { "--timestamp" , TIMESTAMP},
1048 { "--stats" , STATS},
1049 { "--maxlossrate" , MAXLOSSRATE},
1050 { "--check" , CHECK},
1051 { "-s" , SIZE},
1052 { "--size" , SIZE},
1053 { "--count" , COUNT},
1054 { "--remote" , REMOTE},
1055 { "--consistence" , CONSISTENCE},
1056 { "--ignore_old" , IGNORE_OLD},
1057 { "-t" , TRACE},
1058 { "--trace" , TRACE},
1059 { "-E" , ERRPRINTLEVEL},
1060 { "--errprintlevel", ERRPRINTLEVEL},
1061 };
1062 int opt_no= sizeof(options) / sizeof(option);
1063 enum commands operation=CMD_NOTHING;
1064
1065 char *interfaces[MAX_INTERFACES];
1066 int interface_no=0;
1067 int n[45], i, l, tracelevel= -1, errprintlevel= -1;
1068 int flag=0;
1069 int loops=1;
1070 double sleep= 0;
1071 double leave= 0;
1072 double maxlossrate= -1;
1073 double loopdelay= 0;
1074 int quietlevel=-1;
1075 int countsize =sizeof(int);
1076 int countstart=0;
1077 int last_valid_n;
1078 int rc, opt_index;
1079 int rt_prios[]= {-1, -1};
1080 int opt;
1081 char *st;
1082
1083 if (argc<2)
1084 my_exit("error, option/command missing\n");
1085
1086 opt_index= 1;
1087 while(opt_index<argc)
1088 {
1089 opt= match(argc, argv, &opt_index, options, opt_no);
1090 switch (opt)
1091 {
1092 case -1:
1093 my_exit("unknown option: %s\n", argv[opt_index]);
1094 case HELP:
1095 print_help();
1096 return 0;
1097 case INTERFACE:
1098 if (match_st(argc, argv, &opt_index, &st))
1099 my_exit("interface name missing!\n");
1100 if (interface_no >= MAX_INTERFACES)
1101 my_exit("too many interfaces given (more than %d)\n",
1102 MAX_INTERFACES);
1103 interfaces[interface_no++]= st;
1104 break;
1105 case REALTIME:
1106 for(i=0; i<=1; i++)
1107 {
1108 rc= match_int(argc, argv, &opt_index, &(rt_prios[i]));
1109 if (rc==-1)
1110 my_exit("error, argument missing\n");
1111 if (rc==-2)
1112 my_exit("error, argument is not a number\n");
1113 };
1114 break;
1115 case LEAVE:
1116 rc= match_float(argc, argv, &opt_index, &leave);
1117 if (rc==-1)
1118 my_exit("the leave parameter is missing!\n");
1119 if (rc==-2)
1120 my_exit("the leave parameter is is not a number!\n");
1121 if (leave < 0)
1122 my_exit("the leave parameter must be positive\n");
1123 break;
1124 case TRACE:
1125 rc= match_int(argc, argv, &opt_index, &tracelevel);
1126 if (rc==-1)
1127 my_exit("the tracelevel parameter is missing!\n");
1128 if (rc==-2)
1129 my_exit("the tracelevel parameter is is not a number!\n");
1130 if (tracelevel<0)
1131 my_exit("trace level must be positive\n"
1132 "(input was %d)\n", tracelevel);
1133 break;
1134 case ERRPRINTLEVEL:
1135 rc= match_int(argc, argv, &opt_index, &errprintlevel);
1136 if (rc==-1)
1137 my_exit("the errprintlevel parameter is missing!\n");
1138 if (rc==-2)
1139 my_exit("the errprintlevel parameter is is not a number!\n");
1140 if (errprintlevel<0)
1141 my_exit("errprintlevel must be positive\n"
1142 "(input was %d)\n", errprintlevel);
1143 break;
1144 case CHECK:
1145 flag|= T_CHECK;
1146 break;
1147 case REMOTE:
1148 flag|= T_REMOTE;
1149 break;
1150 case CONSISTENCE:
1151 /* implies the check-flag, too */
1152 flag|= (T_CONSISTENCE | T_CHECK);
1153 /* countsize is changed to 8 !!! */
1154 countsize= 8;
1155 break;
1156 case IGNORE_OLD:
1157 flag|= T_IGNORE_OLD;
1158 break;
1159 case LOOP:
1160 rc= match_int(argc, argv, &opt_index, &loops);
1161 if (rc==-1)
1162 my_exit("the loop parameter is missing!\n");
1163 if (rc==-2)
1164 my_exit("the loop parameter is is not a number!\n");
1165 if (loops<1)
1166 my_exit("loop-parameter should be greater than zero!\n"
1167 "(input was %ld)\n", loops);
1168 break;
1169 case LOOPDELAY:
1170 rc= match_float(argc, argv, &opt_index, &loopdelay);
1171 if (rc==-1)
1172 my_exit("the loopdelay parameter is missing!\n");
1173 if (rc==-2)
1174 my_exit("the loopdelay parameter is is not a number!\n");
1175 break;
1176 case SLEEP:
1177 rc= match_float(argc, argv, &opt_index, &sleep);
1178 if (rc==-1)
1179 my_exit("the sleep parameter is missing!\n");
1180 if (rc==-2)
1181 my_exit("the sleep parameter is is not a number!\n");
1182 break;
1183 case QUIET:
1184 rc= match_int(argc, argv, &opt_index, &quietlevel);
1185 if (rc==-1)
1186 my_exit("the quiet parameter is missing!\n");
1187 if (rc==-2)
1188 my_exit("the quiet parameter is is not a number!\n");
1189 if ((quietlevel<0) || (quietlevel>5))
1190 my_exit("only quiet-levels 0 to 5 are allowed\n"
1191 "(input was %d)\n", quietlevel);
1192 break;
1193 case TIMESTAMP:
1194 flag|= T_TIMESTAMP;
1195 break;
1196 case STATS:
1197 flag|= T_STATS;
1198 break;
1199 case MAXLOSSRATE:
1200 rc= match_float(argc, argv, &opt_index, &maxlossrate);
1201 if (rc==-1)
1202 my_exit("the max loss rate parameter is missing!\n");
1203 if (rc==-2)
1204 my_exit("the max loss rate parameter is is not a number!\n");
1205 break;
1206 case SIZE:
1207 rc= match_int(argc, argv, &opt_index, &countsize);
1208 if (rc==-1)
1209 my_exit("the count parameter is missing!\n");
1210 if (rc==-2)
1211 my_exit("the count parameter is is not a number!\n");
1212 if ((countsize<1) || (countsize>8))
1213 my_exit("[bytes]-parameter must be between 1 and 8 !!\n");
1214 break;
1215 case COUNT:
1216 rc= match_int(argc, argv, &opt_index, &countstart);
1217 if (rc==-1)
1218 my_exit("the countstart parameter is missing!\n");
1219 if (rc==-2)
1220 my_exit("the countstart parameter is is not a number!\n");
1221 if ((countstart<0))
1222 my_exit("[count]-parameter must be greater than 0 !!\n");
1223 break;
1224 case BITRATE:
1225 if (operation!=CMD_NOTHING)
1226 my_exit("contradicting options\n");
1227 operation=CMD_BITRATE;
1228 rc= match_int(argc, argv, &opt_index, &(n[0]));
1229 if (rc==-1)
1230 my_exit("the port parameter is missing!\n");
1231 if (rc==-2)
1232 my_exit("the port parameter is is not a number!\n");
1233 break;
1234 case RWTEST:
1235 if (operation!=CMD_NOTHING)
1236 my_exit("contradicting options\n");
1237 operation=CMD_RWTEST;
1238 for(i=0; i<=5; i++)
1239 {
1240 rc= match_int(argc, argv, &opt_index, &(n[i]));
1241 if (rc==-1)
1242 my_exit("error, argument missing\n");
1243 if (rc==-2)
1244 my_exit("error, argument is not a number\n");
1245 };
1246 break;
1247 case WRITE:
1248 case WRITE_LATER:
1249 case WRITE_LATER_W:
1250 case WRITE_INHIBIT:
1251 case WRITE_RTR:
1252 if (operation!=CMD_NOTHING)
1253 my_exit("contradicting options\n");
1254 switch (opt)
1255 {
1256 case WRITE:
1257 operation=CMD_WRITE; break;
1258 case WRITE_LATER:
1259 operation=CMD_WRITE_LATER; break;
1260 case WRITE_LATER_W:
1261 operation=CMD_WRITE_LATER_W; break;
1262 case WRITE_INHIBIT:
1263 operation=CMD_WRITE_INHIBIT; break;
1264 case WRITE_RTR:
1265 operation=CMD_WRITE_RTR; break;
1266 }
1267 l=2;
1268 if (operation==CMD_WRITE_INHIBIT)
1269 l=3; /* one more parameter */
1270 for(i=0; i<=l; i++)
1271 {
1272 rc= match_int(argc, argv, &opt_index, &(n[i]));
1273 if (rc==-1)
1274 my_exit("error, argument missing\n");
1275 if (rc==-2)
1276 my_exit("error, argument is not a number\n");
1277 };
1278 break;
1279 case READ:
1280 case READ_NOW:
1281 if (operation!=CMD_NOTHING)
1282 my_exit("contradicting options\n");
1283 switch (opt)
1284 {
1285 case READ:
1286 operation=CMD_READ; break;
1287 case READ_NOW:
1288 operation=CMD_READ_NOW; break;
1289 }
1290 for(i=0; i<=2; i++)
1291 {
1292 rc= match_int(argc, argv, &opt_index, &(n[i]));
1293 if (rc==-1)
1294 my_exit("error, argument missing\n");
1295 if (rc==-2)
1296 my_exit("error, argument is not a number\n");
1297 };
1298 break;
1299 case QUEUE_READ:
1300 if (operation!=CMD_NOTHING)
1301 my_exit("contradicting options\n");
1302 operation= CMD_QUEUE_READ;
1303 rc=0;
1304 last_valid_n=-1;
1305 while ((rc==0) && (last_valid_n<21))
1306 {
1307 last_valid_n++;
1308 rc= match_int(argc, argv, &opt_index, &(n[last_valid_n]));
1309 switch(last_valid_n)
1310 {
1311 case 0:
1312 if (rc!=0)
1313 my_exit("error, port missing\n");
1314 break;
1315 case 1:
1316 if (rc!=0)
1317 my_exit("error, timeout missing\n");
1318 break;
1319 case 2:
1320 if (rc!=0)
1321 my_exit("error, first object-id missing\n");
1322 break;
1323 default:
1324 if (rc!=0)
1325 last_valid_n--;
1326 break;
1327 }
1328 };
1329 break;
1330 }; /* switch */
1331 }; /* while */
1332 if (interface_no==0)
1333 {
1334 printf("Error, no interfaces defined\n");
1335 return 1;
1336 }
1337 if (!init_socan(interfaces, interface_no,
1338 tracelevel, errprintlevel,
1339 rt_prios[0], rt_prios[1]))
1340 return 1;
1341
1342 switch(operation)
1343 {
1344 case CMD_NOTHING:
1345 printf("error, no command given\n");
1346 return 1;
1347 case CMD_BITRATE:
1348 test_bitrate(n[0]);
1349 break;
1350 case CMD_RWTEST:
1351 test_simple_rw(n[0], n[1], n[2], n[3], n[4], n[5],
1352 flag);
1353 break;
1354 case CMD_WRITE:
1355 case CMD_WRITE_LATER:
1356 case CMD_WRITE_LATER_W:
1357 case CMD_WRITE_INHIBIT:
1358 case CMD_WRITE_RTR:
1359 test_write(n[0], n[1], n[2], n[3],
1360 loops, loopdelay, sleep, leave, quietlevel,
1361 operation,
1362 countsize,countstart,
1363 flag);
1364 break;
1365 case CMD_READ:
1366 case CMD_READ_NOW:
1367 test_read(n[0], n[1], n[2],
1368 loops, loopdelay, sleep, leave,
1369 maxlossrate, quietlevel,
1370 (operation==CMD_READ_NOW),
1371 countsize, flag);
1372 break;
1373 case CMD_QUEUE_READ:
1374 test_queue_read(n[0], n[1], n+2, last_valid_n-1,
1375 loops, loopdelay, sleep, leave, maxlossrate,
1376 quietlevel, countsize, flag);
1377 break;
1378 }
1379 return(0);
1380 }
socan_rc socan_user_area(unsigned char port, unsigned short cob, void **area)
Definition socan.c:1642
bool socan_close(socan_hdl h)
Definition socan.c:1196
socan_rc socan_write_inhibit(socan_hdl hdl, unsigned char port, unsigned short cob, const void *data, unsigned long *inhibit_time)
Definition socan.c:2072
char * socan_str_rc(socan_rc rc)
Definition socan.c:372
socan_rc socan_port_bitrate(unsigned char port, unsigned int *bitrate)
Definition socan.c:1089
socan_rc socan_read(socan_hdl hdl, unsigned char port, unsigned short cob, void *data)
Definition socan.c:1758
socan_rc socan_obj_ts(unsigned char port, unsigned short cob, unsigned long *ts)
Definition socan.c:1549
socan_rc socan_use_queue(unsigned char port, unsigned short cob)
Definition socan.c:1600
socan_rc socan_readnow(socan_hdl hdl, unsigned char port, unsigned short cob, void *data)
Definition socan.c:1698
socan_rc socan_set_inhibit(unsigned char port, unsigned short cob, unsigned long inhibit_time)
Definition socan.c:1580
socan_rc socan_write(socan_hdl hdl, unsigned char port, unsigned short cob, const void *data)
Definition socan.c:1927
bool socan_rc_is_error(socan_rc rc)
Definition socan.c:395
socan_hdl socan_open(void)
Definition socan.c:1151
socan_rc socan_queue_read(socan_hdl hdl, unsigned char *port, unsigned short *cob, void *data)
Definition socan.c:1867
socan_rc socan_add_obj(socan_hdl hdl, unsigned char port, unsigned short cob, unsigned char length, unsigned int tmo_ms, socan_obj_type type)
Definition socan.c:1459
socan_rc socan_writelater(socan_hdl hdl, unsigned char port, unsigned short cob, const void *data)
Definition socan.c:2000
socan_rc socan_new_user_area(unsigned char port, unsigned short cob, unsigned int size, void **area)
Definition socan.c:1621
c header file for socan object layer library.
socan_rc
Definition socan.h:176
@ SOCAN_LOST
Definition socan.h:181
@ SOCAN_OLD
Definition socan.h:179
@ SOCAN_WAIT
Definition socan.h:183
@ SOCAN_OK
Definition socan.h:177
socan_obj_type
Definition socan.h:162
@ SOCAN_WRITE
Definition socan.h:164
@ SOCAN_WRITE_RTR
Definition socan.h:166
@ SOCAN_READ
Definition socan.h:163
@ SOCAN_READ_RTR
Definition socan.h:165