
UDS (ISO 14229) (Unified Diagnostic Services) это бинарный прикладной протокол. Обычно этот протокол гоняют поверх протокола ISO-TP в CAN шине между ECU. Подробно протокол описан в стандарте ISO-14229. UDS - это диалоговый протокол, то есть работает по принципу запрос - ответ. Получается, что тут есть master и slave узлы. Ещё говорят клиент и сервер. Где клиент - это тестировочное оборудование (обычно LapTop), а сервер - ECU. В качестве ECU может выступать контроллер форсунок, автоматическая коробка передач, телематический блок, кузовная электроника, HMI или прочая электронная плата внутри автомобиля.
Бинарные протоколы хороши тем, что они компактные.
В этой заметке я расскажу про наиболее полезные пакеты UDS протокола. Вы получите представление о том, с какой стороны следует подходить к 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 подпрограммой можно открыть и закрыть дверной замок.
Вот так может выглядеть обновление и считывание прошивки с ECU. Надо отладить всего 4 пакета: RequestDownload, RequestUpload, TransferData и RequestTransferExit.

Теория
Массив - непрерывная последовательность байт. Массив обладает размером.
Структура - набор переменных разного типа данных
Пакет - бинарная структура в массиве
UDS cервис - это просто входной пакет, на который спецификацией определён ответный пакет.
Сервер - это ECU. ECU - электронная плата с микроконтроллером, которая решает какую-либо задачу внутри автомобиля. Это может быть плата управления автоматической коробкой переключения передач (АКПП), контроллер бензиновых (или газовых) форсунок, телематический блок, плата управления батареей BMS, плата управления подвеской, плата электро-усилителя руля (Electric Power Steering ), плата управления обогревом и конидционером, плата управления тяговым инвертором, сигнализация, плата управления парковочной видеокамерой заднего вида, плата управления подушкой безопасности, приборная панель, плата управления АБС, плата управления ESP, кузовная электроника (габаритные огни), парковочный радар, радар круиз контроля, мультимедийная система (infotainment ), плата управления подогревом сидений. Всё что угодно.
Клиент - LapTop. Тестировочное оборудование с программой UDS-клиента внутри.
Файл - именованный массив в памяти (обычно энерго независимой). У файла всегда есть имя (иногда метаданные) .
Идентификатор - имя переменной выражаемое в виде натурального числа
Метаданные - информация о другой информации, или данные, относящиеся к дополнительной информации о содержимом или объекте. Метаданные раскрывают сведения о признаках и свойствах, характеризующих какие-либо сущности, позволяющие автоматически искать и управлять ими в больших информационных потоках.
Параметр - это переменная, которая помимо адреса в памяти, значения и размера несет в себе ещё и метаданные про физическую величину, размерность, тип данных, единицы измерения, множитель, тип доступа, формат записи, допустимый интервал значений и прочее, и прочее.
Примером параметра может служить обороты двигателя. Это физическая переменная угловой скорости, представляется действительным числом, 4 байта, измеряемая в оборотах в секунду. Множитель тысячи (*1000). Её можно только читать. Может принимать только положительные значения. И так далее.
Что надо из доков?
Полный стандарт UDS - это четыре сотни страниц английской словесности! Спека определяет 26 разных как снежинки пакетов.
#6 | Документ | Пояснение | 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: положительный и отрицательный. Положительные ответы легко узнать так как они начинаются с запрашиваемого SID + 0x40.
Аппаратная часть
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-устройством.
Кодов отрицательный ответов много. Вот некоторые из них

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.
ReadDataByPeriodicIdentifier (0x2A)
Пакет ReadDataByPeriodicIdentifier позволяет клиенту запрашивать периодическую передачу значений параметров данных с ECU, идентифицированного одним или несколькими идентификаторами periodicDataIdentifier.

