Запустить код один раз после программирования

Я использую EEPROM для энергонезависимого хранения настроек проекта. После повторной загрузки скетча на мою плату (через SPI через ArduinoISP) EEPROM сбрасывается до полного значения 0xFF, и мне приходится вручную выполнять «программный сброс» с помощью второго переключателя, который инициализирует EEPROM с помощью его значения по умолчанию.

Можно ли запустить сегмент кода один и только один раз после первой загрузки после программирования?

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

, 👍5

Обсуждение

Лично я считаю, что ваш путь очень прост: запрограммируйте бит EEPROM, установите его и измените после выполнения однократной инициализации. Это также очень гибко, если вы хотите сделать это несколько раз (например, просто используйте счетчик в EEPROM). Или, если инициализация выполнена неправильно, можно не сбрасывать бит., @Michel Keijzers

измените настройку высокого предохранителя в файле boards.txt, чтобы сохранить содержимое EEPROM у интернет-провайдера., @Juraj

@Juraj Решение с предохранителем сработало, хотя пришлось прошивать вручную через avrdude (D6 вместо DE). Это нормально, что изменение его в boards.txt не приведет к обновлению при прошивке (/прошивка с помощью ArduinoISP)?, @towe

Фьюзы записываются только тогда, когда вы выбираете опцию «записать загрузчик» в Arduino IDE. PS Вы также можете использовать AVRdude для прямой записи в EEPROM., @Gerben

см. пример eeprom_crc библиотеки EEPROM, @Juraj


2 ответа


8

Это проблема X->Y. Вот решение для X:

Бит 3 старшего предохранителя ATmega328p контролирует, сохраняется ли память EEPROM при стирании микросхемы. Вы можете изменить настройку высокого напряжения в файле boards.txt. Перезапустите IDE, чтобы применить новые настройки.

Фьюзы записываются, когда вы выбираете опцию «записать загрузчик» в Arduino IDE.

,

@TobiasWeiß, ты можешь принять ответ, @Juraj

Мне кажется, что редактирование файла boards.txt немного менее «переносимо», чем мне бы хотелось. Я считаю, что проверка того, является ли EEPROM, который гарантированно равен 0 после инициализации, равен 1 (после перепрошивки), является более чистой., @towe

портативный? кто-нибудь еще прошьет его через провайдера?, @Juraj

Да, к сожалению. Я описал, как подключить ArduinoISP к плате проекта и как прошить его с помощью IDE, но редактирование файла кажется слишком сложным., @towe


2

На самом деле я немного повозился с подобными вещами или, альтернативно, с тем, как обеспечить форматирование предыдущих настроек EEPROM (или аналогичных) при загрузке нового скетча.

Есть два значения (в данном случае макросы C), которые встроены в программу при ее компиляции (для Arduino программа перекомпилируется при каждой загрузке), которые можно использовать для определения того, является ли программа «свежей». "

Вам нужны следующие значения: __DATE__ и __TIME__. Они преобразуются в массивы символов (в основном строки) во время запуска компилятора. Вы можете сохранить их непосредственно в EEPROM или использовать какой-либо хэш, чтобы преобразовать его в удобное число для хранения. Затем при каждой загрузке кода сравнивайте сохраненное значение со значением, вычисленным на основе значений, закодированных в программе. Если они различаются, перезапишите сохраненное значение новым и выполните однократный код.

Что-то вроде

byte i=0;
char checkVal[]=__TIME__ __DATE__;
for (int j=0; j<strlen(checkVal); j++){
  i+=(byte)checkVal[j];//Создает сумму по модулю 256 значений ASCII символов (действительно плохой хэш)
}
if(EEPROM.read(26)!=i){//сохраненное местоположение EEPROM (произвольное) – не стесняйтесь использовать выравнивание износа или какой-либо другой метод
  //ЗДЕСЬ ВЫПОЛНЯТЬ ОДИН РАЗ КОД
  EEPROM.write(26,i);//сохраняем новое значение, чтобы остановить его повторный запуск
}
,