CAN总线(Controller AreaNetwork,控制器局域网络)由德国博世公司于上世纪80年代提出,近20年来,随着CAN总线在工业测控与汽车领域的普及,CAN网络威廉希尔官方网站
不断优化,取得了长足发展。如今CAN总线已经成为了汽车上不可或缺的重要环节,ECU内部的CAN总线开发也占到了ECU开发中的很大分量。在汽车中为了满足车载系统的不同要求,主要采用高速CAN和低速CAN。这两者以不同的总线速率工作以获得最佳的性价比,在两条总线之间采用CAN网关进行连接。 CAN 总线标准主要在ISO 11898这个文档里,此外还有Bosch 的CAN 2.0。 CAN 是一种总线,所有的设备(称为节点,Node)都接在同一条线上。所有节点可以(尽管不应该)同时操作总线。 CAN 是串行的,一般只需要 3 根线:CAN_H、CAN_L、GND。CAN_H与CAN_L差分传送数据,物理上应该双绞,而 GND 做线壳。电压不定,一般来说 5V 电源时,要表示0,CAN_H和CAN_L都是 2.5V;表示 1,CAN_H是 3.5V,CAN_L是 1.5V。 CAN 线在物理上(不用在意如何)实现了“线与(wired-AND)”的连接方式——任何一个节点输出0,总线即为0。 CAN设备在Linux系统中以网络设备的形式呈现,通常设备名为can[n],n为从0开发的自然数。使用ifconfig命令可以查看到系统中的CAN设备。在LInux系统中提供SocketCAN接口来方便开发者操作CAN设备。 1.初始化CAN设备:
- int can_fd;
- struct sockaddr_can addr;
- struct ifreq ifr;
-
- can_fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);
- strcpy(ifr.ifr_name, "can0");
-
- /* determine the interface index */
- ioctl(s, SIOCGIFINDEX, &ifr);
- addr.can_family = AF_CAN;
- addr.can_ifindex = ifr.ifr_ifindex;
- /* bind the socket to a CAN interface */
- bind(s, (struct sockaddr *)&addr, sizeof(addr));
复制代码
2. 收发操作: CAN设备收发数据是以Frame的结构,在Linux中表示如下:
- struct can_frame {
- canid_t can_id;//CAN 标识符
- __u8 can_dlc;//数据场的长度
- __u8 data[8];//数据
- };
复制代码
3. 发送数据:
- struct can_frame frame;
- int wsize;
- frame.can_id = 0x123;//如果为扩展帧,那么 frame.can_id = CAN_EFF_FLAG | 0x123;
- frame.can_dlc = 1; //数据长度为 1
- frame.data[0] = 0xAB; //数据内容为 0xAB
复制代码
4. 接收数据:
- struct can_frame frame;
- int rsize;
- rsize = read(s, &frame, sizeof(frame));
复制代码
5. 过滤规则:
在接收的时,可以预先设置过滤规则,实现CAN帧报文的过滤。Linux提供了can_filter结构体来实现。
|