嵌入式Linux系列第10篇:使用CAN

简介: 嵌入式Linux系列第10篇:使用CAN

1.引言


CAN总线由于其高可靠性,被广泛的应用在汽车电子及工业领域。生活中常见的一个使用CAN的地方是汽车OBD接口,它一般位于汽车方向盘的左下角,是一个16针的插座,其中里面就有一个CAN接口,可以用来查看汽车的刹车、转向、故障信息等。单片机或处理器上如果有CAN控制器,外围再搭配一个CAN收发器,就可以进行通信了。本篇对Linux下CAN使用做个简单总结,希望对大家有所帮助。

2.环境介绍

2.1.硬件

1) 网上的一个第三方做的NUC972开发板:



有兴趣购买的朋友,可以去他们的淘宝店购买:https://s.click.taobao.com/X8mza8w2) CAN相关电路


为了进行后面的实验,将CAN0的H和CAN1的H,CAN0的L和CAN1的L分别短接起来。结合我之前遇到的实际问题,对上面电路做两点说明: i)从处理器芯片CAN控制器出来的两个引脚TX和RX,和CAN收发器的TX(上图收发器芯片的1脚D)和RX(上图收发器芯片的4脚R)是直连的,就是TX连接TX,RX连接RX,千万别把TX和RX连接在一起了,这个和串口里的交叉连接不是一回事。当年就因为这个小问题,我在一个客户那里折腾了老半天。ii) 收发器出来的CANH和CANL之间有一个120欧姆电阻,CAN总线结构如下,这个120欧姆电阻只需要在两侧的节点上加就行,用来保证整个总线的阻抗匹配。这个得注意,虽然有时不加也能通信,但是还是得按照CAN总线的要求加上,不然通信会不稳定的。

2.2.软件

1) Uboot继续使用之前文章用的,无需改动。

2) Kernel在上一篇基础上,要做一定的修改。3) Rootfs在上一篇用Buildroot生成的基础上,要做一定的修改。

3.内核配置

内核CAN配置


-

4.Buildroot配置

iproute2配置

使能can-utils工具,用来支持candump/cansend命令

socketcand配置

5.收发测试

5.1.命令行调试

将上述修改后的内核和文件系统下载到板子里启动后,

1) ifconfig -a 查看全部接口,可以看到can0和can1接口



2) 输入下面两条指令ip link set can0 up type can bitrate 500000ip link set can1 up type can bitrate 500000


ifconfig 可以看到两个can接口



下面的两条指令完成can0接收,can1发送,可以看到收发正常candump can0 &cansend can1 888#11223344



如果也让can1接收,通过can0或者can1发送,两个can口都可以接收到数据。


5.2.C代码实现

1) 代码实现的功能是,先通过can0发送一串数据,然后不断接收数据并打印。完整代码见百度网盘。

2)执行can_demo程序,可以看到can1会收到can0发送的数据


如果通过cansend can1 12345678#1122334455 发送数据


程序会打印出接收到的数据:


里面有一个重要的数据结构说明如下:

/**
* struct can_frame - basic CAN frame structure
* @can_id:  CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
* @can_dlc: frame payload length in byte (0 .. 8) aka data length code
* N.B. the DLC field from ISO 11898-1 Chapter 8.4.2.3 has a 1:1
* mapping of the 'data length code' to the real payload length
* @data:    CAN frame payload (up to 8 byte)
*/
structcan_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)));
};
/*
* Controller Area Network Identifier structure
*
* bit 0-28: CAN identifier (11/29 bit)
* bit 29: error message frame flag (0 = data frame, 1 = error message)
* bit 30: remote transmission request flag (1 = rtr frame)
* bit 31: frame format flag (0 = standard 11 bit, 1 = extended 29 bit)
*/
typedef__u32 canid_t ;
#define CAN_MAX_DLEN 8

6.结束语


本篇为大家介绍了Linux下CAN接口的简单使用,欢迎大家多交流,可以在网页下方留言讨论

相关文章
|
6月前
|
消息中间件 存储 缓存
【嵌入式软件工程师面经】Linux系统编程(线程进程)
【嵌入式软件工程师面经】Linux系统编程(线程进程)
133 1
|
8天前
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
59 13
|
6月前
|
网络协议 算法 Linux
【嵌入式软件工程师面经】Linux网络编程Socket
【嵌入式软件工程师面经】Linux网络编程Socket
199 1
|
4月前
|
NoSQL Linux C语言
嵌入式GDB调试Linux C程序或交叉编译(开发板)
【8月更文挑战第24天】本文档介绍了如何在嵌入式环境下使用GDB调试Linux C程序及进行交叉编译。调试步骤包括:编译程序时加入`-g`选项以生成调试信息;启动GDB并加载程序;设置断点;运行程序至断点;单步执行代码;查看变量值;继续执行或退出GDB。对于交叉编译,需安装对应架构的交叉编译工具链,配置编译环境,使用工具链编译程序,并将程序传输到开发板进行调试。过程中可能遇到工具链不匹配等问题,需针对性解决。
150 3
|
4月前
|
传感器 人工智能 网络协议
:嵌入式 Linux 及其用途
【8月更文挑战第24天】
219 0
|
5月前
|
Ubuntu 算法 Linux
嵌入式Linux的学习误区
**嵌入式Linux学习误区摘要** 1. **过度聚焦桌面Linux** - 许多学习者误将大量时间用于精通桌面Linux系统(如RedHat、Fedora、Ubuntu),认为这是嵌入式Linux开发的基石。 - 实际上,桌面Linux仅作为开发工具和环境,目标不应是成为Linux服务器专家,而应专注于嵌入式开发工具和流程。 2. **盲目阅读Linux内核源码** - 初学者在不了解Linux基本知识时试图直接研读内核源码,这往往导致困惑和挫败感。 - 在具备一定嵌入式Linux开发经验后再有针对性地阅读源码,才能有效提升技能。
|
5月前
|
缓存 安全 网络协议
【Linux】已解决:There are no enabled repos. Run “yum repolist all” to see the repos you have. You can en
【Linux】已解决:There are no enabled repos. Run “yum repolist all” to see the repos you have. You can en
1171 1
|
6月前
|
物联网 Linux 芯片
学习嵌入式是选择单片机还是Linux?
单片机通常指的是一种集成了处理器、存储器和各种外设接口的微控制器芯片,常见的有STC、51系列、AVR、ARM Cortex-M等。单片机具有低成本、低功耗、实时性强等特点,适用于对资源要求较低、功耗要求较低、实时性要求较高的嵌入式系统。学习单片机开发可以让您深入了解嵌入式系统的底层原理和硬件编程,对于对嵌入式系统底层开发感兴趣的人来说,是一个很好的选择。
146 4
|
6月前
|
消息中间件 安全 Java
【嵌入式软件工程师面经】Linux多进程与多线程
【嵌入式软件工程师面经】Linux多进程与多线程
82 1
|
6月前
|
存储 缓存 Unix
【嵌入式软件工程师面经】Linux文件IO
【嵌入式软件工程师面经】Linux文件IO
54 1

热门文章

最新文章