0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

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

英創(chuàng)信息技術(shù) ? 作者:英創(chuàng)信息技術(shù) ? 2019-10-22 11:34 ? 次閱讀

CAN(Controller Area Network)即控制器局域網(wǎng),由于具有高性能、高可靠性以及簡單的網(wǎng)絡(luò)結(jié)構(gòu),在工業(yè)系統(tǒng)中越來越受到人們的重視,并迅速成為了目前國際上應(yīng)用最廣泛的現(xiàn)場總線之一。

英利嵌入式Linux工控主板EM9260是一款面向工業(yè)自動化領(lǐng)域的高性價比工控板,板上帶有標(biāo)準(zhǔn)CAN通訊接口。與板上其他標(biāo)準(zhǔn)通訊接口一樣,EM9260的CAN接口實現(xiàn)了相應(yīng)的嵌入式Linux驅(qū)動程序,應(yīng)用程序可以通過打開文件的進行讀寫的標(biāo)準(zhǔn)方式實現(xiàn)對CAN總線接口的數(shù)據(jù)通訊。本文側(cè)重于介紹CAN通訊方案。

硬件組成

EM9260嵌入式Linux工控板的CAN均采用了PHILIPS半導(dǎo)體公司的SJA1000T CAN總線控制器,SJA1000是一款獨立的控制器,主要用于汽車和一般工業(yè)環(huán)境中的控制器局域網(wǎng)絡(luò)(CAN)芯片,它是PHILIPS半導(dǎo)體PCA82C200 CAN控制器(BasicCAN)的替代產(chǎn)品,而且它增加了一種新的工作模式(PeliCAN),這種模式支持具有很多新特性的CAN 2.0B協(xié)議。

EM9260的CAN通訊接口可提供高達(dá)1Mbps的數(shù)據(jù)傳輸速率,當(dāng)采用5Kbps的的數(shù)據(jù)傳輸速率時其通訊距離最高可達(dá)到10KM。硬件的錯誤檢定特性也增強了CAN的抗電磁干擾能力,這給數(shù)據(jù)的遠(yuǎn)程可靠傳輸提供了有利保證。

EM9260的CAN通訊接口根據(jù)用戶的需要分為兩種:一種帶光電隔離,一種不帶光電隔離。帶光電隔離CAN總線通訊模塊的CAN收發(fā)器端的所有信號電源與其它部分完全隔離,可承受至少1Kv(有效值)的電壓沖擊。光電隔離的功能可在EM9260的應(yīng)用底板上來實現(xiàn),英利公司在EM9260評估底板上提供了相應(yīng)的參考電路。

CAN驅(qū)動接口函數(shù)

1、CAN報文的幀格式簡介
在CAN2.0B中存在兩種不同的幀格式,其主要的區(qū)別在于標(biāo)識符的長度,具有11位標(biāo)識符的幀稱為標(biāo)準(zhǔn)幀,而包括有29位標(biāo)識符的幀稱為擴展幀。下面分別介紹數(shù)據(jù)幀的格式。

1、CAN2.0B標(biāo)準(zhǔn)幀
CAN標(biāo)準(zhǔn)幀信息為11個字節(jié),包括兩部分:信息和數(shù)據(jù)部分。前3個字節(jié)為信息部分,如圖所示:

注:1、字節(jié)1為幀信息。D7位表示幀格式,在標(biāo)準(zhǔn)幀中,F(xiàn)F=0;D6位表示幀的類型,RTR=0表示為數(shù)據(jù)幀,RTR=1表示為
遠(yuǎn)程幀,在一般的數(shù)據(jù)通訊中,只使用數(shù)據(jù)幀;DLC表示數(shù)據(jù)幀實際的數(shù)據(jù)長度
2、字節(jié)2、字節(jié)3為報文識別碼,11位有效
3、字節(jié)4~字節(jié)11為數(shù)據(jù)幀的實際數(shù)據(jù),遠(yuǎn)程幀時無效

2、CAN2.0B擴展幀
CAN標(biāo)準(zhǔn)幀信息為13個字節(jié),包括兩部分:信息和數(shù)據(jù)部分。前5個字節(jié)為信息部分,如圖所示:

注:1、字節(jié)1為幀信息。D7位表示幀格式,在擴展幀中,F(xiàn)F=1;D6位表示幀的類型,RTR=0表示為數(shù)據(jù)幀,RTR=1表示為
遠(yuǎn)程幀;DLC表示數(shù)據(jù)幀實際的數(shù)據(jù)長度
2、字節(jié)2~字節(jié)5為報文識別碼,29位有效
3、字節(jié)6~字節(jié)13為數(shù)據(jù)幀的實際數(shù)據(jù),遠(yuǎn)程幀時無效

