95640 eeprom чем читать
Перейти к содержимому

95640 eeprom чем читать

Прошивка EEPROM блока AirbagVW10 при помощи USB-программатора CH341A

В предыдущем посте — www.drive2.ru/l/540840424927920973/ у меня отвалился блок управления airbag.

Прозвонил несколько мест, которые восстанавливают блоки управления подушками после аварий, правят дампы EEPROM и после всех этих разговоров, сказок и ценников принял решение разобраться с этим вопросом самостоятельно, тем более, что опыт в перепрошивке всего чего только можно у меня приличный, да и программатор где-то завалялся.

Первым делом добрался и снял блок управления Airbag, находится он в центральной консоли под органами управления климатом или кондиционером.

Чтобы туда добраться, нужно снять пластиковую боковину справа от ног водителя, открутив один болт при помощи Torx T15, а затем открутить кронштейн, к которому крепится эта пластиковая боковина, при помощи головки на 10. Пластиковый кронштейн крепится на шпильках и притянут пластиковыми гайками на 10.

Далее видим сам блок управления подушками безопасности, он крепится тремя гайками на 10, одна гайка со стороны водителя, две — со стороны пассажира. Ко всем гайкам можно добраться из-под ног водителя, к одной прямо, к двум остальным — на ощупь.

После того, как гайки откручены, можно вынимать блок SRS Airbag и отключать его от косы-разъема. Вот, как это выглядит вкратце.

Далее я принёс блок домой к компу и столкнулся со сложностью, которая заключалась в нестандартных винтах, которые имеют пятигранную форму внутри и по центру имеют штырёчек, который мешает туда что-либо вставить, чтобы зацепиться за вырезы в головке.

Плоской отвёрткой я отломал центральные штырьки, наклонив их сперва в одну сторону, затем в другую. Обламываются они под корень, очень аккуратно, затем плоской отвёрткой побольше зацепился за выступы и спокойно открутил все винты. Затянуты они были прилично.

Блок разбирается на три части, одна из них печатная плата с чипом EEPROM, который нужно расчехлить.

На плате нужно найти чип, который нам нужно прошить нормальным дампом. В моём случае это чип с маркировкой ATMEL 25640AN.

Работа с параметрами в EEPROM, как не износить память

Доброго времени суток. Прошлая моя статья про параметры в EEPROM была, мягко говоря, немного недопонята. Видимо, я как-то криво описал цель и задачу которая решалась. Постараюсь в этот раз исправиться, описать более подробно суть решаемой проблемы и в этот раз расширим границы задачи.

А именно поговорим о том, как хранить параметры, которые необходимо писать в EEPROM постоянно.

Многим может показаться, что это очень специфическая проблема, но на самом деле множество устройств именно этим и занимаются — постоянно пишут в EEPROM. Счетчик воды, тепловычислитель, одометр, всяческие журналы действий пользователя и журналы, хранящие историю измерений, да просто любое устройство, которое хранит время своей работы.

Особенность таких параметров заключается в том, что их нельзя писать просто так в одно и то же место EEPROM, вы просто израсходуете все циклы записи EEPROM. Например, если, необходимо писать время работы один раз в 1 минуту, то нетрудно посчитать, что с EEPROM в 1 000 000 циклов записей, вы загубите его меньше чем за 2 года. А что такое 2 года, если обычное измерительное устройство имеет время поверки 3 и даже 5 лет.

Кроме того, не все EEPROM имеют 1 000 000 циклов записей, многие дешевые EEPROM все еще производятся по старым технологиям с количеством записей 100 000. А если учесть, что 1 000 000 циклов указывается только при идеальных условиях, а скажем при высоких температурах это число может снизиться вдвое, то ваша EEPROM способно оказаться самым ненадежным элементом уже в первый год работы устройства.

Поэтому давайте попробуем решить эту проблему, и сделать так, чтобы обращение к параметрам было столь же простым как в прошлой статье, но при этом EEPROM хватало бы на 30 лет, ну или на 100 (чисто теоретически).

Итак, в прошлой статье, я с трудом показал, как сделать, так, чтобы с параметрами в EEPROM можно было работать интуитивно понятно, не задумываясь, где они лежат и как осуществляется доступ к ним

Для начала проясню, для чего вообще нужно обращаться по отдельности к каждому параметру, этот момент был упущен в прошлой статье. Спасибо товарищам @Andy_Big и @HiSER за замечания.

Все очень просто, существует огромный пласт измерительных устройств, которые используют полевые протоколы такие как HART, FF или PF, где пользовательские команды очень атомарные. Например, в HART протоколе есть отдельные команды — запись единиц изменения, запись верхнего диапазона, запись времени демпфирования, калибровка нуля, запись адрес опроса и т.д. Каждая такая команда должна записать один параметр, при этом успеть подготовить ответ и ответить. Таких параметров может быть до 500 — 600, а в небольших устройствах их около 200.

Если использовать способ, который предложил пользователь @HiSER- это будет означать, что для перезаписи одного параметра размером в 1 byte, я должен буду переписать всю EEPROM. А если алгоритм контроля целостности подразумевает хранение копии параметров, то для 200 параметров со средней длиной в 4 байта, мне нужно будет переписать 1600 байт EEPROM, а если параметров 500, то и все 4000.

Малопотребляющие устройства или устройства, питающиеся от от токовой петли 4-20мА должны потреблять, ну скажем 3 мА, и при этом они должны иметь еще достаточно энергии для питания модема полевого интерфейса, графического индикатора, да еще и BLE в придачу. Запись в EEPROM очень энергозатратная операция. В таких устройствах писать нужно мало и быстро, чтобы средний ток потребления был не высоким.

Очевидно, что необходимо, сделать так, чтобы микроконтроллер ел как можно меньше. Самый простой способ, это уменьшить частоту тактирования, скажем до 500 КГц, или 1 Мгц (Сразу оговорюсь, в надежных применениях использование режима низкого потребления запрещено, поэтому микроконтроллер все время должен работать на одной частоте). На такой частоте, простая передача 4000 байт по SPI займет около 70 мс, прибавим к этому задержку на сохранение данных в страницу (в среднем 7мс на страницу), обратное вычитывание, и вообще обработку запроса микроконтроллером и получим около 3 секунд, на то, чтобы записать один параметр.

Поэтому в таких устройствах лучше чтобы доступ к каждому параметру был отдельным, и обращение к ним должно быть индивидуальным. Их можно группировать в структуру по смыслу, или командам пользователя, но лучше, чтобы все они не занимали больше одной страницы, а их адреса были выравнены по границам страницы.

Но вернемся к нашей основной проблеме — мы хотим постоянно писать параметры.

Как работать с EEPROM, чтобы не износить её

Те кто в курсе, можете пропустить этот раздел. Для остальных краткое, чисто мое дилетантское пояснение.

Как я уже сказал, число записей в EEPROM ограничено. Это число варьируется, и может быть 100 000, а может и 1 000 000. Так как же быть, если я хочу записать параметр 10 000 000 раз? И здесь мы должны понять, как внутри EEPROM устроен доступ к ячейкам памяти.

Итак, в общем случае вся EEPROM разделена на страницы. Страницы изолированы друг от друга. Страницы могут быть разного размера, для небольших EEPROM это, скажем, 16, 32 или 64 байта. Каждый раз когда вы записываете данные по какому-то адресу, EEPROM копирует все содержимое страницы, в которой находятся эти данные, во внутренний буфер. Затем меняет данные, которые вы передали в этом буфере и записывает весь буфер обратно. Т.е. по факту, если вы поменяли 1 байт в странице, вы переписываете всю страницу. Но из-за того, что страницы изолированы друг от друга остальные страницы не трогаются.

Таким образом, если вы записали 1 000 000 раз в одну страницу, вы можете перейти на другую страницу и записать туда еще 1 000 000 раз, потом в другую и так далее. Т.е. весь алгоритм сводится к тому, чтобы писать параметр не в одну страницу, а каждый раз сдвигаться в следующую страницу. Можно закольцевать эти действия и после 10 раз, снова писать в исходную страницу. Таким образом, вы просто отводите под параметр 10 страниц, вместо 1.

Да придется пожертвовать память, но как сделать по другому, я пока не знаю. Если есть какие мысли — пишите в комментариях.

Анализ требований и дизайн

Итак, мы почти поняли что хотим. Но давайте немного формализуем это. Для начала, назовем наши параметры, которые нужно писать постоянно — AntiWearNvData (антиизносные данные). Мы хотим, чтобы обращение к ним было такое же простое и юзер френдли, как и к кешируемым параметрам из предыдущей статьи.

Все требования можно сформулировать следующим образом:

Пользователь должен задать параметры EEPROM и время обновления параметра

На этапе компиляции нужно посчитать количество необходимых страниц (записей), чтобы уложиться в необходимое время работы EEPROM. Для этого нужно знать:

Количество циклов перезаписи

Время обновления параметра

Время жизни устройства

Хотя конечно, можно было дать возможность пользователю самому задавать количество записей, но что-то я хочу, чтобы все считалось само на этапе компиляции.

Каждая наша переменная(параметр) должна иметь уникальный начальный адрес в EEPROM

Мы не хотим сами руками задавать адрес, он должен высчитываться на этапе компиляции

При каждой следующей записи, адрес параметра должен изменяться, так, чтобы данные не писались по одному и тому же адресу

Это также должно делаться автоматически, но уже в runtime, никаких дополнительных действий в пользовательском коде мы делать не хотим.

Мы не хотим постоянно лазить в EEPROM, когда пользователь хочет прочитать параметр

Обычно EEPROM подключается через I2C и SPI, передача данных по этим интерфейсам тоже отнимает время, поэтому лучше кэшировать параметры в ОЗУ, и возвращать сразу копию из кеша.

При инициализации мы должны найти самую последнюю запись, её считать и закешировать.

За целостность должен отвечать драйвер.

За алгоритм проверки целостности отвечает драйвер, если при чтении он обнаружил несоответствие он должен вернуть ошибку. В нашем случае, пусть в качестве алгоритма целостности будет простое хранение копии параметра. Сам драйвер описывать не буду, но приведу пример кода.

Ну кажется это все наши хотелки. Как и в прошлой статье давайте прикинем дизайн класса, который будет описывать такой параметр и удовлетворять нашим требованиям:

Класс AntiWearNvData будет похож на, CachedNvData из прошлой статьи, но с небольшими изменениям. При каждой записи в EEPROM, нам нужно постоянно сдвигать адрес записи, поэтому необходимо хранить индекс, который будет указывать на номер текущей записи. Этот индекс должен записываться в EEPROM вместе с параметром, чтобы после инициализации можно было найти запись с самым большим индексом — эта запись и будет самой актуальной. Индекс можно сделать uint32_t точно хватит на 30 лет — даже при 100 000 циклах записи.

И вот наш класс:

Посмотрим на то, как реализуются наши требования таким дизайном.

Пользователь должен задать параметры EEPROM и время обновления параметр

В отличии от CachedNvData Из предыдущей статьи здесь появился параметр updateTime . На основе этого параметра можно посчитать сколько записей необходимо для того, чтобы уложиться в ожидаемое время жизни EEPROM. Сами параметры EEPROM можно задать в отдельном заголовочнике. Например, так:

Вообще можно было бы обойтись и без updateTime . И для каждого параметра задавать необходимое количество самим. Но я решил, все переложить на компилятор, потому что самому считать лень. В итоге сам расчет необходимого количества записей, с учетом, что все они выравнены по границам страницы, будет примерно таким:

При каждой следующей записи, адрес параметра должен изменяться, так, чтобы данные не писались по одному и тому же адресу

Еще одной особенностью нашего противоизносного параметра является тот факт, что кроме самого значения, мы должны хранить еще и его индекс. Индекс нужен нам для двух вещей:

По нему мы будет рассчитывать следующий адрес записи

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

Для этого заведена специальная структура tAntiWear . Её то мы и будем сохранять при вызове метода Set(. ) , который, кроме непосредственно записи, еще сдвигает индекс текущей записи на 1.

Давайте посмотрим как реализован метод расчета текущего адреса записи:

Мы не хотим постоянно лазить в EEPROM, когда пользователь хочет прочитать параметр

Метод Get() — крайне простой, он просто возвращает копию из ОЗУ

Теперь самое интересное, чтобы проинициализировать копию в ОЗУ правильным значением, необходимо при запуске устройства считать все записи нашего параметра и найти запись с самым большим индексом. Наверняка есть еще разные методы хранения данных, например, связанный список, но использование индекса, показалось мне ну прямо очень простым.

В общем-то и все класс готов, полный код класса:

Полный код класса

По аналогии с CachedNvData из прошлой статьи, все параметры должны быть зарегистрированы в едином списке, причем, в этом списке мы можем регистрировать как и CachedNvData , так и наши AntiWearNvData параметры.

Я немного переделал список, так как IAR компилятор все еще не понимает много фишек из С++17, и собственно теперь список принимает только типы, а не ссылки на параметры. Кроме того, теперь у него появились методы SetToDefault и Init . Первый нужен, например, чтобы сбросить все параметры в их начальное значение. А второй, чтобы проинициализировать кешируемые в ОЗУ копии.

