a2l to xdf. Что такое a2l файлы?

Что такое 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:

post-2-0-12342700-1427313800.jpg

Кликаем правой кнопкой мышки в поле Parameter Tree и создаем новый параметр (в нашем  случае карту) выбирая «Insert New XDF Parameter».

post-2-0-43314300-1427313806.jpg

На откроется окно выбора типа параметра:

1 скаляр

2.битовый флаг

3.карта   <- то что нам нужно!

4.какая-то функция (никогда не понадобится  )

5.патч (до этого вряд ли дорастём    )

post-2-0-10323000-1427314488.jpg

Слева в окошке появился новый параметр. Нажимаем на него правой кнопкой мыши и выбираем его свойства «Edit Parametr XDF info».

Откроется главное окно настроек карты. Сюда мы и будем забивать все данные из a2l файла.

post-2-0-45738600-1427315114.jpg

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.

post-2-0-68400000-1427315246.jpg

Вкладка Rows предназначен для описания оси по Х. Мы знаем что у нас 20 значений по Х, забиваем их в поле «number of rows».

Остальные параметры оси пока не трогаем, рассмотрим позже. Идем далее, на вкладку Columns, описания оси Y.

post-2-0-98539000-1427315252.jpg

Из a2l мы также знаем что у нас 16 элементов по оси Y, забиваем в поле «Number of Columns».

Пока все, нажимаем «apply» , смотрим что у нас получилось.

Для того чтобы проверить что отображает карта, необходимо загрузить бинарный файл  прошивки командой File->open bin. После загрузки файла, можно нажать на вновь созданный параметр xdf  и посмотреть результат.

post-2-0-59765900-1427317198.jpg

Видим карту, уже похожую на карту УОЗ. Типичная монотонно возрастающая поверхность.

Теперь применим формулу пересчета, найденную ранее в a2l -файле. Для нужно зайти в параметры  таблицы и перейти на вкладку  «Conversion».

В появившемся окне  нажать кнопку «Edit Global Table Equation» и ввести новую формулу пересчета для элементов таблицы нажав edit справа:

"0.375*X-23.625" <- формула пересчета

post-2-0-01237800-1427317731.jpg

Нажимаем Ok и затем Apply  в главных свойствах таблицы.

Для того чтобы обновить  таблицу, нужно её закрыть и открыть снова. Видим нашу карту УОЗ, уже с вменяемыми значениями угла.

post-2-0-63391900-1427318109.jpg

Оси остаются некорректными. Пересчет для осей (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.

post-2-0-68400000-1427315246.jpg

Забиваем данные осей во вкладки rows и columns соответственно, получаем искомую карту под 91-ый октан.

post-2-0-01176900-1427320333.jpg