Сообщение запроса клиента содержит одно или несколько однобайтовых значений periodicDataIdentifier, которые идентифицируют записи данных, поддерживаемые сервером. periodicDataIdentifier представляет собой младший байт dataIdentifier из диапазона dataIdentifier, зарезервированного для этой службы (0xF2XX, см. C.1 для допустимых значений periodicDataIdentifier), например, periodicDataIdentifier 0xE3, используемый в этой службе, — это dataIdentifier 0xF2E3.
Формат и определение записи данных должны соответствовать специфике производителя транспортного средства и могут включать аналоговые входные и выходные сигналы, цифровые входные и выходные сигналы, внутренние данные и информацию о состоянии системы, если это поддерживается сервером.
При получении запроса ReadDataByPeriodicIdentifier, отличного от stopSending, сервер должен проверить, соответствуют ли условия для выполнения службы.
Параметр periodicDataIdentifier может поддерживаться только с одним значением transmissionMode в данный момент времени. Изменение расписания periodicDataIdentifier должно выполняться при получении сообщения-запроса, в котором параметр transmissionMode установлен на новое расписание для того же periodicDataIdentifier. Поддержка нескольких расписаний для разных periodicDataIdentifier может осуществляться по запросу производителя транспортного средства.
ВАЖНО — Если условия соблюдены, ECU должен отправить положительный ответ, содержащий только идентификатор службы. Сервер никогда не должен отправлять отрицательный ответ после того, как он принял первоначальный запрос, отправив положительный ответ.
После получения первоначального положительного ответа сервер должен получить доступ к элементам данных записей, указанных параметром(ами) periodicDataIdentifier, и передать их значение в отдельных периодических ответных сообщениях для каждого periodicDataIdentifier, содержащих соответствующие параметры dataRecord.
Отдельные периодические сообщения ответа на данные, определенные для передачи данных periodicDataIdentifier клиенту, следующие за первоначальным положительным ответным сообщением, должны включать periodicDataIdentifier и данные periodicDataIdentifier, но не идентификатор службы положительного ответа.
Задокументированная периодическая частота для конкретного режима передачи определяется как время между любыми двумя последовательными ответными сообщениями с одним и тем же periodicDataIdentifier, когда запланирован только один periodicDataIdentifier. Если одновременно запланировано несколько periodicDataIdentifier, эффективный период между одним и тем же periodicDataIdentifier будет варьироваться в зависимости от следующих параметров проектирования:
–частота вызовов периодического планировщика,
–количество доступных идентификаторов адресной информации периодических ответных сообщений, специфичных для протокола, выделяемых на каждый вызов планировщика (например, идентификатор CAN в CAN)
–количество периодических идентификаторов данных, которые можно определить параллельно для одновременной передачи.
Значения этих параметров повлияют на то, насколько увеличится эффективный период между одинаковыми периодическими идентификаторами данных (periodicDataIdentifier), если одновременно передается несколько periodicDataIdentifier. Поэтому все вышеупомянутые параметры проектирования должны быть указаны производителем транспортного средства. Каждый раз, когда вызывается периодический планировщик, он должен определять, готовы ли к передаче какие-либо periodicDataIdentifier.
Периодическая частота является целым кратным периодической частоте вызовов планировщика.
Например, две различные реализации ЭБУ могут поддерживать быстрый режим передачи с периодичностью 10 мс и одним уникальным идентификатором адресной информации периодического ответного сообщения данных. Если первая реализация вызывает периодический планировщик каждые 10 мс, время между вызовами одного и того же periodicDataIdentifier увеличится до 20 мс при ��ланировании двух periodicDataIdentifier и до 40 мс при планировании четырех periodicDataIdentifier. Если вторая реализация вызывает периодический планировщик каждые 5 мс, время между вызовами одного и того же periodicDataIdentifier останется равным 10 мс при планировании двух periodicDataIdentifier и увеличится до 20 мс при планировании четырех periodicDataIdentifier.
При получении запроса ReadDataByPeriodicIdentifier, включающего параметр transmissionMode stopSending, сервер должен либо остановить периодическую передачу periodicDataIdentifier(s), содержащихся в запросе, либо остановить передачу всех periodicDataIdentifier, если в запросе не указан конкретный идентификатор. Ответное сообщение на этот параметр transmissionMode содержит только идентификатор службы.
Сервер может ограничить количество периодических идентификаторов данных (periodicDataIdentifier), которые могут поддерживаться одновременно, в соответствии с договоренностью, достигнутой производителем транспортного средства и поставщиком системы. Превышение максимального количества периодических идентификаторов данных, которые могут поддерживаться одновременно, приведет к одному отрицательному ответу, и ни один из периодических идентификаторов данных в этом запросе не будет запланирован. Повторение одного и того же периодического идентификатора данных в одном сообщении запроса не допускается, и сервер должен игнорировать их все, кроме одного периодического идентификатора данных, если клиент нарушает это правило.
transmissionMode - Этот параметр определяет частоту передачи запрошенных периодических идентификаторов данных (periodicDataIdentifiers), которые будут использоваться сервером.
periodicDataIdentifier - Этот параметр идентифицирует запрашиваемую клиентом запись данных сервера (см. C.1 и описание службы выше для подробного определения параметра). Должна быть возможность запросить несколько periodicDataIdentifiers в рамках одного запроса.
Данные объекта periodicDataIdentifier передаются периодически (с обновленными данными) с частотой, определяемой параметром transmissionMode запроса.
После получения первоначального положительного ответа, для каждого поддерживаемого periodicDataIdentifier в запросе сервер должен начать отправлять одно периодическое ответное сообщение с данными.
Данная служба не поддерживает параметры данных ответного сообщения в положительном ответном сообщении.
Запись 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бит МК получается вот такой пакет.

