When sending a large number of CAN messages from a script (in our case, to
initialize a servo), rtcansend can be somewhat slow because every message
requires a setup and teardown.

I added a --file flag to rtcansend which allows you to instead read bytes
from a file (or stdin, using '-' as the filename). The file has one CAN
message per line, in the same format (space-separated) as it would have
been in the can-msg on the command line. Blank lines are ignored. Lines
which start with a ' ' (space) or '#' (hash) character are ignored. If a
filename is given, any can-msg specified on the command line is ignored.

I hope this of use to someone, and it'd be really great if this could be
merged!

Thanks,
Daniel

https://gist.github.com/dmd/5267158 and inlined here:

--- xenomai-2.6.2.1/src/utils/can/rtcansend.c 2013-01-22 14:37:05.000000000
-0500
+++ robot4/crob/rtcansendmulti.c 2013-03-28 17:47:21.436106822 -0400
@@ -1,4 +1,5 @@
 #include <stdio.h>
+#include <string.h>
 #include <stdlib.h>
 #include <signal.h>
 #include <unistd.h>
@@ -18,9 +19,10 @@
 static void print_usage(char *prg)
 {
     fprintf(stderr,
-    "Usage: %s <can-interface> [Options] <can-msg>\n"
+    "Usage: %s <can-interface> [Options] [<can-msg>]\n"
     "<can-msg> can consist of up to 8 bytes given as a space separated
list\n"
     "Options:\n"
+    " -f, --file=FILENAME   file to read bytes from instead of the command
line. one list per line.\n"
     " -i, --identifier=ID   CAN Identifier (default = 1)\n"
     " -r  --rtr             send remote request\n"
     " -e  --extended        send extended frame\n"
@@ -45,7 +47,7 @@
 static nanosecs_rel_t timeout = 0;
 static struct can_frame frame;
 static struct sockaddr_can to_addr;
-
+const char* input_filename = NULL;

 void cleanup(void)
 {
@@ -127,6 +129,7 @@

     struct option long_options[] = {
  { "help", no_argument, 0, 'h' },
+ { "file", required_argument, NULL, 'f'},
  { "identifier", required_argument, 0, 'i'},
  { "rtr", no_argument, 0, 'r'},
  { "extended", no_argument, 0, 'e'},
@@ -148,15 +151,20 @@

     frame.can_id = 1;

-    while ((opt = getopt_long(argc, argv, "hvi:l:red:t:cp:sL:",
+    while ((opt = getopt_long(argc, argv, "hvi:l:red:t:cp:sL:f:",
       long_options, NULL)) != -1) {
  switch (opt) {
  case 'h':
     print_usage(argv[0]);
     exit(0);

+ case 'f':
+    input_filename = optarg;
+    break;
+
  case 'p':
     print = strtoul(optarg, NULL, 0);
+    /* fall through */

  case 'v':
     verbose = 1;
@@ -263,18 +271,6 @@
  }
     }

-    if (count)
- frame.can_dlc = sizeof(int);
-    else {
- for (i = optind + 1; i < argc; i++) {
-    frame.data[dlc] = strtoul(argv[i], NULL, 0);
-    dlc++;
-    if( dlc == 8 )
- break;
- }
- frame.can_dlc = dlc;
-    }
-
     if (rtr)
  frame.can_id |= CAN_RTR_FLAG;

@@ -298,7 +294,49 @@
  goto failure;
     }

-    rt_task();
+    if (input_filename != NULL) {
+ if (!strcmp(input_filename, "-"))
+    input_filename = "/dev/stdin";
+
+ FILE *file = fopen(input_filename, "r");
+
+ if (file != NULL) {
+    char line [1024];
+    while (fgets(line, sizeof line, file) != NULL) {
+ // put the data into frame
+ char * pch;
+ if (line[0] == '#' || line[0] == ' ' || line[0] == '\n') continue;
+ pch = strtok(line, " ");
+ dlc = 0;
+ while ((pch != NULL) && (dlc < 8)) {
+    frame.data[dlc] = strtoul(pch, NULL, 0);
+    pch = strtok(NULL, " ");
+    dlc++;
+ }
+ frame.can_dlc = dlc;
+ rt_task();
+    }
+    fclose(file);
+ }
+ else {
+    perror(input_filename);
+    goto failure;
+ }
+    }
+    else {
+ if (count)
+    frame.can_dlc = sizeof(int);
+ else {
+    for (i = optind + 1; i < argc; i++) {
+ frame.data[dlc] = strtoul(argv[i], NULL, 0);
+ dlc++;
+ if( dlc == 8 )
+    break;
+    }
+    frame.can_dlc = dlc;
+ }
+ rt_task();
+    }

     cleanup();
     return 0;
_______________________________________________
Xenomai mailing list
[email protected]
http://www.xenomai.org/mailman/listinfo/xenomai

Reply via email to