Source-lib第四弹: can总线使用。
can总线的具体原理我就不说了,我也是第一次使用。可以看下下面的博客:
http://blog.youkuaiyun.com/righthek/article/details/17515465
老套路先看代码:
1、先初始化了两个can口
2、然后创建了个子进程
3、子进程用于1秒发送一帧数据。父进程用于接收数据,并打印到串口上。
1.初始化了两个can口
要设置can口必须先关闭can口,而且要先设置波特率。不然无法打开can口。
还有can的驱动框架已经套用网络框架了,所以可以使用socket。
接下来做了一个socket连接。
2、子进程发送
按指定的can_id,指定的帧格式进程一定长度的数据发送。
帧格式一共有三种:标准帧,扩展帧,远程帧。
3、父进程接收
就是read函数,读取一个can_frame结构体的数据,返回can_id
这个结构体如下:
这是个can0和can1的通信例子,接线如下:
效果图如下:
can总线的具体原理我就不说了,我也是第一次使用。可以看下下面的博客:
http://blog.youkuaiyun.com/righthek/article/details/17515465
老套路先看代码:
unsigned char send_buf[10] = {0xA5, 0xB4, 0xC3, 0xD2};
unsigned char rev_buf[10] = {0};
int rev_can_id = 0;
int main(int argc, char** argv)
{
pid_t pid = -1;
int master_fd;
int slave_fd;
master_fd = can_init(CAN0, 1000000, 0xA5A6, EXTENDED_FRAME);
slave_fd = can_init(CAN1, 1000000, 0xA5A6, EXTENDED_FRAME);
if (master_fd == -1 || slave_fd == -1) {
ERR("get fd\n");
return -1;
}
pid = fork();
if (pid == -1) {
ERR("fork\n");
} else if (pid == 0) {/* 子进程 */
while (1) {
can_send_data(master_fd, send_buf, 4);
sleep(1);
}
} else {
while (1) {
rev_can_id = read_frame(slave_fd, rev_buf, 4);
//DEBUG("rev_can_id= %x\n", rev_can_id);
/* 扩展帧最高位为1,定义的又是无符号型所以会被识别为负数 */
if (rev_can_id != -1) {
INFO("rev_can_id = %x\n", rev_can_id);
INFO("rev_buf: %x %x %x %x\n", rev_buf[0], rev_buf[1], rev_buf[2], rev_buf[3]);
}
sleep(1);
}
}
return 0;
}
2、然后创建了个子进程
3、子进程用于1秒发送一帧数据。父进程用于接收数据,并打印到串口上。
1.初始化了两个can口
EXPORT int can_init(int port,
int bitrate,
int can_id,
int frame_type
)
{
int socket_fd = -1;
close_can(port);
set_bitrate(port, bitrate);
open_can(port);
socket_fd = socket_can_listen(port);
if (socket_fd < 0) {
ERR("socket_can_listen\n");
return -1;
}
set_can_filter(socket_fd, can_id, frame_type);
g_can_id = can_id;
g_frame_type = frame_type;
return socket_fd;
}
还有can的驱动框架已经套用网络框架了,所以可以使用socket。
接下来做了一个socket连接。
2、子进程发送
EXPORT int can_send_data(int socket_fd, unsigned char *data_buf, int len)
{
return send_frame(socket_fd, g_can_id, g_frame_type, data_buf, len);
}
帧格式一共有三种:标准帧,扩展帧,远程帧。
3、父进程接收
EXPORT int read_frame(int socket_fd, unsigned char *rev_buf, int len)
{
struct can_frame frame;
int ret = read_hardware(socket_fd, &frame, sizeof(struct can_frame));
if (ret < 0) {
DEBUG("can raw socket read\n");
return -1;
}
memcpy(rev_buf, frame.data, len);
return frame.can_id;
}
这个结构体如下:
/*
struct can_frame {
canid_t can_id; // 32 bit CAN_ID + EFF/RTR/ERR flags
__u8 can_dlc; // frame payload length in byte (0 .. CAN_MAX_DLEN)
__u8 data[CAN_MAX_DLEN] __attribute__((aligned(8)));
};
*/
这是个can0和can1的通信例子,接线如下:
效果图如下:
本文档介绍了如何在IMX6UL上通过CAN接口进行通信,包括初始化CAN口、发送和接收数据的代码示例,以及CAN总线的硬件接线说明。
1252

被折叠的 条评论
为什么被折叠?