TesterPresent (0x3E) [Hello пакет для индикации присутствие клиента]
Этот пакет используется для того, чтобы сообщить ECU , что LapTop все ещё подключен к транспортному средству и что определенные диагностические службы и средства связи, которые были активированы ранее, должны оставаться активными.
Этот Blink пакет используется для удержания ECU (или нескольких ECU) в диагностической сессии, отличной от defaultSession. Это может быть сделано путем периодической передачи сообщения запроса TesterPresent. Опять таки, с каким именно периодом надо отправлять пакет TesterPresent спека не говорит.

Чтение информации по Diagnostic Trouble Codes Service(0x19)
Этот сервис позволяет клиенту читать состояние диагностических кодов ошибок на ECU от любого сервера или группы серверов. Если иное не требуется конкретной подфункцией то сервер должен возвращать всю информацию о DTC (например связанную или несвязанную с выбросами). Этот сервис позволяет сделать следующее:
Получите количество кодов DTC, соответствующих маске состояния DTC, определенной клиентом.
Получить список всех кодов неисправности, соответствующих маске состояния кодов неисправности, определенной клиентом.
Получить список кодов DTC в конкретной функциональной группе, соответствующих маске состояния DTC, определенной клиентом.
Получите все коды DTC со статусом «постоянный код неисправности».
RequestTransferExit (0x37)
Данный пакет используется клиентом для завершения переноса данных между клиентом и сервером. Под переносом подразумевается загрузка или скачивание непрерывной последовательности байтов. Попросту LapTop берёт и запрашивает окончание переноса байтов. Поэтому закономерно что этот пакет работает в тандеме с такими пакетами как RequestDownload, RequestUpload и TransferData. Сам по себе пакет RequestTransferExit не работает.

transferRequestParameterRecord - Данная запись параметров содержит параметры, необходимые ECU для поддержки передачи данных. Формат и длина этих параметров зависят от производителя автомобиля. Можно и вовсе ничего не писать.
transferResponseParameterRecord - Этот параметр должен содержать параметры, необходимые клиенту для поддержки передачи данных. Формат и длина этого параметра (параметров) зависят от производителя транспортного средства. Можно и вовсе ничего не писать.
InputOutputControlByIdentifier (0x2F) (Управление входами и выходами по их идентификатору)
Сервис InputOutputControlByIdentifier используется клиентом для подстановки значения входного сигнала, внутренней функции сервера и/или управления силой в значение выходного сигнала (исполнительного механизма) электронной системы. В целом, этот сервис используется для относительно простой (например, статической) подстановки входного сигнала/управления выходным сигналом, тогда как сервис routineControl используется, если необходима более сложная подстановка входного сигнала/управление выходным сигналом.
Сообщение запроса клиента содержит идентификатор данных (dataIdentifier), который ссылается на входной сигнал, внутреннюю функцию сервера и/или выходной сигнал(ы) (исполнительный механизм(ы)) (в случае доступа к управлению устройством он может ссылаться на группу сигналов) сервера. Параметр controlOptionRecord должен содержать всю информацию, необходимую для входного сигнала(ов), внутренней функции(й) и/или выходного сигнала(ов) сервера. Производитель транспортного средства может потребовать, чтобы сообщение запроса содержало controlEnableMask, если идентификатор данных, которым необходимо управлять, ссылается на более чем один параметр (т.е. идентификатор данных упакован или представлен в виде битовой карты). Если производитель транспортного средства решит поддерживать концепцию EnableMask, параметр controlEnableMask является обязательным для всех типов запросов InputOutputControlByIdentifier для этой услуги. Если запрашивается inputOutputControlByIdentifier для dataIdentifier, который ссылается на измеренное выходное значение или значение обратной связи, сервер должен отвечать за подстановку правильного целевого значения в стратегию управления сервера, чтобы обычная стратегия управления сервера попыталась достичь желаемого состояния из сообщения запроса клиента.

