UDS (ISO 14229) (Unified Diagnostic Services) это бинарный протокол. Обычно этот протокол гоняют поверх протокола ISO-TP в CAN шине между ECU. Подробно протокол описан в стандарте ISO 14229. Это диалоговый протокол, то есть работает по принципу запрос-ответ. Получается что тут есть master и slave узлы. Ещё говорят клиент сервер. Где клиент - это тестировочное оборудование, а сервер - ECU.

В этой заметке я расскажу про наиболее полезные пакеты UDS протокола.

Что надо из спецификаций?

Полная спецификация UDS составляет 400+ страниц. Документ называется International Standard ISO 14229-1, Road vehicles — Unified diagnostic services (UDS) — Part 1: Specification and requirements

Код спеки

Пояснение

1

ISO 14229-1

Спецификация прикладного уровня UDS

2

ISO 11899-2

Controller area network

3

ISO-15765

Transport Layer

Стек протоколов выстраивается в пирамиду.

На самом деле формально ничто не запрещает гонять этот UDS и по другим интерфейсам. Как в случае с протоколом XCP. Например по тому же UART. UDS это же про то как на входной массив байт выдать ответный выходной массив байт. Только и всего... Режим UDS over UART весьма полезен для модульных тестов UDS. Чтобы разграничить возможные ошибки в реализации ISO-TP от ошибок в реализации UDS. В связи с этим я бы порекомендовал Вам не приколачивать гвоздями свой код UDS к CAN коду, а добавить возможность переключаться между интерфейсами в зависимости от конфига в экземпляре UDS драйвера. Условно, вы можете объявить три экземпляра UDS. Первый прикрепить к CAN, второй UDS вывести на UART2, а третий просто оставить без интерфейсов чисто как SW экземпляр специально для модульных тестов.

Что позволяет протокол UDS?

UDS работает на уровне приложения и на сеансовом уровне модели OSI-7. UDS протоколом можно перезагрузить микроконтроллер, обновлять прошивку, управлять агрегатами автомобиля, считывать диагностические параметры агрегатов и прочее.

Действие

1

считать\стереть коды ошибок – DTC

2

запросить текущие параметры датчиков и блоков управления (ECU)

3

Обновить прошивку

4

давать команды исполнительным механизмам. Запускать подпрограммы

5

Прописывать калибровочные данные

6

Прописывать и читать конфигурационные данные

7

Перезагрузить устройство

Переменные в этом протоколе (такие как DID) передаются в формате Big-Endian. Контрольная сумма в UDS отсутствует, так как она и так проверяется на канальном уровне, где работает CRC15 от CAN пакетов.

Подпрограммы встроены в саму прошивку ECU и могут быть начаты по UDS команде от клиента. Например UDS подпрограммой можно открыть и закрыть дверной замок.

Что надо из доков?

Полный стандарт UDS это четыре сотни страниц!

#

Документ

Пояснение

pages

1

ISO 14229

Стандарт описывает уровень приложения для UDS

464

UDS это надстройка над протоколом ISO-TP(ISO-15765). Про ISO-TP у меня есть отдельный текст: Обзор Протокола ISO-TP [ISO 15765-2] https://habr.com/ru/articles/798489/.

Есть два типа ответов от ECU: положительный и отрицательный.

Аппаратная часть.
UDS не определяет внешний вид разъёма. Однако скорее всего UDS будет на 6 и 14 пинах разъёма OBD2. К слову, в легковых автомобилях разъём OBD2 реализован в виде гнезда. Поэтому для подключения Вам потребуется ответная часть в виде вилки. Перед установкой вилки обязательно проверьте, что между разъёмами не очутилась всяческая грязь в виде фольги от папиросок или прочих проводников.

Структура UDS совместимых сетей передачи данных

Архитектура UDS протокола подразумевает наличие клиента и сервера.

С сервером USD всё понятно. Это ECU. В качестве клиента в конечном счете будет выступать LapTop.

При этом тестированную утилиту можно написать тоже на Си пере используя значительную часть Си кода прошивки в виде консольного Win приложения.

Структура UDS пакета для запроса.

Рассмотрим структуру бинарного пакета для запроса.

Поле #1: SID Service ID [1-Byte]

Поле #2: UDS Sub Function [1-Byte]

Некоторые UDS запросы имеют под функцию а некоторые нет.

