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
- 主要區別:
- CAN-FD:可以理解成CAN協議的升級版,只升級了協議,物理層未改變。
- CAN與CAN-FD主要區別:傳輸速率不同、資料長度不同、幀格式不同、ID長度不同。
- 由傳統CAN轉移到CANFD比較方便。
- 傳輸速率
- CAN:最大傳輸速率1Mbps。
- CAN-FD:速率可變,仲裁位元率最高1Mbps(與CAN相同),資料位元率最高8Mbps。
- 資料長度
- CAN:一幀資料最長8位元組
- CAN-FD:一幀資料最長64位元組。
- CAN與CANOpen的關係
CAN的物理層分了三層分別是MDI,PMA和PLS,資料鏈路層分了兩層:MAC與LLC。這五層就是最原始的CAN協議,標準是ISO11898。也就是說CAN協議一開始是沒有應用層的。後來有一種叫CANOpen的基於CAN的應用層協議被開發出來,標準是CiA301。
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