Сервер должен отправить положительное ответное сообщение, если управление запросом было успешно запущено или достигло желаемого состояния. Сервер должен отправить положительное ответное сообщение на запрос с параметром inputOutputControlParameter, равным returnControlToECU, даже если dataIdentifier в данный момент не находится под управлением тестера. Кроме того, при получении запроса returnControlToECU сервер всегда должен предоставлять клиенту возможность установить все биты controlMask (если поддерживается) в значение «1», чтобы полностью вернуть управление пакетированным или битовым dataIdentifier обратно в ЭБУ. Формат и длина байтов controlState, следующих за параметром inputOutputControlParameter в параметре controlOptionRecord запроса, должны точно соответствовать длине и формату dataRecord запрашиваемого dataIdentifier. Таким образом, гарантируется, что фактическое состояние выхода или входа может быть получено с помощью службы ReadDatabyIdentifier с тем же DID.
При использовании службы inputOutputControlByIdentifier для подстановки входных данных или управления выходными данными, к блоку управления, принимающему запрос, предъявляются два основных требования.
№ | Требование |
1 | отключение соответствующего(их) объекта(ов) данных, на который(е) ссылается(ются) параметр(ы) в dataIdentifier, от всех вышестоящих стратегий управления, которые в противном случае обновляли бы значение объекта данных. |
2 | подстановка значения в соответствующий(ие) объект(ы) данных, который(е) будет(ут) использоваться для всех последующих действий стратегии управления. |
Например, запрос тестера на прямое включение фар должен предотвратить влияние положения переключателя фар на выходной сигнал фар и подставить желаемое состояние «Вкл.» в объект(ы) данных, используемый(ые) функциями, которые в конечном итоге определяют желаемое состояние выходного сигнала фар.
Данная служба позволяет управлять одним идентификатором данных (dataIdentifier) и соответствующим ему параметром (параметрами) в одном запросе. В этом случае сервер ответит одним сообщением, содержащим идентификатор данных запроса, а также информацию о статусе управления (controlStatus).
Пакеты класса 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 в общем виде

RequestFileTransfer (0x38) (Запрос на перемещение файла)
Сервис requestFileTransfer используется LapTop-ом для инициирования передачи файловых данных либо от клиента к серверу, либо от сервера к клиенту (загрузка или выгрузка). Кроме того, этот сервис обладает возможностями для получения информации о файловой системе.
Данный пакет предназначена в качестве альтернативного решения для служб RequestDownload и RequestUpload, поддерживая функциональность загрузки и выгрузки данных, если сервер использует файловую систему для хранения данных.
При настройке процесса загрузки или выгрузки данных в файловую систему или из нее следует использовать службу RequestFileTransfer, заменяющую RequestDownload или RequestUpload. Фактическая передача данных и завершение передачи данных реализуются с помощью TransferData и RequestTransferExit, как это используется с пакетами RequestDownload или RequestUpload. Эта служба также включает функциональность для удаления файлов или каталогов в файловой системе сервера. В этом случае службы TransferData и RequestTransferExit не применяются.