2、CAN應(yīng)用數(shù)據(jù)結(jié)構(gòu)
英利公司提供的基于嵌入式Linux下的CAN操作API函數(shù),為了方便用戶的使用,結(jié)合目前常用的一些方法,對于CAN接口接收的數(shù)據(jù)報文采用了以下結(jié)構(gòu)。

struct can_frame
{
canid_t can_id; /* 用于定義CAN報文ID以及 EFF/RTR/ERR等標(biāo)志 */
__u8 can_dlc; /* 用于定義can報文數(shù)據(jù)包長度0-8 */
__u8 data[8]; /* 用于定義can報文數(shù)據(jù) */
};

其中的can報文ID為一個32 bit大小的結(jié)構(gòu),其中各個bit位定義如下:
typedef __u32 canid_t;
bit 0-28: CAN 報文的id(標(biāo)準(zhǔn)幀11bit/擴展幀為29bit).
bit 29 : CAN報文錯誤幀標(biāo)志(0 = data frame, 1 = error frame)
bit 30 : CAN報文遠(yuǎn)程幀標(biāo)志( 1 = rtr frame )
bit 31 : CAN報文幀格式標(biāo)志 (0 = 標(biāo)準(zhǔn)幀, 1 = 擴展幀 )

在進行CAN通訊時需要設(shè)置相關(guān)的參數(shù),包括波特率、選取的數(shù)據(jù)濾波方式等,其中對于濾波器的設(shè)置,在濾波器的作用下,只有當(dāng)接收報文中的標(biāo)識位和驗收濾波器預(yù)定義的位值相等時,CAN控制器才允許將收到的報文存入RXFIFO中。為了方便使用,在英利公司的API函數(shù)中采用了一個struct accept_filter用來設(shè)置相關(guān)驗收濾波器的相關(guān)定義。

struct accept_filter
{
unsigned int accept_code; /* 用于定義CAN報文驗收代碼位 32bit*/
unsigned int accept_mask; /* 用于定義CAN報文驗收屏蔽位 32bit*/
unsigned char filter_mode; /* 用于定義CAN報文濾波模式 */
};

3、CAN通訊接口API函數(shù)
EM9260的系統(tǒng)內(nèi)核中實現(xiàn)了CAN接口的驅(qū)動,實現(xiàn)CAN接口 open( ) / close() 、read( ) / write( )等函數(shù)操作。和在Linux下操作設(shè)備的方式和操作文件的方式一樣,調(diào)用open( )打開設(shè)備文件,再調(diào)用read( )、write( )對CAN接口進行數(shù)據(jù)讀寫操作。另外在此驅(qū)動程序的基礎(chǔ)上,封裝了一套簡單實用的API函數(shù),以滿足對于CAN接口一些特殊參數(shù)設(shè)置的需要。各個函數(shù)的定義在can_api.h文件下,在該頭文件中對于各個API函數(shù)均有相應(yīng)的中文說明。

具體在進行應(yīng)用程序開發(fā)時,首先調(diào)用CAN接口的open( )函數(shù)打開CAN接口:
sprintf( portname, '/dev/em9x60_can%d', CanNo );
m_fd = open(portname, O_RDWR |O_NONBLOCK );

得到有效的文件描述符m_fd后,然后可調(diào)用can_api.h文件中定義的API函數(shù)對CAN接口進行相應(yīng)的通訊參數(shù)設(shè)置:
CAN_StartChip( m_fd );
CAN_SetBaudRate( m_fd, baudrate );
CAN_SetGlobalAcceptanceFilter( m_fd, AcceptanceFilter );

再調(diào)用read( ) / write( ) 實現(xiàn)CAN數(shù)據(jù)的收發(fā)操作。

4、CAN通訊接口的數(shù)據(jù)收發(fā)應(yīng)用示例
在英利公司提供的CAN方案中,CAN通訊的數(shù)據(jù)收發(fā)均采用的中斷方式,驅(qū)動程序中已自動完成了數(shù)據(jù)的收發(fā),以及內(nèi)部定義的CAN接收緩沖區(qū)和發(fā)送緩沖區(qū)的管理。對于用戶開發(fā)應(yīng)用程序來說,只需要調(diào)用英創(chuàng)公司提供的CAN通訊API函數(shù)中的收發(fā)函數(shù)即可。本小節(jié)主要介紹一個CAN通訊的綜合應(yīng)用示例程序。

