Linux CAN程式設計詳解

2021-09-11 17:55:13 字數 3314 閱讀 9060

最近寫了個自認為不錯的基於linux socket can程式,主要功能:

程式具備全部can功能,包括can標準幀/擴充套件幀接收與傳送、can匯流排錯誤判斷、環迴等功能

適用基於linux socket機制實現的can介面,可用於嵌入式linux的can測試

程式採用標準linux命令列引數選項形式,接受使用者引數

現把原始碼進行分享

功能介紹

介紹:本socket can程式具備全部can功能,包括can標準幀/擴充套件幀接收與傳送、can匯流排錯誤判斷、環迴等功能

適用基於linux socket機制實現的can介面,可用於嵌入式linux中的can測試程式

程式採用標準linux命令列引數選項形式,接受使用者引數

用法: ./cantool [選項]…

選項:-p, –port=can介面號 指定can介面號,從1開始, 預設為 1(即can1介面)

-b, –baud=波特率 指定can通訊波特率,單位kbps,預設為 250 kbps

可用波特率:5,10,20,40,50,80,100,125,200,250,400,500,666,800,1000

-i, –frame-id=幀id 指定can傳送幀id(hex格式), 預設為1801f456

-d, –data=資料 指定can傳送幀資料, 預設為:00 01 ff ff ff ff ff ff,位元組資料間以空格隔開

-f, –freq=間隔 指定can幀傳送間隔,單位ms, 預設為250ms, 最小值為1ms

-t, –times=次數 指定can幀傳送次數, 預設為0次

-s, 指定can傳送幀為標準幀, 預設為傳送擴充套件幀

-i, 幀id每傳送一幀遞增, 預設不遞增

-g, 傳送資料每傳送一幀遞增, 預設不遞增

-l, 傳送資料時本地環迴, 預設不環回

–help 顯示此幫助資訊並退出

注意,以下can幀id作為系統使用:

0x00000001 – tx timeout (by netdevice driver)

0x00000002 – lost arbitration / data[0]

0x00000004 – controller problems / data[1]

0x00000008 – protocol violations / data[2..3]

0x00000010 – transceiver status / data[4]

0x00000020 – received no ack on transmission

0x00000040 – bus off

0x00000080 – bus error (may flood!)

0x00000100 – controller restarted

使用 ctrl^c 組合鍵結束程式執行

部分原始碼

int main(int argc, char **ar**)

; bool carry_bit = false;// 進製標誌

int segment_id;//id for shared memo

if (parse_options(argc, ar**))

if (!find_can(port))

close_can(port);// 必須先關閉can,才能成功設定can波特率

set_bitrate(port, bitrate);// 操作can之前,先要設定波特率

open_can(port, bitrate);

send_socket_fd = socket_connect(port);

recv_socket_fd = socket_connect(port);

//printf("send_socket_fd = %d, recv_socket_fd = %d\n", send_socket_fd, recv_socket_fd);

if (send_socket_fd < 0 || send_socket_fd < 0)

set_can_filter();

set_can_loopback(send_socket_fd, lp);

printf_head();

memset(&sendframe, 0x00, sizeof(sendframe));

memset(&recvframe, 0x00, sizeof(recvframe));

if (extended_frame) // 指定傳送幀型別:擴充套件幀或標準幀

else

sendframe.can_dlc = dlc;

memcpy(sendframe.data, send_frame_data, dlc);

segment_id = shmget(ipc_private, sizeof(int), s_irusr | s_iwusr);// allocate memo

pframeno = (int *)shmat(segment_id, null, 0);// attach the memo

if (pframeno == null)

*pframeno = 1;

run = true;

pid = fork();

if(pid == -1)

else if(pid == 0) // 子程序,用於傳送can幀

else

}if (send_frame_data_inc_en && dlc > 0)

psend_data->s.dl++;

if (dlc <= 4)

}else if (dlc <= 8)

carry_bit = false;}}

}send_frame_times--;

}exit(0);

}else // 父程序,接收can幀

}while(((pid = wait(&status)) == -1) && (errno == eintr))

}disconnect(&send_socket_fd);

disconnect(&recv_socket_fd);

shmdt(pframeno);// detach memo

shmctl(segment_id, ipc_rmid, null);// remove

return 0;

}

使用示例

程式原始碼

Linux CAN程式設計詳解

最近寫了個自認為不錯的基於linux socket can程式,主要功能 程式具備全部can功能,包括can標準幀 擴充套件幀接收與傳送 can匯流排錯誤判斷 環迴等功能 適用基於linux socket機制實現的can介面,可用於嵌入式linux的can測試 程式採用標準linux命令列引數選項形...

Linux CAN驅動及測試總結

平台 zynq 7010 核心 linux3.14.52 xilinx官網can驅動相關 1 核心中開啟can匯流排 1 進入核心原始碼頂層目錄 cd opt hzzd linux linux xlnx xilinx v2014.2.01 2 make arch arm cross compile ...

Linux can匯流排除錯學習記錄

由於最近工作需要,需要用到can匯流排,自己以前又沒有用到過can匯流排,所以記錄下來自己的學習過程。由於我是在linux下操作can匯流排的,所以一下內容主要是linux下的can操作過程。首先,配置linux下can驅動,我所用的平台是am335x,am335x有兩個can介面,can0和can...