USD пакет может полностью поместиться в 8 байт, как запрос так и ответ.

Поле №3: Data Identifier DID [2 байта]

DID - это переменные ECU, которые можно читать или писать. Физически DID хранятся либо в RAM либо в Flash памяти микроконтроллера (NVRAM). Каждый DID адресуется 16-битным адресом. То есть в ECU может храниться до 65536 переменных. Сами же эти DID переменные могут быть совершенно любого размера, как по 1 байту, так и целые массивы. Чисто теоретически через DID можно прочитать скорость автомобиля, обороты двигателя и прочие переменные ECU. Чтобы прочитать DID надо использовать сервис 0x22-Read Data by Idenvifier (RDBI). Чтобы прочитать DID надо использовать сервис 0x2E-Write Data By Identifier (WDBI)

В самом простом случае использования по UDS можно читать данные по их ID. Для этого есть сервис SID=0x22.

ECUReset (0x11)
UDS позволяет перезагрузить микроконтроллер. Для этого достаточно буквально отправить два байта.

ReadDataByIdentifier (SID=0x22) service
Этот сервис позволяет клиенту запрашивать значения данных по одному или более идентификатору данных DID.

Запрос клиент содержит одно или более двухбайтовых DID значений, которые соответствуют данным. Формат и определение записей данных должны быть определены производителем ECU. Там могут быть показания аналоговых входов, цифровых входов или выходов, внутренние данные, статус системы и прочее.

Сервер может ограничить количество DIDов которые запрашивают одновременно за раз.

Получив пакет SID=0x22 ECU должен извлечь запрашиваемые данные с заданным DID и передать их значение в одном положительном ответе, который содержит соответствующее значение данных. Запрос может содержать тот же самый DID несколько раз. ECU должен рассматривать каждый DID как отдельный параметр и отвечать данными для каждого DID, как запрошено.

UDS предусматривает положительный и отрицательный ответ. В случае положительного ответа в ответном пакете к оригинальному SID прибавляется константа 0x40. Вот пример запроса скорости транспортного средства (DID=0xF40D) по UDS. В пакете DID передается в big-endian формате, то есть старшим байтом вперёд.

Это же в составе с ISO-TP

Однако есть и отрицательные ответы. Это может произойти если Вы запросили значение DID про который ECU ничего не знает. В случае негативного ответа это может быть, когда сервис не поддерживается.

Вот все коды ошибок для ответа на пакет ReadDataByIdentifier

NRC

Description

Mnemonic

0x13

incorrectMessageLengthOrInvalidFormat

IMLOIF

0x14

responseTooLong

RTL

0x22

conditionsNotCorrect

CNC

0x31

requestOutOfRange

ROOR

0x33

securityAccessDenied

SAD

Вот так выглядит попытка прочитать не валидный DID=0xAAAA, который не поддерживает ECU.

Прибор просто посылает значение 0x31 (requestOutOfRange), что запрошенное 16-битное значение DID не поддерживается этим конкретным CAN-устройством.

Кодов отрицательный ответов много. Вот некоторые из них

SID 0x7F
SID 0x7F

ReadScalingDataByIdentifier (SID=0x24)

Этот сервис показывает как интерпретировать данные из ECU. Это необходимо для визуализации данных полученных от ECU. Благодаря пакету ReadScalingDataByIdentifier LapTop запрашивает у ECU информацию про его внутренние переменные. Для каждой доступной переменной можно узнать её тип данных(uint8 int32 float string и т п), физическую величину (скорость, массу, ток), размер (1, 2, 5  байта), единицы измерения (градусы или радианы, паскали, бары, атмосферы или сила на кв метр) и размерный множитель (милли, пико, нано и т. п.). Всё это называется словом scaling information.  У каждого DID должна быть известная информация про тип, размер, величину, единицы измерения, множитель. Запрос от LapTop содержит одно ID переменной. Формат поля dataRecord должны быть определены по желанию производителя транспортного средства и могут включать сигналы аналоговых входов или выходов, цифровые входы, внутренние данные, информацию про статус системы. В случае получения пакета запроса ReadScalingDataByIdentifier микроконтроллер должен получить доступ к информации про переменную и передать значения в положительном ответе.

