# Diagnostics ------------- [TOC] powertrain-build has two ways of handling diagnostics, depending on the use case. The code for finding the diagnostics blocks can be found in [parseCoreIdentifiers.m](https://opendev.org/volvocars/powertrain-build/src/branch/master/powertrain_build/matlab_scripts/CodeGen/parseCoreIdentifiers.m) and [parseDIDs.m](https://opendev.org/volvocars/powertrain-build/src/branch/master/powertrain_build/matlab_scripts/CodeGen/parseDIDs.m). ## Basics All functions that are asking the core for permission to run need to have an ID – this is called a Function ID. Permission to run can be withheld due to errors in the system, this is called Inhibition. The relationship between which functions should be stopped for which faults (which are reported using an Event ID) is possible to calibrate. Fail safes (reconfigurations) use the same method/mechanism, but instead of stopping when an error is detected, they are activated. ### DTCs An event ID is used for storing an event (Diagnostic Trouble Code (DTC)) in the Diagnostic Event Manager (DEM). An event can be a detected fault, system not working according to specification or a placeholder where we might want to store additional information at the occurrence of the event. The stored events are DTCs when read with a tester. ### DIDs DID is short for Data Identifier and is part of the Unified Diagnostic Services (UDS) protocol, where it represents data items within an electronic control module (ECM) of a car. DIDs can include things like sensor readings, actuator positions, and diagnostic trouble codes (DTCs). DIDs are used to access and manipulate these data items through the UDS protocol, which allows for communication between diagnostic tools and the vehicle’s onboard computer. ## Using CSV Files These files are generally stored in *\/ConfigDocuments* but can also be stored in *\/Projects/\/ConfigDocuments*, however, an update in *\/Projects/\/ProjectCfg.json* is required for the latter. ### How to Define a Function ID Name * Add the FiD (Function Identifier) in the sheet *CoreIdNameDefinition_FunctionIDs.csv*. * Enter in which projects this FiD is to be defined in the project columns.​ * All FiDs shall have the prefix *VcFi*, and all Fail safes shall have the prefix *VcFiFs*. * If a used FiD is not configured in the core, the project will not compile. ![fid_table](../images/target_link/fid_table.PNG) ### How to Add a Failsafe/Permission in a Model This requires a special setup. The block needs to be named "FiM_GetFunctionPermission" in order for powertrain-build to pick it up. To handle this functionality it is currently recommended that this block uses a [custom code block](./custom_code_block.md) to handle the functionality, depending on the target. A named constant is typically the input to this block. ### How to Define an Event ID Name * Add the Event Id in the sheet *CoreIdNameDefinition_EventIDs.csv*. * Enter in which projects these EvIds shall be defined in the project columns. * All Event IDs shall have the prefix *VcEv*. * If a used Event ID is not configured in the core, the project will not compile. The structure of this csv file is the same as the one for Function IDs. ### How to Add Event Reporting in a Model This requires a special setup. There are typically one block per event type. For example "Dem_SetEventStatus – Pre-Failed" block for reporting faults, "Dem_SetEventStatus – Pre-Passed" block for reporting test passed. "Dem_SetEventStatus – Failed" and "Dem_SetEventStatus - Passed" are also possible. To handle this functionality it is currently recommended that this block uses a [custom code block](./custom_code_block.md) to handle the functionality, depending on the target. A named constant is typically the input to these blocks. ### How to Define a DID powertrain-build can read a few DID files depending on the use case and the data type of the DIDs. Parsed DID files include *DIDIds_Float32.csv*, *DIDIds_FullRange_Float32.csv*, *DIDIds_FullRange_UInt32.csv* and *DIDIds_UInt32.csv*. ![did_table](../images/target_link/did_table.PNG) ### How to Add a DID in a Model This requires a special setup. In order to get powertrain-build to collect DIDs, create a new mask called "DID", it can contain a simple inport followed by an outport block. ### Generated DID Files In terms of DIDs, powertrain-build will generate two sets C code. The first set, named *VcDidDefinitions.c/h*, defines the DIDs in a struct and maps them to their hex IDs. The second set, named *VcDIDApi.c/h*, defines the functions for retrieving the DIDs. ## Using YAML Files ### How to Define an Event ID Name (YAML) Regarding Simulink blocks, the setup is the same as with [CSV files](#how-to-add-event-reporting-in-a-model). Additionally, metadata for DTCs need to be added to a DTC configuration file (*ConfigDocuments/DTCs.yaml*). The content of the file should be a yaml dictionary mapping DTCs to their corresponding hex value (event ID). Example of a DTC definition file: ```yaml { "VcModelDtcOne": 0x123ABC, "VcModelDtcTwo": 0xABC123, "VcModelDtcThree": 0xFFFFFF } ``` powertrain-build will generate two files, *VcCoreSupplierAbstraction.c/h*. The header file maps the function e.g. `Dem_SetEventStatus(EventName, EventStatus)` (from a custom code block) to a macro `VcCoreSupplierAbstraction_##EventName##_SetEventStatus(EventStatus)`. The source file will contain all required DTC functions which in turn call the functions available in the target. Example of *VcCoreSupplierAbstraction.h*: ```c #ifndef VCCORESUPPLIERABSTRACTION_H #define VCCORESUPPLIERABSTRACTION_H /* Core API Supplier Abstraction */ #include "tl_types.h" #include "Rte_LVC.h" /* enum EventStatus {passed=0, failed=1, prepassed=2, prefailed=3} */ #define Dem_SetEventStatus(EventName, EventStatus) VcCoreSupplierAbstraction_##EventName##_SetEventStatus(EventStatus) #include "PREDECL_CODE_ASIL_D_START.h" UInt8 VcCoreSupplierAbstraction_VcModelDtcOne_SetEventStatus(UInt8 EventStatus); UInt8 VcCoreSupplierAbstraction_VcModelDtcTwo_SetEventStatus(UInt8 EventStatus); UInt8 VcCoreSupplierAbstraction_VcModelDtcThree_SetEventStatus(UInt8 EventStatus); #include "PREDECL_CODE_ASIL_D_END.h" #endif /* VCCORESUPPLIERABSTRACTION_H */ ``` Example of *VcCoreSupplierAbstraction.c*: ```c #include "VcCoreSupplierAbstraction.h" #include "CVC_CODE_ASIL_D_START.h" UInt8 VcCoreSupplierAbstraction_VcModelDtcOne_SetEventStatus(UInt8 EventStatus) { Rte_Call_DTC_123ABC_VcModelDtcOne_SetEventStatus(EventStatus); return 0; } UInt8 VcCoreSupplierAbstraction_VcModelDtcTwo_SetEventStatus(UInt8 EventStatus) { Rte_Call_DTC_ABC123_VcModelDtcTwo_SetEventStatus(EventStatus); return 0; } UInt8 VcCoreSupplierAbstraction_VcModelDtcThree_SetEventStatus(UInt8 EventStatus) { Rte_Call_DTC_FFFFFF_VcModelDtcThree_SetEventStatus(EventStatus); return 0; } #include "CVC_CODE_ASIL_D_END.h" ``` **NOTE:** each of the *Rte_Call_DTC_\** functions must be present in the target. ### How to Define a DID (YAML) Regarding Simulink blocks, the setup is the same as with [CSV files](#how-to-add-a-did-in-a-model). Additionally, metadata for DIDs need to be added to a DID configuration file (*ConfigDocuments/DIDs.yaml*). Add the name of the file to the projects *ProjectCfg.json* file, by adding a new element `"didDefFile": "DIDs.yaml"` in the *ProjectInfo* section. There are six available function calls for each DID. * Read data function. * Min and max read data functions. * Condition check function. * Min and max condition check functions. The metadata for each DID includes an ID and which of above functions should be generated or not, including their respective data types. Note that the same ID cannot be used for a function type more than once, as this would generate the same function call (overwrite). There is one function type per DID function call, read_data, read_data_min, read_data_max, condition_check, condition_check_min and condition_check_max. The "nr_of_bytes" key is optional. Example of a DID definition file: ```yaml { "dummy_did_one": { "id": "DA00", "data_type": "uint8", "nr_of_bytes": 1, "function_type": "read_data" }, "dummy_did_two": { "id": "DA00", "data_type": "Dcm_NegativeResponseCodeType", "function_type": "condition_check" }, "dummy_did_three": { "id": "DA01", "data_type": "uint8", "function_type": "read_data_max" } } ``` powertrain-build will generate two files, *VcDIDAPI.c/h*. It contains the generated functions for each DID, based on the data from the DID definition file as well as the unit configuration json file. Example of *VcDIDAPI.h*: ```c #ifndef VCDIDAPI_H #define VCDIDAPI_H #include "tl_basetypes.h" #include "Rte_LVC.h" #include "PREDECL_DISP_ASIL_D_START.h" extern CVC_DISP_ASIL_D Bool dummy_did_one; extern CVC_DISP_ASIL_D Bool dummy_did_two; extern CVC_DISP_ASIL_D Bool dummy_did_three; #include "PREDECL_DISP_ASIL_D_END.h" #include "PREDECL_CODE_ASIL_D_START.h" void DID_DA00_Runnable_ReadData(uint8 *Data); void DID_DA00_Runnable_ConditionCheckRead(Dcm_NegativeResponseCodeType *ErrorCode); void DID_DA01_Runnable_MAX_ReadData(uint8 *Data); #include "PREDECL_CODE_ASIL_D_END.h" #endif /* VCDIDAPI_H */ ``` Example of *VcDIDAPI.c*: ```c #include "VcDIDAPI.h" #include "CVC_CODE_ASIL_D_START.h" void DID_DA00_Runnable_ReadData(uint8 *Data) { memcpy(Data, &dummy_did_one, 1); } void DID_DA00_Runnable_ConditionCheckRead(Dcm_NegativeResponseCodeType *ErrorCode) { memcpy(ErrorCode, &dummy_did_two, sizeof(Dcm_NegativeResponseCodeType)); } void DID_DA01_Runnable_MAX_ReadData(uint8 *Data); { memcpy(Data, &dummy_did_three, sizeof(uint8)); } #include "CVC_CODE_ASIL_D_END.h" ``` **NOTE:** these functions must be present in the target. ## Notes See [generateYamlInterfaceFile](../project_config.md#generateYamlInterfaceFile), which makes powertrain-build read different files and generates different versions of the files *VcDIDApi.c/h* and *VcCoreSupplierAbstraction.h*.