CAN总线作为工业现场最常用的总线协议之一,应用十分广泛。英创公司推出的ESMARC系列工控主板中的ESM3352、ESM3354、ESM6800、ESM680、ESM7000等都板载了两路CAN总线供客户使用,同时也推出了扩展方案来应对各种需求(扩展方案只能支持带有ISA总线的主板型号),客户可以通过英创工控主板上的ISA总线扩展出4路CAN总线,具体的方案可以参考文章:《6路独立CAN总线的实现方案》,所以在英创提供的方案中CAN总线资源是十分丰富的。
Linux系统对于CAN总线的支持是采用的Socket CAN方式,Scoket CAN使用了socket接口和Linux网络协议栈,这种方法使得CAN设备驱动可以通过网络接口函数来调用,这样大大地方便了熟悉Linux网络编程的程序员,由于调用的都是标准的socket 函数,也使得应用程序便于移植,而不会因为硬件的调整而修改应用程序,这样加强了应用程序的可维护性。关于Socket CAN的资料在Linux内核文档中有更为详细的介绍https://www.kernel.org/doc/Documentation/networking/can.txt。在英创公司提供的资料中,也包含了使用Scoket CAN的例程。
Socket CAN提供的接口没有包含对CAN总线设置的功能,所以在程序中使用CAN总线通讯之前,需要先使用英创公司移植的iproute2中的ip命令来设置CAN总线,比如波特率、采样点的设置等,关于使用ip命令来设置CAN总线的详细方法可以参考文章:《EM9287 Linux Socket CAN驱动简介》,目前我们的例程也是使用的这种方法设置CAN总线,客户还可以参考我们提供的例程。
为了简化客户的操作,让程序更加简单易读,英创公司特地移植了libsocketcan库,这个库提供了接口函数来设置CAN总线,弥补了Socket CAN中缺少的部分。下面我们就来介绍如何利用libsocketcan提供的函数设置CAN总线,首先介绍常用的函数有四个:
/** * 关闭CAN总线 * * 函数会关闭指定的CAN总线,将状态置为down,最好在设置之前调用一次 * * 参数说明: * name:代入CAN总线的名称(即使用ifconfig –a命令查看到的名称),例如can0或者 * can1等 * * 返回值说明: * 0 成功 * -1 失败 * */ int can_do_stop(const char *name) /** * 设置CAN总线波特率 * * 函数设置CAN总线的波特率 * * 参数说明: * name:代入CAN总线的名称(即使用ifconfig –a命令查看到的名称),例如can0或者 * can1等 * bitrate:需要设置的波特率。 * * 返回值说明: * 0 成功 * -1 失败 * */ int can_set_bitrate(const char * __u32) /** * 设置CAN总线复位时间 * * 函数设置CAN总线的复位时间(单位毫秒),一旦CAN总线出现bus_off,经过设置时长会自动复位 * * 参数说明: * name:代入CAN总线的名称(即使用ifconfig –a命令查看到的名称),例如can0或者can1等 * restart_ms:需要设置的复位时间 * * 返回值说明: * 0 成功 * -1 失败 * */ int can_set_restart_ms( const char *name, __u32 restart_ms) /** * 启动CAN总线 * * 函数会启动指定的CAN总线,将状态置为up * * 参数说明: * name:代入CAN总线的名称(即使用ifconfig –a命令查看到的名称),例如can0或者 * can1等 * * 返回值说明: * 0 成功 * -1 失败 * */ int can_do_start( const char *name )
利用这四个函数就能够完成对CAN总线的设置,如果在代码中需要使用libsocketcan提供的函数,需要包含头文件libsocketcan.h,并且在链接库中增加libsocketcan的选项,增加库的方法和使用必读手册中介绍的增加线程库方法是完全相同的,示例代码如下:
#include <libsocketcan.h> int main() { int i, devnum, bitrate, restime; char devname[5]; devnum = 0; sprintf(devname, "can%d", devnum); i = can_do_stop(devnum); bitrate = 500000; i += can_set_bitrate(devnum, bitrate); restime = 50; i += can_set_restart_ms(devnum, restime); i += can_do_start(devnum); if(i < 0) { printf("fail to set %s!\n", devname); return i; } }
上面的代码可以代替CAN总例程中使用ip命令对CAN总线的初始化设置,如果客户还有一些比较特殊的需求,比如设置特定的采样和工作模式等,可以在libsocketcan的官方网站:https://lalten.github.io/libsocketcan/Documentation/html/group__extern.html上查看其它更多的函数及其功能介绍。
如果有感兴趣的客户,可以和英创工程师联系,索取完整工程文件。
成都英创信息技术有限公司 028-8618 0660