Проблема фиксированного 100км одометра в диагностике
Многим владельцам приборных панелей первого поколения давно известна проблема со статическим показателем одометра в бортовой сети автомобиля. Это можно увидеть в диагностических программах. Вот например на моей машине видно 96км (почему 96 непонятно и куда делись 4км? 😀). Но на самом деле приборка сообщает статическим 100км пробегом (мы это увидим позже).
Также на форуме посвященной этому устройству этот вопрос поднимался - link
Под приборками первого поколения я подразумеваю приборки с dashboard-ом у которого есть EventHub:
У первого поколения есть две ревизии V01 и V02. Можно видеть в "Версии протокола" например как вверху V02 (на самом деле это номер версии bootloader MCU). Есть некоторые отличия, но архитектурно этих ревизии одинаковые. Как в остальных моделях обстоят дела с бортовым одометром я не знаю.
Об этой проблеме, насколько мне известно, многократно сообщали разработчикам и продавцам из КНР, но наши рисовые друзья либо не слышали, либо не понимали что от них хотят и проблема так и осталась. А с выпуском новых версий данной приборки надежды на исправление этой проблемы окончательно растворились.
Возможно есть еще какие-то сюрпризы, но за три года эксплуатации я их не обнаружил (кривой перевод и как я с ним боролся может расскажу в другой раз).
Глобально оценить те проблемы, которые связаны со статическим одометром, мне тяжело. Я не являюсь автоэлектриком, но логика подсказывает что они должны быть. А вот насколько критические - это вопрос. Современный автомобиль - это компьютер на колесах. Думаю многие модели поведения ЭБУ имеют в своем алгоритме работы данные одометра. Первое что приходит в голову - это аккумулятор. Характеристики аккумулятора изменяются со временем и автомобиль меняет формулу заряда АКБ на основании того, какой пробег у авто. Поэтому при регистрации нового АКБ в памяти сохраняется на каком пробеге была произведена замена. Я аккумулятор менял еще до того как установил приборку, но уверен что при замене на новый и его регистрации я бы столкнулся с проблемой его прописать.
Вообще идея что это надо как-то пофиксить была с самого начала. Но как всегда нехватка свободного времени делает свое дело...
.....прошло больше года.
И вот появилось свободное окно, и я принимаю решение идти собирать дамп с CAN шины. В наличии у меня Arduino + модуль (MCP2512+TJA1050) со скетчем canhacker.
В CAN-ID 0x330 находится одометр, который отсылает KOMBI (приборная панель). И тут видно что он статический со значением 0x64 = 100км. Периодичность посылки раз в 10 секунд. Как же так разработчики могли дать в штагу... Ну хоть что-то шлет и то хорошо. А то я думал что она совсем молчит в эфире, но нет. Было подозрение что внешняя температура тоже неправильная, т.к. датчик внешней температуры подключен непосредственно на приборную панель и она отвечает за передачу этого значения в сеть авто. Но с ним все было в порядке:
Теперь есть задача - каким-то образом заменить 100км на реальный пробег, который в приборной панели есть и мы его видим на дисплее. Также мы его в настройках 0168 приборки можем задавать вручную, хотя этот функционал мне кажется довольно странным. Пробег это ж "священная корова" и крутить его могут только перекупы, а тут все штатно 😉.
Ладно, какие есть варианты?
- Лабудатор. Т.е. устройство которое устанавливается в разрыв CAN шины приборки и бортовой сетью. И оно уже модифицирует пробег. Что-то типа такогоцена около 10$. Заказал глубоко не анализируя. Даже если не подойдет для этой задачи то покрутить всегда его можно. МК STM32F105RBT6 в хозяйстве может когда-то пригодится. (потом уже выяснится что он для моей задачи не подойдет)
- Брать как-то информацию с Dashboard-а приборки (плата процессора общего назначения на базе T.507, который собственно и занимается визуализацией) и отправлять в CAN. Тут встает вопрос как подавить текущий 0x330 с 100км. Опять нужна врезка какая-то.
- Как-то крутить MCU. Именно он отвечает за связь приборки с бортовой сетью автомобиля и именно ион формирует ту самую константу в 100км. MCU реализован на базе GD32/STM32 МК. У меня STM32F105VCT6
- Забить и ездить как ездил до этого.
Первый вариант с лабудатором выглядит самым реалистичным, но встает вопрос - как его интегрировать с приборкой чтобы пробег как-то ему передать. Т.е. надо с нуля написать софт с взаимодействием с Dashboard-ом. Но это кажется самым адекватным решением потому что он будет охватывать и второй вариант одновременно. Но еще одно устройство - это еще одна точка отказа.
Третий вариант - это погрузится в reverse engenering прошивки и в область микроконтроллеров, организации памяти, UART-ов, и прочих интерфейсов. Опыта раньше такого не было, так по мелочи..
Был выбран третий вариант, потому что простых путей не ищем, но несколько раз хотелось остановиться на четвертом 😊. Но я на моменте принятия решения даже не представлял сколько всего придется перелопатить. Но ни о чем не жалею.
Заказал на Алике devboard на базе МК GD32F305VCT6. Такой на некоторых моделях приборок устанавливается. STM32F105VCT6 и GD32F305VCT6 аналоги, но у GD32 частота выше.
Пока едет devboard неспешно изучаю материнскую плату приборки со стороны MCU.
Присутствует EEPROM (I2C).
Значит есть вероятность что какие-то данные MCU сохраняет в энергонезависимой памяти. В стоковой приборке я думаю пробег лежит там.
Значит есть вероятность что какие-то данные MCU сохраняет в энергонезависимой памяти. В стоковой приборке я думаю пробег лежит там.
CAN трансивер
Если бы я на том этапе внимательно прочитал dataseet на этот трансивер, то сэкономил бы много времени (но об этом позже).
Если бы я на том этапе внимательно прочитал dataseet на этот трансивер, то сэкономил бы много времени (но об этом позже).
Также прозвонил куда подключается датчик внешней температуры. Через обвязку подается на АЦП. При подключении резистора 10кОм приборка показывала 9.5 градусов. Если у кого-то плывет температура (видел такие сообщения в ветке форума), то можно проверить эту цепь и скорректировать доп. сопротивлением последовательно или параллельно, все зависит в какую сторону. Не уверен что там линейная связь, но попробовать всегда можно не разбирая приборки.
Еще одно требование, которое я поставил по этой задаче для себя - ничего не выпаивать с платы. Я понимаю что кому-то легче сдуть EEPROM или FLASH, подкинуть программатор и слить дамп. Я не эксперт в этом деле, поэтому задача усложняется для меня, но не становится менее интересной (такое же условие у меня было и с реверсом Dashboard модуля на Linux T.507, которое было успешно реализовано, но сейчас не об этом).
Через две недели приехал devboard
Первым делом пробую прошивать с помощью j-link ту прошивку, которую я использую - jly_can_1293_129A_1295_E70_230321NL_v10.bin у себя на авто. Именно с ней я и буду работать. Функциональности в ней достаточно. Это последняя насколько я знаю прошивка, которая нормально работает с Dashboard-ом где 3D анимация дверей, капота и багажника.
Естественно после прошивки никакого чуда не случилось. Логический анализатор никакой активности на пинах UART-а не заметил. Я начал смотреть именно с них, т.к. заглянул первым делом в strings прошивки. И там явно есть что печатать в консоль.
и вижу скорость инициализации 460800. Переименовываю каждую функцию (x_<name function>) в которой нахожу хоть какою-либо логику. Потому что изначально там полный хаос - 1312 функций.
Именно USART2 используется для вывода в консоль.
До этого момента, после штудирования дизасма, у меня уже было понимание что прошивка лежит начиная с 0x08003000 на флеше. А соответственно 0x08000000 - 0x08002FFF - это bootloader которого у меня нет. И слить его с помощью jtag не получится, т.к. МК под Read Protected. Еще один барьер. Но иду опять в дизасм и работаю с ним. Ищу какие команды реализованы для работы в консоли. Напомню промежуточную цель - запустить прошивку на devboard-е. Все найденные команды описывать не буду, остановлюсь на одной, которая меня заинтересовала MMR
Задача номер 1 - определить на какой UART. Глубоких знаний не было по работе с Revers Engineering Tools, но как раз для этого я этим и занимаюсь, чтобы ознакомится поглубже.
На плате вижу что USART1 (USART0 у GD32) используется для взаимодействия с T.507, поэтому ищу адресацию USART2 (USART1 у GD32)
На плате вижу что USART1 (USART0 у GD32) используется для взаимодействия с T.507, поэтому ищу адресацию USART2 (USART1 у GD32)
Именно USART2 используется для вывода в консоль.
Теперь самое время найти этот порт на материнской плате. Вот тут он оказался
Остальные пины - это контакты JTAG.
пробую прочитать 4 байта по адресу например 0x200001A4
ну и хорошо ж 😊 (кстати команду mmr я посмотрел в более поздних прошивках разработчики её убрали). Они защитили флэш от чтения, но оставили возможность читать любую область памяти из консоли (в том числе из флэша). Это была их ошибка. Пишу скрипт и вычитываю 0x08000000 - 0x08002FFF небольшими чанками по 4К
ну и хорошо ж 😊 (кстати команду mmr я посмотрел в более поздних прошивках разработчики её убрали). Они защитили флэш от чтения, но оставили возможность читать любую область памяти из консоли (в том числе из флэша). Это была их ошибка. Пишу скрипт и вычитываю 0x08000000 - 0x08002FFF небольшими чанками по 4К
По первым байтам вижу что это что-то живое. Конвертирую в бинарник. И для проверки произвожу такую же операцию с областью памяти прошивки. Сравниваю то что сдампил с файлом прошивки
- одинаковые. Это значит что и bootloader у меня на руках.
Беру bootloader и шью им devboard, а с адреса 0x08003000 уже заливаю прошивку. Подключаюсь к USART2 и вижу
Не то что хотелось бы, но уже что-то. Какую бы я скорость не подбирал, ничего не получалось. Но логический анализатор выручил. Скорость оказалась 1474560. Подозреваю это из-за того что бутлоадер с STM32, а запускаю на GD32, а у него тактовая частота выше (но могу ошибаться).
Беру bootloader и шью им devboard, а с адреса 0x08003000 уже заливаю прошивку. Подключаюсь к USART2 и вижу
Не то что хотелось бы, но уже что-то. Какую бы я скорость не подбирал, ничего не получалось. Но логический анализатор выручил. Скорость оказалась 1474560. Подозреваю это из-за того что бутлоадер с STM32, а запускаю на GD32, а у него тактовая частота выше (но могу ошибаться).
Результат:
И мы видим в этой функции вызов заглушки на 100км. Не понятно почему китайцы так сделали. Очень похоже что это осталось с какого-то этапа разработки. Но не могло же уйти это в прод. Но ушло!
Так зачем мы это все делаем? Одометр!
Просто для меня на devboard экспериментировать удобней.
И опять пошел штудировать дезасемблер... Долго штудировал, но с помощью функций работы с EEPROM удалось выйти на подозреваемого.
и да - это он 0x149 = 329!
при эмуляции ЭБУ "на столе" я могу управлять скоростью и оборотами тем самым на приборке изменяю значение одометра и да, он меняется в этой ячейке памяти.
при эмуляции ЭБУ "на столе" я могу управлять скоростью и оборотами тем самым на приборке изменяю значение одометра и да, он меняется в этой ячейке памяти.
Но это только пол дела. Нам надо его теперь как-то передать вместо наших искомых 100км. Что для этого нужно? А нужно найти как происходит передача CAN-id 0x330. Пошел искать...
.........
Похоже кандидат найден
И мы видим в этой функции вызов заглушки на 100км. Не понятно почему китайцы так сделали. Очень похоже что это осталось с какого-то этапа разработки. Но не могло же уйти это в прод. Но ушло!
Посмотрел кто еще использует адрес dword 200001A4. И похоже что никто. Ок. Было принято решение заменить в пуле констант кода 200001A4 на наш 20000484 (адрес одометра) ну и убрать то присвоение
dword_200001A4 = v16
чтобы его v16 не переписал. Забил его NOP-ами.
Что ж... Идем проверять.
..... Но я пропущу ту часть как я "будил" приборку, чтобы заставить её "на столе" отсылать 0x330. На самом деле этот этап забрал у меня много времени, т.к. чтобы увидеть от приборки первый RX мне пришлось разобраться в чем разница между HS-CAN и FT-CAN, разницу между CAN трансиверами, программировать STM32F103 bluepill + TJA1055T, научиться паять микросхему на переходник SOIC-14 на DIP-14 и многое другое. Иногда хотелось остановиться. Но...
В итоге я увидел на оригинальной прошивке "на столе"
[ 487520 ms] RX 330 [8] 64 00 00 00 FF FF FD FF
[ 497518 ms] RX 330 [8] 64 00 00 00 FF FF FD FF
Шьём патченную через USB на приборку.
Идем шить приборку в BMW.
подключаю ISTA+ тру ошибки с 96км, перечитываю заново (знаю что ошибки будут так как нет монитора CIC и самой оригинальной приборки - видно на первом скрине этой статьи).
И вот результат
Спасибо за внимание ✌
PS: повторюсь, я не являюсь экспертом в области автоэлектрики, программирования и электроники. Работаю в области ИТ, но по совсем другому профилю. Поэтому допускаю что граммотные люди и профессионалы решили бы эту задачу другим способом и за более короткий промежуток времени. Но для меня это был просто эксперимент в свободное от работы время.
Доброго времени суток! Подскажите, можно ли с вами как то связаться?
ОтветитьУдалить