Что такое a2l-файл? Откуда они берутся?
Каждый начинающий тюнер задается вопросом — «где взять данные о том что лежит в бинарном файле прошивки?», «по каким адресам? какие карты?». В это ему помогут a2l файлы. По сути, а2l файл — это инженерная карта прошивки, т.е. в нем описаны все основные калибровки и константы бинарного файла прошивки, а в новых стандартах и фунции. Существует масса программ интерпретирующих а2л файлы, к примеру — WinOLS. Эти программы парсят инженерную карту и отображают пользователю уже удобоваримые карты в виде таблиц и графиков. Пользователь может изменять данные в этих понятных человеку таблицах (картах) и программа автоматически изменить нужные байты в бинарном файле прошивки. Но, как правило, все эти программы -платные.Есть не менее известный стандарт хранения данных о калибровках в прошивке — xdf. Xdf специально разрабатывался для программы TunerPro. Программа полностью бесплатна. Если уметь читать и понимать что находится в а2л файлах, можно на базе имеющегося а2л создать xdf и пользоваться им в TunerPro.
A2l -это текстовый формат файла, который описывает практически ВСЮ информацию о прошивке. Эту информацию предоставляет сам производитель. Точнее, он не хочет её предоставлять широким массам 😀 , но файлы всё равно утекают в сеть и тут за дело берутся доморощенные тюнеры 😀 -самоучки. Что мы видим в этом файле, на примере блока Siemens МS43 от BMW? Как его использовать применительно к бинарному файлу прошивки?
Если открыть a2l в текстовом редакторе (я рекомендую Notepad++), мы увидим кучу всевозможных begin и end и какие — то данные между ними. Давайте сконцентрируемся на этих блоках, заключенных между begin и end… Вот пример одного из них.
/begin CHARACTERISTIC kf_zw_roz91_vanos_tl__n__lm "KF_ZW_ROZ91_VANOS_TL" MAP 0x4ebd5 a_13 5 LINEAR_______23_625000__0H___126 -23.625 72.0 /begin IF_DATA ASAP1B_ADDRESS DP_BLOB 0x4ebd5 /end IF_DATA /begin AXIS_DESCR COM_AXIS lm_zw MAF_16_RES49 16 0.0 1389.0 AXIS_PTS_REF sstm_lm_zw_kf_zw_tkw_vanos_tl MAX_GRAD 100 MONOTONY MON_INCREASE /end AXIS_DESCR /begin AXIS_DESCR COM_AXIS drehzahl IS_13_RES84 20 0.0 8160.0 AXIS_PTS_REF sstm_n_kf_zw_tkw_vanos_tl MAX_GRAD 100 MONOTONY MON_INCREASE /end AXIS_DESCR /end CHARACTERISTIC
/begin CHARACTERISTIC означает начало описания какой-то таблицы или константы
/end CHARACTERISTIC означает окончание описания какой-то таблицы или константы
/begin AXIS_DESCR начало описание оси для величины, описываемой в рассматриваемом блоке
/end AXIS_DESCR окончание описания оси
В данном случае идёт описание для величины kf_zw_roz91_vanos_tl__n__lm. Тег MAP -означает что это карта. Далее идет адрес с которого начинается эта карта — 0x4ebd5. Остальные вещи пока опустим, будут рассмотрены позже.
Как узнать размер этой карты? Для этого как раз и существует блок описания осей карты, тег COM_AXIS как раз указывает на одну из осей. Видно, что первая ось имеет 16 отсчетов, вторая ось имеет 20 отсчетов. Отсюда мы получаем карту 16×20.
Значение величины нам до сих пор не известно, но мы уже знаем что это какая-то карта. Идём в заметку с описанием сокращений a2l файлов от старых Сименсов (оно конечно больше для MS43) и начинаем разгадывать кроссворд kf_zw_roz91_vanos_tl__n__lm:
kf — Kennfeld- карта
zw — Zündwinkel(угол опережения зажигания,УОЗ)
roz91 — октановое число 91
vanos — управление ваносом активно
tl — Teillast( частичные нагрузки)
n- количество оборотов
lm — Lüftmasse (массовый расход воздуха= нагрузка).
С уверностью можно сказать– что это карта УОЗ для низкооктанового бензина , работающая на частичных нагрузках при активном ваносе.
Как перетащить данные их a2l в xdf проект(файл?)
Перенос данных из a2l файла рассмотрим на примере карты УОЗ низкооктанового топлива для MS43.
/begin CHARACTERISTIC ip_iga_ron_91_pl_ivvt__n__maf "IP_IGA_RON_91_PL_IVVT" MAP 0x77045 <- адрес карты a_17 <- обозначение типа данных в карте (байт, 2 байта, loHi, Hilo и т.п.) 5 LINEAR_______23_625000__0H___72_ <- тег формулы пересчета -23.625 72 <- диапазон изменения данных карты. Т.е. УОЗ может быть от -23 до 72 /begin AXIS_DESCR <- начало описание оси Х COM_AXIS maf_iga <- название оси по Х. По названию ищется описание оси далее по a2l файлу LINEAR______0_000000__0H___13818 16 0 1389 AXIS_PTS_REF ldpm_maf_iga_2 <- по тегу AXIS_PTS ldpm_maf_iga_2 будет лежать адрес нахождения оси! MAX_GRAD 100 MONOTONY MON_INCREASE /end AXIS_DESCR /begin AXIS_DESCR COM_AXIS n <- название оси по Y. По названию ищется описание оси далее по a2l файлу LINEAR______0_000000__0H___81612 20 0 8160 AXIS_PTS_REF ldpm_n_14 <- по тегу AXIS_PTS ldpm_n_14 будет лежать адрес нахождения оси! MAX_GRAD 100 MONOTONY MON_INCREASE /end AXIS_DESCR /end CHARACTERISTIC
Ищем тип данных a_17 в a2l — файле:
/begin RECORD_LAYOUT a_17 FNC_VALUES 1 UBYTE ROW_DIR DIRECT /end RECORD_LAYOUT
В описании стоит «UBYTE», что означает что данные занимают 1 беззнаковый байт, т.е. диапазон изменения величины от 0..255 в десятичной системе исчисления, или FF в шестнадцатеричной системе исчисления. Также возможны следующие типы данных в картах:
UBYTE — 1 байт, целое без знака
SBYTE — 1 байт, целое со знаком
UWORD — 2 байта, целое без знака
SWORD — 2 байта, целое со знаком
ULONG — 4 байта, целое без знака
SLONG — 4 байта, целое со знаком
A_UINT64 — 8 байт, целое без знака
A_INT64 — 8 байт, целое со знаком
FLOAT32_IEEE 4 байта с плавающей точкой
FLOAT64_IEEE 8 байт с плавающей точкой
Как пересчитать каждое значение в полученной таблице? Для этого и нужен тег «LINEAR_______23_625000__0H___72_».
Если поискать по названию LINEAR_______23_625000__0H___72_ в a2l, то найдем нашу формулу для пересчета:
/begin COMPU_METHOD LINEAR_______23_625000__0H___72_ "" FORM "%5.1" "уRK" /begin FORMULA "0.375*X-23.625" <- формула пересчета FORMULA_INV "2.6666667*X+63.0" /end FORMULA /end COMPU_METHOD
Здесь «X» означает «сырые» данные в памяти. В нашем случае это каждая ячейка в таблице величиной в 1 байт. Вообще все формулы пересчета в a2l файлах открываются тегом «COMPU_METHOD».
Теперь посмотрим как это работает на примере xdf -файла под tunerPro.
Открываем tunerPro, создаем новый xdf:
Кликаем правой кнопкой мышки в поле Parameter Tree и создаем новый параметр (в нашем случае карту) выбирая «Insert New XDF Parameter».
На откроется окно выбора типа параметра:
1 скаляр
2.битовый флаг
3.карта <- то что нам нужно!
4.какая-то функция (никогда не понадобится )
5.патч (до этого вряд ли дорастём
)
Слева в окошке появился новый параметр. Нажимаем на него правой кнопкой мыши и выбираем его свойства «Edit Parametr XDF info».
Откроется главное окно настроек карты. Сюда мы и будем забивать все данные из a2l файла.
Title — название нашей карты. Допустим «Карта УОЗ на 91-ом октане».
Description — тут описание нашей карты, для чего она нужна и в каких расчетах учавствует.
Adress (Hex) — адрес первого элемента карты. В случае ip_iga_ron_91_pl_ivvt__n__maf адрес 0x77045. Забиваем его в это поле.
Cell Data Size — размер данных. В нашей карте данные занимают 1 байт (UBYTE), значит и выбираем 1 байт.
Signed (знаковый) — флаг отмечается если используется знаковый тип данных, т.е. SBYTE, SWORD и т.п. В нашем случае флаг не выставляется, так как в этой карте используется UBYTE.
LSB First -порядок байт в многобайтовом значении. Если бы значения таблицы были по 2 байта и больше, то выставление этого флага означает что слева стоящий байт в слове -младший, снятие флага — старший. Т.е. флаг определяет порядок «чтения» слова, справа — налево или слева — направо. В нашем случае не используется, потому что у нас всего 1 байт.
Output type — тип отображаемых данных. Данное поле позволяет выбрать формат предоставления данных на карте:
Floating point — число с плавающей точкой в десятичной системе
integer — целое число в десятичной системе <- мы будем отображать УОЗ в целых числах, в десятичной системе, выбираем это поле
Hex — «сырые» данные в hex
ASCII String — отображение данных в виде символов ASCII кода, соответствующего значению в таблицке Т.е. вместо 20, в таблице отобразится символ, соответствующий этому коду — «а». Этот режим практически не используется.
Остальные параметры пока не трогаем, идём дальше на вкладку Rows.
Вкладка Rows предназначен для описания оси по Х. Мы знаем что у нас 20 значений по Х, забиваем их в поле «number of rows».
Остальные параметры оси пока не трогаем, рассмотрим позже. Идем далее, на вкладку Columns, описания оси Y.
Из a2l мы также знаем что у нас 16 элементов по оси Y, забиваем в поле «Number of Columns».
Пока все, нажимаем «apply» , смотрим что у нас получилось.
Для того чтобы проверить что отображает карта, необходимо загрузить бинарный файл прошивки командой File->open bin. После загрузки файла, можно нажать на вновь созданный параметр xdf и посмотреть результат.
Видим карту, уже похожую на карту УОЗ. Типичная монотонно возрастающая поверхность.
Теперь применим формулу пересчета, найденную ранее в a2l -файле. Для нужно зайти в параметры таблицы и перейти на вкладку «Conversion».
В появившемся окне нажать кнопку «Edit Global Table Equation» и ввести новую формулу пересчета для элементов таблицы нажав edit справа:
"0.375*X-23.625" <- формула пересчета
Нажимаем Ok и затем Apply в главных свойствах таблицы.
Для того чтобы обновить таблицу, нужно её закрыть и открыть снова. Видим нашу карту УОЗ, уже с вменяемыми значениями угла.
Оси остаются некорректными. Пересчет для осей (COMPU_METHOD) может быть найден по тегам LINEAR______0_000000__0H___13818 и LINEAR______0_000000__0H___81612 соответственно:
/begin COMPU_METHOD LINEAR______0_000000__0H___13818 "" FORM "%5.1" "mg/stk" <-измеряемая величина, в данном случае это значение МАФ /begin FORMULA "0.021194781*X" <- формула пересчета для оси Х FORMULA_INV "47.181425*X" /end FORMULA /end COMPU_METHOD
/begin COMPU_METHOD LINEAR______0_000000__0H___81612 "" FORM "%4.0" "rpm" <-измеряемая величина, т.е. обороты двигателя /begin FORMULA "1.0*X" <- формула пересчета FORMULA_INV "1.0*X" /end FORMULA /end COMPU_METHOD
Ну и не забываем про адреса где лежат сами данные для осей, ищем по «ldpm_maf_iga_2» и по «ldpm_n_14». Нам нужно описание осей, т.е. тег AXIS_PTS
/begin AXIS_PTS ldpm_maf_iga_2 "maf_iga" 0x74FB4 maf_iga a_743 100 LINEAR______0_000000__0H___13818 <-стоит заметить, что расчетная формула дублируется в описании оси! 16 0 1389 /end AXIS_PTS
/begin AXIS_PTS ldpm_n_14 "n" 0x74F8A n a_743 100 LINEAR______0_000000__0H___81612 <-стоит заметить, что расчетная формула дублируется в описании оси! 20 0 8160 /end AXIS_PTS
Для того чтобы указать tunerPro, что ось берется из прошивки, а не прописывается руками или назначается по-умолчанию, в списке Lable source нужно выбрать Internal (с англ. внутренний), сразу откроется список опций для оси, уже определенной в прошивке. Как раз наш случай .
Не забываем про описание типа данных для каждой оси. Т.е. про то самое поле «a_743», по аналогии c «a_17» для главной таблицы. Для обоих осей описание типа данных является одинаковым. Ищем RECORD_LAYOUT с названием «a_743» в документе, находим:
RECORD_LAYOUT a_743 AXIS_PTS_X 1 UWORD INDEX_INCR DIRECT RECORD_LAYOUT
Тут тип данных -«UWORD«, т.е. 2 без знаковых байта ( 0…65535) или проще -двух байтовое слово.
В настройках каждой оси, выбираем -> 2 байта -> Integer (Row Label Type).
Запись DIRECT означает что чтение каждого слова происходит слева направо (или LoHi), сначала младший байт, потом старший байт. Что это значит относительно tunerPro настроек оси? Это и есть та самая пресловутая галочка LSB First в настройках оси , её стоит отмечать при наличии DIRECT.
Забиваем данные осей во вкладки rows и columns соответственно, получаем искомую карту под 91-ый октан.