Переменная scalingByteExtension содержит единицы измерения, формат и множитель. Это нужно для представления переменной в дружественном для человека виде. Для каждой размерности в UDS предусмотрен числовой код в виде натурального числа. Поле scalingByteExtension определяет множитель для более компактного представления числа в памяти. Поле scalingByteExtension применимо только для формул, чисел и битовых масок. Для переменных типа unit первым байтом определяется единицы измерения переменной. Коды множителей перечислены в таблице Table C.8 — Unit/format scalingByteExtension encoding.

Запись NVRAM по ID. WriteDataByIdentifier (SID=0x2E)

Сервис WriteDataByIdentifier позволяет LapTop-у прописывать информацию во внутренности ECU по идентификатору данных. Можно прописывать так называемые dataRecord. Данные идентифицируются по идентификатору данных. Идентификатор данных имеет разрядность 16 бит. Благодаря этому сервису можно прописывать конфигурационные данные в ECU. Например VIN номер. Прописывать NVRAM память. При этом надо ограничивать доступ на изменение определенных ID.

Чтение сырой памяти по физическим адресам микроконтроллера

UDS протокол позволяет читать физическую память. Для этого заложены пакеты типа ReadMemoryByAddress (SID: 0x23). UDS клиент должен запоминать, что и сколько он хотел прочитать, так как в ответном пакете от ECU отсутствует повторение значения адреса и размера пакета. В ответе только данные.

Запись сырой физической памяти WriteMemoryByAddress (SID=0x3D)

Протокол UDS позволяет прописывать произвольную физическую память. В случае 32бит МК получается вот такой пакет.

Чтение информации по Diagnostic Trouble Codes Service(0x19)

Этот сервис позволяет клиенту читать состояние диагностических кодов ошибок на ECU от любого сервера или группы серверов. Если иное не требуется конкретной подфункцией то сервер должен возвращать всю информацию о DTC (например связанную или несвязанную с выбросами). Этот сервис позволяет сделать следующее:

--Получите количество кодов DTC, соответствующих маске состояния DTC, определенной клиентом.

--Получить список всех кодов неисправности, соответствующих маске состояния кодов неисправности, определенной клиентом.

--Получить список кодов DTC в конкретной функциональной группе, соответствующих маске состояния DTC, определенной клиентом.

--Получите все коды DTC со статусом «постоянный код неисправности».

Пакеты класса RoutineControl (Управление Подпрограммами) (SID=0x31)

Служба RoutineControl используется клиентом для выполнения определенной последовательности шагов и получения любых уместных результатов. Этот сервис обладает большой гибкостью, но типичное использование может включать в себя такие функции, как
стирание памяти, сброс, запуск самотестирования и контроль изменения значения сервера с течением времени, включая предопределенные последовательности (например, закрытие
складной крыши), и это лишь некоторые из них.

Сервис RoutineControl используется клиентом для следующего

Описание

sub-function

Mnemonic

Количество аргументов

Начать подпрограмму

0x01

STR

1-2

остановить подпрограммы

0x02

STPR

1

запросить результат подпрограммы

0x03

RRR

1

Каждой подпрограмме поставлен в соответствие 2-байтовый идентификатор подпрограммы routineIdentifier.

Начать процедуру по ID

Процедура должна быть запущена в памяти сервера через некоторое время между завершением сообщение запроса StartRoutine и завершение первого ответного сообщения, если ответное сообщение положительное или отрицательный, указывающий, что запрос уже выполнен или находится в процессе выполнения.

Подпрограммы могут быть либо тестами, которые выполняются вместо обычного рабочего кода, либо подпрограммами, которые активируются и выполняется при нормальном рабочем коде. В частности, в случае теста это может быть необходимо переключить сервер в конкретный диагностический сеанс с помощью службы DiagnosticSessionControl или разблокировать сервер с помощью службы SecurityAccess перед использованием службы StartRoutine.

Остановить подпрограмму по ID

Серверная процедура должна быть остановлена в памяти сервера ECU через некоторое время после завершения сообщение запроса StopRoutine и завершение первого ответного сообщения, если ответное сообщение положительное или отрицательный, указывающий, что запрос на остановку процедуры уже выполнен или находится в процессе выполнения.

Запросить результат подпрограммы по ID

Эта подфункция используется клиентом для запроса результатов (например, информации о статусе выхода), на которые ссылается подпрограмму, генерируемую подпрограммой, которая выполнялась в памяти сервера.

На основании результатов подпрограммы, которые могли быть получены в положительном ответном сообщении Параметр подфункции stopRoutine (например, нормальный/ненормальный выход с результатами) requestRoutineResults должна использоваться подфункция.

Примером routineResults могут быть данные, собранные сервером, которые не могут быть переданы во время выполнения подпрограммы из-за ограничений производительности сервера (ECU).

Вот так выглядит бинарная структура пакета запроса для RoutineControl в общем виде

Итоги
Появилось некоторое представление о UDS протоколе. Научились читать параметры по сервису SID=0x22 и запускать подпрограммы по UDS ( SID=0x31 ).

UDS больше похож не на протокол, а на набор протоколов. Для каждого сервиса предусмотрена своя уникальная бинарная структура пакета, как для запроса, так и для ответа.

UDS настолько велик, что как правило мало, кто делает полную поддержку всех UDS сервисов. Обычно ограничиваются реализацией запуска подпрограмм, чтением / записью DIDов, чтением / запись физической памяти и пакета для Reset.

Словарь

акроним

расшифровка

UDS

Unified Diagnostic Services

ECU

Electronic Control Units

OSI

open systems interconnection

ISO

International Organization for Standardization

OEM

Original Equipment Manufacturers

OBD

On-Board Diagnostics

OBD2

On-Board Diagnostics 2

DTC

Diagnostic Trouble Codes

SA

Source Address

RA

Remote Address

NRC

Negative Response Code

NVRAM

Non-Volatile Random-Access Memory

TA

Target Address

LEV

Level

PCI

Protocol Control Information

SID

Service ID

SF

Single Frame

FC

Flow Control

DID

Data IDentifier

CAN

Controller area network

VIN

Vehicle Identification Number

URLs

Ссылка

URL

UDS Explained - A Simple Intro (Unified Diagnostic Services)

https://www.csselectronics.com/pages/uds-protocol-tutorial-unified-diagnostic-services

Протокол UDS

https://canhacker.ru/protocol-uds/

Обзор Протокола ISO-TP [ISO 15765-2]

https://habr.com/ru/articles/798489/

Аналитика по протоколу UDS

https://docs.google.com/spreadsheets/d/1Ekn3QwzHQcWOr1hZNXl0AYL49xHQO4UmvD1kE-T71_s/edit#gid=430258010

Обзор USB-CAN переходника USB2CANFD_V1

https://habr.com/ru/articles/944112/

Как собрать Си программу в OS Windows

https://habr.com/ru/articles/754972/

Вопросы

--Какой может быть максимальный размер UDS DID? Можно ли одним UDS DIDом прочитать или прописать всю прошивку? Размер DID ограничен сверху размером одной ISO-TP транзакции. А это 4kByte. Также могут быть ограничения по оставшейся RAM памяти в микроконтроллере на котором собран данный ECU.

--Как можно протестировать реализацию UDS протокола?

--Какие UDS DID значения общие для всех автопроизводителей?

--Существует ли какая-нибудь готовая клиентская Windows утилита (c GUI или консольный вариант), которая опрашивает ECU по CAN через UDS протокол? Чтобы прочитать стандартные в UDS DID параметры. Такие как VIN номер, серийный номер ECU, дату производства ECU, дату программирования ECU, название производителя ECU и прочее. Vector CANape, TOSUN TSMaster

--Можно ли по UDS читать/писать произвольные адреса физической памяти? Если да то какой cерсис позволяет это делать? Какой пакет UDS предназначен для чтения физической памяти микроконтроллера?

--Зачем в 2006 понадобился автомобильный протокол UDS, если тремя годами ранее уже в 2003 был автомобильный протокол XCP? И UDS и XCP могут читать и писать произвольную память, оба могут обновлять прошивку. Они ориентированы на разные задачи: UDS-диагностику и XCP-калибровку. XCP нужен разработчикам. UDS - техникам.

--Какими UDS пакетами следует обновлять прошивку?

--Какие еще прикладные протоколы могут быть в автомобиле кроме UDS? J1939, On-Board Diagnostics (OBD2), World-Wide Harmonized OBD (WWH-OBD), CCP, XCP.

Комментарии (1)


  1. VBKesha
    07.11.2025 20:29

    Какие еще прикладные протоколы могут быть в автомобиле кроме UDS?

    KWP2000(TP20) ещё, и наверно его предшественник TP16.