Подавляющее большинство специалистов-новичков не задаются вопросом - что такое контрольная сумма и зачем она нужна. Но только до поры до времени, пока не столкнутся с каким-нибудь важным вопросом, связанным с контрольной суммой. В сегодняшней статье мы постараемся как можно более простыми словами, с приведением примеров, объяснить смысл данной сущности.
Итак, начнем с определения (этот абзац рекомендуем прочитать медленно и вдумчиво). Контрольная сумма (КС) - это результат работы некоторой функции, преобразующей исходные данные фиксированной или произвольной длины в набор данных фиксированной длины. Условно говоря, КС рассчитывается по некоторому алгоритму, некоторой формуле, на вход которой подаются данные, а на выходе получается результат вычислений над этими данными. По контрольной сумме ЭБУ определяет целостность информации, записанной в его память.
Если звучит муторно и сумбурно, то давайте рассмотрим пример функции расчёта КС. Возможно так смысл применения КС станет понятнее.
Для простоты примера возьмем не Flash-память, а память EEPROM от Bosch ME7.5 (VW Golf4), которая содержит 512 байт информации (см. скриншот).
Область EEPROM рассматриваемого автомобиля содержит пин приборной панели, синхронизацию иммобилайзера и прочие данные. Вся область данных занимает 512 байт, которые можно условно разделить на 32 строки по 16 байт. Большинство строк содержат в себе 14 байт «полезной» информации, а 2 последних байта рассматриваемых строк - это КС. Некоторые строки (например, первая) не содержат в себе КС.
Для тех строк, где КС присутствует, в данном конкретном случае, она вычисляется следующим образом:
CS = LittleEndian((0xFFFF – (page_number – 0x01)) – (value(page_number * 0x10 + 0x00) + value(page_number * 0x10 + 0x01) + value(page_number * 0x10 + 0x02) + … + value(page_number * 0x10 + 0x0D))), где
page_number – номер строки от 0x00 до 0x1F;
value(address) – значение по адресу, указанному внутри скобок;
LittleEndian - порядок записи байтов от младшего к старшему (к примеру, если КС равна 0xFB7B, то в порядке Little Endian она записывается как 0x7BFB);
Все значения начинаются префикса 0x, что значит, что они записаны в шестнадцатеричной системе счисления.
Интереса ради, можно открыть стандартный калькулятор Windows в режиме «программист» и пересчитать КС какой-нибудь строки. Скажем, третьей строки (она же 0x02):
CS = LittleEndian((0xFFFF – (0x02 – 0x01)) – (value(0x20) + value(0x21) + value(0x22) + … + value(0x2D))) = LittleEndian((0xFFFF – (0x02 – 0x01)) – (0x05 + 0x01 + 0x02 + 0x00 + 0x02 + 0x2B + 0x01 + 0x00 + 0x03 + 0x00 + 0x69 + 0xC1 + 0x00 + 0xA5)) = LittleEndian((0xFFFE) – (0x0208)) = LittleEndian(0xFDF6) = 0xF6FD
Сходится? Еще бы! (если не верите, то посмотрите на изображение выше и не поленитесь пересчитать самостоятельно)
А что если КС не сошлась бы? В таком случае, машина бы просто не завелась. Ведь на этапе самодиагностики (в процессе включения), ЭБУ бы пересчитал КС каждой строки, увидел бы несхождения (хотя бы одной строке), и принял это за нарушение целостности данных, что бывает при неисправностях элементов памяти ЭБУ.
К слову, каждый ЭБУ использует собственные способы расчета КС. Более того, для разных областей данных могут использоваться разные способы расчета.
Ладно. Оставим теорию и вернемся к практике. На практике нам требуется записывать тюнинговые прошивки (калибровки) в ЭБУ двигателя. И, очевидно, что эти прошивки должны быть с пересчитанной КС. Иначе, если мы запишем прошивку с непересчитанной КС, то при запуске ЭБУ увидит несхождение КС и, как минимум, зафиксирует ошибку. Как максимум, запуск двигателя не состоится.
Впрочем, не стоит сильно переживать по этому поводу. Редакторы калибровок, в которых мы работаем, в большинстве случаев, пересчитывают КС в сохраняемой прошивке. Более того, сами флэшеры перед записью прошивки всегда проверяют и пересчитывают КС (если она некорректна), исключая ну совсем уж уникальные случаи. Единственное место, где следует работать крайне внимательно - инженерные способы записи (BSL, BDM, JTAG). В зависимости от используемого оборудования, автоматического пересчета КС при записи может и не быть.