0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

EM9260嵌入式Linux工控板的CAN通讯方案解析

英创信息技术 作者:英创信息技术 2019-10-22 11:34 次阅读

CAN(Controller Area Network)即控制器局域网,由于具有高性能、高可靠性以及简单的网络结构,在工业系统中越来越受到人们的重视,并迅速成为了目前国际上应用最广泛的现场总线之一。

英利嵌入式Linux工控主板EM9260是一款面向工业自动化领域的高性价比工控板,板上带有标准CAN通讯接口。与板上其他标准通讯接口一样,EM9260的CAN接口实现了相应的嵌入式Linux驱动程序,应用程序可以通过打开文件的进行读写的标准方式实现对CAN总线接口的数据通讯。本文侧重于介绍CAN通讯方案。

硬件组成

EM9260嵌入式Linux工控板的CAN均采用了PHILIPS半导体公司的SJA1000T CAN总线控制器,SJA1000是一款独立的控制器,主要用于汽车和一般工业环境中的控制器局域网络(CAN)芯片,它是PHILIPS半导体PCA82C200 CAN控制器(BasicCAN)的替代产品,而且它增加了一种新的工作模式(PeliCAN),这种模式支持具有很多新特性的CAN 2.0B协议。

EM9260的CAN通讯接口可提供高达1Mbps的数据传输速率,当采用5Kbps的的数据传输速率时其通讯距离最高可达到10KM。硬件的错误检定特性也增强了CAN的抗电磁干扰能力,这给数据的远程可靠传输提供了有利保证。

EM9260的CAN通讯接口根据用户的需要分为两种:一种带光电隔离,一种不带光电隔离。带光电隔离CAN总线通讯模块的CAN收发器端的所有信号电源与其它部分完全隔离,可承受至少1Kv(有效值)的电压冲击。光电隔离的功能可在EM9260的应用底板上来实现,英利公司在EM9260评估底板上提供了相应的参考电路。

CAN驱动接口函数

1、CAN报文的帧格式简介
在CAN2.0B中存在两种不同的帧格式,其主要的区别在于标识符的长度,具有11位标识符的帧称为标准帧,而包括有29位标识符的帧称为扩展帧。下面分别介绍数据帧的格式。

1、CAN2.0B标准帧
CAN标准帧信息为11个字节,包括两部分:信息和数据部分。前3个字节为信息部分,如图所示:

注:1、字节1为帧信息。D7位表示帧格式,在标准帧中,FF=0;D6位表示帧的类型,RTR=0表示为数据帧,RTR=1表示为
远程帧,在一般的数据通讯中,只使用数据帧;DLC表示数据帧实际的数据长度
2、字节2、字节3为报文识别码,11位有效
3、字节4~字节11为数据帧的实际数据,远程帧时无效

2、CAN2.0B扩展帧
CAN标准帧信息为13个字节,包括两部分:信息和数据部分。前5个字节为信息部分,如图所示:

注:1、字节1为帧信息。D7位表示帧格式,在扩展帧中,FF=1;D6位表示帧的类型,RTR=0表示为数据帧,RTR=1表示为
远程帧;DLC表示数据帧实际的数据长度
2、字节2~字节5为报文识别码,29位有效
3、字节6~字节13为数据帧的实际数据,远程帧时无效

2、CAN应用数据结构
英利公司提供的基于嵌入式Linux下的CAN操作API函数,为了方便用户的使用,结合目前常用的一些方法,对于CAN接口接收的数据报文采用了以下结构。

struct can_frame
{
canid_t can_id; /* 用于定义CAN报文ID以及 EFF/RTR/ERR等标志 */
__u8 can_dlc; /* 用于定义can报文数据包长度0-8 */
__u8 data[8]; /* 用于定义can报文数据 */
};

其中的can报文ID为一个32 bit大小的结构,其中各个bit位定义如下:
typedef __u32 canid_t;
bit 0-28: CAN 报文的id(标准帧11bit/扩展帧为29bit).
bit 29 : CAN报文错误帧标志(0 = data frame, 1 = error frame)
bit 30 : CAN报文远程帧标志( 1 = rtr frame )
bit 31 : CAN报文帧格式标志 (0 = 标准帧, 1 = 扩展帧 )

在进行CAN通讯时需要设置相关的参数,包括波特率、选取的数据滤波方式等,其中对于滤波器的设置,在滤波器的作用下,只有当接收报文中的标识位和验收滤波器预定义的位值相等时,CAN控制器才允许将收到的报文存入RXFIFO中。为了方便使用,在英利公司的API函数中采用了一个struct accept_filter用来设置相关验收滤波器的相关定义。

struct accept_filter
{
unsigned int accept_code; /* 用于定义CAN报文验收代码位 32bit*/
unsigned int accept_mask; /* 用于定义CAN报文验收屏蔽位 32bit*/
unsigned char filter_mode; /* 用于定义CAN报文滤波模式 */
};