После получения сервером запроса RequestFileTransfer, ECU должен предпринять все необходимые действия для получения или передачи данных, прежде чем отправить положительный ответ.
modeOfOperation - Этот параметр данных определяет тип операции, применяемой к файлу или каталогу, указанному в параметре filePathAndName. Значения параметра данных определены в Приложении G.
filePathAndNameLength - Определяет длину в байтах для параметра filePath.
filePathAndName - Определяет расположение файловой системы сервера, куда следует добавить, удалить, заменить или прочитать файл, в зависимости от параметра modeOfOperation. Кроме того, этот параметр включает имя файла, который следует добавить, удалить, заменить или прочитать, как часть пути к файлу. Если параметр modeOfOperation равен 0x05 (ReadDir), этот параметр указывает каталог для чтения. Каждый байт этого параметра должен быть закодирован в формате ASCII.
dataFormatIdentifier - Э��от параметр данных представляет собой однобайтовое значение, при этом каждый полубайт кодируется отдельно. Старший полубайт определяет метод сжатия (compressionMethod), а младший полубайт — метод шифрования (encryptingMethod). Значение 0x00 указывает, что ни метод сжатия, ни метод шифрования не используются. Значения, отличные от 0x00, зависят от производителя транспортного средства. Если параметр modeOfOperation равен 0x02 (DeleteFile) и 0x05 (ReadDir), этот параметр не должен включаться в сообщение запроса.
fileSizeParameterLength - Определяет длину в байтах для обоих параметров fileSizeUncompressed и fileSizeCompressed. Если параметр modeOfOperation равен 0x02 (DeleteFile), 0x04 (ReadFile) или 0x05 (ReadDir), этот параметр не должен быть включен в сообщение запроса.
fileSizeUncompressed-Определяет размер несжатого файла в байтах. Если параметр modeOfOperation равен 0x02 (DeleteFile), 0x04 (ReadFile) или 0x05 (ReadDir), этот параметр не должен включаться в сообщение запроса.
lengthFormatIdentifier - Определяет длину (количество байтов) параметра maxNumberOfBlockLength. Если параметр modeOfOperation равен 0x02 (DeleteFile), этот параметр не будет включен в ответное сообщение.
maxNumberOfBlockLength -Этот параметр используется в сообщении положительного ответа requestFileTransfer для информирования клиента о том, сколько байтов данных (maxNumberOfBlockLength) следует включить в каждое сообщение запроса TransferData от клиента или сколько байтов данных сервер включит в сообщение положительного ответа TransferData при загрузке данных. Эта длина отражает полную длину сообщения, включая идентификатор службы и параметры данных, присутствующие в сообщении запроса TransferData или сообщении положительного ответа. Этот параметр позволяет клиенту адаптироваться к размеру буфера приема сервера, прежде чем начать передачу данных на сервер, или указать, сколько байтов данных будет включено в каждое сообщение положительного ответа TransferData в случае загрузки данных. Сервер обязан принимать запросы transferData, длина которых равна указанному значению maxNumberOfBlockLength. Принимаются ли запросы transferData меньшей длины, чем maxNumberOfBlockLength, в зависимости от сервера.
ПРИМЕЧАНИЕ. Последний запрос transferData в пределах данного блока может быть меньше, чем maxNumberOfBlockLength. Серверу не разрешается записывать дополнительные байты данных (т.е., байты заполнения), не содержащиеся в сообщении transferData (ни в сжатом, ни в несжатом формате), поскольку это повлияет на адрес памяти, куда будут записаны данные последующего запроса transferData. Если параметр modeOfOperation равен 0x02 (DeleteFile), этот параметр не должен включаться в ответное сообщение.
fileSizeOrDirInfoParameterLength - Определяет длину в байтах для обоих параметров fileSizeUncompressedOrDirInfoLength и fileSizeCompressed. Если параметр modeOfOperation равен 0x01 (AddFile), 0x02 (DeleteFile) или 0x03 (ReplaceFile), этот параметр не должен включаться в ответное сообщение.
fileSizeUncompressedOrDirInfoLength Определяет размер несжатого файла для загрузки или длину информации о каталоге для чтения в байтах. Если параметр modeOfOperation равен 0x01 (AddFile), 0x02 (DeleteFile) или 0x03 (ReplaceFile), этот параметр не должен включаться в ответное сообщение.
fileSizeCompressed - Определяет размер сжатого файла в байтах. Если параметр modeOfOperation равен 0x01 (AddFile), 0x02 (DeleteFile, 0x03 (ReplaceFile)) или 0x05 (ReadDir), этот параметр не должен включаться в ответное сообщение.
CommunicationControl (0x28) [Управление Общением]
Это сервис понять назначение которого трудно даже после многократного перечитывания спецификации. Поэтому просто привожу дословный перевод.
Целью сервиса CommunicationControl является включение/отключение передачи и/или приема определенных сообщений ECU (например, сообщений связи приложений).

communicationType (byte)- этот параметр используется для указания типа связи, которой надо управлять. Значения задают конкретные биты. Биты внутри позволяют управлять несколькими типами связи одновременно (normalCommunication и (или) networkManagementCommunication). Детализация бинарной структуры представлена в приложении B.1. Например первые два бита со значением 3 отключают сообщения normalCommunicationMessages и networkManagementCommunicationMessages. Старший нимбл определяет какая подсеть должна быть подключена (или отключена) к принимаемому ECU, когда соответствующий сервис управления общением принимается.
Вы чего-нибудь поняли? Я - нет. Но это дословный перевод спецификации.

