基於CAN總線的汽車診斷協議UDS(ECU底層模塊移植開發)


一、意義
為了指導開發工程師,正確的使用診斷模塊,快速開發出滿足車廠要求的診斷功能。

二、診斷模塊介紹

此診斷模塊根據ISO-14229-1文檔,並結合部分車廠的文檔進行開發,使用面向對象的思路進行設計,將模塊需要處理的所有事情封裝在模塊內部,留出模塊處理過程接口和配置接口供調用接口的工程師使用。通過調用配置接口,可以配置我們想要的功能。通過調用處理過程接口,診斷模塊便能提供診斷服務,無需其他操作,便能實現診斷功能,開發起來方便快捷。

使用過程中的復雜之處在於配置,需要根據具體項目的診斷需求進行具體配置。以下詳細介紹。

三、接口與配置說明

1、類型定義

1)、安全等級定義

typedef enum{

       LEVEL_ZERO = 7,//安全等級0,當一個服務不需要安全解鎖時,使用此安全等級。

       LEVEL_ONE = 1,//安全等級1,當一個服務可以在安全等級1時,使用此安全等級。

       LEVEL_TWO = 2,//安全等級2,當一個服務可以在安全等級2時,使用此安全等級。

       LEVEL_THREE = 4,//安全等級3,當一個服務可以在安全等級3時,使用此安全等級。

LEVEL_FOUR = 8,//安全等級4,工廠模式會話使用此安全等級,用戶零部件商下線配置。

       LEVEL_UNSUPPORT = 0,//不支持,當一個服務在某個會話模式不支持時,使用此等級。

}SecurityLevel;

2)、復位類型,參考ISO-14229-1中11服務復位類型的定義。

typedef enum{

       HARD_RESET = 1,//硬件復位

       KEY_OFF_ON_RESET = 2,//關開鑰匙復位

       SOFT_RESET = 3,//軟件復位

       ENABLE_RAPID_POWER_SHUTDOWN = 4,//預留,一般不使用

       DISABLE_RAPID_POWER_SHUTDOWN = 5,//預留,一般不使用

}EcuResetType;

3)、DTC類型定義。

typedef enum{

       ISO15031_6DTCFORMAT= 1,

       ISO14229_1DTCFORMAT = 2,

       SAEJ1939_73DTCFORMAT = 3,

}DTCFormatIdentifier;

 

 

 

4)、診斷故障狀態定義

typedef enum{

       PASSED,//測試通過

       IN_TESTING,//測試未完成

       FAILED,//測試失敗

}DTCTestResult;

5)DID類型定義

typedef enum{

       EEPROM_DID,//靜態存儲器DID,存儲在EEPROM中的DID使用此類型

       REALTIME_DID,//實時DID,存儲在RAM中,會實時改變的數據使用此類型

       IO_DID,//輸入輸出控制DID,需要通過2F服務控制的DID使用此類型

}DIDType;

6)、DID的讀寫屬性

typedef enum{

       READONLY = 1,//只讀

       WRITEONLY = 2,//只寫

       READWRITE = 3,//可讀寫

}ReadWriteAttr;

7)、通信控制參數

typedef enum{

       ERXTX,//enableRxAndTx

       ERXDTX,//enableRxAndDisableTx

       DRXETX,//disableRxAndEnableTx

       DRXTX,//disableRxAndTx

       //ERXDTXWEAI,//enableRxAndDisableTxWithEnhancedAddressInformation

       //ERXTXWEAI,//enableRxAndTxWithEnhancedAddressInformation

}CommulicationType;

8)、通信控制的控制對象參數

typedef enum{

       NCM = 1,//application message

       NWMCM,//network manage message

       NWMCM_NCM,//application and netwrok manage message

}communicationParam;

9)、子功能在會話的支持情況

typedef enum{

       SUB_DEFAULT = 1,//sub function supported in default session

       SUB_PROGRAM = 2,//sub function supported in program session

       SUB_EXTENDED = 4,////sub function supported in extedned session

SUB_FACTORY = 8,//sub funcion supported in factory session,

       SUB_ALL = 7,//sub function supported in both of three session

}SubFunSuppInSession;

10)、診斷故障碼的等級,僅在HD10中有使用

typedef enum{

       LEVEL_A,

       LEVEL_B,

       LEVEL_C,

}DTCLevel;

11)、輸入輸出控制接口函數原型

typedef uint8_t (*IoControl)(uint8_t ctrl, uint8_t param);

Ctrl表示控制類型:

0:歸還控制權到ECU

1:恢復默認狀態

2:凍結當前

3:短時調整