3、CAN通讯接口API函数
EM9260的系统内核中实现了CAN接口的驱动,实现CAN接口 open( ) / close() 、read( ) / write( )等函数操作。和在Linux下操作设备的方式和操作文件的方式一样,调用open( )打开设备文件,再调用read( )、write( )对CAN接口进行数据读写操作。另外在此驱动程序的基础上,封装了一套简单实用的API函数,以满足对于CAN接口一些特殊参数设置的需要。各个函数的定义在can_api.h文件下,在该头文件中对于各个API函数均有相应的中文说明。

具体在进行应用程序开发时,首先调用CAN接口的open( )函数打开CAN接口:
sprintf( portname, '/dev/em9x60_can%d', CanNo );
m_fd = open(portname, O_RDWR |O_NONBLOCK );

得到有效的文件描述符m_fd后,然后可调用can_api.h文件中定义的API函数对CAN接口进行相应的通讯参数设置:
CAN_StartChip( m_fd );
CAN_SetBaudRate( m_fd, baudrate );
CAN_SetGlobalAcceptanceFilter( m_fd, AcceptanceFilter );

再调用read( ) / write( ) 实现CAN数据的收发操作。

4、CAN通讯接口的数据收发应用示例
在英利公司提供的CAN方案中,CAN通讯的数据收发均采用的中断方式,驱动程序中已自动完成了数据的收发,以及内部定义的CAN接收缓冲区和发送缓冲区的管理。对于用户开发应用程序来说,只需要调用英创公司提供的CAN通讯API函数中的收发函数即可。本小节主要介绍一个CAN通讯的综合应用示例程序。

app_cantest是一个支持CAN数据通讯的示例,该例程采用了面向对象的C++编程,把CAN数据通讯作为一个对象进行封装,用户调用该对象提供的接口函数即可方便地完成CAN数据通讯的操作。

// 定义CAN通讯类
class EM9X60_CAN
{
private:
// 通讯线程标识符ID
pthread_t m_thread;
// CAN接收线程
static int ReceiveThreadFunc( void* lparam );
public:
EM9X60_CAN();
virtual ~EM9X60_CAN();
// 已打开的CAN文件描述符
int m_fd;
unsigned int m_canid;
can_frame rxmsg;
// 退出数据接收线程标志
int m_ExitThreadFlag;
// 按照指定的参数打开CAN接口,并创建CAN接口接收线程
int OpenCAN( int CanNo, CAN_BAUDRATE baudrate, accept_filter*AcceptanceFilter );
// 关闭接口并释放相关资源
int CloseCAN( );
// 初始化设置CAN数据包id信息
int InitCanIDInfo( struct CanIDInfo* pcanid );
// CAN接口写数据
int WriteCAN( char* Buf, int len );
// CAN接收数据处理函数
virtual int PackagePro( char* Buf, int len );
};

OpenCAN 函数用于根据输入参数打开CAN设备,并创建CAN数据接收线程。

res = pthread_create( &m_thread, &attr, (void*)&ReceiveThreadFunc, (void*)this );

ReceiveThreadFunc函数是CAN数据接收和处理的主要核心代码,在该函数中调用select( ),等待串口数据的到来。对于接收到的数据处理也是在该函数中实现,在本例程中处理为简单的数据回发,用户可结合实际的应用修改此处代码,修改PackagePro( )函数即可。流程如下:

int EM9X60_CAN::ReceiveThreadFunc(void* lparam)
{
EM9X60_CAN *pCAN = (EM9X60_CAN*)lparam;
int len;
// 定义读事件集合
fd_set fdRead;
int ret;
struct timeval aTime;
while( 1 )
{
// 收到退出事件,结束线程
if( pCAN->m_ExitThreadFlag )
{
break;
}
FD_ZERO(&fdRead);
FD_SET(pCAN->m_fd,&fdRead);
aTime.tv_sec = 0;
aTime.tv_usec = 30000;
ret = select( pCAN->m_fd+1,&fdRead,NULL,NULL,&aTime );
if (ret < 0 )
{
pCAN->CloseCAN( );
break;
}
if (ret >= 0)
{
// 判断是否读事件
if (FD_ISSET(pCAN->m_fd,&fdRead))
{
len = read( pCAN->m_fd, (char*)&pCAN->rxmsg, sizeof(can_frame) );
while( len > 0 )
{
// 对接收的数据进行处理,这里为简单的数据回发
pCAN->PackagePro( (char*)&pCAN->rxmsg, len );
// 处理完毕
len = read( pCAN->m_fd, (char*)&pCAN->rxmsg, sizeof(can_frame) );
}
}
}
}
printf( 'ReceiveThreadFunc finished\n' );
pthread_exit( NULL );
return 0;
}

需要注意的是,select( )函数中的时间参数在Linux下,每次都需要重新赋值,否则会自动归0。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    87

    文章

    10942

    浏览量

    206545
  • 嵌入式主板
    +关注

    关注

    7

    文章

    6060

    浏览量

    34565