Но опять таки, что такое normalCommunicationMessages ? Что такое networkManagementCommunicationMessages?
nodeIdentificationNumber (word)— это 2-байтовое значение, представляющее собой уникальный идентификационный номер узла, где-либо подключенного к сети в транспортном средстве. Или в подсети. Это ECUшный ID. Если ID в принятом пакете совпадает с его ID, то выполняется функция из запроса сервиса CommunicationControl
Например LIN совместимый ECU c уникальным адресом ECU в одной модели подключен к сети F, а в другой модели этот же модуль подключен к сети G.
К которому невозможно обратиться по адресу в более низких уровнях модели ISO-7. Параметр nodeIdentificationNumber существует в кадре запроса только когда controlType установлен в значения o 0x04 или 0x05.

При этом один и тот же узел может быть подключен к различным сетям в разных моделях автомобилей (например, узел LIN с уникальным адресом узла подключен к сети A в одной модели, а тот же узел подключен к сети B в другой модели). Получается что nodeIdentificationNumber - это аналог MAC адреса в автомобиле. Таким образом, nodeIdentificationNumber обеспечивает механизм, в рамках которого связанный главный узел, к которому подк��ючен удаленный узел, переводит соответствующую сеть в определенный диагностический режим (например, отключает обычную связь в сети LIN). Только связанный главный узел, который обнаружил подключение соответствующего узла, идентифицированного nodeIdentificationNumber, должен выполнять запрошенную услугу communicationControl.
ControlDTCSetting (85 hex) (Управление настройками диагностических кодов неисправностей )
Сервис ControlDTCSetting используется клиентом для остановки или возобновления установки диагностических кодов неисправностей (DTC) на сервере (серверах).
Пакет ControlDTCSetting можно использовать для прекращения установки диагностических кодов неисправностей на отдельном ECU или в группе ECU. Если ECU, к которому обращаются, не может прекратить установку диагностических кодов неисправностей, он должен ответить отрицательным сообщением ControlDTCSetting, указывающим причину отклонения.
Обновление информации о битах состояния DTC должно продолжаться после выполнения запроса ControlDTCSetting, при этом подфункция должна быть установлена в значение «вкл.», или при истечении времени ожидания на уровне сессии (сервер переходит в состояние defaultSession). Сервер должен по-прежнему отправлять положительный ответ, если услуга поддерживается в активной сессии с запрошенной подфункцией, установленной в значение «вкл.» или «выкл.», даже если запрошенное состояние настройки DTC уже активно.
Если клиент отправляет сообщение clearDiagnosticInformation (14 hex), параметр ControlDTCSetting не должен запрещать сброс памяти кодов неисправностей сервера.
Если операция ECUReset будет успешно выполнена, это позволит повторно устанавливать коды неисправностей (DTC).

Запрашиваемый пакет передает две переменные.
ControlDTCSetting - Параметр используется в сообщении запроса ControlDTCSetting для указания ECU о том, следует ли прекратить или возобновить настройку диагностических кодов неисправностей.
DTCSettingControlOptionRecord- Этот параметр является необязательным для пользователя и передает данные на сервер при управлении настройкой DTC. Он может содержать список кодов неисправностей (DTC), которые необходимо включить или выключить.
Итоги
Появилось некоторое представление о 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 | |
Обзор Протокола ISO-TP [ISO 15765-2] | |
Обзор USB-CAN переходника USB2CANFD_V1 | |
Как собрать Си программу в OS Windows |
Вопросы
--Какой может быть максимальный размер UDS DID? Можно ли одним UDS DIDом прочитать или прописать всю прошивку? Размер DID ограничен сверху размером одной ISO-TP транзакции. А это 4kByte. Также могут быть ограничения по оставшейся RAM памяти в микроконтроллере на котором собран данный ECU.
--Как можно протестировать реализацию UDS протокола?
--Какие UDS DID значения общие для всех автопроизводителей? Наверняка же такие есть.
--Какие UDS RID значения общие для всех автопроизводителей?
--Существует ли какая-нибудь готовая клиентская 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 протоколе есть аналог MAC адреса?
--Какие еще прикладные протоколы могут быть в автомобиле кроме UDS? J1939, On-Board Diagnostics (OBD2), World-Wide Harmonized OBD (WWH-OBD), CCP, XCP.
--Зачем в UDS протоколе нужен сервис CommunicationControl?
--С каким именно периодом надо отправлять пакет TesterPresent? Раз в минуту? Раз в секунду? Раз в 30 секунд?