NXP

imx6 socketcan 发送问题

2019-07-12 12:44发布

参考cansend 的方法进行发送can 数据。

// 我今天参考了 NXP 官网,用了旧一版的 libsocket, 但是我觉得总体上来说变话是没有的。 // 参考: https://community.nxp.com/docs/DOC-1437 // 进入 canutils-4.0.6 目录 // 在 src 目录下, 可以看到 cansend.c vim src/cansend.c // 直接看到 main 函数 48 int main(int argc, char **argv) 49 { // 默认的一些参数 56 int family = PF_CAN, type = SOCK_RAW, proto = CAN_RAW; 58 int s, opt, ret, i, dlc = 0, rtr = 0, extended = 0; // ... ... // 这里直接是获取了所有的参数并解析它 75 while ((opt = getopt_long(argc, argv, "hf:t:p:vi:lre", long_options, NULL)) != -1) { 76 switch (opt) { 77 case 'h': // 打印帮助信息 78 print_usage(basename(argv[0])); 79 exit(0); 80 81 case 'f': // 家族 82 family = strtoul(optarg, NULL, 0); 83 break; 84 85 case 't': // 类型 86 type = strtoul(optarg, NULL, 0); 87 break; 88 89 case 'p': // 协议 90 proto = strtoul(optarg, NULL, 0); 91 break; 92 93 case 'v': // 打印发送的数据 94 verbose = 1; 95 break; 96 97 case 'l': // 循环次数 98 if (optarg) 99 loopcount = strtoul(optarg, NULL, 0); 100 else // 或是是无数次 101 infinite = 1; 102 break; 103 case 'i': // 指定接口 -ican0 104 frame.can_id = strtoul(optarg, NULL, 0); 105 break; 106 107 case 'r': // 指定是否是远程帧 108 rtr = 1; 109 break; 110 111 case 'e': // 扩展帧 112 extended = 1; 113 break; 114 115 case VERSION_OPTION: // 打印版本信息 116 printf("cansend %s ", VERSION); 117 exit(0); 118 119 default: 120 fprintf(stderr, "Unknown option %c ", opt); 121 break; 122 } 123 } // ... ... 134 interface = argv[optind]; // 指定接口, 这里的话第一个参数应该是要 -i 指定接口 // ... ... 139 s = socket(family, type, proto); // 申请一个套接字,我引用了这里 140 if (s < 0) { 141 perror("socket"); 142 return 1; 143 } // 指定家族 145 addr.can_family = family; 146 strcpy(ifr.ifr_name, interface); 147 if (ioctl(s, SIOCGIFINDEX, &ifr)) { 148 perror("ioctl"); 149 return 1; 150 } 151 addr.can_ifindex = ifr.ifr_ifindex; // ... ... 绑定 153 if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 154 perror("bind"); 155 return 1; 156 } // 数据, 数据包的大小, 我修改了这里,这里我直接获取了qt界面上一个text 的属性。 158 for (i = optind + 1; i < argc; i++) { 159 frame.data[dlc] = strtoul(argv[i], NULL, 0); 160 dlc++; 161 if (dlc == 8) 162 break; 163 } 164 frame.can_dlc = dlc; // 扩展帧 167 if (extended) { 168 frame.can_id &= CAN_EFF_MASK; 169 frame.can_id |= CAN_EFF_FLAG; 170 } else { 171 frame.can_id &= CAN_SFF_MASK; 172 } // 远程帧, 远程帧是没有数据发送的请注意 174 if (rtr) 175 frame.can_id |= CAN_RTR_FLAG; // 这里是判断是否循环, 我参考了这里只发了一次,把循环条件去掉了。 185 while (infinite || loopcount--) { 186 ret = write(s, &frame, sizeof(frame)); 187 if (ret == -1) { 188 perror("write"); 189 break; 190 } 191 } // 关闭套接字 193 close(s); 194 return 0; 195 }