Принудительный запуск загрузчика через программу

Я пытаюсь выяснить, можно ли программно запустить функцию двойного нажатия кнопки сброса, реализованную в модифицированной версии загрузчика SAM-BA Atmel. Интересующая плата - Arduino Zero. В случае, если это невозможно с помощью стандартной настройки платы, если это может быть достигнуто путем модификации оборудования или загрузчика.

, 👍1


1 ответ


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

3

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

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

// zero specific; но другие платы используют те же значения AFAIK
// (в board_definitions_arduino_zero.h)
#define BOOT_DOUBLE_TAP_ADDRESS  (0x20007FFCul)
#define BOOT_DOUBLE_TAP_DATA  (*((volatile uint32_t *) BOOT_DOUBLE_TAP_ADDRESS))

// для всех загрузчиков (в main.c)
#define DOUBLE_TAP_MAGIC 0x07738135

Когда загрузчик запускается после сброса, он проверяет, был ли это сброс питания (POR) или нет. Если это был POR, он устанавливает значение индикатора равным 0 BOOT_DOUBLE_TAP_DATA = 0;.

Если он не обнаруживает POR, загрузчик продолжает проверять значение индикатора, установлено ли оно на магию крана.

Если волшебство найдено, то значение индикатора возвращается к 0 и запускается загрузчик. В противном случае значение устанавливается равным "double tap magic": BOOT_DOUBLE_TAP_DATA = DOUBLE_TAP_MAGIC. Загрузчик ждет 500 мс, чтобы позволить пользователю сбросить ноль во второй раз (двойное нажатие), и сбрасывает значение индикатора после этого интервала времени.


Как это сделать:

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


Предостережения:

  • Если загрузчик был изменен, это может сделать ваш код бесполезным.
  • У меня нет времени проверять свои идеи, так что это просто непроверенный метод. Он может потерпеть неудачу по каким-то причинам, которых я на самом деле не вижу.
  • Вы должны найти способ сбросить ноль с помощью программы. Я знаю некоторые методы, но до сих пор не пробовал ни одного из них.

Методы сброса: (в качестве отправной точки для вашего поиска)

Я где-то читал, что ноль поддерживает метод CMSIS NVIC_SystemReset.

Этот метод часто используется для контроллеров ARM M0 (например, SAMD11).

SCB_AIRCR = SCB_AIRCR_VECTKEY(0x5FA) | SCB_AIRCR_SYSRESETREQ_MASK;

Вот моя кодовая "идея" (непроверенная):

#define BOOT_DOUBLE_TAP_ADDRESS  (0x20007FFCul)
#define BOOT_DOUBLE_TAP_DATA  (*((volatile uint32_t *) BOOT_DOUBLE_TAP_ADDRESS))
#define DOUBLE_TAP_MAGIC 0x07738135

// много кода ....

void resetWithDoubleTap()
{
   BOOT_DOUBLE_TAP_DATA = DOUBLE_TAP_MAGIC;
   NVIC_SystemReset();
}

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

,

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