/* * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD * All rights reserved. * * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use * exclusively with CVA's microcontroller products. This file can be freely * distributed within development tools that are supporting such microcontroller * products. * * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. */ #ifndef _UDS_H_ #define _UDS_H_ /*! \brief Contains public interface to various functions related * to the Unified Diagnostic Services (UDS) following ISO 14229 */ /******************************************************************************* * the includes ******************************************************************************/ #include #include #include #include #include "stimer.h" #include "isotp.h" #ifdef __cplusplus extern "C" { #endif /******************************************************************************* * the defines ******************************************************************************/ #define NRC_GENERAL_REJECT (0x10) #define NRC_SERVICE_NOT_SUPPORTED (0x11) #define NRC_SUBFUNCTION_NOT_SUPPORTED (0x12) #define NRC_INVALID_MESSAGE_LENGTH_OR_FORMAT (0x13) #define NRC_RESPONSE_TOO_LONG (0x14) #define NRC_CONDITIONS_NOT_CORRECT (0x22) #define NRC_REQUEST_SEQUENCE_ERROR (0x24) #define NRC_REQUEST_OUT_OF_RANGE (0x31) #define NRC_SECURITY_ACCESS_DENIED (0x33) #define NRC_INVALID_KEY (0x35) #define NRC_EXCEEDED_NUMBER_OF_ATTEMPTS (0x36) #define NRC_REQUIRED_TIME_DELAY_NOT_EXPIRED (0x37) #define NRC_UPLOAD_DOWNNLOAD_NOT_ACCEPTED (0x70) #define NRC_TRANSFER_DATA_SUSPENDED (0x71) #define NRC_GENERAL_PROGRAMMING_FAILURE (0x72) #define NRC_WRONG_BLOCK_SEQUENCE_COUNTER (0x73) #define NRC_SERVICE_BUSY (0x78) #define NRC_SUBFUNC_NOT_SUPPORTED_IN_ACTIVE_SESSION (0x7E) #define NRC_SERVICE_NOT_SUPPORTED_IN_ACTIVE_SESSION (0x7F) #define POSITIVE_RSP (0x40) #define NEGATIVE_RSP (0x7F) #define UDS_GET_POSITIVE_RSP(sid) (POSITIVE_RSP + sid) #define UDS_MAX_PAYLOAD_SIZE (2050) #define UDS_SA_NONE (0) #define UDS_SA_LEVEL_1 (0x01) #define UDS_SA_LEVEL_3 (0x03) #define UDS_SA_LEVEL_09 (0x09) #define UDS_SA_LEVEL_63 (0x63) #define UDS_SESSION_DEFAULT (0x01) #define UDS_SESSION_PROGRAMMING (0x02) #define UDS_SESSION_EXTENDED (0x03) #define UDS_SESSION_SAFTY (0x04) #define UDS_SESSION_SUPPLIER (0x60) #define UDS_SERVICE_NUM (15) #define UDS_SA_LEVEL_NUM (3) #define UDS_GET_SUB_FUNCTION(byte) ((byte)&0x7fu) #define BYTES_OF(x) (sizeof(x) / sizeof(uint8_t)) #define UDS_RSP_LEN_MAX (64) /* DID type */ #define UDS_VAR_TYPE_NONVOL_STORAGE (1 << 0) /* set if non-volatile data */ #define UDS_VAR_TYPE_MAY_READ (1 << 1) /* set if readable */ #define UDS_VAR_TYPE_MAY_WRITE (1 << 2) /* set if writable */ #define UDS_DID_TYPE_RAM_RW (UDS_VAR_TYPE_MAY_READ | UDS_VAR_TYPE_MAY_WRITE) #define UDS_DID_TYPE_NVM_RW (UDS_VAR_TYPE_NONVOL_STORAGE | UDS_VAR_TYPE_MAY_READ | UDS_VAR_TYPE_MAY_WRITE) #define UDS_DID_TYPE_NVM_WO (UDS_VAR_TYPE_NONVOL_STORAGE | UDS_VAR_TYPE_MAY_WRITE) #define UDS_DID_TYPE_NVM_RO (UDS_VAR_TYPE_NONVOL_STORAGE | UDS_VAR_TYPE_MAY_READ) /******************************************************************************* * the typedefs ******************************************************************************/ /*! \brief Forward declaration of UDS object */ struct _UdsType_; typedef struct _UdsType_ UdsType; /*! \brief The Data-by-ID definition of UDS */ typedef struct _Uds_DidType_ { uint16_t did; uint8_t type; uint8_t sessionLevel; uint8_t securityLevel; uint8_t *pBytes; uint16_t length; void (*function)(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen); } Uds_DidType; /*! \brief The definition of UDS DID table */ typedef Uds_DidType *Uds_DidTable; /*! \brief UDS service definition */ typedef struct _Uds_ServiceType_ { uint8_t sid; uint8_t minLen; bool subFuncOwner; void (*service)(UdsType *obj, const uint8_t msgBuf[], uint16_t msgLen); } Uds_ServiceType; /*! \brief The definition of UDS service table */ typedef const Uds_ServiceType *Uds_ServiceTable; /*! \brief The definition of UDS security table * \note The table should be like table[SID number][security level number] */ typedef const bool *Uds_SecurityTableType; /*! \brief The definition of UDS initialization parameters */ typedef struct _Uds_ParamsType_ { IsoTp_Params isotpParams; uint16_t p2Server_ms; uint16_t p2xServer_10ms; uint16_t s3Server_ms; } Uds_ParamsType; /*! \brief The UDS prototype definition */ struct _UdsType_ { bool active; uint8_t session; uint8_t securityLevel; uint32_t serviceNum; Uds_ServiceTable seviceTable; Uds_SecurityTableType securityTable; Uds_DidTable didTable; uint16_t didNum; IsoTpType isotp; bool suppressPosRsp; bool isFuncAddr; uint8_t curServiceIdx; uint8_t payload[UDS_MAX_PAYLOAD_SIZE]; int64_t timeStamp_ms; uint16_t p2Server_ms; uint16_t p2xServer_10ms; uint16_t s3Server_ms; StimerType p2ServerTimer; StimerType p2xServerTimer; StimerType s3ServerTimer; }; /******************************************************************************* * the globals ******************************************************************************/ /******************************************************************************* * the function prototypes ******************************************************************************/ extern void TxTestMsg (uint8_t * data); /*! \brief Initializes the UDS object. */ extern void Uds_Init(UdsType *obj, const Uds_ParamsType *pParams); /*! \brief The main service of UDS object. * \note Suggest run every 1ms */ extern void Uds_Run(UdsType *obj); /*! \brief This function gives a positive response */ static inline void Uds_PositiveResponse(UdsType *obj, const uint8_t data[], uint16_t len) { Stimer_Start(&obj->s3ServerTimer, obj->s3Server_ms); if(obj->suppressPosRsp == true) { return; } IsoTp_Send(&obj->isotp, data, len); return; } /*! \brief This function gives a nagative response */ static inline void Uds_NegativeResponse(UdsType *obj, uint8_t sid, uint8_t rsp_nrc) { uint8_t temp_buf[8] = {0}; if(rsp_nrc != NRC_SERVICE_BUSY) { Stimer_Start(&obj->s3ServerTimer, obj->s3Server_ms); } if(obj->isFuncAddr && (rsp_nrc == NRC_SERVICE_NOT_SUPPORTED || rsp_nrc == NRC_SUBFUNCTION_NOT_SUPPORTED || rsp_nrc == NRC_REQUEST_OUT_OF_RANGE || rsp_nrc == NRC_SUBFUNC_NOT_SUPPORTED_IN_ACTIVE_SESSION || rsp_nrc == NRC_SERVICE_NOT_SUPPORTED_IN_ACTIVE_SESSION)) { return; } temp_buf[0] = NEGATIVE_RSP; temp_buf[1] = sid; temp_buf[2] = rsp_nrc; IsoTp_Send(&obj->isotp, temp_buf, 3); } /*! \brief This function provide the time base for the UDS process */ static inline void Uds_Tick(UdsType *obj) { obj->timeStamp_ms++; Stimer_Tick(&obj->p2ServerTimer); Stimer_Tick(&obj->p2xServerTimer); Stimer_Tick(&obj->s3ServerTimer); } #ifdef __cplusplus } #endif /* extern "C" */ #endif /* _UDS_H_ */