ECUXML — это формат на основе XML, используемый в HOBDrive для описания параметров датчиков ЭБУ (электронного блока управления) автомобиля. Каждый файл .ecuxml определяет набор диагностических параметров OBD2/KWP2000 — как запрашивать данные у ЭБУ, как разбирать байты ответа и как отображать полученные значения пользователю.
Файлы ECUXML компилируются в классы-провайдеры датчиков на C# на этапе сборки с помощью утилиты ecuxml2cs либо загружаются динамически во время выполнения из внешних файлов.
<eval>)
<parameters>Каждый файл ECUXML имеет единственный корневой элемент <parameters>:
<?xml version="1.0" encoding="utf-8" ?>
<parameters namespace="MyECU"
description="My ECU description"
description-ru="Описание ЭБУ"
standard-header="7E1">
<!-- глобальные элементы и определения параметров -->
</parameters>
| Атрибут | Обязательный | Описание |
|---|---|---|
namespace |
Нет | Префикс пространства имён датчиков. Все идентификаторы параметров в этом файле будут иметь префикс Namespace., если идентификатор ещё не содержит точку. По умолчанию "Default". |
description |
Нет | Краткое описание профиля ЭБУ на английском. Отображается в интерфейсе выбора профиля. |
description-ru |
Нет | Краткое описание на русском. |
standard-header |
Нет | Заголовок ELM327 по умолчанию (ATSH), применяемый ко всем датчикам OBD2 в этом файле, если не переопределён для конкретного параметра. |
Эти дочерние элементы <parameters> настраивают профиль ЭБУ в целом. Они должны располагаться перед элементами <parameter>.
<include>Включает другой файл ECUXML. Параметры из включённого файла загружаются в тот же реестр датчиков. Пути указываются относительно текущего файла.
<include>../kwp2000.ecuxml</include>
<include>IM-FAN.ecuxml</include>
Допускается несколько элементов <include>.
<header>Строка заголовка ELM327 по умолчанию. Применяется ко всем датчикам OBD2, если не переопределена. Это альтернатива атрибуту standard-header на корневом элементе.
<header>7E1</header>
Может также содержать расширенные AT-команды, разделённые точкой с запятой:
<header>ATSH773; ATCRA774; ATFCSH773; 1092;</header>
<obd2-header>Необязательный заголовок OBD2 по умолчанию. Если указан, это значение добавляется к строке инициализации ELM327. Также используется для восстановления заголовка по умолчанию после чтения датчика с пользовательским заголовком.
<obd2-header>7E0</obd2-header>
Или с расширенными командами:
<obd2-header>ATSH7E0; ATCRA7E8; ATFCSH7E0;</obd2-header>
<init-string>Команды инициализации ELM327, разделённые точкой с запятой. Отправляются адаптеру при активации данного профиля ЭБУ.
<init-string>
ATSP6; ATAL; ATSH7E0; ATST32;
</init-string>
<disable-obd2>Определяет, загружаются ли стандартные датчики OBD2 вместе с пользовательскими датчиками этого файла.
<disable-obd2>false</disable-obd2>
"false" → стандартные датчики OBD2 используются (т.е. UseOBD2 = true)При отключении доступны только датчики, определённые в этом файле ECUXML (и включённых файлах).
<models>Список названий производителей автомобилей, разделённых запятыми или переводами строк. Используется для группировки в интерфейсе выбора ЭБУ.
<models>
Mitsubishi
</models>
<models>Peugeot, Citroen</models>
<description lang="...">Подробное описание профиля ЭБУ, отображаемое в интерфейсе. Атрибут lang задаёт язык ("en" или "ru").
<description lang="en">
Extra OBD2 sensors for turbocharger diagnostics.
</description>
<description lang="ru">
Дополнительные датчики OBD2 для диагностики турбокомпрессора.
</description>
<parameter>Каждый <parameter> определяет один датчик. Атрибут id обязателен и служит идентификатором датчика в его пространстве имён.
<parameter id="CoolantTemp" display="PID05">
<!-- дочерние элементы, описывающие датчик -->
</parameter>
| Атрибут | Описание |
|---|---|
id |
Обязательный. Уникальный идентификатор датчика. Итоговый ID датчика будет Namespace.id, если id ещё не содержит точку. |
display |
Необязательный отображаемый псевдоним. Используется в некоторых профилях ЭБУ как альтернативный код (например, Renault PR003, Toyota PID1). |
Тип создаваемого датчика зависит от того, какие дочерние элементы присутствуют внутри <parameter>. Парсер проверяет их в определённом порядке приоритета:
Датчик, который напрямую запрашивает данные у ЭБУ командой (mode+PID или raw-команда) и разбирает байты ответа.
Создаётся когда: отсутствуют элементы <base>, <base-raw>, <base-data>, <class> или <text>.
<parameter id="CoolantTemp">
<mode>1</mode>
<command>05</command>
<valuea>1</valuea>
<offset>-40</offset>
<description>
<name>Coolant Temperature</name>
<unit>celsius</unit>
</description>
</parameter>
Или с использованием сокращения <address> (OBD2 Mode 1):
<parameter id="Lambda11" display="LAMBDA11">
<address><byte>0x34</byte></address>
<valueab>0.0000305</valueab>
</parameter>
Или с использованием сырой командной строки:
<parameter id="Core03">
<raw>2103</raw>
<valuea>0</valuea>
</parameter>
Датчик, значение которого вычисляется на основе одного или двух других датчиков.
Создаётся когда: присутствует <base> и отсутствует <average>.
<parameter id="TC_CINP">
<base>IntakeManifoldPressure</base>
<valuea>0.01</valuea>
<offset>0</offset>
<description>
<name>TC Pressure</name>
<unit>bar</unit>
</description>
</parameter>
С двумя базовыми датчиками и выражением eval:
<parameter id="CombinedValue">
<base>SensorA</base>
<base2>SensorB</base2>
<eval>Sensor_Value * 2 + Sensor2_Value</eval>
</parameter>
Переменные, доступные в <eval> для производных датчиков:
Sensor_Value — текущее значение датчика <base>Sensor2_Value — текущее значение датчика <base2> (если указан)Датчик, который читает сырые байты ответа (включая все заголовки) другого датчика OBD2 и извлекает значение по определённому смещению.
Создаётся когда: присутствует <base-raw> и отсутствуют <text> / <dump>.
<parameter id="CVTdegr">
<base-raw>Core10</base-raw>
<word-31>1</word-31>
<offset>0</offset>
</parameter>
Используется семейство методов getraw() — смещения являются абсолютными позициями в массиве сырых байтов (включая заголовки протокола).
Переменные, доступные в <eval> для датчиков base-raw:
Sensor — объект базового датчика OBD2. Для доступа к данным используйте функции get(), get_word() и др.Датчик, который читает байты данных другого датчика OBD2, пропуская стандартные заголовки протокола.
Создаётся когда: присутствует <base-data> (и отсутствуют <base> / <base-raw>).
<parameter id="TireSensor1">
<base-data>Core_21A8</base-data>
<eval>get(15)*0.2</eval>
<description>
<unit>psi</unit>
</description>
</parameter>
Используется семейство методов get() — смещения отсчитываются от начала полезной нагрузки данных (после байтов mode+command).
Переменные, доступные в <eval> для датчиков base-data:
Sensor — объект базового датчика OBD2. Используйте функции get(), get_word() и др.Датчик, возвращающий текстовую строку из ответа ЭБУ, а не числовое значение (например, VIN-код, название ЭБУ).
Создаётся когда: присутствует элемент <text>.
Прямой текстовый датчик OBD2:
<parameter id="VIN">
<mode>9</mode>
<command>2</command>
<text/>
</parameter>
Производный текстовый датчик из сырых данных:
<parameter id="ECUID_ECUIDT">
<raw>1A80</raw>
<text/>
</parameter>
Производный текстовый датчик из сырых данных другого датчика с eval:
<parameter id="StatusText">
<base-data>CoreSensor</base-data>
<text/>
<eval>... выражение, возвращающее строку ...</eval>
</parameter>
<text>| Атрибут | Описание |
|---|---|
offset |
Смещение в байтах от начала ответа для начала чтения текста. |
length |
Максимальное количество байтов для чтения. |
Аналогичен текстовому датчику, но формирует шестнадцатеричный дамп сырых байтов. Полезен для диагностического отображения необработанных данных.
Создаётся когда: присутствует элемент <dump> с источником <base-data>.
<parameter id="ID_TireSensor_1">
<base-data>TireSensorID</base-data>
<dump offset="1" length="4"/>
</parameter>
<dump>| Атрибут | Описание |
|---|---|
offset |
Смещение в байтах от начала данных для начала дампа. |
length |
Количество байтов для дампа. |
Датчик, вычисляющий скользящее среднее значений другого датчика за указанное количество измерений.
Создаётся когда: присутствует элемент <average> вместе с <base>.
<parameter id="Avg_ECUFuelLevel">
<base>ECUFuelInTank</base>
<average length="15"/>
<description>
<unit>liters</unit>
</description>
</parameter>
<average>| Атрибут | Описание |
|---|---|
length |
Количество значений для усреднения (размер окна интегрирования). |
Датчик, реализованный именованным классом C#, а не логикой извлечения значений ECUXML.
Создаётся когда: присутствует элемент <class>.
<parameter id="MIL">
<class>KWPMILSensor</class>
</parameter>
<parameter id="ClearDTC">
<class>hobd.ClearDTCSensor</class>
</parameter>
Класс должен быть зарегистрирован в реестре датчиков и наследоваться от CoreSensor.
Существует три способа указать, какую команду отправить ЭБУ:
<mode>1</mode> <!-- Режим OBD2, в hex (напр., 1 = текущие данные) -->
<command>0C</command> <!-- OBD2 PID, в hex -->
По умолчанию режим 1, если не указан.
Эквивалентно указанию mode 1 + заданный PID:
<address><byte>0x34</byte></address>
Шестнадцатеричная строка, отправляемая напрямую ELM327. Точки с запятой в строке преобразуются в символы возврата каретки (несколько команд). Переопределяет mode+command.
<raw>2103</raw>
<raw>14FF00</raw>
<raw>1A80</raw>
<header>Переопределение заголовка для конкретного параметра. Изменяет заголовок ELM327 (ATSH) для запросов этого датчика, переопределяя как standard-header, так и глобальный <header>.
<parameter id="SpecialSensor">
<header>7E1</header>
<raw>2201</raw>
<valuea>1</valuea>
</parameter>
<data-offset>Переопределяет длину команды по умолчанию для разбора ответа. Обычно парсер пропускает CommandLength байтов (по умолчанию: 2, для Mode+Command) после нахождения маркера ответа. Этот элемент изменяет количество пропускаемых байтов.
<data-offset>2</data-offset> <!-- пропустить 2 байта после маркера ответа -->
<data-offset>3</data-offset> <!-- пропустить 3 байта (напр., для 3-байтных команд) -->
Извлечение одного байта из данных ответа с умножением на масштабирующий коэффициент.
| Элемент | Смещение | Описание |
|---|---|---|
<value> или <valuea> |
0 | Первый байт данных (байт A) |
<valueb> |
1 | Второй байт данных (байт B) |
<valuec> |
2 | Третий байт данных (байт C) |
<valued> |
3 | Четвёртый байт данных (байт D) |
<value-N> |
N | Байт по смещению N |
Содержимое элемента — это масштабирующий коэффициент (множитель):
<valuea>0.392157</valuea> <!-- результат = байт_A * 0.392157 -->
<valueb>1</valueb> <!-- результат = байт_B * 1 -->
<value-6>1</value-6> <!-- результат = байт_по_смещению_6 * 1 -->
Извлечение 16-битного слова big-endian (два последовательных байта) с умножением на масштаб.
| Элемент | Смещение | Описание |
|---|---|---|
<valueab> |
0 | Слово из байтов A, B (смещения 0, 1) |
<valuebc> |
1 | Слово из байтов B, C (смещения 1, 2) |
<valuecd> |
2 | Слово из байтов C, D (смещения 2, 3) |
<word-N> |
N | Слово начиная со смещения N |
<valueab>0.0000305</valueab> <!-- результат = word(A,B) * 0.0000305 -->
<word-31>1</word-31> <!-- результат = слово по смещению 31 -->
Извлечение 32-битного двойного слова big-endian (четыре последовательных байта) с умножением на масштаб.
| Элемент | Смещение | Описание |
|---|---|---|
<dword-N> |
N | Двойное слово начиная со смещения N |
<dword-0>0.001</dword-0> <!-- результат = dword по смещению 0 * 0.001 -->
Для ЭБУ, передающих данные в порядке байтов little-endian:
| Элемент | Описание |
|---|---|
<wordle-N> |
16-битное слово little-endian по смещению N |
<dwordle-N> |
32-битное двойное слово little-endian по смещению N |
<wordle-8>0.0018252</wordle-8> <!-- LE-слово по смещению 8 -->
После извлечения исходного числового значения применяются следующие преобразования в указанном порядке:
<signed/>)Если присутствует, извлечённое значение переинтерпретируется как знаковое целое:
sbyte (от -128 до 127)short (от -32768 до 32767)int<signed/>
результат = исходное_значение * масштаб + смещение
Где масштаб берётся из содержимого элемента значения, а смещение — из элемента <offset>.
<valuea>1</valuea>
<offset>-40</offset> <!-- напр., температура ОЖ: байт_A * 1 + (-40) -->
<bit> и <bit-width>)Если указан <bit>, результат сдвигается вправо на заданное количество бит, затем маскируется для извлечения <bit-width> бит (по умолчанию: 1).
<bit>10</bit> <!-- извлечь бит 10 -->
<bit-width>3</bit-width> <!-- извлечь 3 бита -->
Формула: результат = (int(масштабированное_значение) >> bit) & ((1 << bit_width) - 1)
Часто используется для извлечения булевых флагов или небольших полей из байтов состояния:
<parameter id="FuelSystemStatus_Trim">
<base>FuelSystemStatus</base>
<value>1</value>
<bit>10</bit>
</parameter>
<cut-low> и <cut-high>)Обнуление недопустимых/зашумлённых значений:
<cut-low>500</cut-low> <!-- значения ниже 500 становятся 0 -->
<cut-high>220</cut-high> <!-- значения выше 220 становятся 0 -->
<cut-low>: если результат < порога, результат = 0<cut-high>: если результат > порога, результат = 0Полезно для фильтрации ошибок ЭБУ (например, фантомные показания оборотов при выключенном двигателе):
<parameter id="RPM">
<base>RPM</base>
<value>1</value>
<cut-low>500</cut-low>
</parameter>
<mil-group>)Для датчиков MIL (индикатор неисправности) указывает, к какой группе диагностических кодов неисправностей относится данный датчик:
<mil-group>TPMS_Suzuki</mil-group>
<mil-group>HyundaiSRS</mil-group>
<eval>)Элемент <eval> содержит динамическое выражение, вычисляющее значение датчика. При наличии переопределяет стандартный конвейер извлечения значений (масштаб/смещение).
<eval>get(13)*0.2</eval>
<eval>(0.000000002344*(get(13)^5))+(-0.000001387*(get(13)^4))+(0.0003193*(get(13)^3))+(-0.03501*(get(13)^2))+(2.302*get(13))+(-36.6)</eval>
<eval>get(6)*65536+get(7)*256+get(8)</eval>
<eval>Sensor_Value * 2 + Sensor2_Value</eval>
Вычислитель выражений основан на движке формул, подобном Excel. Поддерживаются:
+, -, *, /, %, ^ (степень)<, <=, >, >=, =, !=, <>&&, ||, !условие ? значение_истина : значение_ложь&:=( )| Приоритет | Операторы | Описание |
|---|---|---|
| 1 | ( ), f(x) |
Группировка, вызовы функций |
| 2 | !, ~, -, + |
Унарные операторы |
| 3 | ^ |
Степень (левоассоциативная: a^b^c = (a^b)^c) |
| 4 | *, /, % |
Умножение, деление, остаток |
| 5 | +, - |
Сложение, вычитание |
| 6 | & |
Конкатенация строк |
| 7 | <, <=, >, >= |
Сравнение |
| 8 | =, !=, <> |
Равенство |
| 9 | && |
Логическое И |
| 10 | \|\| |
Логическое ИЛИ |
| 11 | ?: |
Тернарный условный оператор |
| 12 | := |
Присваивание |
Поддерживается пять типов данных: double, int, hexadecimal, string и boolean.
Целые числа и шестнадцатеричные значения автоматически преобразуются в double при вычислениях. Для явного преобразования используйте int().
Движок выражений поддерживает следующие стандартные функции:
Abs, Acos, And, Asin, Atan, Atan2, Avg, Ceiling, Cos, Cosh, Exp, Fact, Floor, Format, Hex, If, Left, Len, Ln, Log, Lower, Max, Min, Mid, Not, Or, Pow, Right, Round, Sign, Sin, Sinh, Sqr, Sqrt, StDev, Trunc, Upper, Val, Var
If(условие; значение_истина; значение_ложь)Условная функция. Эквивалентна условие ? значение_истина : значение_ложь.
Примечание: аргументы функции разделяются точкой с запятой (;), а не запятыми.
Эти функции доступны только в выражениях <eval> в определениях параметров ECUXML. Они работают с буфером сырых данных текущего датчика.
get(offset)Возвращает один байт из буфера данных датчика по заданному смещению. Смещение отсчитывается от начала полезной нагрузки данных (после пропуска маркера ответа и байтов команды).
<eval>get(0)</eval> <!-- первый байт данных -->
<eval>get(13)*0.2</eval> <!-- байт по смещению 13 с масштабированием -->
get_word(offset)Возвращает 16-битное слово big-endian (два байта), начиная с заданного смещения.
<eval>get_word(8)*0.1</eval>
<eval>get_word(2)*0.005+2.1</eval>
get_dword(offset)Возвращает 32-битное двойное слово big-endian (четыре байта), начиная с заданного смещения.
<eval>get_dword(0)*0.001</eval>
get_wordle(offset)Возвращает 16-битное слово little-endian, начиная с заданного смещения.
<eval>get_wordle(0)*0.3144</eval>
get_dwordle(offset)Возвращает 32-битное двойное слово little-endian, начиная с заданного смещения.
<eval>get_dwordle(0)</eval>
to_signed_byte(value) / to_signed(value)Преобразует байтовое значение (0–255) в знаковый байт (от -128 до 127).
<eval>to_signed_byte(get(5))*0.5</eval>
to_signed_word(value)Преобразует 16-битное беззнаковое значение в знаковое 16-битное целое (от -32768 до 32767).
<eval>to_signed_word(get_word(0))*0.1</eval>
to_signed_dword(value)Преобразует 32-битное беззнаковое значение в знаковое 32-битное целое.
В зависимости от типа датчика, в выражениях eval доступны различные переменные:
| Тип датчика | Доступные переменные |
|---|---|
Прямой OBD2 (<raw> или <mode>/<command>) |
Sensor — объект датчика OBD2 (используйте get(), get_word() и др.) |
Производный (<base>) |
Sensor_Value — значение double базового датчика; Sensor2_Value — значение датчика <base2> |
Base-raw (<base-raw>) |
Sensor — объект базового датчика OBD2 |
Base-data (<base-data>) |
Sensor — объект базового датчика OBD2 |
Каждый параметр может иметь один или несколько блоков <description> для локализации.
<parameter id="CVTTemp">
<description>
<name>CVT Temperature</name>
<description>CVT oil temperature</description>
<unit>celsius</unit>
<display>CVTTEMP</display>
</description>
<description lang="ru">
<name>Темп. CVT</name>
<description>Температура масла вариатора</description>
<unit>celsius</unit>
</description>
</parameter>
<description>| Атрибут | Описание |
|---|---|
lang |
Код языка ("en", "ru" и др.). Если не указан, по умолчанию "" (по умолчанию/английский). |
<description>| Элемент | Описание |
|---|---|
<name> |
Человекочитаемое имя датчика. Отображается в интерфейсе. |
<description> |
Развёрнутое описание / текст подсказки. |
<unit> |
Строка единицы измерения (например, celsius, bar, psi, km, volts, liters, rpm, cm). HOBDrive использует её для конвертации единиц. |
<display> |
Переопределение формата отображения. |
Стандартная температура охлаждающей жидкости OBD2 (PID 0x05):
<parameter id="CoolantTemp">
<address><byte>0x05</byte></address>
<valuea>1</valuea>
<offset>-40</offset>
<description>
<name>Coolant Temperature</name>
<unit>celsius</unit>
</description>
</parameter>
Формула вычисления: байт_A * 1 + (-40) → температура в °C.
Фильтрация зашумлённых значений оборотов:
<parameter id="RPM">
<base>RPM</base>
<value>1</value>
<cut-low>500</cut-low>
</parameter>
Берёт существующее значение датчика оборотов, пропускает без изменений (масштаб=1), но возвращает 0, если ниже 500.
Давление TPMS из многобайтового ответа:
<parameter id="TireSensor1">
<description>
<unit>psi</unit>
</description>
<base-data>Core_21A8</base-data>
<eval>get(15)*0.2</eval>
</parameter>
Читает байт по смещению 15 из полезной нагрузки Core_21A8, умножает на 0.2.
Преобразование температуры масла CVT с помощью аппроксимирующего полинома:
<parameter id="CVTTemp">
<description lang="ru">
<name>Темп. CVT</name>
<unit>celsius</unit>
</description>
<base-data>Core03</base-data>
<eval>(0.000000002344*(get(13)^5))+(-0.000001387*(get(13)^4))+(0.0003193*(get(13)^3))+(-0.03501*(get(13)^2))+(2.302*get(13))+(-36.6)</eval>
</parameter>
Чтение идентификационного номера транспортного средства (VIN):
<parameter id="VIN">
<description>
<name>VIN Code</name>
<description>Vehicle's VIN code</description>
</description>
<mode>9</mode>
<command>2</command>
<text/>
</parameter>
Отображение идентификаторов датчиков давления в шинах:
<parameter id="ID_TireSensor_1">
<base-data>TireSensorID</base-data>
<dump offset="1" length="4"/>
</parameter>
<parameter id="VIN">
<raw>1A90</raw>
<text/>
</parameter>
<parameter id="SteeringAngle">
<base-data>CoreSensor</base-data>
<wordle-8>0.0018252</wordle-8>
<signed/>
</parameter>
<parameter id="MIL">
<class>KWPMILSensor</class>
<raw>1800FF00</raw>
<mil-group>HyundaiSRS</mil-group>
</parameter>
<parameter id="Avg_ECUFuelLevel">
<description lang="ru">
<name>Уровень топлива (ЭБУ, сред.)</name>
<unit>liters</unit>
</description>
<base>ECUFuelInTank</base>
<average length="15"/>
</parameter>
<?xml version="1.0" encoding="utf-8" ?>
<parameters namespace='Mitsubishi_4N15'
description="Mitsubishi 4N15+AT_V8AWG+TPMS+OBD">
<disable-obd2>false</disable-obd2>
<obd2-header>ATSH7E0; ATCRA7E8; ATFCSH7E0;</obd2-header>
<header>ATSH7E0; ATCRA7E8; ATFCSH7E0;</header>
<init-string>
ATSP6; ATST32; ATAT0; ATSH7E0; ATCRA7E8; ATFCSH7E0; ATFCSD300040; ATFCSM1;
</init-string>
<models>Mitsubishi</models>
<include>mitsubishi_eng_4n15.ecuxml</include>
<include>mitsubishi_at_v8awg.ecuxml</include>
<include>mitsubishi_ks_tpms.ecuxml</include>
<!-- Дополнительные параметры для этой комбинации -->
</parameters>
Файлы ECUXML в проекте HOBDrive организованы по производителям автомобилей:
ecu/
├── obd2.ecuxml # Стандартные дополнительные датчики OBD2
├── kwp2000.ecuxml # Общие датчики протокола KWP2000
├── _cuts.ecuxml # Патч: фильтрация зашумлённых значений датчиков
├── _gpsspeed.ecuxml # Патч: использование скорости GPS вместо ЭБУ
├── _micas_obd2.ecuxml # Патч: топливная коррекция для ЭБУ Micas
├── _vaz_obd2.ecuxml # Патч: топливная коррекция для автомобилей ВАЗ
├── _toyotajdmclear.ecuxml # Патч: логика сброса MIL для JDM
├── China/ # Китайские автомобили (Chery, Geely, Haval и др.)
├── ChryslerDodgeJeep/
├── CitroenPeugeot/
├── FiatLanciaAlfaRomeo/
├── FordMazda/
├── GM/
├── HyundaiKIA/
├── Mercedes/
├── Mitsubishi/
├── Nissan/
├── Opel/
├── Renault/
├── SsangYong/
├── Subaru/
├── Suzuki/
├── Toyota/
├── VAG/
└── VAZ_GAZ_UAZ_ZAZ/
Файлы с префиксом подчёркивания (_*.ecuxml) — это «патч»-файлы, которые модифицируют или переопределяют существующие датчики.
Файлы ECUXML обрабатываются утилитой сборки ecuxml2cs:
.ecuxml разбираются парсером ECUXMLParser в объекты ECUXMLRootElement.EcuXmlTemplate.tt), наследующий BaseECUXMLSensorProvider. Сгенерированный класс содержит предварительно разобранные определения параметров в виде объектов ECUXMLParameterElement.ECUXMLSensorProviderRegistry.cs — связывает имена файлов .ecuxml с соответствующими сгенерированными классами провайдеров датчиков.ECUXMLDescriptionRegistry.cs — хранит метаданные профилей ЭБУ (название, строка инициализации, модели) для профилей, у которых определён элемент <models>.Во время выполнения ECUXMLSensorProvider сначала проверяет скомпилированный реестр на совпадение имени файла; если совпадение не найдено, выполняется разбор файла ECUXML напрямую с диска через FilesECUXMLSensorProvider.
| Элемент | Описание |
|---|---|
<class> |
Имя класса C#, реализующего этот датчик |
<mode> |
Режим OBD2 (hex), по умолчанию: 1 |
<command> |
OBD2 PID (hex) |
<address><byte>0xNN</byte></address> |
Сокращение для mode 1 + PID NN |
<raw> |
Сырая hex-строка команды (точки с запятой → CR) |
<header> |
Переопределение заголовка ELM327 для датчика |
<data-offset> |
Переопределение длины команды для ответа |
<base> |
Ссылка на базовый датчик (производный) |
<base2> |
Ссылка на второй базовый датчик (производный) |
<base-raw> |
Ссылка на базовый датчик (доступ к сырым байтам) |
<base-data> |
Ссылка на базовый датчик (доступ к байтам данных) |
<value> / <valuea> |
Масштабирующий коэффициент, байт по смещению 0 |
<valueb> |
Масштабирующий коэффициент, байт по смещению 1 |
<valuec> |
Масштабирующий коэффициент, байт по смещению 2 |
<valued> |
Масштабирующий коэффициент, байт по смещению 3 |
<value-N> |
Масштабирующий коэффициент, байт по смещению N |
<valueab> |
Масштабирующий коэффициент, big-endian word по смещению 0 |
<valuebc> |
Масштабирующий коэффициент, big-endian word по смещению 1 |
<valuecd> |
Масштабирующий коэффициент, big-endian word по смещению 2 |
<word-N> |
Масштабирующий коэффициент, big-endian word по смещению N |
<wordle-N> |
Масштабирующий коэффициент, little-endian word по смещению N |
<dword-N> |
Масштабирующий коэффициент, big-endian dword по смещению N |
<dwordle-N> |
Масштабирующий коэффициент, little-endian dword по смещению N |
<signed/> |
Интерпретировать значение как знаковое целое |
<offset> |
Аддитивное смещение, применяемое после масштабирования |
<bit> |
Величина сдвига вправо для извлечения бита |
<bit-width> |
Количество извлекаемых бит (по умолчанию: 1) |
<cut-low> |
Обнуление результата, если ниже порога |
<cut-high> |
Обнуление результата, если выше порога |
<eval> |
Динамическое выражение (переопределяет масштаб/смещение) |
<text/> |
Пометить как текстовый датчик |
<dump/> |
Пометить как датчик hex-дампа |
<average/> |
Пометить как датчик усреднения |
<mil-group> |
Идентификатор группы MIL/DTC |
<description> |
Локализованное имя, описание, единица измерения |