天天看點

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

目錄

  • CAN 協定簡析
    • 何為CAN
    • CAN 電氣屬性
      • 顯隐性電平
      • 接線
      • 端接電阻
      • 速度距離
    • CAN 協定
      • 1、資料幀
      • 2、遙控幀
      • 3、錯誤幀
      • 4、過載幀
      • 5、幀間隔
    • CAN 速率
    • I.MX6ULL FlexCAN 簡介
  • 硬體原理圖分析
  • 實驗程式編寫
    • 修改裝置樹
    • 使能Linux 核心自帶的FlexCAN 驅動
  • FlexCAN 測試
    • 檢查CAN 網卡裝置是否存在
    • 移植iproute2
    • 移植can-utils 工具
    • CAN 通信測試

CAN 是目前應用非常廣泛的現場總線之一,主要應用于汽車電子和工業領域,尤其是汽車領域,汽車上大量的傳感器與子產品都是通過CAN 總線連接配接起來的。CAN 總線目前是自動化領域發展的熱點技術之一,由于其高可靠性,CAN 總線目前廣泛的應用于工業自動化、船舶、汽車、醫療和工業裝置等方面。I.MX6ULL 自帶了CAN 外設,是以可以開發CAN 相關的裝置,本章我們就來學習一下如何驅動I.MX6U-ALPHA 開發闆上的CAN 接口。

CAN 協定簡析

有關CAN 協定詳細内容請參考開發闆資料裡面由瑞薩電子編寫的《CAN 入門教程》,路徑為:4、參考資料->CAN 入門教程.pdf,本小節參考自此教程。

何為CAN

CAN 的全稱為Controller Area Network,也就是控制區域網路絡,簡稱為CAN。CAN 最早是由德國BOSCH(博世)開發的,目前已經是國際标準(ISO 11898),是目前應用最廣泛的現場總線之一。BOSCH 主要是做汽車電子的,是以CAN 一開始主要是為汽車電子準備的,事實也是如此,CAN 協定目前已經是汽車網絡的标準協定。當然了,CAN 不僅僅應用于汽車電子,經過幾十年的發展,CAN 協定的高性能和高可靠性已經得到了業界的認可,目前除了汽車電子以外也廣泛應用于工業自動化、醫療、工業和船舶等領域。

以汽車電子為例,汽車上有空調、車門、發動機、大量傳感器等,這些部件都是通過CAN總線連在一起形成一個網絡,車載網絡結構如圖66.1.1.1 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

圖66.1.1.1 中各個單元通過CAN 總線連接配接在一起,每個單元都是獨立的CAN 節點。同一個CAN 網絡中所有單元的通信速度必須一緻,不同的網絡之間通信速度可以不同。比如圖66.1.1.1 中125Kbps 的CAN 網絡下所有的節點速度都是125Kbps 的,整個網絡由一個網關與其他的網絡連接配接。

CAN 的特點主要有一下幾點:

  • ①、多主要制

    在總線空閑時,所有單元都可以發送消息(多主要制),而兩個以上的單元同時開始發送消息時,根據辨別符(Identifier 以下稱為ID)決定優先級。ID 并不是表示發送的目的位址,而是表示通路總線的消息的優先級。兩個以上的單元同時開始發送消息時,對各消息ID的每個位進行逐個仲裁比較。仲裁獲勝(被判定為優先級最高)的單元可繼續發送消息,仲裁失利的單元則立刻停止發送而進行接收工作。

  • ②、系統的柔軟性

    與總線相連的單元沒有類似于“位址”的資訊。是以在總線上增加單元時,連接配接在總線上的其它單元的軟硬體及應用層都不需要改變。

  • ③、通信速度快,距離遠

    最高1Mbps(距離小于40M),最遠可達10KM(速率低于5Kbps)。

  • ④、具有錯誤檢測、錯誤通知和錯誤恢複功能

    所有單元都可以檢測錯誤(錯誤檢測功能),檢測出錯誤的單元會立即同時通知其他所有單元(錯誤通知功能),正在發送消息的單元一旦檢測出錯誤,會強制結束目前的發送。強制結束發送的單元會不斷反複地重新發送此消息直到成功發送為止(錯誤恢複功能)。

  • ⑤、故障封閉功能

    CAN 可以判斷出錯誤的類型是總線上暫時的資料錯誤(如外部噪聲等)還是持續的資料錯誤(如單元内部故障、驅動器故障、斷線等)。由此功能,當總線上發生持續資料錯誤時,可将引起故障的單元從總線上隔離出去。

  • ⑥、連接配接節點多

    CAN 總線是可同時連接配接多個單元的總線。可連接配接的單元總數理論上是沒有限制的。但實際上可連接配接的單元數受總線上的時間延遲及電氣負載的限制。降低通信速度,可連接配接的單元數增加;提高通信速度,則可連接配接的單元數減少。

CAN 電氣屬性

顯隐性電平

CAN 總線使用兩根線來連接配接各個單元:CAN_H 和CAN_L,CAN 控制器通過判斷這兩根線上的電位差來得到總線電平,CAN 總線電平分為顯性電平和隐性電平兩種。

  • 顯性電平表示邏輯“0”,此時CAN_H 電平比CAN_L 高,分别為3.5V 和1.5V,電位差為2V。
  • 隐形電平表示邏輯“1”,此時CAN_H 和CAN_L 電壓都為2.5V 左右,電位差為0V。

CAN 總線就通過顯性和隐形電平的變化來将具體的資料發送出去,如圖66.1.2.1 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

接線

CAN 總線上沒有節點傳輸資料的時候一直處于隐性狀态,也就是說總線空閑狀态的時候一直處于隐性。CAN 網絡中的所有單元都通過CAN_H 和CAN_L 這兩根線連接配接在一起,如圖66.1.2.2 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

端接電阻

途中所有的CAN 節點單元都采用CAN_H 和CAN_L 這兩根線連接配接在一起,CAN_H 接CAN_H、CAN_L 接CAN_L,CAN 總線兩端要各接一個120Ω的端接電阻,用于比對總線阻抗,吸收信号反射及回撥,提高資料通信的抗幹擾能力以及可靠性。

速度距離

CAN 總線傳輸速度可達1Mbps/S,最新的CAN-FD 最高速度可達5Mbps/S,甚至更高,CAN-FD 不在本章讨論範圍,感興趣的可以自行查閱相關資料。CAN 傳輸速度和總線距離有關,總線距離越短,傳輸速度越快。

CAN 協定

通過CAN 總線傳輸資料是需要按照一定協定進行的,CAN 協定提供了5 種幀格式來傳輸資料:資料幀、遙控幀、錯誤幀、過載幀和幀間隔。其中資料幀和遙控幀有标準格式和擴充格式兩種,标準格式有11 位辨別符(ID),擴充格式有29 個辨別符(ID)。這5 中幀的用途見表66.1.3.1:

幀類型 幀用途
資料幀 用于CAN節點單元之間進行資料傳輸的幀
遙控幀 用于接收單元向具有相同ID 的發送單元請求資料的幀
錯誤幀 用于當檢測出錯誤時向其它單元通知錯誤的幀
過載幀 用于接收單元通知其尚未做好接收準備的幀
間隔幀 用于将資料幀及遙控幀與前面的幀分離開來的幀

1、資料幀

資料幀由7 段組成:

①、幀起始,表示資料幀開始的段。

②、仲裁段,表示該幀優先級的段。

③、控制段,表示資料的位元組數及保留位的段。

④、資料段,資料的内容,一幀可發送0~8 個位元組的資料。

⑤、CRC 段,檢查幀的傳輸錯誤的段。

⑥、ACK 段,表示确認正常接收的段。

⑦、幀結束,表示資料幀結束的段。

資料幀結構如圖66.1.3.1 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

圖66.1.3.1 給出了資料幀标準格式和擴充格式兩種幀結構,圖中D 表示顯性電平0、R 表示隐性電平1,D/R 表示顯性或隐性,也就是0 或1,我們來簡單分析一下資料幀的這7 個段。

①、幀起始

幀起始很簡單,标準格式和擴充格式都是由一個位的顯性電平0 來表示幀起始。

②、仲裁段

仲裁段表示幀優先級,仲裁段結構如圖66.1.3.2 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

标準格式和擴充格式的仲裁段不同,從圖66.1.3.2 可以看出,标準格式的ID 為11 位,發送順序是從ID10 到ID0,最高7 位ID10~ID4 不能全為隐性(1),也就是禁止0X1111111XXXXX這樣的ID。擴充格式的ID 為29 位,基本ID 從ID28 到ID18,擴充ID 由ID17 到ID0,基本ID 與标準格式一樣,禁止最高7 位都為隐性。

③、控制段

控制段由6 個位構成,表示資料段的位元組數,标準格式和擴充格式的控制段略有不同,如圖66.1.3.3 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

圖66.1.3.3 中r1 和r0 為保留位,保留位必須以顯性電平發送。DLC 為資料長度,高位在前,DLC 段有效值範圍為0~8。

④、資料段

資料段也就是幀的有效資料,标準格式和擴充格式相同,可以包含0~8 個位元組的資料,從最高位(MSB)開始發送,結構如圖66.1.3.4 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

注意,圖66.1.3.4 中資料段的0~64 為bit,對應到位元組就是0~8 位元組。

⑤、CRC 段

CRC 段儲存CRC 校準值,用于檢查幀傳輸錯誤,标準格式和擴充格式相同,CRC 段結構如圖66.1.3.5 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

從圖66.1.3.5 可以看出,CRC 段由15 位的CRC 值與1 位的CRC 界定符組成。CRC 值的計算範圍包括:幀起始、仲裁段、控制段、資料段,接收方以同樣的算法進行計算,然後用計算得到的CRC 值與此CRC 段進行比較,如果不一緻的話就會報錯。

⑥、ACK 段

ACK 段用來确認接收是否正常,标準格式和擴充格式相同,ACK 段結構如圖66.1.3.6 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

從圖66.1.3.7 可以看出,ACK 段由ACK 槽(ACK Slot)和ACK 界定符兩部分組成。發送單元的ACK,發送2 個隐性位,而接收到正确消息的單元在ACK 槽(ACK Slot)發送顯性位,通知發送單元正常接收結束,這個過程叫發送ACK/傳回ACK。發送ACK 的是所有接收單元中接收到正常消息的單元,所謂正常消息是指不含填充錯誤、格式錯誤、CRC 錯誤的消息,這些接收單元既不處于總線關閉态也不處于休眠态的所有接收單元中。

⑦、幀結束

最後就是幀結束段,标準格式和擴充格式相同,幀結束段結構如圖66.1.3.7 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

從圖66.1.3.7 可以看出,幀結束段很簡單,由7 位隐性位構成。

2、遙控幀

接收單元向發送單元請求資料的時候就用遙控幀,遙控幀由6 個段組成:

①、幀起始,表示資料幀開始的段。

②、仲裁段,表示該幀優先級的段。

③、控制段,表示資料的位元組數及保留位的段。

④、CRC 段,檢查幀的傳輸錯誤的段。

⑤、ACK 段,表示确認正常接收的段。

⑥、幀結束,表示資料幀結束的段。

遙控幀結構如圖66.1.3.8 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

從圖66.1.3.8 可以看出,遙控幀結構基本和資料幀一樣,最主要的差別就是遙控幀沒有資料段。遙控幀的RTR 位為隐性的,資料幀的RTR 位為顯性,是以可以通過RTR 位來區分遙控幀和沒有資料的資料幀。遙控幀沒有資料,是以DLC 表示的是所請求的資料幀資料長度,遙控幀的其他段參考資料幀的描述即可。

3、錯誤幀

當接收或發送消息出錯的時候使用錯誤幀來通知,錯誤幀由錯誤标志和錯誤界定符兩部分組成,錯誤幀結構如圖66.1.3.9 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

錯誤标志有主動錯誤标志和被動錯誤标志兩種,主動錯誤标志是6 個顯性位,被動錯誤标志是6 個隐性位,錯誤界定符由8 個隐性位組成。

4、過載幀

接收單元尚未完成接收準備的話就會發送過載幀,過載幀由過載标志和過載界定符構成,過載幀結構如圖66.1.3.10 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

過載标志由6 個顯性位組成,與主動錯誤标志相同,過載界定符由8 個隐性位組成,與錯誤幀中的錯誤界定符構成相同。

5、幀間隔

幀間隔用于分隔資料幀和遙控幀,資料幀和遙控幀可以通過插入幀間隔來将本幀與前面的任何幀隔開,過載幀和錯誤幀前不能插入幀間隔,幀間隔結構如圖66.1.3.11 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

圖66.1.3.11 中間隔由3 個隐性位構成,總線空閑為隐性電平,長度沒有限制,本狀态下表示總線空閑,發送單元可以通路總線。延遲發送由8 個隐性位構成,處于被動錯誤狀态的單元發送一個消息後的幀間隔中才會有延遲發送。

CAN 速率

CAN 總線以幀的形式發送資料,但是最終到總線上的就是“0”和“1”這樣的二進制資料,這裡就涉及到了通信速率,也就是每秒鐘發送多少位資料,前面說了CAN2.0 最高速度為1Mbps/S。對于CAN 總線,一個位分為4 段:

①、同步段(SS)

②、傳播時間段(PTS)

③、相位緩沖段1(PBS1)

④、相位緩沖段2(PBS2)

這些段由Tq(Time Quantum)組成,Tq 是CAN 總線的最小時間機關。幀由位構成,一個位由4 個段構成,每個段又由若幹個Tq 組成,這個就是位時序。1 位由多少個Tq 構成、每個段又由多少個Tq 構成等,可以任意設定位時序。通過設定位時序,多個單元可同時采樣,也可任意設定采樣點。各段的作用和Tq 數如圖66.1.4.1 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

1 個位的構成如圖66.1.4.2 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

圖66.1.4.2 中的采樣點是指讀取總線電平,并将讀到的電平作為位值的點。位置在PBS1結束處。根據這個位時序,我們就可以計算CAN 通信的波特率了。具體計算方法,我們等下再介紹,前面提到的CAN 協定具有仲裁功能,下面我們來看看是如何實作的。

在總線空閑态,最先開始發送消息的單元獲得發送權。

當多個單元同時開始發送時,各發送單元從仲裁段的第一位開始進行仲裁。連續輸出顯性電平最多的單元可繼續發送。實作過程,如圖66.1.4.3 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

圖66.1.4.3 中,單元1 和單元2 同時開始向總線發送資料,開始部分他們的資料格式是一樣的,故無法區分優先級,直到T 時刻,單元1 輸出隐性電平,而單元2 輸出顯性電平,此時單元1 仲裁失利,立刻轉入接收狀态工作,不再與單元2 競争,而單元2 則順利獲得總線使用權,繼續發送自己的資料。這就實作了仲裁,讓連續發送顯性電平多的單元獲得總線使用權。

關于CAN 協定就講到這裡,關于CAN 協定更詳細的内容請參考《CAN 入門教程》。

I.MX6ULL FlexCAN 簡介

I.MX6ULL 帶有CAN 控制器外設,叫做FlexCAN,FlexCAN 符合CAN2.0B 協定。FlexCAN完全符合CAN 協定,支援标準格式和擴充格式,支援64 個消息緩沖。I.MX6ULL 自帶的FlexCAN子產品特性如下:

①、支援CAN2.0B 協定,資料幀和遙控幀支援标準和擴充兩種格式,資料長度支援0~8 位元組,可程式設計速度,最高1Mbit/S。

②、靈活的消息郵箱,最高支援8 個位元組。

③、每個消息郵箱可以配置為接收或發送,都支援标準和擴充這兩種格式的消息。

④、每個消息郵箱都有獨立的接收掩碼寄存器。

⑤、強大的接收FIFO ID 過濾。

⑥、未使用的空間可以用作通用RAM。

⑦、可程式設計的回測模式,用于進行自測。

⑧、可程式設計的優先級組合。

……

FlexCAN 支援四種模式:正常模式(Normal)、當機模式(Freeze)、僅監聽模式(Listen-Only)和回環模式(Loop-Back),另外還有兩種低功耗模式:禁止模式(Disable)和停止模式(Stop)。

①、正常模式(Normal)

在正常模式下,FlexCAN 正常接收或發送消息幀,所有的CAN 協定功能都使能。

②、當機模式(Freeze)

當MCR 寄存器的FRZ 位置1 的時候使能此模式,在此模式下無法進行幀的發送或接收,CAN 總線同步丢失。

③、僅監聽模式(Listen-Onley)

當CTRL 寄存器的LOM 位置1 的時候使能此模式,在此模式下幀發送被禁止,所有錯誤計數器被當機,CAN 控制器工作在被動錯誤模式,此時隻會接收其他CAN 單元發出的ACK 消息。

④、回環模式(Loop-Back)

當CTRL 寄存器的LPB 位置1 的時候進入此模式,此模式下FlexCAN 工作在内部回環模式,一般用來進行自測。從模式下發送出來的資料流直接回報給内部接收單元。

前面在講解CAN 協定的時候說過CAN 位時序,FlexCAN 支援CAN 協定的這些位時序,控制寄存器CTRL 用于設定這些位時序,CTRL 寄存器中的PRESDIV、PROPSEG、PSEG1、PSEG2 和RJW 這5 個位域用于設定CAN 位時序。

PRESDIV 為CAN 分頻值,也即是設定CAN 協定中的Tq 值,公式如下:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

fCANCLK為FlexCAN 子產品時鐘,這個根據時鐘章節設定即可,設定好以後就是一個定值,是以隻需要修改PRESDIV 即可修改FlexCAN 的Tq 頻率值。

Tq 定了以後我們結合圖66.1.4.1 中的各個段來看一下如何設定FlexCAN 的速率:

SS:同步段(Synchronization Segment),在I.MX6ULL 參考手冊中叫做SYNC_SEG,此段固定為1 個Tq 長度,是以不需要我們去設定。

PTS:傳播時間段(Propagatin Segment),FlexCAN 的CTRL 寄存器中的PROPSEG 位域設定此段,可以設定為0~ 7,對應1~8 個Tq。

PBS1:相位緩沖段1(Phase Buffer Segment 1),FlexCAN 的CRTL 寄存器中的PSEG1 位域設定此段,可以設定為0~ 7,對應1~8 個Tq。

PBS2:相位緩沖段2(Phase Buffer Segment 2),FlexCAN 的CRTL 寄存器中的PSEG2 位域設定此段,可以設定為1~ 7,對應2~8 個Tq。

SJW:再同步補償寬度(reSynchronization Jump Width),FlexCAN 的CRTL 寄存器中的RJW位域設定此段,可以設定0~ 3,對應1~4 個Tq。

FlexCAN 的CAN 位時序如圖66.1.5.1 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

根據圖66.1.5.1 所示,SYNC+SEG+(PROP_SEG+PSEG1+2)+(PSEG2+1)就是總的Tq,是以FlexCAN 的波特率就是:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

關于I.MX6ULL 的FlexCAN 控制器就講解到這裡,如果想更加詳細的了解FlexCAN,請參考《I.MX6ULL 參考手冊》的“Chapter 26 Flexible Controller Area Network(FLEXCAN)”章節。

硬體原理圖分析

正點原子I.MX6U-ALPHA 開發闆CAN 接口原理圖如圖66.2.1 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

圖66.2.1 中TJA1050 是CAN 收發器,通過TJA1050向外界提供CAN_H 和CAN_L 總線,R10 是一個120 歐的端接比對電阻;

CAN1_TX 和CAN1_RX 是I.MX6ULL FlexCAN1 的發送和接收引腳,對應I.MX6ULL 的UART3_CTS 和UART3_RTS 這兩個引腳。。

實驗程式編寫

修改裝置樹

NXP 原廠提供的裝置樹已經配置好了FlexCAN 的節點資訊(FlexCAN1 和FlexCAN2),但是我們還是要來看一下如何配置I.MX6ULL 的CAN1 節點。首先看一下I.MX6ULL 的FlexCAN裝置樹綁定文檔,打開Documentation/devicetree/bindings/net/can/ fsl-flexcan.txt,此文檔描述了FlexCAN 節點下的相關屬性資訊,這裡就不做介紹了,大家自行查閱。

1、FlexCAN1 引腳節點資訊

首先肯定是CAN1 引腳配置資訊,打開imx6ull-alientek-emmc.dts,找到如下所示内容:

1 pinctrl_flexcan1: flexcan1grp{
2 fsl,pins = <
3 MX6UL_PAD_UART3_RTS_B__FLEXCAN1_RX 0x1b020
4 MX6UL_PAD_UART3_CTS_B__FLEXCAN1_TX 0x1b020
5 >;
6 };
           

第3 和第4 行将UART3_RTS 和UART3_CTS 這兩個引腳分别複用為FlexCAN1 的RX 和TX,電氣屬性都設定為0x1b020。

2、FlexCAN1 控制器節點資訊

打開imx6ull.dtsi 檔案,找到名為“flexcan1”的節點,内容如下:

1 flexcan1: [email protected]02090000 {
2 compatible = "fsl,imx6ul-flexcan", "fsl,imx6q-flexcan";
3 reg = <0x02090000 0x4000>;
4 interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
5 clocks = <&clks IMX6UL_CLK_CAN1_IPG>,
6 <&clks IMX6UL_CLK_CAN1_SERIAL>;
7 clock-names = "ipg", "per";
8 stop-mode = <&gpr 0x10 1 0x10 17>;
9 status = "disabled";
10 };
           

注意示例代碼66.3.1.2 中的flexcan1 節點不需要我們修改,這裡隻是告訴大家FlexCAN1

完整節點資訊。根據第2 行的compatible 屬性就可以找到I.MX6ULL 的FlexCAN 驅動源檔案,

驅動文名為drivers/net/can/flexcan.c。第9 行的status 屬性為disabled,是以FlexCAN1 預設關閉

的。在imx6ull-alientek-emmc.dts 中添加使能FlexCAN1 的相關操作,找到如下所示代碼:

1 &flexcan1 {
2 pinctrl-names = "default";
3 pinctrl-0 = <&pinctrl_flexcan1>;
4 xceiver-supply = <&reg_can_3v3>;
5 status = "okay";
6 };
           

第3 行指定FlexCAN1 所使用的pinctrl 節點為pinctrl_flecan1,也就是示例代碼66.3.1.1 中的pinctrl 節點。

第4 行xceiver-supply 屬性指定CAN 收發器的電壓為3.3V。

第5 行将flexcan1 節點的status 屬性改為“okay”,也就是使能FlexCAN1。

3、關閉FlexCAN2 相關節點

I.MX6ULL 帶有兩個CAN 控制器:FlexCAN1 和FlexCAN2,NXP 官方的EVK 開發闆這兩個CAN 接口都用到了,是以NXP 官方的裝置樹将這兩個CAN 接口都使能了。但是,正點原子的I.MX6U-ALPHA 開發闆将FlexCAN2 的IO 配置設定給了ECSPI3,是以正點原子的I.MX6U-ALPHA 開發闆就不能使用CAN2,否則的話ECSPI3 外設就無法使用。關閉FlexCAN2 節點很簡單,在imx6ull-alientek-emmc.dts 檔案中找到名為“flexcan2”的節點,然後将其屏蔽掉即可。

重新編譯裝置樹,我們還需要配置Linux 核心,使能核心裡面的FlexCAN 驅動。

使能Linux 核心自帶的FlexCAN 驅動

NXP 官方提供的linux核心預設已經內建了I.MX6ULL 的FlexCAN 驅動,但是沒有使能,是以我們需要配置Linux 核心,打開FlexCAN 驅動,步驟如下:

1、使能CAN 總線

首先打開CAN 總線子系統,在Linux 下CAN 總線是作為網絡子系統的,配置路徑如下:

-> Networking support
	-> <*> CAN bus subsystem support //打開CAN 總線子系統
           

如圖66.3.2.1 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

2、使能Freescale 系CPU 的FlexCAN 外設驅動

接着使能Freescale 系CPU 的FlexCAN 外設驅動,配置路徑如下:

-> Networking support
	-> CAN bus subsystem support
		-> CAN Device Drivers
			-> Platform CAN drivers with Netlink support
				-> <*> Support for Freescale FLEXCAN based chips //選中
           

配置如圖66.3.2.2 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

配置好以後重新編譯核心,然後使用新的核心和裝置樹啟動開發闆。

FlexCAN 測試

檢查CAN 網卡裝置是否存在

使用新編譯的核心和裝置樹啟動開發闆,然後輸入如下指令:

前面我們說了,Linux 系統中把CAN 總線接口裝置作為網絡裝置進行統一管理,是以如果FlexCAN 驅動工作正常的話就會看到CAN 對應的網卡接口,如圖66.4.1.1 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

從圖66.4.1.1 可以看出,有一個名為“can0”的網卡,這個就是I.MX6U-ALPHA 開發闆上的CAN1 接口對應的can 網卡裝置。如果使能了I.MX6ULL 上的FlexCAN2 的話也會出現一個 名為“can1”的can 網卡裝置。

移植iproute2

在移植ip 指令的時候必須先對根檔案系統做個備份!防止操作失誤導緻系統啟動失敗!切記!筆者的血淚經驗教訓!

busybox 自帶的ip 指令并不支援對can 的操作,是以我們需要重新移植ip 指令,也就是iproute2,iproute2 源碼下載下傳位址為:https://mirrors.edge.kernel.org/pub/linux/utils/net/iproute2/。這

裡我們下載下傳4.4.0 版本的,筆者試過最新的版本,但是編譯一直有問題。4.4.0 版本的iproute2 已經下載下傳好放到了開發闆CD光牒中,路徑為:1、例程源碼->7、第三方庫源碼-> iproute2-4.4.0.tar.gz。

将iproute2-4.4.0.tar.gz 發送到ubuntu 中并解壓,指令如下:

tar -vxzf iproute2-4.4.0.tar.gz
           

解壓完成以後會得到一個名為“iproute2-4.4.0”的目錄,進入此目錄中,打開Makefile 并修改。在Makefile 中找到下面這行:

CC := gcc
           

改為

CC:=arm-linux-gnueabihf-gcc
           

修改完成以後如圖66.4.2.1 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

Makefile 修改完成以後直接使用“make”指令編譯,編譯成功以後就會在iproute2 源碼的ip 目錄下得到一個名為“ip”的指令,如圖66.4.2.2 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

以下操作請嚴格按照教程步驟來!否則可能會導緻系統無法啟動!

1、将交叉編譯得到的ip 拷貝到開發闆中

首先将交叉編譯到的ip 指令拷貝到開發闆中,先不要替換開發闆根檔案系統中原有的ip 指令!切記!切記!先拷貝到開發闆根檔案系統的其他目錄裡面,比如我這裡就拷貝到/lib/modules/4.1.15 這個目錄裡面,指令如下:

sudo cp ip /home/zuozhongkai/linux/nfs/test_rootfs/lib/modules/4.1.15/ -f
           

拷貝完成以後在開發闆上先執行一下新的ip 指令,檢視一下版本号,指令如下:

cd lib/modules/4.1.15/
./ip -V //執行新的ip 指令,檢視版本号
           

如果新編譯的ip 指令運作正确的話就會列印出其版本号,如圖66.4.2.3 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

2、在開發闆根檔案系統中用新的ip 指令替換原來的

注意,此步驟在開發闆中執行!開發闆根檔案系統中原來的ip 指令是busybox 自帶的,存放在/sbin 目錄下。接下來,我們使用新的ip 指令替換原來的,在開發闆中執行如下指令:

cd lib/modules/4.1.15/
cp ip /sbin/ip -f
           

拷貝完成以後将/lib/modules/4.1.15/目錄下的ip 指令删除掉,重新開機開發闆,檢視根檔案系統是否可以正常啟動!如果正常啟動的話輸入如下指令檢視ip 指令版本号:

結果如圖66.4.2.4 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

至此,iproute2 中的ip 指令就已經移植好了,稍後的can 測試中我們會使用ip 指令來設定can0 網卡的相關資訊。

3、替換ip 指令以後系統啟動失敗怎麼辦?

如果在替換ip 指令的時候操作失誤可能會導緻開發闆系統啟動失敗,如圖66.4.2.5 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

從圖66.4.2.5 可以看出,系統啟動失敗,提示“Object “it” is unknown, try “ip help”.”,這是因為ip 指令替換錯誤導緻的!是以說一定要嚴格按照本節教程講解的步驟替換ip 指令。遇到圖66.4.2.5 中的錯誤以後解決方法很簡單,把以前的ip 指令替換回來就行了,這就是前面強烈建議大家對根檔案系統做個備份的原因!!!最簡單的方法就是用備份的根檔案系統重新做一遍!

移植can-utils 工具

can0 網卡已經出現了,但是工作正不正常還不知道,必須要進行資料收發測試。這裡我們使用can-utils 這個工具來對can0 網卡進行測試,是以要先移植can-utils 到我們的開發闆根檔案系統中。can-utils 源碼我們已經下載下傳下來放到了開發闆CD光牒中,路徑為:1、例程源碼->7、第三方庫源碼-> can-utils-2020.02.04.tar.gz。

在ubuntu 中建立一個名為“can-utils”的目錄來存放can-utils 的編譯結果。然後将can-utils源碼拷貝到ubuntu 中并解壓,指令如下:

解壓完成以後得到一個名為“can-utils-2020.02.04”的目錄,這個即使can-utils 源碼,進入到此目錄中,然後配置并編譯,指令如下:

cd can-utils-2020.02.04 //進入can-utils 源碼目錄
./autogen.sh //先執行autogen.sh,生成配置檔案configure
./configure --target=arm-linux-gnueabihf --host=arm-linux-gnueabihf --prefix=/home/zuozhongkai/linux/IMX6ULL/tool/can-utils --disable-static --enable-shared //配置
make //編譯
make install
           

編譯完成以後就會前面建立的“can-utils”目錄下就會多出一個“bin”目錄,此目錄下儲存着can-utils 的各種小工具,如圖66.4.3.1 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

将圖66.4.3.1 中的所有can-utils 小工具全部拷貝到開發闆根檔案系統下的/usr/bin 目錄下,指令如下:

sudo cp bin/* /home/zuozhongkai/linux/nfs/rootfs/usr/bin/ -f

           

拷貝完成以後我們就可以使用這些小工具來測試CAN 了。

CAN 通信測試

正點原子的I.MX6U-ALPHA 開發闆上隻有一個CAN 接口,是以我們還需要另外一個CAN裝置,可以使用另一塊I.MX6U-ALPHA 開發闆,或者USB 轉CAN 裝置,這裡我兩個都測試一下。

1、兩塊ALPHA 開發闆連接配接測試

準備兩塊ALPHA 開發闆,然後将CAN 接口連接配接起來,ALPHA 開發闆上CAN 接線端子如圖66.4.4.1 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

将兩個開發闆的CAN 接口連接配接起來,注意,CAN_H 接CAN_H,CAN_L 接CAN_L!

①、收發測試

首先使用ip 指令設定兩個開發闆的CAN 接口,首先設定CAN 接口的速度,輸入如下所示指令:

上述指令設定can0 速度為500Kbit/S,兩個CAN 裝置的速度要設定為一樣的!速度設定好以後打開can0 網卡,指令如下:

can0 打開以後就可以使用can-utils 裡面的小工具進行資料收發測試了。一個開發闆用來接收資料,一個用來發送資料,接收資料的開發闆使用candump 指令,輸入如下指令:

發送資料的開發闆使用cansend 指令向接收單元發送8 個位元組的資料:0X11、0X22、0X33、0X44、0X55、0X66、0X77、0X88。輸入如下指令:

cansend 指令用于發送can 資料,“5A1”是幀ID,“#”号後面的“11.22.33.44.55.66.77.88”就是要發送的資料,十六進制。CAN2.0 一次最多發送8 個位元組的資料,8 個位元組的資料之間用“.”隔開。

如果CAN 工作正常的話接收端就會接收到上面發送過來的這8 個位元組的資料,如圖66.4.4.2所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

從圖66.4.4.2 可以看出,接收端的can0 接口接收到了8 個位元組的資料,幀ID 為5A1,說明CAN 驅動工作正常。

如果要關閉can0 的話輸入如下指令:

ifconfig can0 down
           

②、回環測試

如果要在一個闆子上進行CAN 回環測試,按照如下指令設定CAN:

ifconfig can0 down //如果can0 已經打開了,先關閉
ip link set can0 type can bitrate 500000 loopback on //開啟回環測試
ifconfig can0 up //重新打開can0
candump can0 & //candump 背景接收資料
cansend can0 5A1#11.22.33.44.55.66.77.88 //cansend 發送資料
           

如果回環測試成功的話那麼開發闆就會收到發送給自己的資料,如圖66.4.4.3 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

2、USB 轉CAN 卡測試

接下來我們使用一個USB 轉CAN 卡與正點原子的I.MX6U-ALPHA 開發闆進行資料收發測試,這裡我使用的是周立功出品的USBCAN 裝置,型号為“USBCAN-I+”,如圖66.4.4.4 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

首先設定開發闆的can0 接口,速度為500Kbit/S,指令如下:

ip link set can0 type can bitrate 500000 //設定can0,速率500Kbit
ifconfig can0 up //打開can0
candump can0 & //candump 背景接收資料
           

按照USBCAN 說明手冊設定好USB CAN 卡,速度設定為500Kbit,首先通過USBCAN 向ALPHA 發送資料,發送的資料如圖66.4.4.5 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

從圖66.4.4.5 可以看出,USBCAN 發送了5 幀資料幀,幀類型為标準幀,這5 幀資料都是一樣的,幀ID 分别為0~4。開發闆CAN 接口工作正常的話就會接收到這5 幀資料,接收到的資料如圖66.4.4.6 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

從圖66.4.4.6 可以看出,開發闆can0 接口接收到了5 幀資料,和USBCAN 發送的一緻。

也可以通過開發闆向USBCAN 發送資料,輸入如下指令發送資料:

USBCAN 接收到資料,如圖66.4.4.7 所示:

Linux CAN 驅動實驗CAN 協定簡析硬體原理圖分析實驗程式編寫FlexCAN 測試

關于CAN 驅動就講解到這裡,如果要編寫CAN 總線應用的話就直接使用Linux 提供的SocketCAN 接口,使用方法類似網絡通信,本教程不講解應用程式設計。

繼續閱讀