TS-4900 CAN: Difference between revisions
(Created page with "The i.MX6 includes 2 CAN controllers which support the SocketCAN interface. Before proceeding with the examples, see the Kernel's CAN documentation [https://www.kernel.org/do...") |
No edit summary |
||
Line 9: | Line 9: | ||
## Dump data & errors: | ## Dump data & errors: | ||
candump | candump can0 & | ||
## Send the packet with: | ## Send the packet with: | ||
Line 16: | Line 16: | ||
#data 1 = 0x1 | #data 1 = 0x1 | ||
#data 2 = 0x0c | #data 2 = 0x0c | ||
cansend can0 | cansend can0 -i 0x7Df 3 1 0c | ||
</source> | </source> | ||
This example packet is designed to work with the Ozen Elektronik myOByDic 1610 ECU simulator to read the RPM speed. This device will return data from candump with: | This example packet is designed to work with the Ozen Elektronik myOByDic 1610 ECU simulator to read the RPM speed. This device will return data from candump with: | ||
<0x7e8> [8] 04 41 0c 60 40 00 00 00 | |||
<0x7e9> [8] 04 41 0c 60 40 00 00 00 | |||
In this case, | In this case, columns 6 and 7 are the current RPM value. This shows a simple way you can prove out the communication before moving to another language, but this next example sends the same packet and parses the same response in C: | ||
<source lang=c> | <source lang=c> | ||
#include <stdio.h> | #include <stdio.h> |
Revision as of 12:42, 18 August 2014
The i.MX6 includes 2 CAN controllers which support the SocketCAN interface. Before proceeding with the examples, see the Kernel's CAN documentation here.
This board comes preinstalled with can-utils which can be used to communicate over a CAN network without writing any code. The candump utility can be used to dump all data on the network
## First, set the baud rate and bring up the device:
ip link set can0 type can bitrate 250000
ip link set can0 up
## Dump data & errors:
candump can0 &
## Send the packet with:
#can_id = 0x7df
#data 0 = 0x3
#data 1 = 0x1
#data 2 = 0x0c
cansend can0 -i 0x7Df 3 1 0c
This example packet is designed to work with the Ozen Elektronik myOByDic 1610 ECU simulator to read the RPM speed. This device will return data from candump with:
<0x7e8> [8] 04 41 0c 60 40 00 00 00 <0x7e9> [8] 04 41 0c 60 40 00 00 00
In this case, columns 6 and 7 are the current RPM value. This shows a simple way you can prove out the communication before moving to another language, but this next example sends the same packet and parses the same response in C:
#include <stdio.h>
#include <pthread.h>
#include <net/if.h>
#include <string.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <assert.h>
#include <linux/can.h>
#include <linux/can/raw.h>
int main(void)
{
int s;
int nbytes;
struct sockaddr_can addr;
struct can_frame frame;
struct ifreq ifr;
struct iovec iov;
struct msghdr msg;
char ctrlmsg[CMSG_SPACE(sizeof(struct timeval)) + CMSG_SPACE(sizeof(__u32))];
char *ifname = "can0";
if((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
perror("Error while opening socket");
return -1;
}
strcpy(ifr.ifr_name, ifname);
ioctl(s, SIOCGIFINDEX, &ifr);
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("socket");
return -2;
}
/* For the ozen myOByDic 1610 this requests the RPM guage */
frame.can_id = 0x7df;
frame.can_dlc = 3;
frame.data[0] = 3;
frame.data[1] = 1;
frame.data[2] = 0x0c;
nbytes = write(s, &frame, sizeof(struct can_frame));
if(nbytes < 0) {
perror("write");
return -3;
}
iov.iov_base = &frame;
msg.msg_name = &addr;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = &ctrlmsg;
iov.iov_len = sizeof(frame);
msg.msg_namelen = sizeof(struct sockaddr_can);
msg.msg_controllen = sizeof(ctrlmsg);
msg.msg_flags = 0;
do {
nbytes = recvmsg(s, &msg, 0);
if (nbytes < 0) {
perror("read");
return -4;
}
if (nbytes < (int)sizeof(struct can_frame)) {
fprintf(stderr, "read: incomplete CAN frame\n");
}
} while(nbytes == 0);
if(frame.data[0] == 0x4)
printf("RPM at %d of 255\n", frame.data[3]);
return 0;
}
Other languages have bindings to access CAN such as Python using C-types, Java using JNI.