只有當ctrl為3時存在param,param參數根據具體的DID而不同,如當控制開關時,可以表示為:

0:關

1:開,

如控制檔位時

1:1檔

2:2檔

....

12)、安全解鎖算法接口函數原型

typedef uint32_t (*SecurityFun)(uint32_t);

此原型表示一個函數指針,有一個uint32_t型的參數,表示種子。返回uint32_t型值,表示根據算法算出的秘鑰

13)、DTC的檢測接口函數原型

typedef DTCTestResult (*DetectFun)(void);

無參數,需要返回DTCTestResult 類型的值,2表示測試失敗,0表示測試通過,1表示正在測試(測試未完成)。

14)、復位接口函數原型。

typedef void (*ResetCallBack)(EcuResetType);

參數

EcuResetType:復位類型,取值范圍,1-5,分別表示硬件復位,key-off-on復位,軟件復位。通常用1和3。

15)、通信控制接口函數原型

typedef void (*CommCallBack)(CommulicationType , communicationParam);

參數:

CommulicationType :參考1.7定義

communicationParam:參考1.8定義

16)、CAN發送接口函數原型

typedef uint8_t (*SendCANFun)(uint32_t ID, uint8_t *array, uint8_t length, uint8_t priority);

注:以上所有接口函數原型供診斷開發時使用,開發時必須提供以上接口,否則診斷模塊將無法正常工作。

 

#define       USE_MALLOC              0//1:使用動態內存分配,0:不使用動態內存分配。

#define          USE_J1939_DTC            0//僅HD10使用,建議不修改

當時不使用動態內存分配時候,存在以下參數,可調節。

/*======================== buf size config ================================*/ 

#define MAX_DTC_NUMBER                           35//最大DTC個數

#define MAX_DID_NUMBER                           70//最大DID個數

#define MAX_SNAPSHOT_NUMBER                10//最大快照信息個數

#define MAX_GROUP_NUMBER                      5//最大DTC組個數

/*======================== buf size config ================================*/ 

 

2、接口函數

1)、診斷基本配置函數

void Diagnostic_Init(uint32_t requestId, uint32_t responseId, uint32_t funRequestId, uint16_t EEPromStartAddr, uint16_t EEpromSize,SendCANFun sendFun,uint16_t p2CanServerMax, uint16_t p2ECanServerMax);

requestId:診斷儀請求ID(物理尋址)

responseId:ECU響應ID(物理尋址)

funRequestId:功能尋址請求ID

EEPromStartAddr:診斷模塊可使用的EEPROM起始

EEpromSize:診斷模塊可使用的EEPROM的大小

sendFun:診斷模塊發送CAN報文使用的函數指針

p2CanServerMax:診斷的響應時間參數限制(未發送78響應時,具體可參數項目診斷規范)

p2ECanServerMax:診斷的響應時間參數限制(發送了78響應后,具體可參數項目診斷規范)

2)、診斷額外支持的請求和響應ID(僅HD10使用)

void Diagnostic_Set2ndReqAndResID(uint32_t requestId1, uint32_t responseId1,uint32_t funRequestId1);

requestId1:診斷儀第二請求ID(物理尋址)

responseId1:ECU第二響應ID(物理尋址)

funRequestId1:第二功能尋址請求ID

3)、診斷模塊釋放接口

void Diagnostic_DelInit(void);

此接口會處理釋放內存,保存故障碼的操作,一定要在休眠之前調用。

4)、診斷模塊報文接收函數

void Diagnostic_RxFrame(uint32_t ID,uint8_t* data,uint8_t IDE,uint8_t DLC,uint8_t RTR);

此函數需要在接收中斷中調用,如果不調用,診斷模塊將無法收到任何報文,無法提供任何服務。參數:

ID:報文ID,可以是11位和29位ID

Data:報文數據指針

IDE:參考S12G手冊

DLC:報文長度

RTR:參考S12G手冊

5)、診斷模塊時間基數函數

void Diagnostic_1msTimer(void);

此函數需要在1毫秒的RTI中斷中調用,如不調用,診斷模塊所有與超時相關的功能將不能工作(包括多幀響應,S3超時等)。

6)、添加安全算法的函數

bool InitAddSecurityAlgorithm(SecurityLevel level, SecurityFun AlgoritthmFun,byte SeedSubFunctionNum,byte KeySubFunctionNum , uint8_t* FaultCounter,uint8_t FaultLimitCounter , uint32_t UnlockFailedDelayTimeMS,SubFunSuppInSession SubFuntioncSupportedInSession,uint8_t KeySize);

此函數的功能是為診斷模塊的添加安全算法,最多支持三個等級的安全算法,如果不添加安全算法,27服務將沒有正響應。參數:

