Когда вы включаете следующий код в источник AVR C, вы, очевидно, можете напрямую программировать предохранители, без необходимости в дополнительной команде или файле .hex:
#include <avr/io.h>
FUSES = {
.low = LFUSE_DEFAULT ,
.high = HFUSE_DEFAULT ,
.extended = EFUSE_DEFAULT ,
};
Есть ли подобная хитрость для программных значений в EEPROM?
Я проверил, /usr/lib/avr/include/avr/fuse.h
где я могу найти некоторые комментарии о макросе, но я не могу найти подобный комментарий в нем, /usr/lib/avr/include/avr/eeprom.h
и интерпретация материала препроцессора немного выходит за рамки моей лиги.
Было бы очень удобно, если бы я мог включить значения EEPROM по умолчанию в исходный код C. Кто-нибудь знает, как этого добиться?
edit1:
Этот трюк FUSES выполняется только во время ISP, а не во время RUN. Таким образом, в результирующем коде сборки в контроллере нет программируемых предохранителей. Вместо этого программист автоматически проходит дополнительный цикл программирования FUSES.
edit2:
Я использую набор инструментов avr-gcc и avrdude в Linux.
Ответы:
С avr-gcc
EEMEM
макрос может быть использован для определения переменной, смотритеlibc
документацию и пример здесь :объявляет массив символов в разделе с именем «.eeprom», который после компиляции сообщает программисту, что эти данные должны быть запрограммированы в EEPROM. В зависимости от вашего программного обеспечения, вам может понадобиться явно указать имя файла «.eep», созданного в процессе сборки, или он может неявно найти его сам.
источник
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 ihex $(src).elf $(src).eeprom.hex
avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U eeprom:w:$(src).eeprom.hex
Да, вы можете вручную записать данные по умолчанию в EEPROM в исходном коде. Во-первых, ознакомьтесь с этим удивительным руководством по EEPROM с AVR: учебное пособие по AVR EEPROM Дина. Кроме того, я должен добавить, что лучше создать файл .eep, содержащий данные EEPROM, используя make-файл, который будет запрограммирован на устройстве вместе с исходным кодом. Однако, если вы не знакомы с различными операциями make-файла и компоновщика, это все равно можно сделать из файла исходного кода - это произойдет, как только цепь запитается, что остановит начальную операцию программы.
В начале программы (перед любым видом основного цикла) вы можете сделать что-то вроде этого:
Функция «update» сначала проверяет, существует ли это значение, чтобы сэкономить на ненужных записях, сохраняя срок службы EEPROM. Тем не менее, выполнение этого для очень многих мест может занять довольно много времени. Может быть, лучше проверить одно место. Если это желаемое значение, то остальные обновления можно полностью пропустить. Например:
Если вы хотите обновить большие объемы данных, попробуйте использовать другие функции, такие как
eeprom_update_block(...)
. И обязательно прочитайте этот урок; это хорошо написано.Вы можете поместить все операторы обновления EEPROM в один условный оператор препроцессора. Это очень просто сделать:
Этот фрагмент кода даже не будет скомпилирован, если вы не выполните следующее:
Вы можете оставить это как комментарий, а затем раскомментировать, если вам нужно изменить значения EEPROM по умолчанию. Для получения дополнительной информации о препроцессоре C, ознакомьтесь с этим онлайн-руководством . Я думаю, что вы можете быть наиболее заинтересованы в разделах о макросах и условных выражениях.
источник
Ch. 7 Setting Initial Values
,EEMEM
переменных компилятор заботится о том, какая переменная находится в EEPROM. Таким образом, вы обращаетесь только к (постоянным, сгенерированным компилятором) указателям на переменные при доступе к данным. Если, с другой стороны, вы явно определяете адрес, где находится каждая переменная, вам придется самостоятельно позаботиться об этих адресах, в том числе убедиться, что никакие переменные не занимают случайно один и тот же адрес, перезаписывая друг друга; или перерасчет всех адресов в случае изменения размера хранилища переменной в будущем и т. д.