在Linux上使用CAN

WORMARZ發表於2024-05-07

1、相關背景知識

  • CAN

控制器區域網路(Controller Area Network),一種序列資料通訊協議。CAN是一種非同步通訊,只有CAN_high和CAN_low兩條訊號線(實際上還需要共地,GND),共同構成一組差分訊號線,以差分訊號的形式進行通訊。CAN通訊節點由一個CAN控制器及CAN收發器,CAN 控制器用於實現實現CAN匯流排的協議底層以及資料鏈路層,用於生成CAN幀並以二進位制碼流的方式傳送,在此過程中進行位填充、新增CRC校驗、應答檢測等操作;將接收到的二進位制碼流進行解析並接收,在此過程中進行收發比對、去位填充、執行CRC校驗等操作。此外還需要進行衝突判斷、錯誤處理等諸多工。CAN收發器(有時也叫做驅動器),用於將二進位制碼流轉換為差分訊號傳送,將差分訊號轉換為二進位制碼流接收。

  • CAN電平
  • CAN 控制器根據兩根線上的電位差來判斷匯流排電平。匯流排電平分為顯性電平(邏輯0):CAN_H電壓為3.5V、CAN_L為1.5V,壓差為2V; 隱性電平(邏輯1):CAN_H和CAN_L電壓均為2.5V,電壓差為0V。傳送方透過使匯流排電平發生變化,將訊息傳送給接收方。在匯流排上顯性電平具有優先權,只要有一個單元(也就是節點)輸出顯性電平,匯流排上即為顯性電平。而隱性電平則具有包容的含義,只有所有的單元都輸出隱性電平,匯流排上才為隱性電平。那麼可以知道,CAN通訊是半雙工的,收發資料需要分開來進行,由於是公用匯流排,在整個網路中,同一時刻只能由一個通訊節點傳送訊號,其餘的節點在該時刻只能接收。
  • CAN匯流排進行端接:一條匯流排至少2個端接,2端接個120Ω的電阻(消除匯流排終端處的訊號反射、確保匯流排得到正確的電平)。
  • CAN與CAN-FD
  • 主要區別:
  1. CAN-FD:可以理解成CAN協議的升級版,只升級了協議物理層未改變
  2. CAN與CAN-FD主要區別:傳輸速率不同、資料長度不同、幀格式不同、ID長度不同。
  3. 由傳統CAN轉移到CANFD比較方便。
  • 傳輸速率
  1. CAN:最大傳輸速率1Mbps。
  2. CAN-FD:速率可變,仲裁位元率最高1Mbps(與CAN相同),資料位元率最高8Mbps。
  • 資料長度
  1. CAN:一幀資料最長8位元組
  2. CAN-FD:一幀資料最長64位元組。
  • CAN與CANOpen的關係

CAN的物理層分了三層分別是MDI,PMA和PLS,資料鏈路層分了兩層:MAC與LLC。這五層就是最原始的CAN協議,標準是ISO11898。也就是說CAN協議一開始是沒有應用層的。後來有一種叫CANOpen的基於CAN的應用層協議被開發出來,標準是CiA301。
CAN協議框架

2、移植canfestival

  • canfestival原始碼下載地址
## 解壓
tar jxvf canfestival-de1fc3261f21.tar.bz2
  • 編譯原始碼

首先執行python --version確認python是2.x的版本。若不是,修改環境變數,讓預設的python指令是使用python2的。

./configure --cc=aarch64-none-linux-gnu-gcc --arch=arm64 --os=unix --kerneldir=../../kernel/ --prefix=$PWD/tmp --target=unix --can=socket --timers=unix --debug=WAR,MSG
 
 
--cc:配置開發板交叉編譯器
--arch:開發板架構
--os:使用系統
--kerneldir:使用的核心實際目錄
--prefix:在原始碼首頁建立一個安裝資料夾
--can:Linux下使用的是socket
--timers:定時器也是Linux自帶的
--debug:返回執行資訊
# 執行下列操作編譯
make clean
make all
make install

......

# 輸出產物
$ ls _install/
bin  include  lib  objdictgen

3、移植iproute2

can驅動使能需要使用到ip指令,但busybox中的ip指令功能不全,需要重新移植完整的iproute2。

iproute2需要依賴libmnl和libbsd,先移植這兩個庫。

  • 移植libmnl
    libmnl原始碼下載地址
tar -jxvf libmnl-1.0.4.tar.bz2
cd libmnl-1.0.4
./configure --prefix=${PWD}/_install --host=aarch64-none-linux
make && make install
ls _install # 檢視編譯產物
  • 移植libbsd
    libbsd原始碼下載地址
tar -xvf libbsd-0.8.7.tar.xz
cd libbsd-0.8.7
./autogen
./configure --prefix=${PWD}/_install --host=aarch64-none-linux
make && make install
ls _install # 檢視編譯產物
  • 移植iproute2
    iproute2原始碼下載地址
tar -xzvf iproute2-5.9.0.tar.gz
cd iproute2-5.9.0
mkdir _install
PKG_CONFIG_PATH=${PWD}/../libmnl-1.0.4/_install/lib/pkgconfig:${PWD}/../libbsd-0.8.7/_install/lib/pkgconfig CC=aarch64-none-linux-gcc AR=aarch64-none-linux-ar ./configure
make
DESTDIR=${PWD}/_install make install
ls _install # 檢視編譯產物

將完整的ip指令移植到開發板後就可以用ip來配置can了。

  • CAN FD常用命令
# 查詢當前網路裝置
ifconfig -a

# 關閉CAN
ip link set can0 down

# 設定仲裁段500k波特率,資料段500k波特率
ip link set can0 type can bitrate 500000 dbitrate 500000 fd on

# 列印can0資訊
ip -details link show can0

# 啟動CAN
ip link set can0 up

4、移植canutils

canutils可以用於測試物理層和鏈路層的CAN協議,其需要依賴libsocketcan。

canutils原始碼下載地址
libsocketcan原始碼下載地址

libsocketcan正常編譯移植即可,但canutils是很老的一個專案了,在編譯64位版本的時候可能會出現問題。在配置工具鏈的時候可能無法透過aarch64工具鏈的檢測,這時候可以在其他專案中找一個config.sub,將這個檔案替換到canutils的config/autoconf/config.sub。我這裡將libmnl-1.0.4/build-aux/config.sub拷了過去,這樣就能支援64位的編譯工具了。

./configure --prefix="$PWD/_install" --host=aarch64-none-linux --enable-debug libsocketcan_LIBS="-L$PWD/../libsocketcan/_install/lib -lsocketcan" libsocketcan_CFLAGS="-I$PWD/../libsocketcan/_install/include" CFLAGS=-I$PWD/../libsocketcan/_install/include

相關文章