Level:能使用LEVEL_ONE,LEVEL_TWO,LEVEL_THREE,不能使用LEVEL_ZERO和LEVEL_UNSUPPORT

AlgoritthmFun:安全解鎖算法函數,參考三.1.12。

SeedSubFunctionNum:此算法支持的請求種子的子功能,如“27 01”中的“01”

KeySubFunctionNum :此算法支持的發送秘鑰的子功能,如“27 02”中的“02”

FaultCounter:預留參數,設置為NULL

FaultLimitCounter:解鎖失敗次數限制,超時此次數時,啟用延時

UnlockFailedDelayTimeMS:解鎖失敗后延時時間,單位為毫秒,如3000表示3秒

SubFuntioncSupportedInSession:子功能在會話模式的支持情況,可以是SUB_PROGRAM ,SUB_EXTENDED,也可以都支持,使用按位或的方式SUB_PROGRAM | SUB_EXTENDED。

KeySize:seed和可以的長度,可以設置為2或者4。設置為2時只使用高生成種子的高兩個字節,解鎖算法生成的秘鑰也需要放到高兩個字節。設置為4時將使用所有字節。

7)、初始化工廠模式安全算法函數

void InitFactorySecuriyAlgorithm(void);

無參數,此函數內部會調用InitAddSecurityAlgorithm函數,添加安全算法,算法包含於內部,如不進行此初始化,工廠模式將無法解鎖。

8)、配置服務的函數

bool InitSetSessionSupportAndSecurityAccess(bool support ,uint8_t service,uint8_t PHYDefaultSession_Security,       uint8_t PHYProgramSeesion_Security,       uint8_t PHYExtendedSession_Security,      uint8_t FUNDefaultSession_Security,       uint8_t FUNProgramSeesion_Security,       uint8_t FUNExtendedSession_Security);

Support:只能為TRUE,如果為FALSE和未配置一樣會有11否定響應。

Service:服務名稱,如0x10,0x11,0x27等(一次只能使用一個)

PHYDefaultSession_Security:服務在物理尋址默認會話支持的安全訪問等級。

PHYProgramSeesion_Security:服務在物理尋址編程會話支持的安全訪問等級。

PHYExtendedSession_Security:服務在物理尋址擴展會話支持的安全訪問等級。

FUNDefaultSession_Security,:服務在功能尋址默認會話支持的安全訪問等級。

FUNProgramSeesion_Security:服務在功能尋址編程會話支持的安全訪問等級。

FUNExtendedSession_Security:服務在功能尋址擴展會話支持的安全訪問等級。

注意:以上6個參數,

如果支持,不需要安全解鎖,則使用LEVEL_ZERO,

如果不支持,則使用LEVEL_UNSUPPORT,

如果需要安全解鎖等級1才能支持,則使用 LEVEL_ONE,

如果需要安全解鎖等級2才能支持,則使用LEVEL_TWO,

如果需要安全解鎖等級3才能支持,則使用LEVEL_THREE,

如果同時支持多個安全等級,則只用按位或的方式,如LEVEL_TWO|LEVEL_THREE

9)、添加DID的接口函數

void InitAddDID(uint16_t DID , uint8_t DataLength , uint8_t* DataPointer , DIDType DidType , IoControl ControlFun , ReadWriteAttr RWAttr,uint16_t EEaddr, bool SupportWriteInFactoryMode);

DID:DID數字,如:0xF190

DataLength:DID的數據長度,如F190為17。

DataPointer:DID數據指針,此指針由應用程序提供,當類型為EEPROM_DID時,此參數設為NULL,類型為IO_DID並且不需要讀時,也可設置為NULL。

DidType:DID的類型可以是EEPROM_DID,REALTIME_DID,IO_DID。

ControlFun:輸入輸出控制的函數指針,當類型不為IO_DID時,此參數設置為NULL。

RWAttr:讀寫屬性

EEaddr:DID的eeprom地址只有DidType為EEPROM_DID時有效,當此參數為0時,診斷模塊將自動分配eeprom地址,因此如果不需要手動指定地址,將此值設置為0即可。

SupportWriteInFactoryMode:是否支持在工廠模式可寫。

注意:工廠模式的會話模式為0x71,需要先切換到10 03擴展會話,才能切換到工廠模式會話,工廠模式寫DID數據需要先27解鎖,分別是27  71請求種子,27  72發送秘鑰。工廠模式解鎖算法包含在診斷模塊內部,對客戶不可見。

10)、添加故障碼的接口函數

#if USE_J1939_DTC

void Diagnostic_DM1MsgEnable(bool dm1en);

