добавить идентификационный номер в загрузчик 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 будут знать, что нужно записать эти данные в нужное место, но не уверен.
У кого-нибудь есть опыт? Делали это раньше?
@codeScriber, 👍1
Обсуждение1 ответ
Лучший ответ:
На самом деле это довольно легко исправить.
Проблема здесь в том, что компилятор не считает, что 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 байт флэш-памяти (хотя вам это делать не обязательно).
- Вам следует уменьшить
FLASHна 8 байт. - В расчет
__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
- Высокочастотный PWM на Adafruit Feather M0
- Проблемы загрузки нулевого загрузчика arduino в atsamd21g18a
- Как получить более быструю загрузку с Adafruit Feather SAMD21?
- Если я использую clock_prescale_set в своем скетче, я потеряю доступ к adafruit feather 32u4?
- Как записать загрузчик?
- Разница в загрузчике Arduino Nano ATmega328P
- Не удается снова загрузиться после смены платы
- Почему я получаю avrdude: stk500v2_ReceiveMessage(): timeout error when uploading to Arduino Mega?
вместо 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