發送請求服務
CanIf的發送請求函數CanIf_Transmit()是上層模塊傳輸L-PDU的通用接口。上層通信層模塊需要通過CanIf的服務啟動傳輸,無法直接訪問CanDrv。如果CanDrv能夠將L-PDU數據寫入CAN硬件傳輸對象中,則發起的傳輸請求成功完成。上層模塊使用API服務CanIf_Transmit ()來發起一個傳輸請求。
CanIf在調用服務CanIf_Transmit()時對L-PDU傳輸執行以下操作:
- 檢查,初始化CanIf的狀態
- 當使用多個CanDrv時,識別CanDrv
- 確定訪問CAN硬件傳輸對象的HTH
- 調用CanDrv的Can_Write()
如果傳輸請求服務CanIf_Transmit()返回E_OK,則傳輸成功完成。
如果一個L-PDU被請求通過一個PDU通道模式來傳輸,這個模式等于CANIF_OFFLINE,那么CanIf應該向DET的Det_ReportRuntimeError()服務報告運行時的錯誤代碼CANIF_E_STOPPED,而CanIf_Transmit() 將返回E_NOT_OK。
發送數據流
發送請求服務CanIf_Transmit ()是基于L-PDU的。對L-SDU特定數據的訪問按以下參數組織:
- 傳輸L-PDU =>L-SDU ID
- 引用包含L-SDU相關數據的數據結構:指向L-SDU的指針,指向元數據的指針和L-SDU長度。
對L-SDU數據結構的引用被用作幾個CanIf API服務中的一個參數,例如CanIf_Transmit()或回調服務
圖3 發送數據流
CanIf會存儲為傳輸而配置的硬件對象信息。函數CanIf_Transmit()將CanTxPduId映射到對應的HTH,并調用函數Can_Write()。
如果總線鏡像是全局啟用的CanIfBusMirroringSupport(),并且通過調用CAN控制器的CanIf_EnableBusMirroring()來激活,那么CanIf通過Can_Write()在控制器上傳輸每幀內容之前將其存儲。只有在實際發送時,才提供總線鏡像模塊。因此,為了能夠從CanIf_TxConfirmation()將其提供給總線鏡像模塊,必須考慮存儲內容。
發送緩沖
在CanIf的范圍內,傳輸過程從調用CanIf_Transmit()開始,到調用上層模塊的回調服務
- CAN硬件傳輸對象
- 如果發送緩沖使能,發送L-PDU緩沖區在CanIf內。
對于觸發傳輸,CanIf只需要存儲給定L-PDU的傳輸請求,而不需要存儲它的數據。當HTH空閑時,通過觸發器傳遞函數及時獲取數據。一個單獨的發送 L-PDU,請求傳輸,永遠不會被存儲兩次。這種行為對應于CAN網絡上常用的周期性通信方式。
如果CanIf在傳輸請求時被CanDrv拒絕,CanIf將啟用傳輸緩沖,并將在傳輸L-PDU緩沖區(CanIfBufferCfg)中存儲一個發送 L-PDU。
基本上,用于緩沖發送L-PDU的整個CanIf中的緩沖區包含一個或多個CanIfBufferCfg。而每個CanIfBufferCfg被分配給一個或多個專用的CanIfBufferHthRef,可以配置為緩沖一個或多個發送I-PDU。但是,在CanIfBufferCfg的總體數量中,每個發送 L-PDU只能緩沖一個實例。
在相應的發送 L-PDU配置中是否啟用傳輸緩沖,CanIf在L-PDU傳輸期間對應的行為是不同的。如果發送緩沖被禁用,并且發送到CanDrv的請求失敗,那么L-PDU不會被復制到CAN控制器,CanIf_Transmit()將返回值E_NOT_OK。如果啟用了傳輸緩沖,并且發送到CanDrv的請求失敗,根據CanIfTxBuffer配置,L-PDU可以存儲在CanIfTxBuffer中。在這種情況下,盡管無法執行傳輸,API CanIf_Transmit()返回E_OK值。在這種情況下,CanIf通過CanIf_TxConfirmation()回調和處理L-PDU未完成的傳輸,而上層不必重試傳輸請求。
傳輸CanIf 發送L-PDU緩沖區的數量,可以獨立于CAN網絡描述文件中定義的傳輸L-PDU的數量來配置。
發送L-PDU通過CanIfBufferCfg配置容器引用HTH,如果不需要傳輸緩沖,也是有效的。在這種情況下,必須將CanIfBufferCfg的緩沖區大小設置為0,然后CanIfBufferCfg配置容器僅用于引用一個HTH。
發送確認服務
如果前一個傳輸請求成功完成,CanDrv會通過調用CanIf_TxConfirmation()將其通知給CanIf。
如果對于CAN控制器,啟用了全局總線鏡像CanIfBusMirroringSupport和激活調用CanIf_EnableBusMirroring(), CanIf將會調用Mirror_ReportCanFrame()對每一幀傳輸控制器確認CanIf_TxConfirmation(),提供存儲內容和實際的ID。
調用回調函數CanIf_TxConfirmation()時,CanIf標識與成功傳輸L-PDU相連的上層通信層,通過調用CanIf的傳輸確認服務(E_OK)來通知其傳輸執行情況?;卣{服務()是由通知的上層模塊實現的。
可以配置上層通信層模塊,通過對不同的I-PDU或I-PDU組使用單個或多個回調服務來處理發送確認。所有那些服務在發送確認L-PDU傳輸請求時,會被CanIf調用。傳輸L-PDU允許分派與目標上層模塊關聯的不同確認服務,該分配是在靜態配置期間完成。
一個發送L-PDU只能分配給一個發送確認回調服務。
如果啟用了CanIfPublicTxConfirmPollingSupport,那么每個CAN控制器的模式處于CAN_CS_STARTED狀態,CanIf將緩沖接收到的TxConfirmation的信息。
接收指示服務
根據AUTOSAR BSW架構,接收到的數據將在上層通信模塊,即AUTOSAR COM、CanNm、CanTp和DCM中進行評估和處理。這意味著,上層模塊既不能使用CanDrv的緩沖區,也不能訪問CanIf的緩沖區。只有當CanIfPublicReadRxPduDataApi設置為TRUE時,CanIf才會在接收路徑中提供內部緩沖。解決了發送緩沖問題,并考慮動態I-PDU。
如果接收到CanDrv L-PDU,則調用CanIf的CanIf_RxIndication ()。對L-PDU特定數據的訪問由以下參數組織:
- 硬件接收句柄(HRH)
- 接收CAN標識符(CanId)
- 接收數據長度
- 參考已收到的L-PDU
接收到的L-PDU依賴于硬件,并分配給通信系統的最低層CanDrv。HRH是CanDrv和使用L-PDU的上層模塊之間的鏈接。HRH標識CAN硬件接收句柄,接收新的CAN L-PDU。
在CanDrv調用CanIf_RxIndication(),指示接收到的L-PDU后,CanIf將按照接收指示進行處理。CanIf無法識別CanDrv是使用臨時緩沖還是直接訪問硬件。它期望在調用CanIf_RxIndication()時得到標準化的L-PDU數據。
CAN硬件接收句柄被鎖定,直到復制到臨時或上層模塊緩沖區的過程結束。硬件對象將在CanIf的CanIf_RxIndication()返回后立即釋放,以避免數據丟失。
CanDrv、CanIf和屬于接收到L-PDU的上層模塊訪問相同的臨時緩沖區,該臨時緩沖區可以位于CAN控制器的硬件接收對象中,也可以位于CanDrv中的臨時緩沖區中。
圖4 接收的信號流
調用CanIf_RxIndication()引用新接收到的L-PDU的參數,如果調用了函數CanIf_RxIndication(),CanIf將對CAN L-PDU進行評估接收,并準備L-SDU供上層通信層訪問。CanIf使用
如果總線鏡像是全局啟用的,并且通過調用CAN控制器的CanIf_EnableBusMirroring()激活,那么CanIf應該為該控制器上用CanIf_RxIndication()來表示的每一幀接收調用Mirror_ReportCanFrame()。
如果調用函數CanIf_RxIndication(),CanIf會按照指定的方式處理接收到的L-PDU。如果軟件過濾拒絕接收到的L-PDU,CanIf會結束對canif_rxindicator()調用的接收指示。
如果CanIf在軟件過濾過程中接受通過CanIf_RxIndication()接收到的L-PDU, CanIf隨后會處理數據長度檢查。如果CanIf在數據長度檢查期間使用CanIf_RxIndication()接收L-PDU, CanIf將根據配置的數據長度的字節數復制到靜態接收緩沖區。
如果為接收的L-SDU配置了元數據,CanIf將PDU有效負載復制到靜態接收緩沖區,并將CANID復制到類型為CAN_ID_32的MetaDataItem。
在數據長度檢查期間,如果CanIf接受通過CanIf_RxIndication()接收到的L-PDU,CanIf會識別是否配置了目標上層模塊(CanIfRxPduUserRxIndicationUL,CanIfRxPduUserRxIndicationName),并為接收到的L-SDU提供接收指示服務。
如果目標上層模塊被配置為提供接收指示服務,CanIf稱之為配置接收指示回調服務CanIfRxPduUserRxIndicationName,提供所需的參數上層通知回調函數的參數CanIf_RxIndication ()。
CanIf在調用CanIf_RxIndication()時執行以下步驟:
- 軟件過濾(只有BasicCAN)
- 數據長度檢查
- 緩沖接收L-SDU
- 調用上層接收指示回調服務
讀取接收到的數據APICanIf_ReadRxPduData()是上層模塊讀取CANL-SDU最近從CAN網絡接收到的公共接口。上層模塊只通過CanIf服務發起接收請求,而不直接訪問CanDrv。發起的接收請求成功完成,CanIf將接收到的L-SDU寫入上層模塊I-PDU緩沖區。
函數CanIf_ReadRxPduData()使得在不依賴接收事件的情況下讀取數據成為可能。在配置時啟用它,不一定為相同L-SDU配置接收指示服務。如果需要,可以啟用接收指示服務。
通過這種方式的類型機制獲得L-SDU,可以選擇由參數CanIfRxPduUserRxIndicationUL和CanIfRxPduReadData,在配置時根據上層模塊的需求,相應的接收L-SDU。
如果配置參數CanIfPublicReadRxPduDataApi設置為TRUE,則CanIf將接收到的L-SDU(在此情況下CanIfRxPduReadData是啟用的)存儲到接收到的L-SDU緩沖區。這意味著,如果配置參數CanIfRxPduReadData設置為TRUE,CanIf必須為這個接收L-SDU分配接收L-SDU緩沖區。
在調用CanIf_RxIndication()并通過軟件過濾和數據長度檢查后,CanIf將接收到的L-SDU存儲在這個接收到的L-SDU緩沖區中。在調用CanIf_ReadRxPduData()指定的接收L-SDU緩沖區時,CanIf應避免搶占接收L-SDU緩沖區的訪問事件。
控制器模式控制服務
CanIf提供用于控制由CanDrv支持的CAN控制器通信模式的服務。這意味著所有CAN控制器都由相應的API服務來控制,以請求和讀取當前控制器模式。
可以通過調用CanIf_SetControllerMode()服務,來根據上層的請求更改CAN控制器狀態。請求通過CanIf經過CanDrv API傳遞到指定的CAN控制器。在CAN網絡上對所有CAN控制器的一致性管理是CanSm的任務。通過這種方式,CanSm負責將CAN網絡的所有CAN控制器按順序設置為睡眠模式或喚醒。
CanIf通過調用函數CanIf_SetControllerMode()或CanIf_ControllerBusOff()接受每個狀態轉換請求。CanIf不決定CAN控制器請求的模式轉換是否有效。CanIf僅通過獲取當前模式和執行請求的模式轉換來與CanDrv交互。
該網絡相關狀態機在CanSm中實現。CanIf只存儲請求的模式并執行請求的轉換。
為了避免頻繁請求CanDrv,可以對每個控制器存儲CanIf_ControllerModeIndication()和Can_GetControllerMode()所指示的最后狀態。需要注意的是,不僅CanSm能夠請求CAN控制器模式的改變。根據CanSm請求的操作模式,CanIf轉發請求CanDrvs。
如果ControllerId引用的控制器模式處于CAN_CS_STOPPED狀態,并且如果CanIf_Transmit()調用中的PduIdType參數被分配給該CAN控制器,那么CanIf_Transmit()調用不會導致Can_Write()調用,而是返回E_NOT_OK。如果ControllerId引用的控制器模式進入CAN_CS_STOPPED狀態,CanIf會清除分配給CAN控制器相應的CanIf傳輸緩沖區。
如果ControllerId引用的控制器模式進入CAN_CS_STOPPED狀態,那么CanIf通過調用(id, E_NOT_OK)為分配給CAN控制器的每個未完成的TxConfirmation,通知相應的上層模塊傳輸失敗。如果啟用了CanIfPublicTxConfirmPollingSupport,那么CanIf還會清除關于TxConfirmation的信息。
這確保了對于每個PDU,都會調用一個正的或負的
-
收發器
+關注
關注
10文章
3436瀏覽量
106056 -
CAN
+關注
關注
57文章
2756瀏覽量
463881 -
路由器
+關注
關注
22文章
3734瀏覽量
113961 -
PDU
+關注
關注
0文章
94瀏覽量
16992
發布評論請先 登錄
相關推薦
評論