добавить идентификационный номер в загрузчик feather m0 (флеш)

Я пытаюсь добавить серийный номер в область флеш-памяти загрузчика платы Adafruit Feather m0. Похоже, область флеш-памяти 0-0x2000 Feather m0 недоступна для записи скетчем Arduino. Я хотел добавить серийный номер в область флеш-памяти 0x2000-8. Идея состоит в том, чтобы включить данные в загрузчик elf\bin, чтобы я мог легко прошить его на устройствах и позже получить к нему доступ, используя адрес флэш-памяти (0x2000 - 8) с помощью NVMCTRL.

Я начал с этого решения:

загрузил код из каталога загрузчика arduino samd21 на github и в ./bootloaders/zero отредактировал скрипт boololoader ld, сначала раздел «Память».

FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x2000 /* Первые 8 КБ используются загрузчиком */
FLASHID (rx) : ORIGIN = 0x00002000 - 0x0008, LENGTH = 8

Затем раздел «Разделы»:

.id_sec :
  {
    KEEP(*(.myid))
  } > FLASHID

Это должно было сэкономить немного места в конце флэш-памяти для идентификатора. Теперь в файле main.c:

__attribute__ ((section(".myid"))) const unsigned long ID = 0xdead1234;

Что должно было сохранить шестнадцатеричное значение 0xdead1234 по адресу (0x2000-8).

Проблема вот в чем: Я скомпилировал этот код и скомпоновал его без проблем, получил файлы .hex, .bin, .elf. Если я прав (если только они каким-то образом не сжаты), я должен увидеть код 0xdead в двоичном файле. НО я этого не делаю. После objdump на двоичном файле (любом из них) я не могу найти 0xde 0xad в каком-либо порядке где-либо еще. arm-none-eabi-size" --format=sysv -t -x build/.elf не отображает новый раздел, который я где-то добавил. Также мне интересно, как я уже сказал, адрес 0x2000 на флэш-памяти недоступен для записи после прошивки с помощью atmel-ice \j-link, даже код загрузчика не может записать туда запись. Я определил в скрипте ld, что мне нужна эта часть памяти флэш-памяти, поэтому я ожидаю, что компилятор + компоновщик + программа прошивки jlink будут знать, что нужно записать эти данные в нужное место, но не уверен.

У кого-нибудь есть опыт? Делали это раньше?

, 👍1

Обсуждение

вместо 0xde 0xad ищите 0xed 0xda ... возможно, он хранится в формате little endian, @jsotola

Ваш вопрос невероятно сложно читать. См. [Как задать хороший вопрос](https://arduino.meta.stackexchange.com/questions/2523/how-to-ask-a-good-question-for-arduino-stack-exchange). Уделите немного времени написанию абзацев, пишите «Я» с заглавной буквы и в целом объясните, что вы пытаетесь сделать., @Nick Gammon

@jsotola Я попробовал это, хорошо зная о порядке байтов. Я, по сути, просто попытался использовать objdump и xxd, а затем дважды выполнить grep: один раз для «ed» и один раз для «da», что должно охватить все возможные варианты., @codeScriber

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

Привет, @NickGammon, я немного изменил вопрос. Надеюсь, теперь он понятнее., @codeScriber

Перекрёстный пост [здесь](https://stackoverflow.com/questions/50113720/). Вопрос выглядит лучше, однако см. [Разрешена ли перекрёстная публикация вопроса на нескольких сайтах Stack Exchange, если вопрос соответствует теме каждого из них?](https://meta.stackexchange.com/questions/64068/) — вам нужно решить, на каком сайте вы хотите задать вопрос. Stack Exchange не позволяет вам задавать вопрос на нескольких своих сайтах., @Nick Gammon

Я могу их понять, хотя иногда мне кажется, что это несправедливо, так как вопрос хорошо подходит к любому из них. StackOverflow более общий, и это действительно вопрос по программированию, однако нужен кто-то, кто также прошивал загрузчик или выполнял определенную процедуру для встроенных устройств в прошлом. Думаю, что в основном я увижу это здесь. В любом случае удалил это со stackoverflow и опубликую заново, если не получу ответа здесь., @codeScriber

Вы знаете, что у samd21 уже есть уникальный серийный номер, [к которому вы можете получить доступ](https://gist.github.com/mgk/c9ec87436d2d679e5d08)., @Gerben


1 ответ


Лучший ответ:

3

На самом деле это довольно легко исправить.

Проблема здесь в том, что компилятор не считает, что const используется для чего-либо, поэтому он (совершенно справедливо) отбрасывает его.

Всё, что вам нужно сделать, это сообщить компилятору, что он используется, и всё должно быть хорошо:

__attribute__((section(".myid"),used)) const unsigned long ID = 0xdead1234;

И при компиляции:

build/.elf  :
section             size         addr
.vectors            0x40          0x0
.text             0x18d4         0x40
.data               0x5c   0x20000000
.bss               0x34c   0x2000005c
.id_sec              0x4       0x1ff8
.ARM.attributes     0x28          0x0
.comment            0x80          0x0
.debug_frame        0x68          0x0
Total             0x1dd0

Тем не менее, вам следует внести еще несколько изменений в скрипт компоновщика, чтобы должным образом изолировать эти 8 байт флэш-памяти (хотя вам это делать не обязательно).

  1. Вам следует уменьшить FLASH на 8 байт.
  2. В расчет __sketch_vectors_ptr следует включить длину FLASHID.

Это:

MEMORY
{
  FLASH   (rx) : ORIGIN = 0x00000000, LENGTH = 0x1FF8 /* First 8KB used by bootloader */
  FLASHID (rx) : ORIGIN = 0x00001FF8, LENGTH = 8
  RAM    (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000-0x0004 /* 4 bytes used by bootloader to keep data between resets */
}

И:

PROVIDE(__sketch_vectors_ptr = ORIGIN(FLASH) + LENGTH(FLASH) + LENGTH(FLASHID));

Таким образом, скомпилированный код загрузчика никогда не сможет быть помещен в область FLASHID (сейчас это невозможно, но если будет выпущена новая версия загрузчика, использующая 100% нижнего блока флэш-памяти, это приведет к конфликту).

Конечно, если вам нужно лишь что-то уникальное для идентификации платы, все устройства AVR и SAMD со встроенной поддержкой USB имеют уникальный идентификационный номер. Он предназначен для использования в качестве последовательного порта USB, но также может использоваться в качестве MAC-адреса для Ethernet (или его частей) или других уникальных адресов «узлов».

,

Спасибо! Проверю сам, если действительно увижу, отмечу как решение., @codeScriber

@codeScriber, обратите внимание на комментарий о том, что у чипа уже есть уникальный идентификатор. Далее, если вы хотите сериализовать таким образом, после установки значений по умолчанию в компиляторе, на практике вам, вероятно, потребуется напрямую перезаписать значения в двоичном файле для прошивки (dd или многие другие инструменты могут записывать данные со смещением), а не перекомпилировать для каждого блока., @Chris Stratton

Я делаю нечто подобное, чтобы установить уникальное значение USERID на чипах PIC32 при программировании загрузчика из HEX-файла. Выделяю его из базы данных, затем фильтрую HEX-файл, изменяя значения, которые необходимо изменить, и пересчитывая контрольные суммы., @Majenko

@ChrisStratton, спасибо, именно это я и планировал сделать, хотя я планировал использовать для этого скрипт Python... но нет, я не знал, что у него есть серийный номер, и я его искал! Вы уверены, что он уникальный? На самом деле я искал уникальный идентификатор arm m0, а не samd21, возможно, моя ошибка была в этом..., @codeScriber

@Majenko Нужно, чтобы это сработало. Если я xxd -g0 для файла .bin, то в конце увижу: '00000000000000003412adde'! Отметил ваш ответ как решение, но, возможно, вам стоит скопировать замечание о том, что для samd21 уже есть уникальный идентификатор..., @codeScriber

Все компоненты AVR с USB имеют уникальный идентификатор, который используется в качестве серийного номера USB. Насчёт SAMD21 я не уверен — сверьтесь с техническим описанием., @Majenko

Из технического описания: «Каждое устройство имеет уникальный 128-битный серийный номер... Уникальность серийного номера гарантируется только при использовании всех 128 бит»., @Craig

Отлично. Я ещё не работал с этими чипами на низком уровне, но планирую это сделать в ближайшие месяцы, как и с серией E70. Скоро я стану по ним мировым экспертом :(., @Majenko