bool InitAddDTC(uint32_t DTCCode,DetectFun MonitorFun,byte DectecPeroid, byte ValidTimes,DTCLevel dtcLevel,uint32_t spn, uint8_t fmi);

#else

bool InitAddDTC(uint32_t DTCCode,DetectFun MonitorFun,byte DectecPeroid, byte ValidTimes,DTCLevel dtcLevel);

#endif

灰色部分僅在HD10中使用,可以不作關注

DTCCode:診斷故障代碼,如0x910223,診斷模塊只使用低24位,高8位設置為零。

MonitorFun:故障檢測函數指針。

DectecPeroid:故障檢測周期,此參數暫未使用,可以設置為0.

ValidTimes:故障有效次數,記錄歷史故障碼的故障出現次數,當在歷史故障和當前故障碼同時置位時,設置為1,當歷史故障碼需要多個點火循環才能置位時,可設置為大於等於2的數。2表示需要兩個點火周期,3表示3個,類推。

dtcLevel:故障等級,僅HD10使用,可以設置為LEVEL_C

11)、添加快照信息接口函數

void InitAddDTCSnapShot(uint8_t recordNumber , uint16_t ID , uint8_t* datap , uint8_t size);

recordNumber:快照信息記錄號,如1,表示全局快照,2,表示局部快照。

ID:此快照的ID,如0x9102表示快照車速信息。

Datap:此快照記錄的內存指針,需要是能表示實時狀態(如實時車速)的內存指針。

Size:此快照的大小,字節數。

12)、設置故障擴展信息-老化計數器的擴展信息號的接口函數

void InitSetAgingCounterRecordNumber(uint8_t RecordNumer);

RecordNumer:老化計數器信息的序號(需要參考診斷規范中19 06的響應信息,一般范圍1-4)

13)、設置故障擴展信息-已老去計數器的擴展信息號的接口函數

void InitSetAgedCounterRecordNumber(uint8_t RecordNumer);

RecordNumer:已老去計數器信息的序號(需要參考診斷規范中19 06的響應信息,一般范圍1-4)

14)、設置故障擴展信息-故障發生次數計數器的擴展信息號的接口函數

void InitSetOccurrenceCounterRecordNumber(uint8_t RecordNumer);

RecordNumer:故障發生次數計數器信息的序號(需要參考診斷規范中19 06的響應信息,一般范圍1-4)

15)、設置故障擴展信息-故障待定計數器的擴展信息號的接口函數

void InitSetPendingCounterRecordNumber(uint8_t RecordNumer);

RecordNumer:故障待定計數器信息的序號(需要參考診斷規范中19 06的響應信息,一般范圍1-4)

16)、設置支持的故障位的接口函數

void InitSetDTCAvailiableMask(uint8_t AvailiableMask);

AvailiableMask:故障位,如0x09表示支持當前位和歷史位

17)、設置DTCgroup的接口函數

void InitAddDTCGroup(uint32_t Group);

Group:14服務的group,目前支持支0xFFFFFF(僅低24位有效),清除所有故障碼。

18)、配置11服務的接口函數

void InitSetSysResetParam(bool support01 , bool support02 , bool support03 , bool support04 ,

bool support05 , ResetCallBack callback, bool supressPosResponse);

support01:11服務是否支持01子功能,TRUE:支持,FALSE:不支持

support02:11服務是否支持02子功能,TRUE:支持,FALSE:不支持

support03:11服務是否支持03子功能,TRUE:支持,FALSE:不支持

support04:11服務是否支持04子功能,TRUE:支持,FALSE:不支持

support05:11服務是否支持05子功能,TRUE:支持,FALSE:不支持

Callback:復位接口函數指針,由應用提供,診斷模塊只調用,具體的復位動作需要應用根據參數執行。

supressPosResponse:是否支持抑制響應,TRUE:支持,FALSE:不支持

19)、配置28服務的接口函數

void InitSetCommControlParam(bool supportSubFun00, bool supportSubFun01 , bool supportSubFun02 , bool supportSubFun03 , bool supportType01, bool supportType02, bool supportType03, CommCallBack callback, bool supressPosResponse);

supportSubFun00:是否支持00子功能-使能接收和發送,TRUE:支持,FALSE:不支持

supportSubFun01:是否支持01子功能-使能接收關閉發送,TRUE:支持,FALSE:不支持

supportSubFun02:是否支持02子功能-關閉接收使能發送,TRUE:支持,FALSE:不支持

supportSubFun03:是否支持03子功能-關閉接收和發送,TRUE:支持,FALSE:不支持

