Linux应用程序--CAN总线
文章摘要:本文描述了关于CAN总线应用程序的编程。
内核版本:linux-3.8.13
硬件平台:AM335x
内核配置: 添加CAN驱动程序及协议
[*] Networking support --->
<*> CAN bus subsystem support --->
<*> Raw CAN Protocol (raw access with CAN-ID filtering)
<*> Broadcast Manager CAN Protocol (with content filtering)
CAN Device Drivers --->
<*> Bosch D_CAN devices --->
<*> Generic Platform Bus based D_CAN driver
AM335x CAN控制器驱动程序位于:drivers/net/can/c_can目录下
c_can_platform.c
c_can.c
系统设置:命令及说明:
配置CAN总线参数
# ip link set can0 type can bitrate 500000 triple-sampling on
或者
# canconfig can0 bitrate 500000 ctrlmode triple-sampling on
bitrate参数用于设置波特率,此处设置为500K bps.
使能CAN总线接口
# ip link set can0 up
或者
# canconfig can0 start
此命令完成后,可通过ifconfig查看到相关接口。
关闭CAN总线接口
# ip link set can0 down
或者
# canconfig can0 stop
示例代码:
/*
* 初始化CAN控制器
*/
int can_open(char* name)
{
int fd;
struct ifreq can_ifr;
struct sockaddr_can can_addr;
// int flag = 1;
// 初始化socket套接字用于CAN设备
fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);
strcpy(can_ifr.ifr_name, name);
ioctl(fd, SIOCGIFINDEX, &can_ifr); // 指定can设备
can_addr.can_family = AF_CAN; // 指定协议族
can_addr.can_ifindex = can_ifr.ifr_ifindex;
bind(fd, (struct sockaddr *)&can_addr, sizeof(can_addr)); // 绑定
//ioctl(fd, FIONBIO, &flag); //设置为非阻塞模式
return fd;
}
/*
* 向CAN总线发送数据
*/
int can_send(int can, int id, unsigned char* buff)
{
int ret;
struct can_frame can_frm = {0};
can_frm.can_id = id;
can_frm.can_dlc = 8;
memcpy(can_frm.data, buff, 8);
ret = write(can, &can_frm, sizeof(can_frm));
if(ret != sizeof(can_frm))
{
printf("can send error: id = %X\r\n", id);
}
return 0;
}
/*
* 向CAN总线读取数据
*/
int can_recv(int can, struct can_frame* pcf)
{
int rxlen;
// 正常情况下返回值为16(struct can_frame的长度)
rxlen = read(can, pcf, sizeof(struct can_frame));
if(rxlen != sizeof(struct can_frame))
{
return -1; // 读取失败
}
return 0;
}