#ifndef _UDS_FBL_SERVICE_36_SOURCE #define _UDS_FBL_SERVICE_36_SOURCE /******************************************************************************* ** Include Section ** *******************************************************************************/ #include "uds_fbl_mgr.h" #include "uds_fbl_service36.h" #include "../cantp/CanTp.h" /******************************************************************************* ** Version Information ** *******************************************************************************/ /******************************************************************************* ** Version Check ** *******************************************************************************/ /******************************************************************************* ** Macro definition ** *******************************************************************************/ /******************************************************************************* ** Global Data ** *******************************************************************************/ #define MIN_TRANSFER_DATA_LENGTH (2U) const uds_nrc nrc_3600[4] = { UDSincorrectMessageLengthOrInvalidFormat,\ UDSrequestSequenceError,\ UDStransferDataSuspended,\ UDSwrongBlockSequenceCounter }; /*--------- <0x36> sub function config start-------------*/ static const DIAG_sunfunction_t SessionSubfunction[] = { {0x00,2,true,0x802,1, NULL,{nrc_3600, 4}} }; /*--------- <0x36>sub function config end---------------*/ /*-------------------------------------------------------*/ /******************************************************************************* ** Function Definitions ** *******************************************************************************/ static bool Check_Nrc_24_Of_Service36(void); static bool Check_Nrc_71_Of_Service36(uint16_t size, uint32_t downlodeAddr, uint32_t requestEndAddr); static bool Check_Nrc_73_Of_Service36(uint8_t currBlockSequenceCnt, uint8_t requestBlockCnt); static bool Check_Nrc_13_Of_Service36(uint16_t requestDataLen, uint16_t maxBlockLen); /*======================================================================================================*/ /* static bool Check_Nrc_24_Of_Service36(void) */ /* -----------------------------------------------------------------------------------------------------*/ /* Function: Check whether 34 services are received before 36 services */ /* Arguments: - */ /* Return: Yes or No */ /*======================================================================================================*/ static bool Check_Nrc_24_Of_Service36(void) { bool nrcFlag = false; if(!udsFbl_Get_Request_Is_Trigger()) { nrcFlag = true; } else { ; } return nrcFlag; } /*======================================================================================================*/ /* static bool Check_Nrc_71_Of_Service36(uint16_t size, uint32_t downlodeAddr, uint32_t requestEndAddr) */ /* -----------------------------------------------------------------------------------------------------*/ /* Function: Check whether the transmission process of 36 service is abnormal */ /* Arguments: size : download data length */ /* downlodeAddr : download address */ /* requestEndAddr : request end address */ /* Return: Yes or No */ /*======================================================================================================*/ static bool Check_Nrc_71_Of_Service36(uint16_t size, uint32_t downlodeAddr, uint32_t requestEndAddr) { bool nrcFlag = false; /* size exclude sid byte and blockSequenceCounter */ if((downlodeAddr + size) > requestEndAddr + 1) /*Check whether the data is out of range*/ { nrcFlag = true; } else {} return nrcFlag; } /*======================================================================================================*/ /* static bool Check_Nrc_73_Of_Service36(uint16_t size, uint32_t downlodeAddr, uint32_t requestEndAddr) */ /* -----------------------------------------------------------------------------------------------------*/ /* Function: Check if block sequence counter error */ /* Arguments: currBlockSequenceCnt : current block sequence counter */ /* requestBlockCnt : request download block */ /* Return: Yes or No */ /*======================================================================================================*/ static bool Check_Nrc_73_Of_Service36(uint8_t currBlockSequenceCnt, uint8_t requestBlockCnt) { bool nrcFlag = false; uint8_t pre_blockcnt; pre_blockcnt = udsFbl_Get_PreDownload_Block_Cnt(); if(requestBlockCnt != currBlockSequenceCnt) { if(requestBlockCnt != pre_blockcnt) { nrcFlag = true; } else { /* do nothing */ } } else { /* do nothing */ } return nrcFlag; } /*======================================================================================================*/ /* static bool Check_Nrc_13_Of_Service36(uint16_t size, uint32_t downlodeAddr, uint32_t requestEndAddr) */ /* -----------------------------------------------------------------------------------------------------*/ /* Function: Check if download block data length exceed max length */ /* Arguments: requestDataLen : request transfer data length */ /* maxBlockLen : The maximum amount of data allowed in a single transfer */ /* Return: Yes or No */ /*======================================================================================================*/ static bool Check_Nrc_13_Of_Service36(uint16_t requestDataLen, uint16_t maxBlockLen) { bool nrcFlag = false; if(requestDataLen > maxBlockLen - MIN_TRANSFER_DATA_LENGTH) { nrcFlag = true; } else {} return nrcFlag; } /*======================================================================================================*/ /* static bool Check_Nrc_92_Of_Service36(void) */ /* -----------------------------------------------------------------------------------------------------*/ /* Function: Check whether the working voltage is in the effective range */ /* Arguments: - */ /* Return: Yes or No */ /*======================================================================================================*/ #if 0 static bool Check_Nrc_92_Of_Service36(void) { /*Check if voltage too high */ return 0; } #endif /*======================================================================================================*/ /* static bool Check_Nrc_93_Of_Service36(void) */ /* -----------------------------------------------------------------------------------------------------*/ /* Function: Check whether the working voltage is in the effective range */ /* Arguments: - */ /* Return: Yes or No */ /*======================================================================================================*/ #if 0 static bool Check_Nrc_93_Of_Service36(void) { /*Check if voltage too low */ return 0; } #endif /*======================================================================================================*/ /* uds_nrc UdsFbl_TransferData36xx(UDSpacket_t* qUDSpacket, uint32_t downlodeAddr_u32) */ /* -----------------------------------------------------------------------------------------------------*/ /* Function: 36 Service specific processing functions */ /* Arguments: - */ /* Return: Yes or No */ /*======================================================================================================*/ uds_nrc UdsFbl_TransferData36xx(UDSpacket_t* qUDSpacket, uint32_t downlodeAddr_u32) { uds_nrc ssNrc = UDSnoReply; uint16_t dataLenth = 0; uint8_t *pData = NULL; uint8_t cnt; uint8_t pre_blockcnt; FLASH_TYPE type; pre_blockcnt = udsFbl_Get_PreDownload_Block_Cnt(); cnt = udsFbl_Get_Download_Block_Cnt(); type = udsFbl_Get_FlashProgram_Type(); pData = &qUDSpacket->Data.Byte[2]; dataLenth = qUDSpacket->size - MIN_TRANSFER_DATA_LENGTH; if(qUDSpacket->Data.Byte[1] == pre_blockcnt) /* curr block num equal to last block num */ { ssNrc = UDSpositiveResp; qUDSpacket->Data.Byte[0] = UDS_GET_POSITIVE_RSP(qUDSpacket->Data.Byte[0]); qUDSpacket->Data.Byte[1] = pre_blockcnt; qUDSpacket->size = 2; } else { /* program FBL or APP or flash driver */ ssNrc = MEM_Program(downlodeAddr_u32, pData, dataLenth); if(UDSpositiveResp == ssNrc || UDSreqCorrectlyRx_RespPending == ssNrc) { qUDSpacket->Data.Byte[1] = cnt; udsFbl_Set_PreDownload_Block_Cnt(cnt); /* calculate offset address */ udsFbl_Set_Download_Addr(downlodeAddr_u32 + dataLenth); if (cnt < 0xFF) { cnt++; } else { cnt = 0; } udsFbl_Set_Download_Block_Cnt(cnt); if((type < FLASH_DRIVER) && (UDSreqCorrectlyRx_RespPending == ssNrc)) /* judge flash program type(FBL,APPL) */ { udsFbl_StartTimer(TIMER_UDS_PROGRAM); } else { qUDSpacket->size = 2; qUDSpacket->Data.Byte[0] = UDS_GET_POSITIVE_RSP(qUDSpacket->Data.Byte[0]); } } else { /* do nothing */ } } return ssNrc; } /*======================================================================================================*/ /* uds_nrc service36_nrc_check(UDSpacket_t* qUDSpacket) */ /* -----------------------------------------------------------------------------------------------------*/ /* Function: 36 service negative response judgment */ /* Arguments: qUDSpacket : CAN message structure pointer */ /* Return: Response type */ /*======================================================================================================*/ uds_nrc service36_nrc_check(UDSpacket_t* qUDSpacket) { uds_nrc returnType = 0; uint8_t const kwpdiag_num = (sizeof(SessionSubfunction)/sizeof(DIAG_sunfunction_t)); uint8_t index = 0; uint8_t index_nrc = 0; uint8_t requestBlockCnt = qUDSpacket->Data.Byte[1]; uint32_t downlodeAddr = udsFbl_Get_Download_Addr(); uint32_t requestEndAddr = udsFbl_Get_Request_EndAddr(); uint8_t downlodeBlockCnt = udsFbl_Get_Download_Block_Cnt(); uint16_t maxBlockLength = udsFbl_Get_maxNumberOfBlockLength(); if(qUDSpacket->size < 3) { returnType = UDSincorrectMessageLengthOrInvalidFormat; } else { for (index = 0; index < kwpdiag_num; index++) { nrc_table_t nrc_table = SessionSubfunction[index].nrc_table; /* Judge abnormal situations according to NRC priority */ for (index_nrc = 0; (index_nrc < nrc_table.nrc_cnt) && (returnType == 0); index_nrc++) { switch (nrc_table.nrc_list[index_nrc]) { case UDSincorrectMessageLengthOrInvalidFormat: if (Check_Nrc_13_Of_Service36(qUDSpacket->size - MIN_TRANSFER_DATA_LENGTH, maxBlockLength)) { returnType = UDSincorrectMessageLengthOrInvalidFormat; } break; case UDSrequestSequenceError: if (Check_Nrc_24_Of_Service36()) { returnType = UDSrequestSequenceError; } break; case UDStransferDataSuspended: if (Check_Nrc_71_Of_Service36(qUDSpacket->size - MIN_TRANSFER_DATA_LENGTH, downlodeAddr, requestEndAddr)) { returnType = UDStransferDataSuspended; } break; case UDSwrongBlockSequenceCounter: if (Check_Nrc_73_Of_Service36(downlodeBlockCnt, requestBlockCnt)) { returnType = UDSwrongBlockSequenceCounter; } break; default: break; } } } } return returnType; /* return highest priority nrc*/ } /*======================================================================================================*/ /* uint8_t ApplDiag_TransferData_36(UDSpacket_t* qUDSpacket) */ /* -----------------------------------------------------------------------------------------------------*/ /* Function: 36 service entry processing function */ /* Arguments: qUDSpacket : CAN message structure pointer */ /* Return: Response type */ /*======================================================================================================*/ uint8_t ApplDiag_TransferData_36(UDSpacket_t* qUDSpacket) { uds_nrc returnType = 0; returnType = service36_nrc_check(qUDSpacket); uint32_t downloadAddr = udsFbl_Get_Download_Addr(); if(UDSpositiveResp == returnType) { returnType = UdsFbl_TransferData36xx(qUDSpacket, downloadAddr); } return returnType; } /*======================================================================================================*/ /* void programCounterCheck(uint16_t* pProgramCounter) */ /* -----------------------------------------------------------------------------------------------------*/ /* Function:service 36 program timer */ /* Arguments: pProgramCounter : program timer counter */ /* Return: - */ /*======================================================================================================*/ void programCounterCheck(uint16_t* pProgramCounter) { if((*pProgramCounter)) { if((*pProgramCounter) == 1) { programSendPendingRsp(); } else { (*pProgramCounter)--; } } else { /* do nothing */ } } /*======================================================================================================*/ /* void programSendPendingRsp(void) */ /* -----------------------------------------------------------------------------------------------------*/ /* Function: 36 service send pending response */ /* Arguments: - */ /* Return: - */ /*======================================================================================================*/ void programSendPendingRsp(void) { udsFbl_StartTimer(TIMER_UDS_PROGRAM); uint8_t transdata[3]; transdata[0] = 0x7F; transdata[1] = 0x36; transdata[2] = 0x78; network_send_udsmsg(transdata,3); } /******************************************************************************* ** End of File ** *******************************************************************************/ #endif /*_UDS_FBL_SERVICE_36_SOURCE*/