supportType01:是否支持控制參數01-一般通信報文,TRUE:支持,FALSE:不支持

supportType02:是否支持控制參數02-網絡管理報文,TRUE:支持,FALSE:不支持

supportType03:是否支持控制參數03-通信報文和網絡管理報文,TRUE:支持,FALSE:不支持

Callback:通信控制接口函數指針,由應用提供,診斷模式只負責調用,控制邏輯由應用實現。

supressPosResponse:是否支持抑制響應,TRUE:支持,FALSE:不支持

20)、配置10服務的接口函數

void InitSetSessionControlParam(bool supportSub01, bool supportSub02,bool supportSub03, bool sub02SupportedInDefaultSession, bool sub03SupportedInProgramSession, bool supressPosResponse);

supportSub01:是否支持01子功能-默認會話,TRUE:支持,FALSE:不支持

supportSub02:是否支持02子功能-編程會話,TRUE:支持,FALSE:不支持

supportSub03:是否支持03子功能-拓展會話,TRUE:支持,FALSE:不支持

sub02SupportedInDefaultSession:在默認會話是否支持02子功能,TRUE:支持,FALSE:不支持

sub03SupportedInProgramSession:在編程會話是否支持03子功能,TRUE:支持,FALSE:不支持

supressPosResponse:是否支持抑制響應,TRUE:支持,FALSE:不支持

21)、配置3E服務的接口函數

void InitSetTesterPresentSupress(bool supressPosResponse);

supressPosResponse:是否支持抑制響應,TRUE:支持,FALSE:不支持

22)、配置85服務的接口函數

void InitSetDTCControlSupress(bool supressPosResponse);

supressPosResponse:是否支持抑制響應,TRUE:支持,FALSE:不支持

23)、配置當前會話模式DID的接口函數

void InitSetCurrentSessionDID(uint16_t m_DID);

由於此數據在診斷模塊,應用無法得到,所以使用此接口即可。此函數內部會添加DID。

24)、配置CAN數據庫DID的接口函數

void InitSetCanDataBaseVersionDID(uint16_t m_DID);

由於此數據在診斷模塊,應用無法得到,所以使用此接口即可。此函數內部會添加DID。

25)、配置CAN診斷版本DID的接口函數

void InitSetCanDiagnosticVersionDID(uint16_t m_DID);

由於此數據在診斷模塊,應用無法得到,所以使用此接口即可。此函數內部會添加DID。

26)、配置網絡管理版本DID的接口函數

void InitSetCanNMVersionDID(uint16_t m_DID);

由於此數據在診斷模塊,應用無法得到,所以使用此接口即可。此函數內部會添加DID。

27)、配置CAN驅動版本DID的接口函數

void InitSetCanDriverVersionDID(uint16_t m_DID);

由於此數據在診斷模塊,應用無法得到,所以使用此接口即可。此函數內部會添加DID。

28)、加載所有診斷模塊數據的接口函數

void Diagnostic_LoadAllData(void);

需要先 配置好DID,安全算法,DTC后才能調用此接口函數,此接口函數回從EEPROM中讀取所有需要的數據。

29)、配置車架號的接口函數

void Diagnostic_ConfigVIN(uint8_t length, uint8_t* data);

HD10使用此函數。

/************set netwrok layer parameters********/

30)、設置網絡層參數的接口函數

void Diagnostic_SetNLParam(uint8_t TimeAs, uint8_t TimeBs, uint8_t TimeCr, uint8_t TimeAr, uint8_t TimeBr, uint8_t TimeCs, uint8_t BlockSize, uint8_t m_STmin, uint8_t FillData);

TimeAs:網絡層定時參數AS

TimeBs:網絡層定時參數BS

TimeCr:網絡層定時參數CR

TimeAr:網絡層定時參數AR

TimeBr:網絡層定時參數BR

TimeCs:網絡層定時參數CS

BlockSize:網絡層參數BloskSieze(BS)

STmin:網絡層定時參數STmin

FillData:未使用字節的填充數據

31)、診斷處理過程的接口函數

void Diagnostic_Proc(void);

此函數時最終實現診斷功能的函數,需要放到主循環不停的調用,如有需要,可以設置定時調用,最大定時為1MS。

3、診斷模塊開發步驟

診斷模塊的開發分為以下四個步驟

1)、在CAN接收中斷中調用Diagnostic_RxFrame函數,保證將接收到的報文傳到診斷模塊。

2)、將RTI中斷配置為1MS,並在RTI中斷函數中調用Diagnostic_1msTimer。

3)、新建診斷模塊初始化函數,在函數中配置所有的服務和參數

4)、在主循環中調用Diagnostic_Proc函數。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM