Создать систему горячей замены прошивки на Arduino Nano?

Разрешает ли архитектура Arduino Nano разрабатывать Sketch, разделенный на два сегмента:

  1. Тот, который принимает через CAN-шину новую версию прошивки и записывает ее во второй сегмент. Цель первого сегмента — срабатывать только при передаче данных.
  2. Сама прошивка.

Я представляю это так:

void loop(){
  
  if (CAN.onReceive(...)){
    // первый сегмент
  }
  else{
    // второй сегмент
  }

}

После завершения передачи скетч просто запускается с обновленным кодом. Это возможно?

, 👍1


2 ответа


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

2

InternalStorageAVR в моей библиотеке ArduinoOTA может записывать двоичный файл в верхнюю половину флэш-памяти классического AVR MCU. Библиотека не позволяет использовать его с Nano из-за малого размера флэш-памяти, но проверку легко снять.

См. расширенный пример OTASketchDownload о том, как использовать InternalStorage с вашим собственным способом загрузки двоичного файла обновления.

InternalStorageAVR требует модифицированного загрузчика Optiboot с функцией copy_flash_pages. Hex-файл с модифицированным загрузчиком доступен в репозитории my_boards GitHub.

использование InternalStorage

  if (!InternalStorage.open(length)) {
    client.stop();
    Serial.println("There is not enough space to store the update. Can't continue with update.");
    return;
  }
  byte b;
  while (length > 0) {
    if (!client.readBytes(&b, 1)) // чтение байта с таймаутом
      break;
    InternalStorage.write(b);
    length--;
  }
  InternalStorage.close();
  
  if (length > 0) {
    Serial.print("Timeout downloading update file at ");
    Serial.print(length);
    Serial.println(" bytes. Can't continue with update.");
    return;
  }

  Serial.println("Sketch update apply and reset.");
  Serial.flush();
  InternalStorage.apply(); // это не возвращает
,

да, это упомянуто в ответе. в ArduinoOTA.h и в InternalStorageAVR.cpp есть #if FLASHEND >= 0xFFFF, @Juraj

Юрай, когда я пытаюсь запустить ваш пример OTASketchDownload, выводится следующее: «Ошибка: «InternalStorage» не был объявлен в этой области. Примечание: предлагаемая альтернатива: «ExternalOTAStorage»». Не могли бы вы подсказать, как это исправить?, @Andrew's Quest

Юрай, можешь пожалуйста уточнить, куда InternalStorage помещает сохранённые байты и как их можно считать обратно? Я просмотрел всю документацию, которую нашёл, но так и не понял., @Andrew's Quest

просто используйте apply(), и он с помощью загрузчика скопирует его по адресу 0 и сбросит MCU. Больше вы ничего с ним сделать не сможете., @Juraj

предположим, я хочу протестировать его локально — в каком формате мне следует передать ему новую версию скетча?, @Andrew's Quest

Формат bin. Скопируйте platform.local.txt из папки extras/avr библиотеки, рядом с platform.txt в пакете boards. Перезапустите IDE. Используйте Export binary из меню Sketch. Это поместит файл .bin рядом с .ino., @Juraj

Он действительно создал для меня файл new_version.bin.ino, но как мне отправить его на плату и заставить InternalStorage прочитать его?, @Andrew's Quest

стандартный способ загрузки библиотеки — загрузка из IDE через WiFi или Ethernet-шилд. другие варианты — загрузка по сети, чтение с SD-карты, чтение с последовательного порта, I2C или любой другой способ передачи, который вы можете реализовать в своем скетче, @Juraj

Юрай, я понимаю, что это уходит далеко от темы этого вопроса, поэтому я задал еще один: https://arduinoprosto.ru/q/95996/how-to-send-a-binary-file-to-a-nano-board-through-an-isp-connection-using-arduin. Буду рад, если ответишь., @Andrew's Quest


2

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

Я понимаю, что получение файла через CAN отличается, но я ожидаю, что большинство основных идей те же самые. Одним из преимуществ SD-карты является то, что весь файл может быть проверен перед записью во флэш-память. У Nano недостаточно оперативной памяти для хранения всех 32 КБ, поэтому я ожидаю, что вам придется делать это «в реальном времени» через CAN.

https://github.com/zevero/avr_boot — один из примеров, поддерживающий ATmega328P (поэтому он должен быть совместим с Nano).

Но по сути то, что вы ищете, — это настроенный загрузчик.

,