-
DoIP (Diagnostic over Internet Protocol) - TSMaster API C 코드카테고리 없음 2025. 4. 11. 15:28
시작하기 전에
정비를 하다보면 진단 통신으로 제어기의 상태를 확인하고, 상태에 따라 제어기를 조작하고, 다시 제어기의 상태를 확인하고, 또 다시 상태에 따라 제어기를 조작하는 일을 반복하는 경우가 많다. 이런 경우 미리 프로그램을 작성해두면 편리하다.
TSMaster Diagnostic의 Automatic Diagnostic 기능을 이용하여 프로그램을 할 수 있다. TSMaster는 이를 진단 플로우(flow)라고 한다.
C나 Python으로 코딩을 하면 더 유연하게 더 복잡한 조작을 프로그램 할 수 있다.
C 코드를 이용하여, DoIP 진단 통신하는 방법을 설명한다.
개요
- DoIP 예제 코드로 방법을 설명한다. 코드는 아래의 구조로 되어있다.
- TSMaster 설정
- 하드웨어 설정
- 채널 설정
- DoIP 설정
- DoIP로 UDS 진단 요청 메시지 전송과 응답 메시지 수신
- GUI를 이용하여 TSMaster를 사용하는 순서와 다를 바 없다.
C 코드
- 아래 C 코드는 TSMaster의 DoIP 기능을 이용하여 이더넷 진단 통신을 하는 예이다.
- (#include "TSMaster.h"에서 짐작할 수 있듯이) 이 코드는 TSMaster의 기능들을 이용한다. TSMaster가 설치되어 있어야 정상적으로 실행된다.
#include <stdio.h> // Include standard input/output library#include <stdint.h> // Include stdint library for fixed-width integer types#include "TSMaster.h" // Include the TSMaster library header file
int main(){// Initialize the TSMaster library with a specific project pathint32_t ret_1_inistial = initialize_lib_tsmaster_with_project("TSMaster", "D:\6.Other\TSMaster\TSMasterPrj");
// int32_t ret_inistial = initialize_lib_tsmaster("TSMaster");printf("initialize_lib_tsmaster_with_project result=%d\n", ret_1_inistial);
int32_t devicesCount = -1; // Variable to hold the count of hardware devices
// Enumerate the hardware devices and get the countint32_t ret_2_hw_devices = tsapp_enumerate_hw_devices(&devicesCount);printf("tsapp_enumerate_hw_devices result=%d\n", ret_2_hw_devices);printf("tsapp_enumerate_hw_devices device-count=%d\n", devicesCount);
// Get hardware information for each device// Loop through each device and retrieve its informationTLIBHWInfo info; // Structure to hold information about hardware devicesfor(int32_t i = 0; i < devicesCount; ++i) {// Get hardware information by indexint32_t ret_3_get_hw_info = tsapp_get_hw_info_by_index(i, &info);printf("tsapp_get_hw_info_by_index result=%d\n", ret_3_get_hw_info);printf("tsapp_get_hw_info_by_index index=%d, vendor=%s, devcie=%s, serial=%s\n", info.FDeviceIndex, info.FVendorName, info.FDeviceName, info.FSerialString);}
// Set the count for various communication channelstsapp_set_can_channel_count(1); // Set the count for CAN channelstsapp_set_lin_channel_count(0); // Set the count for LIN channelstsapp_set_canfd_channel_count(0); // Set the count for CAN FD channelstsapp_set_flexray_channel_count(0); // Set the count for FlexRay channels
// Set the count for Ethernet channelsint32_t ret_4_channel_count = set_ethernet_channel_count(2);printf("set_ethernet_channel_count result=%d\n", ret_4_channel_count);
// Initialize the socket with 2 channelsint32_t ret_5_initialize = tssocket_initialize(2);printf("tssocket_initialize result=%d\n", ret_5_initialize);
// Define MAC address and network parametersuint8_t mac_addr[] = {0xAA,0xBB,0xCC,0xDD,0xEE,0x23};uint16_t vlan = 0;Tip4_addr_t ip;Tip4_addr_t gw;Tip4_addr_t netmask;int16_t mtu = 1500; // Maximum Transmission Unit
// Convert string IP addresses to raw socket address formatrawsocket_aton("172.20.0.36", &ip);rawsocket_aton("255.255.255.252", &gw);rawsocket_aton("255.255.255.0", &netmask);
// Add a device to the socketint32_t ret_6_add_device = tssocket_add_device(2, mac_addr, &vlan, ip, netmask, gw, mtu);printf("tssocket_add_device result=%d\n", ret_6_add_device);
// Create a mapping structure for CAN channelTLIBTSMapping canMapping;// TSMaster CAN FD Channel 1 - Vector VIRTUAL 1 CAN FD Channel 1memset(canMapping.FAppName, 0x00, 32); // Clear application namememcpy(canMapping.FAppName, "TSMaster", sizeof("TSMaster")); // Set application namememset(canMapping.FHWDeviceName, 0x00, 32); // Clear hardware device namememcpy(canMapping.FHWDeviceName, "Vector VIRTUAL", sizeof("Vector VIRTUAL")); // Set hardware device name
canMapping.FAppChannelIndex = 0; // Set application channel indexcanMapping.FAppChannelType = (TLIBApplicationChannelType)0; // Set application channel typecanMapping.FHWDeviceType = (TLIBBusToolDeviceType)2; // Set hardware device typecanMapping.FHWDeviceSubType = 1; // Set hardware device subtypecanMapping.FHWIndex = 0; // Set hardware indexcanMapping.FHWChannelIndex = 0; // Set hardware channel indexcanMapping.FMappingDisabled = 0; // Enable mapping
// Set the mapping for CAN channelint32_t ret_7_can_mapping = tsapp_set_mapping(&canMapping);printf("tsapp_set_mapping for can result=%d\n", ret_7_can_mapping);
// Create a mapping structure for Ethernet channel 1TLIBTSMapping eth1Mapping;// TSMaster Ethernet Channel 1 - TOSUN Ex TE1051 1 Ethernet Channel 1memset(eth1Mapping.FAppName, 0x00, 32); // Clear application namememcpy(eth1Mapping.FAppName, "TSMaster", sizeof("TSMaster")); // Set application namememset(eth1Mapping.FHWDeviceName, 0x00, 32); // Clear hardware device namememcpy(eth1Mapping.FHWDeviceName, "TOSUN Ex TE1051", sizeof("TOSUN Ex TE1051")); // Set hardware device nameeth1Mapping.FAppChannelIndex = 0; // Set application channel indexeth1Mapping.FAppChannelType = (TLIBApplicationChannelType)3; // Set application channel typeeth1Mapping.FHWDeviceType = (TLIBBusToolDeviceType)11; // Set hardware device typeeth1Mapping.FHWDeviceSubType = 27; // Set hardware device subtypeeth1Mapping.FHWIndex = 0; // Set hardware indexeth1Mapping.FHWChannelIndex = 0; // Set hardware channel indexeth1Mapping.FMappingDisabled = 0; // Enable mapping
// Set the mapping for Ethernet channel 1int32_t ret_8_eth1_mapping = tsapp_set_mapping(ð1Mapping);printf("tsapp_set_mapping for eth1 result=%d\n", ret_8_eth1_mapping);
// TSMaster Ethernet Channel 2// Create a mapping structure for Ethernet channel 2TLIBTSMapping eth2Mapping;memset(eth2Mapping.FAppName, 0x00, 32); // Clear application namememcpy(eth2Mapping.FAppName, "TSMaster", sizeof("TSMaster")); // Set application namememset(eth2Mapping.FHWDeviceName, 0x00, 32); // Clear hardware device namememcpy(eth2Mapping.FHWDeviceName, "Unknown", sizeof("Unknown")); // Set hardware device nameeth2Mapping.FAppChannelIndex = 1; // Set application channel indexeth2Mapping.FAppChannelType = (TLIBApplicationChannelType)3; // Set application channel typeeth2Mapping.FHWDeviceType = (TLIBBusToolDeviceType)0; // Set hardware device typeeth2Mapping.FHWDeviceSubType = 27; // Set hardware device subtypeeth2Mapping.FHWIndex = -1; // Set hardware indexeth2Mapping.FHWChannelIndex = -1; // Set hardware channel index// Set the mapping for Ethernet channel 2int32_t ret_9_eth2_mapping = tsapp_set_mapping(ð2Mapping);printf("tsapp_set_mapping for eth2 result=%d\n", ret_9_eth2_mapping);
// Connect to the TSMasterint32_t ret_10_connect = tsapp_connect();printf("tsapp_connect result=%d\n", ret_10_connect);
// Start logging to a specified fileint32_t ret_11_logging_start = tsapp_start_logging("./1.blf");printf("tsapp_start_logging result=%d\n", ret_11_logging_start);
// Define parameters for the DoIP connectionint32_t udsHandle = 0; // Handle for the UDS connectionint32_t ToolType = 0; // Type of the tooluint32_t ChnIndex = 0; // Channel indexchar *Tester_IP = "172.20.0.36"; // Tester IP addressuint16_t Tester_PORT = 31281; // Tester portchar *DUT_IP = "172.20.0.38"; // Device Under Test IP addressuint16_t DUT_PORT = 13400; // Device Under Test port
uint32_t req_id = 0x0E00; // Request IDuint32_t res_id = 0x0373; // Response IDuint32_t func_id = 0x0042; // Function ID
// Create a DoIP connectionint32_t ret_12_diop_create = tsdiag_doip_create(&udsHandle, ToolType, ChnIndex,Tester_IP, Tester_PORT,DUT_IP, DUT_PORT,req_id, res_id, func_id);printf("tsdiag_doip_create result=%d\n", ret_12_diop_create);
// Connect using DoIPint32_t ret_13_doip_connect = tsdiag_doip_connect(udsHandle);printf("tsdiag_doip_connect result=%d\n", ret_13_doip_connect);
uint8_t activate_type = 0xE2; // Activation typebool whether_send_oem_data = true; // Flag to send OEM datauint32_t oem_specific_data = 0xFFFFFFFF; // OEM specific data
// Activate DoIP routingint32_t ret_14_doip_routing = tsdiag_doip_routing_activation(udsHandle, activate_type, whether_send_oem_data, oem_specific_data);printf("tsdiag_doip_routing_activation result=%d\n", ret_14_doip_routing);
sleep(2); // Sleep for 2 seconds
// Define request and response buffers for DoIPuint8_t req[2] = {0x10, 0x3}; // Request data. 진단 요청int32_t req_size = 2; // Request size
uint8_t res[10]; // Response buffer. 진단 응답int32_t res_size = 10; // Response size
// Send request and get responseint32_t ret_15_doip_req_res = tstp_request_and_get_response(udsHandle, req, 2, res, &res_size);printf("tsdiag_doip_routing_activation result=%d\n", ret_15_doip_req_res);// print(res[0:2])// Stop loggingint32_t ret_16_logging_stop = tsapp_stop_logging();printf("tsapp_stop_logging result=%d\n", ret_16_logging_stop);// Disconnect from the TSMasterint32_t ret_17_disconnect = tsapp_disconnect();printf("tsapp_disconnect result=%d\n", ret_17_disconnect);
// Finalize the TSMaster libraryfinalize_lib_tsmaster();
return 0; // Return 0 to indicate successful execution}하드웨어 설정 부분 코딩 팁
- 코드에서 하드웨어 설정 부분은 아래 방법으로 작성할 수 있다.
- 메인 메뉴/ Hardware/ Channel Selection 버튼을 클릭하여 TSMaster Application Channel Selection 창을 연다. 그리고 하드웨어 설정을 한다. 설정을 마친 후, "C" 버튼을 클릭한다.
- C 코드 윈도가 열리고, 코드가 클립보드에 복사된다. 코딩 창에 붙여넣기 하면 된다.
전체 코드는 아래 코드 블록의 내용과 같다. initialize_lib_tsmaster("TSMaster"); tsapp_set_can_channel_count(0); tsapp_set_lin_channel_count(0); tsapp_set_flexray_channel_count(0); tsapp_set_ethernet_channel_count(1); tsapp_set_ai_channel_count(0); tsapp_set_ao_channel_count(0); tsapp_set_di_channel_count(0); tsapp_set_do_channel_count(0); tsapp_set_gps_channel_count(0); TLIBTSMapping m; // TSMaster Ethernet Channel 1 - TS Virtual Device 1 Ethernet Channel 1 m.init(); sprintf_s(m.FAppName, "%s", "TSMaster"); sprintf_s(m.FHWDeviceName, "%s", "TS Virtual Device"); m.FAppChannelIndex = 0; m.FAppChannelType = (TLIBApplicationChannelType)3; m.FHWDeviceType = (TLIBBusToolDeviceType)1; m.FHWDeviceSubType = -1; m.FHWIndex = 0; m.FHWChannelIndex = 0; if (0 != tsapp_set_mapping(&m)) { /* handle error */ }; if (0 != tsapp_connect()){ /* handle error */ }; /* do your work here */ tsapp_disconnect(); finalize_lib_tsmaster();
DoIP 설정
- 코드의 아래 부분은
// Define parameters for the DoIP connectionint32_t udsHandle = 0; // Handle for the UDS connectionint32_t ToolType = 0; // Type of the tooluint32_t ChnIndex = 0; // Channel indexchar *Tester_IP = "172.20.0.36"; // Tester IP addressuint16_t Tester_PORT = 31281; // Tester portchar *DUT_IP = "172.20.0.38"; // Device Under Test IP addressuint16_t DUT_PORT = 13400; // Device Under Test port
uint32_t req_id = 0x0E00; // Request IDuint32_t res_id = 0x0373; // Response IDuint32_t func_id = 0x0042; // Function ID- Diagnostics 창의 Transport Layer 설정에 해당한다.
- 아래 코드에서 udsHandle은
int32_t udsHandle = 0; // Handle for the UDS connection
- 아래 코드에서 udsHandle은 메인 메뉴/ Application/ Diagnostic Module 에서 Add Diagnostic 또는 Add DiagnosticDB으로 추가한 "윈도 번호 - 1"한 값이다. 아래 그림에는 윈도가 2개 있다. 번호는 각각 1과 2이다. udsHandle 값은 각각 0과 1이다.
- 코드의 아래 부분은
uint8_t activate_type = 0xE2; // Activation typebool whether_send_oem_data = true; // Flag to send OEM datauint32_t oem_specific_data = 0xFFFFFFFF; // OEM specific data
// Activate DoIP routingint32_t ret_14_doip_routing = tsdiag_doip_routing_activation(udsHandle, activate_type, whether_send_oem_data, oem_specific_data);printf("tsdiag_doip_routing_activation result=%d\n", ret_14_doip_routing);- Diagnostics 창의 Diagnostic Layer 설정에 해당한다.
UDS 진단 요청 송신과 응답 수신
- DoIP로 진단 요청 메시지를 전송하고 응답 메시지를 수신하는 방법은 아래 코드와 같이 간단하다. 아래 예에서 요청 메시지는 "10 03" (Session Control Extended Diagnostic Session)이다.
// Define request and response buffers for DoIPuint8_t req[2] = {0x10, 0x3}; // Request data. 진단 요청int32_t req_size = 2; // Request size
uint8_t res[10]; // Response buffer. 진단 응답int32_t res_size = 10; // Response size
// Send request and get responseint32_t ret_15_doip_req_res = tstp_request_and_get_response(udsHandle, req, 2, res, &res_size);printf("tsdiag_doip_routing_activation result=%d\n", ret_15_doip_req_res);// print(res[0:2])- 필요에 따라 진단 요청을 변경하며 응답을 해석하는 방법으로 제어기의 진단 기능을 활용할 수 있다.
UDS 진단 요청과 응답을 조합하여 복잡한 혹은 유연한 서비스 플로우를 프로그램할 수 있을 것이다.
- DoIP 예제 코드로 방법을 설명한다. 코드는 아래의 구조로 되어있다.