i.MX6Q -- Linux系统下FlexCAN总线的使用记录

Posted a永不言败a

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了i.MX6Q -- Linux系统下FlexCAN总线的使用记录相关的知识,希望对你有一定的参考价值。

开发板平台:珠海鼎芯D338 – 基于i.MX6Q 
系统平台:Linux3.0.35 + Busybox1.22

1、 需要的工具 
FlexCAN工具包: 
libsocketcan-0.0.10.tar.bz2 
canutils-4.0.6.tar.bz2 
交叉编译器: 
fsl-linaro-toolchain.tar.bz2

2、编译过程: 
交叉编译器: 
环境变量配置命令: 
exportPATH=<YourCompilerPath>/fsl?linaro?toolchain/bin/:PATH

   libsocketcan-0.0.10:
  • 1
  • 2

使用tar命令解压libsocketcan-0.0.10.tar.bz2后,使用如下命令交叉编译并安装。 
./configureprefix=/flexcan/installhost=arm?none?linux?gnueabi make && make install

   canutils-4.0.6:
  • 1
  • 2

同样,交叉编译并安装命令如下。 
./configureprefix=/flexcan/installhost=arm?none?linux?gnueabiCC=arm?none?linux?gnueabi?gcclibsocketcanCFLAGS=?I//flexcan/install/includelibsocketcanLIBS=?lsocketcanLDFLAGS=?L//flexcan/install/libenable?staticmake && make install

   移植拷贝安装目录下(<YourInstallPath>/flexcan/install)的所有文件到D338开发板/usr/目录下即可;
  • 1
  • 2

至此,FlexCAN工具的移植就完成了,直接将文件系统打包为rootfs.tar.bz2,然后拷贝到dchip_MFGTools_Linux3.0.35_MX6Q_UPDATER工具下进行烧写启动就可以使用了,接下来,主要是FlexCAN总线的使用方法及详细说明。

3、错误与解决: 
错误1: 
编译canutils错误 
canconfig.c:34:26: fatal error: libsocketcan.h: No such fileor directory 
解决1: 
将libsocketcan已编译安装目录(/flexcan/install)下的include/can_netlink.h和libsocketcan.h文件,拷贝到canutils4.0.6/include目录下

4、测试过程: 
准备:两个板子CAN总线进行相应管脚对接;

   开发板命令:
  • 1
  • 2

设置比特率: iplinksetcan0uptypecanbitrate125000使can0线 ifconfig can0 up 
查看can0信息: $ ifconfig can0

发送数据到0x123地址: 
$ cansend can0 -i 0x123 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88

接收0x123地址数据: 
canechocan0?v candump can0 –filter 0x123:/未设置ID滤波 
或$ candump can0 –filter 0x123: 0x7FF/设置使用ID滤波 /

说明: 
接收时,未使用ID滤波,可以接收总线上的所有数据,无论ID是否正确; 
接收时,使用ID滤波,就只有符合要求的ID的数据,才做接收,其他ID的数据均丢弃不管。

使用以上测试方法测试时,发现filter id最大可用值为0x7FF; 
ID = 0x7FF = 1111111 1111 = 11bit地址,说明当前使用的是标准格式; 
如果想使用更多地址,需要设置为扩展帧格式。

如何设置CAN总线数据帧为扩展帧格式呢?

经过查看CAN驱动源码发现: 
在d-chip-linux3.0.35/drivers/net/can/flexcan.c中,有如下开始传输函数: 
static int flexcan_start_xmit(struct sk_buff* skb,struct net_device *dev) 

if (cf->can_id & CAN_EFF_FLAG) { 
can_id = cf->can_id & CAN_EFF_MASK; 
ctrl |= FLEXCAN_MB_CNT_IDE | FLEXCAN_MB_CNT_SRR; 
} else { 
can_id = (cf->can_id & CAN_SFF_MASK) << 18; 
}

if (cf->can_id & CAN_RTR_FLAG) 
ctrl |= FLEXCAN_MB_CNT_RTR;

if (cf->can_dlc > 0) { 
u32 data = be32_to_cpup((__be32 *)&cf->data[0]); 
writel(data,&regs->cantxfg[FLEXCAN_TX_BUF_ID].data[0]); 

if (cf->can_dlc > 3) { 
u32 data = be32_to_cpup((__be32 *)&cf->data[4]); 
writel(data,&regs->cantxfg[FLEXCAN_TX_BUF_ID].data[1]); 


查看以上源码发现: 
由cf->can_id & CAN_EFF_FLAG 按位’与’的运算结果来判断当前是否是扩展帧格式,cf->can_id 是命令行设置的Filter ID, CAN_EFF_FLAG宏定义为0x80000000;因此,当命令行下设置ID时,使其最高位( id[31] )为1,即表示选择为扩展帧格式;0表示选择为标准帧格式。 
而cf->can_id & CAN_RTR_FLAG用来判断是否设置远程帧请求;

以下是源码中的结构说明: 
/* 
*Controller Area Network Identifier structure 

*bit 0-28 : CAN identifier (11/29 bit) 
*bit 29 : error frame flag (0 = dataframe, 1 = error frame) 
*bit 30 : remote transmission requestflag (1 = rtr frame) 
*bit 31 : frame format flag (0 =standard 11 bit, 1 = extended 29 bit) 
*/ 
/** 
*struct can_frame - basic CAN frame structure 
*@can_id: the CAN ID of the frame andCAN_*_FLAG flags, see above. 
*@can_dlc: the data length field of the CAN frame 
*@data: the CAN frame payload. 
*/ 
struct can_frame { 
canid_t can_id; /* 32bit CAN_ID + EFF/RTR/ERR flags */ 
__u8 can_dlc; /* datalength code: 0 .. 8 */ 
u8 data[8] __attribute((aligned(8))); /* 设定为8字节对齐 */ 
};

根据以上研究表明,想使用扩展帧格式,可按如下方法使用: 
ifconfigcan0down/?CANCAN?/ ip link set can0 up type can bitrate 125000 /* 配置比特率并打开 */ 
ifconfigcan0/?CAN?/ cansend can0 -i 0x81234567 0x11 0x22 0x33 0x440x55 0x66 0x77 0x88 /* 发送8bytes数据到ID=0x1234567 */

canechocan0?v candump can0 –filter 0x81234567: 或 
$ candump can0 –filter 0x81234567:0x1FFFFFFF 
最大ID地址为0x1FFFFFFF ,即:–filter 0x9FFFFFFF:






































































以上是关于i.MX6Q -- Linux系统下FlexCAN总线的使用记录的主要内容,如果未能解决你的问题,请参考以下文章

基于迅为-i.MX6Q开发板制作镜像方法

飞凌i.MX6Q开发板Android系统下可以实现APP签名啦!速来

飞凌i.MX6Q开发板Android系统下可以实现APP签名啦!速来

ARM开发板如何选型-I.MX6Q开发板

ARM知识分享-i.MX6Q GPIO复用修改方法

产品研发ARM开发板如何选择?飞思卡尔I.MX6Q开发板