Как создать файл eep

Обновлено: 04.07.2024

При программировании микроконтроллеров AVR иногда возникает потребность сохранять данные, которые бы после выключения питания или сброса контроллера не изменяли свое значение. Для этих целей в составе AVR есть энергонезависимая память данных EEPROM (Electrically Erasable Programmable Read-Only Memory — электрически стираемое перепрограммируемое ПЗУ).
EEPROM имеет адресное пространство отличное от адресных пространств ОЗУ и flash памяти, в котором можно читать и записывать одиночные байты. В зависимости от модели микроконтроллера EEPROM может иметь объем от 512 байт (как, например, в микроконтроллере atmega16) до нескольких килобайт. Гарантированное количество циклов перезаписи этой памяти составляет не меньше 100000.
В этой статье на примере atmega16 мы разберемся, как работать с этим типом памяти, какие возможные проблемы при этом могут возникать и как с ними бороться.

Использование EEPROM начинается с объявления переменных, хранящиеся в этой памяти. Синтаксис объявления таких переменных отличается от объявлений обычных переменных (хранящихся в ОЗУ) только наличием ключевого слова. В зависимости от компилятора данное ключевое слово может разным.


Объявление переменной в EEPROM для IAR AVR и CodeVision AVR:

Объявление переменной в EEPROM для AtmelStudio 6:

При объявлении переменных в EEPROM их можно инициализировать, то есть присвоить начальные значения.

Инициализацию переменных хранящихся в ОЗУ компилятор "запихивает" в начало программы микроконтроллера - перед вызовом функции main. И она выполняется каждый раз, когда на микроконтроллер подается питание или происходит его сброс.
С EEPROM переменными ситуация немного другая, их должен инициализировать сам пользователь путем программирования EEPROM специальным файлом (с расширением .eep).
Как сгенерировать файл для EEPROM? Если в коде есть инициализация EEPROM переменных, то AtmelStudio 6 и CodeVision AVR создадут этот файл автоматически. А вот в IAR`e для этого нужно прописывать линкеру команды. Делается это так.
Меню Project > Options. >Linker вкладка Output. Устанавливаем значения по умолчанию - галочка Override default снята, формат - Debug information for C-SPY. На вкладке Extra Options ставим галочку Use Command Options и в окошке ниже прописываем такие строчки:




После компиляции и сборки проекта IAR создаст файл прошивки - .hex и файл для EEPROM`a - .eep

Полученный eep файл записывается с помощью программатора в микроконтроллер.

В IAR`e и CodeVision AVR использование EEPROM переменных по сути ничем не отличается от использования обычных переменных (хранящихся в ОЗУ и регистрах). Вся работа по организации чтения и записи в эти EEPROM переменные выполняется компилятором.

В AtmelStudio для чтения/записи EEPROM переменных используются специальные макросы. Они определены в файле eeprom.h. Вот некоторые из них:

Макросы принимают в качестве параметра адрес переменной размещенной в EEPROM. Для взятия адреса переменной используется оператор &. Примеры ниже поясняют использование этих макросов.

Из этой статьи вы узнали:

- как объявить переменную в EEPROM памяти,
- как создать файл для инициализации EEPROM,
- как прочитать и записать данные в EEPROM.

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

WinAVR IDE

Для работы с исходными текстами подойдёт компонент WinAVR – Programmers Notepad (\hardware\tools\avr\pn\pn.exe) — удобный редактор программиста и интегрированная среда разработки (IDE):

Для более подробного знакомства со средой разработки WinAVR рекомендую статьи
Среда разработки WinAVR.
Makefile и компиляция программы.

Возьмём пример из второй статьи и адаптируем его для Arduino:

Создаём файл avrblink.c

— адаптировали, изменив частоту на 16МГц и время задержки ;) Однако, как видно в исходнике – сейчас МК мигает всем портом D! Т.е., если посмотреть Arduino Pin Mapping – цифровыми выходами, начиная с digital pin 0 и заканчивая digital pin 7.

В WinAVR исходный текст программы компилируется при помощи утилиты make.exe, которая находится в папке WinAVR\utils\bin. Make.exe контролирует генерацию исполняемых файлов из исходного кода программы. Для управления работой этой утилиты используют make-файлы. Make-файл сообщает компилятору, какие команды запускать, какие файлы компилировать и линковать, какой выходной код генерировать и т. д.

Копируем в директорию с нашим .c-файлом Makefile–образец (\hardware\tools\avr\sample\ Makefile)
и вносим требуемые изменения:

указываем тип микроконтроллера


Далее указываем частоту


название нашего проекта


Уровень оптимизации s – можно заменить на 0, чтобы отключить оптимизацию


Тип и порт программатора

Прописываем пути к нужным директориям:
c:\utils\arduino-0016\hardware\tools\avr\utils\bin\
c:\utils\arduino-0016\hardware\tools\avr\bin\
c:\utils\arduino-0016\hardware\tools\avr\avr\bin\
в переменную среды PATH, перезагружаемся и пробуем снова

В ОС Windows это делается через Мой Компьютер — Свойства — Дополнительно — Переменные среды. Выбираете PATH, щёлкаете изменить и через точку с запятой добавляете нужные пути.

WinAVR IDE


Получилось!
А в директории рядом с нашим avrblink.c и Makefile появилось много интересного:
— .dep/avrblink.o.d
— avrblink.eep
— avrblink.elf
— avrblink.hex
— avrblink.lss
— avrblink.lst
— avrblink.map
— avrblink.o
— avrblink.sym

Самый важный из этих файлов — это avrblink.hex. В нем хранится шестнадцатиричный код для загрузки в память программ (Flash ROM) микроконтроллера.

А avrblink.eep — хранит шестнадцатиричный код для загрузки в энергонезависимую память данных (EEPROM).

Мигает :)
Однако, нужно привести нашу программу ближе к стандартному Blink-у и помигать одним встроенным светодиодом на digital pin13. Как видим по схеме или по Arduino Pin Mapping – это пятая линия порта B.

Читаем крайне познавательную статью
AVR GCC :: Управление портами микроконтроллера AVR.
и вносим нужные изменения в нашу программу:

UPD — обновлённая версия для новых версий компилятора:


Компилируем, загружаем в протеус – работает!
Сравним размеры файлов :)
Ардуиновский Blink.hex весит 2031 байт
Наш hex при оптимизации по размеру (OPT = s) по размеру весит 410 байт

а с отключённой оптимизацией (OPT = 0) все 3184 байта!

Теперь осталось разобраться как же в реальности прошить наш .hex в ардуину :)
Например, можно воспользоваться каким-нибудь программатором :)
Однако, у нас ведь есть загрузчик и поэтому можем просто воспользоваться родным приёмом ардуины – самопрограммированием МК.
В любом случае, нам понадобится воспользоваться утилитой AVRDUDE, которая идёт в составе WinAVR и находится внутри Arduino IDE (\hardware\tools\avr\)

AVRDUDE позволяет загружать программы и данные в память микроконтроллера, а также считывать их оттуда. AVRDUDE использует SPI-интерфейс. Существуют версии для Windows и Linux. Первоначальный код был написан Брайеном Дином (Brian S. Dean) и имел название avrprog.

При использвании ардуиновского «параллельного программатора» или популярных для LPT – пяти проводков – нужная дополнительная настройка:

В Windows 2000 и Windows XP запрещена прямая работа с параллельным (LPT) портом, поэтому для нормальной работы AVRDUDE необходимо установить драйвер giveio.sys. Для установки этого драйвера зайдите в папку WinAVR\bin и запустите файл install_giveio.bat (удалить драйвер из системы можно, запустив файл remove_giveio.bat).
В Windows 98 никаких специальных настроек не требуется.

Как видим, всё что делает программа — это формирует команду вида:


разберёмся, что значат все эти параметры:

-F: Игнорировать проверку соединения с МК. Разумеется, такая проверка желательна – поэтому использование этого флага стоит избегать.

-v: так называемый «многословный» (verbose) вывод – полезно для контроля и отладки.

-p : Указываем тип МК для программирования. Например, если бы был ATtiny2313, здесь нужно было бы написать: attiny2313. Мы же указываем нашу атмегу :)
m8 ATmega8
m16 ATmega16
m32 ATmega32

-c : Указываем тип программатора. Если используется STK500 — пишем stk500 и т.д.

-P : указывается коммуникационный порт, к которому подключён программатор. Это может быть COM1 или LPT1 или даже USB.

-b : Указывается скорость для работы с последовательным портом – нужно для программаторов, работающих через COM-порт – таких как STK500.

-D: Отключаем очистку МК перед прошивкой.

-U :r|w|v:[:format]: Самая важная команда – выполнение прошивки.
— тип памяти МК — flash или eeprom (или hfuse, lfuse, efuse для конфигурации фьюзов МК).
r|w|v – флаги определяют, что мы хотим сделать:
r (read — считать)
w (write — записать)
v (verify — проверить).
файл для записи или чтения.
[:format] флаг формата данных. Здесь всегда используется формат «Intel Hex», поэтому стоит i
Таким образом, командой -Uflash:w:«file.hex»:I – мы записываем файл file.hex в FLASH-память МК. Если нам потребуется считать eeprom-память в файл «eedump.hex» – мы напишем -Ueeprom:r:eedump.hex:i

Дополнительные параметры AVRDUDE:

список параметров с их кратким описанием можно получить просто запустив avrdude без параметров или с параметром -?
А более подробную документацию можно найти здесь(\hardware\tools\avr\doc\avrdude\avrdude.pdf).


Ну что же – пробуем прошить. Жму Reset на плате и сразу кнопку “Program”

Ошибка!

AVRDUDE пишет, что не находит своего конфигурационного файла :(
Хм… попробуем ему помочь – дописываем в конец строчку:



И снова перезагружаю плату и жму “Program”.

Ура! Получилось! Пойду допишу об этом нюансе на сайт ардуины ;)

Вот так – научились загружать в ардуину другие программы, которые можно писать хоть на ассемблере! :)

А так же теперь становится понятно, насколько Arduino IDE упрощает процесс программирования микроконтроллеров! :)

Скетч WinAVR-кого Blink-а, перенесённый в Arduino IDE

Комментарии ( 23 )

> Получилось!
У меня ничего не получилось. arduino IDE 18 версии. 17 ошибок в том числе синтаксные. ЧЯДНТ? Возможно у Вас WinAVR установлен в директорию, содержащую в своем имени пробелы или скобки

Здравствуйте!
Не получается. При компиляции выдает ошибку:
avrblink.c:29: fatal error: opening dependency file .dep/avrblink.o.d: No such file or directory

В чем может быть дело? На компе Win7

Попробуй такой Makefile:


Немножко пояснений (:

Переменная MCU — модель микроконтроллера, FREQUENCY — его частота, CC — компилятор, CFLAGS — опции компиляции:
Правило поясняет утилите make, что all и clean могут быть только именами целей, но не файлов.

Первая цель будет собираться утилитой make по умолчанию, если не указать при вызове других целей. Зависит от цели $(FIRMWARE) (у нас это файл avrblink.hex).

Следующая цель зависит от цели $(COMBINED) (файл avrblink.out) и вызывает утилиту avr-objcopy для преобразования собранной цели $(COMBINED) в hex-файл $(FIRMWARE) (avrblink.hex).

Цель зависит от $(OBJS) — списка объектных файлов, которые эта цель слинкует в один файл $(COMBINED).
Цель $(OBJS) соберётся автоматически, т.к. make автоматически вызовет компиляцию .c-файлов в .o-файлы благодаря заданной ранее цели ".c.o".
Ну а цель clean — это чистка «мусора», т.е. всего, что получается после компиляции: пишешь команду make clean и мусора как не бывало.

Можешь для пущего счастья ещё добавить какую-нибудь цель upload, загружающую прошивку на МК, типа:
тогда можно будет командой make upload собрать проект и тут же его залить на МК. Проект соберётся автоматически, так как мы указали, что цель upload зависит от цели $(FIRMWARE).

Любой файл в цифровом мире имеет имя и расширение, которое указывается после точки (если в Вашей ОС не указаны расширения файлов см. Пуск => Панель управления => Параметры папок ). Необходимо расширение для того, чтобы понимать какой тип данных находится в файле и какую программу для его открытия запустить. Например, на стройке есть разные виды гвоздей и когда строителю нужно заколотить гвоздь, то он понимает, что нужен молоток, который является инструментом (программой), а гвозди могут быть совсем разные: 5*50мм гвоздь или кровельный гвоздь или 35мм финишный оцинкованный гвоздь и все эти гвозди как файлы имеют расширение (признак принадлежности к типу) гвоздь и для всех их нужен молоток. Если взять шуруп, то понятно, что нужен другой инструмент и молотком тут не поможешь.

https://alexragulin.ru/img/lesson/69/69d131fb56eef57d5d654e7e43caaec320210327102424.jpg

Расширение файла — это идентификатор, показывающий компьютеру или пользователю, какую программу нужно применить для данного файла.

Прошивки в бытовой технике, как правило, применяются в форматах .bin или .eep , при этом многие программаторы поддерживают гораздо больше расширений, а некоторые могут работать только с файлами одного расширения (например, программатор USBDM работает с расширение .S19 см. урок 5)

Файл может быть переименован пользователем, но при этом содержимое его не изменится, а меняется только программа, которая его запускает (показывает, выполняет, позволяет редактировать и т. д.)

Для того, чтобы перевести из одного формата в другой существуют множество программ, которые называются конвертеры, которые работают по принципу переводчиков, переводя один язык в другой, но смысл (данные) остаются при этом неизменны. При подобном переводе (конвертации) очень важно чтобы соблюдались все условия и смысл (данные) был донесён 100% и для этого не подходит ни один человеческий язык, так как многие слова при переводе могут исказится, а вычислительная техника, которой отчасти является микроконтроллер, понимает только четкие команды (открыть воду, закрыть воду, вращать барабан влево 50 оборотов в минуту), стиральной машине нельзя сказать постирай как постираешь, она не может принимать решения, когда хватит и сколько продолжать, поэтому в цифровом мире используют язык цифр.
Три записи одного и того же, но на разных языках

Разные системы исчисления

Т.е. одно и тоже можно записать на разных языках, но всегда означает одно и тоже, каждому символу в ASCII характерно два символа в 16-ричном виде, которым характерен, в свою очередь, уникальный набор 0 и 1(бит) в количестве 8, что равно одному байту. Если прошивка имеет размер 512 байт, значит там 512 символов ASCII или 512 групп из 8 символов 0 или 1.
Любой hex-редактор (редактор 16-ричных файлов, как правило, прошивок) имеет 3 поля, первое поле это адрес строки, второе поле это данные в 16 ричном(hex) формате(виде) и третье поле, это те же данные только в формате ASCII. Нужно это для большей наглядности во время визуального анализа данных.

какие данные внутри прошивки

В прошивках стиральных машин очень часто встречается понятие перевернутого байта, это означает что данные внутри файла перевернулись по каким либо причинам, возможно программатор так сохранил данные, у некоторых микросхем, так они сохраняются и т.д. нам это не особо важно, то что нам действительно важно, дак это то, что данные в такой прошивки могут не приняться нашим процессором и как многие неверно полагают, «перевернутость байта» не зависит от формата, так как пользователь может сам как угодно назвать файл. Поэтому нужно смотреть на данные внутри файла с помощью наших hex-редакторов и тут нужно разделить прошивки на множество платформ и на примере двух мы постараемся понять (в общем) как они устроенный (см. урок 4). Для перевода из обычного формата в перевернутый или наоборот, достаточно загрузить ее в любой Hex-редактор и нажать перевернуть

Формат S19

С появление новых модулей управления Arcadia, к нам стал пробиваться формат S19 или SREC, текстовый формат прошивок, применяемых на процессорах Freescale от Motorolа, который имеет ряд особенностей в построение и открывается в любом текстовом редакторе.

что такое прошивка в формате S19

Разные форматы прошивок

Это один и тот же файл только показанный в разных форматах, как видно, ничего сложного в том чтобы выявить закономерность, но как мы знаем полная прошивка микроконтроллера (см. Урок 1) состоит не только из конфигурационных данных, но и из основной прошивки, данные которой и дописывает конвертер S19 в начало и конец config, поэтому на выходе мы получаем файл гораздо большего размера (около 150 кб по сравнение с 6-8 изначальным размером).

Читайте также: