socket CAN概念
socketcan子系統(tǒng)是在Linux下CAN協(xié)議(Controller Area Network)實現的一種實現方法。 CAN是一種在世界范圍內廣泛用于自動控制、嵌入式設備和汽車領域的網絡技術。Linux下最早使用CAN的方法是基于字符設備來實現的,與之不同的是Socket CAN使用伯克利的socket接口和linux網絡協(xié)議棧,這種方法使得can設備驅動可以通過網絡接口來調用。Socket CAN的接口被設計的盡量接近TCP/IP的協(xié)議,讓那些熟悉網絡編程的程序員能夠比較容易的學習和使用。
socket CAN的應用
在Socket CAN之前Linux中已經有了一些CAN的實現方法,那為什么還要啟動Socket CAN這個項目呢?大多數已經存在的實現方法僅僅作為某個具體硬件的設備驅動,它們往往基于字符設備并且提供的功能很少。那些方案通常是由一個針對具體硬件的設備驅動提供的字符設備接口來實現原始can幀的發(fā)送和接收,并且直接和控制器硬件打交道。幀隊列和ISO-TP這樣的高層協(xié)議必須在用戶空間來實現。就像串口設備接口一樣,大多數基于字符設備的實現在同一時刻僅僅支持一個進程的訪問。如果更換了CAN控制器,那么同時也要更換另一個設備驅動,并且需要大多數應用程序重新調整以適應新驅動的API。
Socket CAN被設計用來克服以上種種不足。這種新的協(xié)議族實現了用戶空間的socket接口,它構建于Linux網絡層之上,因此可以直接使用已有的隊列功能。CAN控制器的設備驅動將自己作為一個網絡設備注冊進Linux的網絡層,CAN控制器收到的CAN幀可以傳輸給高層的網絡協(xié)議和CAN協(xié)議族,反之,發(fā)送的幀也會通過高層給CAN控制器。傳輸協(xié)議模塊可以使用協(xié)議族提供的接口注冊自己,所以可以動態(tài)的加載和卸載多個傳輸協(xié)議。事實上,CAN核心模塊不提供任何協(xié)議,也不能在沒有加載其它協(xié)議的情況下單獨使用。同一時間可以在相同或者不同的協(xié)議上打開多個套接字,可以在相同或者不同的CAN ID上同時監(jiān)聽和發(fā)送(listen/send)。幾個同時監(jiān)聽具有相同ID幀的套接字可以在匹配的幀到來后接收到相同的內容。如果一個應用程序希望使用一個特殊的協(xié)議(比如ISO-TP)進行通信,只要在打開套接字的時候選擇那個協(xié)議就可以了,接下來就可以讀取和寫入應用數據流了,根本無需關心CAN-ID和幀的結構等信息。
socket CAN通信過程
socket通信模型如下圖:
(一)在服務端建立一個ServerSocket,綁定相應的端口,并且在指定的端口進行偵聽,等待客戶端的連接。
(二)當客戶端創(chuàng)建連接Socket并且向服務端發(fā)送請求。
(三)服務器收到請求,并且接受客戶端的請求信息。一旦接收到客戶端的連接請求后,會創(chuàng)建一個鏈接socket,用來與客戶端的socket進行通信。 通過相應的輸入/輸出流進行數據的交換,數據的發(fā)送接收以及數據的響應等等。
(四)當客戶端和服務端通信完畢后,需要分別關閉socket,結束通信。
socket通信實現步驟:
了解Socket通信模型后,就可以簡化出Socket通信的實現步驟:
(一)創(chuàng)建ServerSocket和Socket。
(二)打開鏈接到Socket的輸入/輸出流。
(三)按照協(xié)議對Socket進行讀/寫操作。
(四)關閉輸入輸出流、關閉Socket。
如何使用socket CAN
就像TCP/IP協(xié)議一樣,在使用CAN網絡之前你首先需要打開一個套接字。CAN的套接字使用到了一個新的協(xié)議族,所以在調用socket(2)這個系統(tǒng)函數的時候需要將PF_CAN作為第一個參數。當前有兩個CAN的協(xié)議可以選擇,一個是原始套接字協(xié)議( raw socket protocol),另一個是廣播管理協(xié)議BCM(broadcast manager)。你可以這樣來打開一個套接字:
在成功創(chuàng)建一個套接字之后,你通常需要使用bind(2)函數將套接字綁定在某個CAN接口上。在綁定 (CAN_RAW)或連接(CAN_BCM)套接字之后,你可以在套接字上使用read(2)/write(2),也可以使用send(2)/sendto(2)/sendmsg(2)和對應的recv*操作。當然也會有CAN特有的套接字選項。