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