一、簡(jiǎn)述
EM9287工控主板CPU為Freescale 的iMX287,主頻454MHz,以具有豐富的通訊接口為特色,可同時(shí)支持雙網(wǎng)口、7路串口、32路GPIO、SPI、I2C以及CAN通訊等接口。CAN是一種在世界范圍內(nèi)廣泛用于自動(dòng)控制、嵌入式設(shè)備和汽車領(lǐng)域的網(wǎng)絡(luò)技術(shù),EM9287 的CAN通訊接口是通過(guò)FlexCAN模塊來(lái)實(shí)現(xiàn)控制局域網(wǎng)絡(luò)協(xié)議(CAN)通信的,F(xiàn)lexCAN模塊同時(shí)支持CAN協(xié)議規(guī)范2.0,包括協(xié)議所規(guī)定的標(biāo)準(zhǔn)幀和擴(kuò)展幀。
Linux下最早使用CAN的方法是基于字符設(shè)備來(lái)實(shí)現(xiàn)的,在EM9287上移植的Linux-3.9.7內(nèi)核中FlexCAN模塊驅(qū)動(dòng)實(shí)現(xiàn)的是Socket CAN方式,Scoket CAN使用了socket接口和Linux網(wǎng)絡(luò)協(xié)議棧,這種方法使得CAN設(shè)備驅(qū)動(dòng)可以通過(guò)網(wǎng)絡(luò)接口函數(shù)來(lái)調(diào)用,這樣大大地方便了熟悉Linux網(wǎng)絡(luò)編程的程序員,由于調(diào)用的都是標(biāo)準(zhǔn)的socket 函數(shù),也使得應(yīng)用程序便于移植,而不會(huì)因?yàn)橛布恼{(diào)整而修改應(yīng)用程序,這樣加強(qiáng)了應(yīng)用程序的可維護(hù)性。關(guān)于Socket CAN在Linux內(nèi)核文檔中有更為詳細(xì)的介紹(/Linux-3.9.7/Documentation/networtking/can.txt)。
本文將簡(jiǎn)要介紹EM9287在Linux-3.9.7內(nèi)核上如何實(shí)現(xiàn)CAN驅(qū)動(dòng)以及如何在應(yīng)用程序中使用Socket CAN。
二、Linux內(nèi)核配置
內(nèi)核配置中增加以下選項(xiàng)(make menuconfig):
Networking support --->
<*> CAN bus subsystem support --->
<*> Raw CAN Protocol (raw access with CAN-ID filtering)
<*> Broadcast Manger CAN Protocol (with content filtering)
<*> CAN Gateway/Router (with netlink configuration)
CAN Device Drivers --->
<*> Platform CAN drivers with Netlink support
[*] CAN bit-timing calculation
<*> Support for Freescale FLEXCAN based chips
EM9287移植的是Linux-3.9.7版本,對(duì)于硬件的描述和配置都是通過(guò)device tree相關(guān)文件進(jìn)行傳遞,除了內(nèi)核的配置外,還需要在相應(yīng)的dst文件中增加can0節(jié)點(diǎn)。如:
can0: can@80032000 {
compatible = 'fsl,imx28-flexcan', 'fsl,p1010-flexcan';
reg = <0x80032000 0x2000>;
interrupts = <8>;
clocks = <&clks 58>, <&clks 58>;
clock-names = 'ipg', 'per';
pinctrl-names = 'default';
pinctrl-0 = <&can0_pins_a>;
};
內(nèi)核編譯成功后,板卡啟動(dòng)顯示即表示flexcan驅(qū)動(dòng)加載成功。
[ 2.022398] CAN device driver interface
[ 2.031257] flexcan 80032000.can: device registered (reg_base=f5032000, irq=190)
三、Socket CAN的測(cè)試
Socket CAN 的使用會(huì)用到ip命令工具,由于busybox中的ip沒(méi)有支持 socket can,所以需要重新移植ip工具,iproute2中的ip可以支持socket can。
1、移植iproute2
從iproute2官方網(wǎng)站上下載源碼,我們這里用到的是iproute2-3.10.0.
1) tar jxvf iproute2-3.10.0
2) 修改Makefie
CC=arm-none-linux-gnueabi-gcc
由于只用到ip工具,所以將別編譯目錄屏蔽:
#SUBDIRS=lib ip tc bridge misc netem genl man
SUBDIRS=lib ip
3) make編譯成功后生成 “ip”
4) 將ip復(fù)制到EM9287的文件系統(tǒng)中,替換原來(lái)busybox中的ip
這樣ip命令工具就算是移植好了。
2、使用ip命令配置can0接口。
// 關(guān)閉can0接口,以便進(jìn)行配置
ifconfig can0 down
// 方法一:配置can0的波特率為250Kbps
ip link set can0 type can bitrate 250000
// 方法二:配置can0的波特率為250Kbps
ip link set can0 type can tp 250 prog-seg 5 phase-seg1 8 phase-seg2 2 sjw 2
// 啟動(dòng)can0接口
ifconfig can0 up
EM9287的FLEXCAN時(shí)鐘選用的是24MHz的外部晶體振蕩時(shí)鐘。為了適應(yīng)各種不同的采樣率,我們采用方法二來(lái)對(duì)can的波特率進(jìn)行設(shè)置,以CiA推薦的采樣點(diǎn)在bit的87.5%處,作為基準(zhǔn)來(lái)計(jì)算:
| 波特率 |
PRESDIV -> fTq |
TSEG1 | TSEG2 | TQ | 采樣點(diǎn) |
| PROPSEG+PSEG1+2 | PSEG2+1 | ||||
| 1000 | 1 -> 12MHz | (0 + 7 + 2)= 9 | (1+1)= 2 | 12 | 83.3% |
| 800 | 1 -> 12MHz | (3 + 7 + 2)= 12 | (1+1)= 2 | 15 | 86.6% |
| 500 | 2 -> 8MHz | (4 + 7 + 2)= 13 | (1+1)= 2 | 16 | 87.5% |
| 250 | 5 -> 4MHz | (4 + 7 + 2)= 13 | (1+1)= 2 | 16 | 87.5% |
| 125 | 11 -> 2MHz | (4 + 7 + 2)= 13 | (1+1)= 2 | 16 | 87.5% |
| 100 | 14 -> 1.6MHz | (4 + 7 + 2)= 13 | (1+1)= 2 | 16 | 87.5% |
| 60 | 24 -> 960KHz | (4 + 7 + 2)= 13 | (1+1)= 2 | 16 | 87.5% |
| 50 | 29 -> 800KHz | (4 + 7 + 2)= 13 | (1+1)= 2 | 16 | 87.5% |
| 20 | 74 -> 320KHz | (4 + 7 + 2)= 13 | (1+1)= 2 | 16 | 87.5% |
| 10 | 149 -> 160KHz | (4 + 7 + 2)= 13 | (1+1)= 2 | 16 | 87.5% |
3、Scoket CAN測(cè)試代碼
就像TCP/IP協(xié)議一樣,在使用CAN網(wǎng)絡(luò)之前首先需要打開(kāi)一個(gè)套接字。CAN的套接字使用到了一個(gè)新的協(xié)議族PF_CAN,所以在調(diào)用socket( )這個(gè)系統(tǒng)函數(shù)的時(shí)候需要將PF_CAN作為第一個(gè)參數(shù)。當(dāng)前有兩個(gè)CAN的協(xié)議可以選擇,一個(gè)是原始套接字協(xié)議( raw socket protocol),另一個(gè)是廣播管理協(xié)議BCM(broadcast manager)。作為一般的工業(yè)應(yīng)用我們選用原始套接字協(xié)議:
s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
在成功創(chuàng)建一個(gè)套接字之后,通常需要使用bind( )函數(shù)將套接字綁定在某個(gè)CAN接口上。在綁定 (CAN_RAW)套接字之后,就可以在套接字上使用read( )/write( )進(jìn)行數(shù)據(jù)收發(fā)的操作。
基本的CAN幀結(jié)構(gòu)體和套接字地址結(jié)構(gòu)體定義在include/linux/can.h
/*
* 擴(kuò)展格式識(shí)別符由 29 位組成。其格式包含兩個(gè)部分:11 位基本 ID、18 位擴(kuò)展 ID。
* Controller Area Network Identifier structure
*
* bit 0-28 : CAN識(shí)別符 (11/29 bit)
* bit 29 : 錯(cuò)誤幀標(biāo)志 (0 = data frame, 1 = error frame)
* bit 30 : 遠(yuǎn)程發(fā)送請(qǐng)求標(biāo)志 (1 = rtr frame)
* bit 31 :幀格式標(biāo)志 (0 = standard 11 bit, 1 = extended 29 bit)
*/
typedef __u32 canid_t;
struct can_frame {
canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
__u8 can_dlc; /* 數(shù)據(jù)長(zhǎng)度: 0 .. 8 */
__u8 data[8] __attribute__((aligned(8)));
};
以下為相關(guān)的測(cè)試代碼:
int main( int argc,char* argv[] )
{
int i1, ret;
int nbytes, baudrate;
int s;
struct sockaddr_can addr;
struct ifreq ifr;
struct can_frame frame;
printf( 'SocketCAN Test V1.0\n' );
// 解析命令行參數(shù), CAN波特率
if( argc > 1 )
{
baudrate = atoi( argv[1] );
}
else
{
baudrate = 250000;
}
printf( 'bitrate is %d\n', baudrate );
set_can_bittiming( baudrate );
s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
printf( 'SOCK_RAW can sockfd:%d\n', s );
if( s < 0 )
{
return -1;
}
int loopback = 0; /* 0 = disabled, 1 = enabled (default) */
setsockopt(s, SOL_CAN_RAW, CAN_RAW_LOOPBACK, &loopback, sizeof(loopback));
strcpy(ifr.ifr_name, 'can0' );
ret = ioctl(s, SIOCGIFINDEX, &ifr);
if( ret < 0 )
{
return -1;
}
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
bind(s, (struct sockaddr *)&addr, sizeof(addr));
for( i1=0; i1<10; i1++ )
{
nbytes = read(s, &frame, sizeof(struct can_frame));
if (nbytes < 0) {
perror('can raw socket read');
return 1;
}
if( nbytes < (int)sizeof(struct can_frame))
{
perror('read: incomplete CAN frame\n');
return 1;
}
/* do something with the received CAN frame: send back */
nbytes = write(s, &frame, sizeof(struct can_frame));
printf( '%d sendbytes: %d\n', i1+1, nbytes );
}
close( s );
return 0;
}
-
Linux
+關(guān)注
關(guān)注
88文章
11581瀏覽量
217090 -
嵌入式主板
+關(guān)注
關(guān)注
7文章
6107瀏覽量
36815
發(fā)布評(píng)論請(qǐng)先 登錄
佛瑞亞如何通過(guò)信息技術(shù)推動(dòng)業(yè)務(wù)增長(zhǎng)
飛騰主板為信創(chuàng)產(chǎn)業(yè)發(fā)展提高硬實(shí)力
DEKRA德凱成為沙特通信和信息技術(shù)設(shè)備技術(shù)法規(guī)認(rèn)證機(jī)構(gòu)
科普|信創(chuàng)是什么?一文讀懂“信息技術(shù)應(yīng)用創(chuàng)新”戰(zhàn)略

英創(chuàng)信息技術(shù)EM9287 Linux Socket CAN驅(qū)動(dòng)簡(jiǎn)介
評(píng)論