app_cantest是一個支持CAN數(shù)據(jù)通訊的示例,該例程采用了面向?qū)ο蟮?a href="http://wenjunhu.com/tags/C++/" target="_blank">C++編程,把CAN數(shù)據(jù)通訊作為一個對象進行封裝,用戶調(diào)用該對象提供的接口函數(shù)即可方便地完成CAN數(shù)據(jù)通訊的操作。

// 定義CAN通訊類
class EM9X60_CAN
{
private:
// 通訊線程標(biāo)識符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;
// 退出數(shù)據(jù)接收線程標(biāo)志
int m_ExitThreadFlag;
// 按照指定的參數(shù)打開CAN接口,并創(chuàng)建CAN接口接收線程
int OpenCAN( int CanNo, CAN_BAUDRATE baudrate, accept_filter*AcceptanceFilter );
// 關(guān)閉接口并釋放相關(guān)資源
int CloseCAN( );
// 初始化設(shè)置CAN數(shù)據(jù)包id信息
int InitCanIDInfo( struct CanIDInfo* pcanid );
// CAN接口寫數(shù)據(jù)
int WriteCAN( char* Buf, int len );
// CAN接收數(shù)據(jù)處理函數(shù)
virtual int PackagePro( char* Buf, int len );
};

OpenCAN 函數(shù)用于根據(jù)輸入?yún)?shù)打開CAN設(shè)備,并創(chuàng)建CAN數(shù)據(jù)接收線程。

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

ReceiveThreadFunc函數(shù)是CAN數(shù)據(jù)接收和處理的主要核心代碼,在該函數(shù)中調(diào)用select( ),等待串口數(shù)據(jù)的到來。對于接收到的數(shù)據(jù)處理也是在該函數(shù)中實現(xiàn),在本例程中處理為簡單的數(shù)據(jù)回發(fā),用戶可結(jié)合實際的應(yīng)用修改此處代碼,修改PackagePro( )函數(shù)即可。流程如下:

int EM9X60_CAN::ReceiveThreadFunc(void* lparam)
{
EM9X60_CAN *pCAN = (EM9X60_CAN*)lparam;
int len;
// 定義讀事件集合
fd_set fdRead;
int ret;
struct timeval aTime;
while( 1 )
{
// 收到退出事件,結(jié)束線程
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 )
{
// 對接收的數(shù)據(jù)進行處理,這里為簡單的數(shù)據(jù)回發(fā)
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( )函數(shù)中的時間參數(shù)在Linux下,每次都需要重新賦值,否則會自動歸0。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11304

    瀏覽量

    209476
  • 嵌入式主板
    +關(guān)注

    關(guān)注

    7

    文章

    6085

    瀏覽量

    35330
收藏 人收藏

    評論

    相關(guān)推薦

    AT91SAM9260工控主板

    `關(guān)鍵詞:9260核心9260核心模塊,ATMEL9260杭州啟揚智能科技有限公司隆重推出ARM架構(gòu)EZ9260 ARM9
    發(fā)表于 04-21 10:05

    嵌入式Linux CAN的相關(guān)資料推薦

    文章目錄前言CAN終端測試SocketCANC語言CAN發(fā)送示例C語言CAN接收示例微信公眾號前言這是前篇:嵌入式Linux i.MX開發(fā)
    發(fā)表于 10-27 09:40

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

    英利EM9x60系列工控主板包括兩個型號:EM9160和EM9260。為便于讀者了解和使用英利產(chǎn)品,本手冊中一些部分會以EM9160為例進行
    發(fā)表于 11-09 21:47 ?34次下載

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

    英創(chuàng)公司新近推出的嵌入式工控主板EM9160是一款專門面向工業(yè)智能設(shè)備的高性價比ARM9+WinCE平臺,該工控主板不僅配置了常規(guī)的標(biāo)準(zhǔn)通訊
    發(fā)表于 04-09 15:49 ?36次下載

    嵌入式LinuxCAN接口調(diào)試

    CAN(Controller Area Network)總線是嵌入式設(shè)備最為常用的接口之一,常用于汽車以及工業(yè)自動化等嵌入式領(lǐng)域,因此本文就基于嵌入式
    發(fā)表于 04-29 16:40 ?3277次閱讀

    基于EM9170嵌入式工控主板的通用數(shù)采方案

    方案EM9170嵌入式工控和應(yīng)用擴展底板EX810構(gòu)成,EM9170作為核心
    的頭像 發(fā)表于 10-12 11:36 ?1527次閱讀
    基于<b class='flag-5'>EM</b>9170<b class='flag-5'>嵌入式</b><b class='flag-5'>工控</b>主板的通用數(shù)采<b class='flag-5'>方案</b>

    基于EM9460的ETA501使用方法

    本文將以EM9460為例介紹ETA501的使用方法,該方法同樣適用于英利的其他Linux嵌入式主板產(chǎn)品,如EM9160、EM9260等。
    的頭像 發(fā)表于 10-27 11:09 ?1931次閱讀

    英創(chuàng)信息技術(shù)工控主板的復(fù)位管理介紹

     英創(chuàng)公司的工控主板是基于ARM9 CPU、預(yù)裝正版WinCE的嵌入式主板產(chǎn)品。作為嵌入式應(yīng)用,系統(tǒng)的可靠啟動是其可靠性的重要組成部分。本文針對嵌入式應(yīng)用的特點、介紹英創(chuàng)基于ATMEL
    的頭像 發(fā)表于 11-14 10:03 ?1673次閱讀
    英創(chuàng)信息技術(shù)<b class='flag-5'>工控</b>主板的復(fù)位管理介紹

    英創(chuàng)信息技術(shù)嵌入式Linux工控EM9160介紹

    I2C總線是一種2線制的主從通訊協(xié)議,主要運用于器件之間的數(shù)據(jù)通訊,在嵌入式系統(tǒng)中得到非常廣泛的應(yīng)用。作為一款高性價比的嵌入式Linux
    的頭像 發(fā)表于 01-14 10:57 ?1337次閱讀
    英創(chuàng)信息技術(shù)<b class='flag-5'>嵌入式</b><b class='flag-5'>Linux</b><b class='flag-5'>工控</b><b class='flag-5'>板</b><b class='flag-5'>EM</b>9160介紹

    英創(chuàng)信息技術(shù)嵌入式Linux工控EM9160介紹

    嵌入式Linux主板EM9160主要應(yīng)用之一就是可以作為智能終端的核心平臺,智能終端總是帶有一種顯示單元。EM9160作為一種高效、低成本的產(chǎn)品解決
    的頭像 發(fā)表于 01-14 11:20 ?1389次閱讀

    英創(chuàng)信息技術(shù)EM9170嵌入式主板CAN通訊接口使用說明

    英創(chuàng)公司推出的基于WinCE 6.0操作系統(tǒng)的嵌入式工控板卡EM9170,上帶有2路獨立的CAN總線接口,均為FlexCAN模塊。Flex
    的頭像 發(fā)表于 01-15 11:43 ?1889次閱讀

    英創(chuàng)信息技術(shù)Linux嵌入式工控支持電容屏介紹

    隨著嵌入式應(yīng)用對GUI圖形界面需求的增加,Qt在Linux嵌入式設(shè)備中的使用越來越廣泛,許多應(yīng)用也都對人機交互界面有一定的要求。因此觸摸屏、鼠標(biāo)等設(shè)備等支持也變得重要起來,英創(chuàng)Linux
    的頭像 發(fā)表于 02-03 09:37 ?6548次閱讀
    英創(chuàng)信息技術(shù)<b class='flag-5'>Linux</b><b class='flag-5'>嵌入式</b><b class='flag-5'>工控</b><b class='flag-5'>板</b>支持電容屏介紹

    嵌入式Linux串口擴展的驅(qū)動設(shè)計方案解析

    方案介紹WK2X系列UARTs在嵌入式Linux(Android)下擴展多串口方案,尤其是嵌入式Lin
    發(fā)表于 08-31 15:35 ?1449次閱讀
    <b class='flag-5'>嵌入式</b><b class='flag-5'>Linux</b>串口擴展的驅(qū)動設(shè)計<b class='flag-5'>方案</b><b class='flag-5'>解析</b>

    嵌入式Linux CAN

    文章目錄前言CAN終端測試SocketCANC語言CAN發(fā)送示例C語言CAN接收示例微信公眾號前言這是前篇:嵌入式Linux i.MX開發(fā)
    發(fā)表于 10-19 18:33 ?6次下載
    <b class='flag-5'>嵌入式</b><b class='flag-5'>Linux</b> <b class='flag-5'>CAN</b>

    嵌入式Linux network

    文章目錄前言網(wǎng)絡(luò)通信簡介服務(wù)器程序客戶端程序運行微信公眾號前言這是前篇:嵌入式Linux i.MX開發(fā)嵌入式Linux NFS
    發(fā)表于 11-02 10:51 ?15次下載
    <b class='flag-5'>嵌入式</b><b class='flag-5'>Linux</b> network