Также в CachedNvData я добавил параметр recordSize и recordCounts = 1 . Чтобы расчет адреса параметра был унифицирован для разного типа параметров.

Результат

Собственно все, теперь мы можем регистрировать в списке любые параметры:

Замечу, что пользователю параметров нужно только объявить параметр и список, а вся портянка с кодом, до этого, пишется один раз. Используются параметры точно также как и CachedNvData .

Что произойдет в этом примере, когда мы будем писать 10,11,12. 15 в наш параметр. Каждый раз при записи, адрес параметра будет смещаться на размер параметра + размер индекса + размер копии параметра и индекса. Как только количество записей превысит максимальное количество, параметр начнет писаться с начального адреса.

На картинке снизу как раз видно, что число 15 с индексом 5 записалось с начального адреса, а 10 теперь нет вообще.

В данном случае после сброса питания, при инициализации, будет найдена запись с индексом 5 и значением 15 и это значение и индекс будут записаны в кэшируемую копию нашего параметра.

Вот и все, надеюсь в этой статье цель получилось пояснить более детально, спасибо за то, что прочитали до конца.

Прочесть память. Как крадут прошивку устройств и как от этого защищаются

Статья написа­на по мотивам док­лада Демида Узень­кова — спе­циалис­та ком­пании ИНФО­РИОН. Выс­тупле­ние сос­тоялось на кон­ферен­ции RuCTFE 2020. За помощь в под­готов­ке пуб­ликации редак­ция бла­года­рит коман­ду «Ха­кер­дом».

Как ты пом­нишь, у лам­повых при­емни­ков не было никаких про­шивок, а единс­твен­ное, что мог­ло помешать тво­ему любопытс­тву, — это анод­ное нап­ряжение, которое, впро­чем, хотя бы не напада­ло на тебя само. Сей­час же все по‑дру­гому: мне попада­лись устрой­ства, которые агрессив­но про­тиво­дей­ство­вали мне с самого начала, еще на эта­пе раз­борки кор­пуса. С него мы и нач­нем.

Вскрытие

Пер­вое, что тебя может ждать на пути к завет­ной памяти с про­шив­кой, — это хорошо зак­рытый кор­пус. Вро­де бы никаких проб­лем: взял крес­товую отвер­тку… Пос­той, а точ­но ли крес­товую? Сей­час сущес­тву­ет минимум пара десят­ков форм головок вин­тов, и, конеч­но, далеко не все они откру­чива­ются нор­маль­ными челове­чес­кими инс­тру­мен­тами. Для раз­борки одно­го устрой­ства, нап­ример, мне приш­лось над­филем выпили­вать из плос­кой отвер­тки нуж­ную фор­му.

О труд­ностях с вин­тами мож­но почитать в статье на Egear.

До­пус­тим, ты подоб­рал (или сде­лал) отвер­тку нуж­ной фор­мы. Молодец! Откру­тил вин­ты, под­нял крыш­ку, пос­лышал­ся треск тек­сто­лита — и устрой­ство мож­но отправ­лять на помой­ку. Все потому, что пла­та в тво­ем гад­жете не прос­то бол­тает­ся внут­ри кор­пуса, а слож­ным обра­зом объ­еди­нена с раз­ными его час­тями. Обыч­но это дела­ется с помощью спе­циаль­ных защелок, которые встав­ляют­ся в отвер­стия пла­ты, а при раз­борке кор­пуса лома­ют ее, делая даль­нейшее изу­чение бес­полез­ным.

Или треск не пос­лышал­ся. Тог­да ты под­клю­чаешь­ся к тому, что обна­ружил, чита­ешь память, а чита­ются одни нули. Как такое мог­ло про­изой­ти? Сов­ремен­ные тех­нологии поз­воля­ют про­изво­дить кро­хот­ные SMD-фото­эле­мен­ты, вро­де фотот­ранзис­торов, которые обыч­но при­меня­ются в такой защите. Ког­да устрой­ство обна­ружи­вает, что на его пла­ту попада­ет хоть нем­ного све­та (даже через малень­кое отвер­стие в кор­пусе), про­шив­ка кон­трол­лера сти­рает­ся, а тебе оста­ется нефун­кци­ональ­ное устрой­ство. И хорошо, если защита не спа­лит чего‑нибудь физичес­ки!

В некото­рые устрой­ства, нап­ример бло­ки питания компь­юте­ров, про­изво­дите­ли встра­ивают сиг­наль­ную дымовую шаш­ку, которая сооб­щает о полом­ке. При ее сра­баты­вании аро­мат­ный синий дым отпра­вит тебя в магазин за новым бло­ком питания.

Де­ло в том, что неп­ривыч­ный к подоб­ным фокусам взор не может сра­зу отли­чить фотот­ранзис­тор от того же све­тоди­ода, да и при­выч­ный тоже вряд ли с ходу спра­вит­ся. Если вооб­ще заметит.

Осмотр платы

Ес­ли вскры­тие не показа­ло, что паци­ент умер от вскры­тия, я сна­чала осматри­ваю пла­ту в поис­ках пинов отла­доч­ных интерфей­сов — обыч­но это JTAG или UART. Глав­ная проб­лема не в том, что нуж­ные кон­такты могут быть в очень неожи­дан­ных мес­тах, а в том, что обыч­но они отклю­чены. Конеч­но, даже в 2021 году все еще хва­тает уни­кумов, которые отправ­ляют в прод устрой­ства с вклю­чен­ным UART, но количес­тво таковых стре­митель­но пада­ет.

Ес­ли тебе не повез­ло — вари­антов нем­ного: или пла­кать в подуш­ку, или искать чип памяти на бор­ту и читать его непос­редс­твен­но.

И вот с этим тебя ожи­дает уйма инте­рес­ного! Думал, нуж­но прос­то вытащить вось­миногую мик­руху в DIP-кор­пусе, похожую на ста­рый чип с BIOS? Как бы не так! Сей­час есть минимум четыре отно­ситель­но широко при­меня­емых вида памяти, и некото­рые из них могут быть похожи друг на дру­га так, что не раз­личишь.

Память

Преж­де чем я рас­ска­жу, что и как делать с памятью, давай сна­чала раз­берем­ся, какая она вооб­ще быва­ет и как ее отли­чить от дру­гих ком­понен­тов на пла­те.

По опы­ту про­цес­сор (на скрин­шоте выше по цен­тру) обыч­но квад­ратной фор­мы и исполня­ется в BGA, а память пря­моуголь­ная и дела­ется в SOP-кор­пусах.

Час­то в уль­тра­пор­татив­ных вычис­литель­но мощ­ных устрой­ствах (смар­тфо­нах, нап­ример) исполь­зует­ся бутер­брод из про­цес­сора и памяти — так мень­ше раз­меры и задер­жки при работе. Форм‑фак­тор, конеч­но, BGA — прос­то потому, что ничего дру­гого в кро­хот­ный кор­пус запих­нуть нель­зя.

ROM — пос­тоян­ную память — отли­чить доволь­но лег­ко. Пред­положим, чип с ней ты уже нашел. Теперь давай раз­берем­ся, какая она быва­ет.

Нас инте­ресу­ет EEPROM (Electrically Erasable Programmable Read-Only Memory), FRAM (сег­нето­элек­три­чес­кая память) и NOR/NAND flash — они тебе уже и так зна­комы. Из них ты мог не слы­шать толь­ко о FRAM — ее начали при­менять око­ло пяти лет назад, так что она еще не осо­бо популяр­на.

EEPROM

Сре­ди осо­бен­ностей этой памяти — побай­товые чте­ние и запись. Такая память самая дол­говеч­ная: по рас­четам, она может сох­ранять информа­цию в течение при­мер­но двух­сот лет! Но за надеж­ность при­ходит­ся пла­тить — глав­ным обра­зом объ­емом, с которым у это­го вида памяти все пло­хо: типич­ный объ­ем такого чипа изме­ряет­ся в килобай­тах. Из‑за низ­кого объ­ема для хра­нения про­шивок этот тип памяти поч­ти не при­меня­ется. Ну а раз загово­рили о минусах — сто­ит и о низ­кой ско­рос­ти ска­зать.

Устройство ячейки памяти EEPROMУс­трой­ство ячей­ки памяти EEPROM

Ре­сурс ячей­ки — око­ло мил­лиона цик­лов переза­писи. По срав­нению с сов­ремен­ными ячей­ками NAND, у которых этот показа­тель находит­ся в пре­делах нес­коль­ких десят­ков тысяч цик­лов, EEPROM-память прос­то нере­аль­но надеж­ная.

Продолжение доступно только участникам

Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

Добавить комментарий

Ваш адрес email не будет опубликован.