參考cansend 的方法進行發送can 數據。
-
cansend 的生成,請查考:http://www.cnblogs.com/chenfulin5/p/6797756.html
-
cansend 代碼跟蹤:
// 我今天參考了 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\n", VERSION);
117 exit(0);
118
119 default:
120 fprintf(stderr, "Unknown option %c\n", 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 }