收藏 人收藏

    评论

    相关推荐

    AT91SAM9260工控主板

    `关键词:9260核心9260核心模块,ATMEL9260杭州启扬智能科技有限公司隆重推出ARM架构EZ9260 ARM9
    发表于 04-21 10:05

    一种基于EM335x的工控应用方案

    EM335x资源并提供实际应用方法,英创公司基于EM335x工控主板,设计了以通讯为主的嵌入式工控
    发表于 07-05 16:48

    嵌入式Linux CAN的相关资料推荐

    文章目录前言CAN终端测试SocketCANC语言CAN发送示例C语言CAN接收示例微信公众号前言这是前篇:嵌入式Linux i.MX开发
    发表于 10-27 09:40

    嵌入式Linux network的相关资料分享

    文章目录前言网络通信简介服务器程序客户端程序运行微信公众号前言这是前篇:嵌入式Linux i.MX开发嵌入式Linux NFS
    发表于 11-05 09:29

    英利Linux工控主板使用必读(EM9x60)

    英利EM9x60系列工控主板包括两个型号:EM9160和EM9260。为便于读者了解和使用英利产品,本手册中一些部分会以EM9160为例进行
    发表于 11-09 21:47 33次下载

    嵌入式工控主板EM9160的PWM功能

    英创公司新近推出的嵌入式工控主板EM9160是一款专门面向工业智能设备的高性价比ARM9+WinCE平台,该工控主板不仅配置了常规的标准通讯
    发表于 04-09 15:49 36次下载

    CAN接口COM组件的实现

    控制器局域网( CAN )是一个串行、异步、多主的通信协议,它以其高性能、高可靠性以及灵活的设计受到人们的重视,应用越来越广泛。英创公司的ARM9 工控主板如EM9161,EM9260
    发表于 06-09 15:31 57次下载

    嵌入式LinuxCAN接口调试

    CAN(Controller Area Network)总线是嵌入式设备最为常用的接口之一,常用于汽车以及工业自动化等嵌入式领域,因此本文就基于嵌入式
    发表于 04-29 16:40 3041次阅读

    基于EM9170嵌入式工控主板的通用数采方案

    方案EM9170嵌入式工控板和应用扩展底板EX810构成,EM9170作为核心板插在EX810应用底板上工作,主要的接口资源均从EX81
    的头像 发表于 10-12 11:36 1281次阅读
    基于<b class='flag-5'>EM</b>9170<b class='flag-5'>嵌入式</b><b class='flag-5'>工控</b>主板的通用数采<b class='flag-5'>方案</b>

    基于EM9460的ETA501使用方法

    本文将以EM9460为例介绍ETA501的使用方法,该方法同样适用于英利的其他Linux嵌入式主板产品,如EM9160、EM9260等。
    的头像 发表于 10-27 11:09 1647次阅读

    英创信息技术9260系列嵌入式主板调试浅谈

    操作系统平台,这使得英创嵌入式主板能够应用在智能设备、工业控制、通讯管理等等更加广泛的领域。为了方便客户开发,英创公司的ARM9系列嵌入式主板(包括EM9000和
    的头像 发表于 11-01 09:24 1667次阅读
    英创信息技术<b class='flag-5'>9260</b>系列<b class='flag-5'>嵌入式</b>主板调试浅谈

    英创信息技术工控主板的复位管理介绍

    AT91SAM9芯片的各个产品线的启动特点,这些产品包括:EM9160、EM9260EM9360、EM9360G、EM9160L等。用户在
    的头像 发表于 11-14 10:03 1313次阅读
    英创信息技术<b class='flag-5'>工控</b>主板的复位管理介绍

    英创信息技术嵌入式Linux工控EM9160介绍

    I2C总线是一种2线制的主从通讯协议,主要运用于器件之间的数据通讯,在嵌入式系统中得到非常广泛的应用。作为一款高性价比的嵌入式Linux
    的头像 发表于 01-14 10:57 1073次阅读
    英创信息技术<b class='flag-5'>嵌入式</b><b class='flag-5'>Linux</b><b class='flag-5'>工控</b>板<b class='flag-5'>EM</b>9160介绍

    英创信息技术EM9287 Linux Socket CAN驱动简介

    CAN是一种在世界范围内广泛用于自动控制、嵌入式设备和汽车领域的网络技术,EM9287 的CAN通讯接口是通过FlexCAN模块来实现控制
    的头像 发表于 01-16 10:12 1254次阅读
    英创信息技术<b class='flag-5'>EM</b>9287 <b class='flag-5'>Linux</b> Socket <b class='flag-5'>CAN</b>驱动简介

    嵌入式Linux CAN

    文章目录前言CAN终端测试SocketCANC语言CAN发送示例C语言CAN接收示例微信公众号前言这是前篇:嵌入式Linux i.MX开发板
    发表于 10-19 18:33 6次下载
    <b class='flag-5'>嵌入式</b><b class='flag-5'>Linux</b> <b class='flag-5'>CAN</b>