254 lines
8.3 KiB
C
Raw Normal View History

2024-03-30 15:05:00 +08:00
/*
* 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 <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <stddef.h>
#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)
2024-04-02 09:46:43 +08:00
#define UDS_SA_LEVEL_09 (0x09)
2024-03-30 15:05:00 +08:00
#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))
2024-05-06 10:22:27 +08:00
#define UDS_RSP_LEN_MAX (64)
2024-03-30 15:05:00 +08:00
/* 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
******************************************************************************/
2024-05-06 10:22:27 +08:00
/*! \brief Forward declaration of UDS object
*/
struct _UdsType_;
typedef struct _UdsType_ UdsType;
2024-03-30 15:05:00 +08:00
/*! \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;
2024-05-06 10:22:27 +08:00
void (*function)(UdsType *obj,uint8_t dataBuf[], uint8_t dataLen);
2024-03-30 15:05:00 +08:00
} 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
******************************************************************************/
2024-04-02 09:46:43 +08:00
extern void TxTestMsg (uint8_t * data);
2024-03-30 15:05:00 +08:00
/*! \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_ */