Даташит AVR103 рассматривает вопросы практического применения режимов программирования EEPROM микроконтроллеров AVR:
• Объясняется принцип доступа к EEPROM • Как уменьшить время обновления ячеек EEPROM до 50% • Реализация драйвера доступа к EEPROM • Обратно-совместимый код
В этом даташите показана реализация драйвера, использующего режимы программирования EEPROM, доступные в некоторых моделях микроконтроллеров AVR, таких как ATmega48/88/168, ATtiny13, ATtiny2313 и ATmega256x. Драйвер позволяет экономить как энергопотребление, так и время выполнения путем использования более эффективных режимов записи данных в память EEPROM. Правильное использование режимов программирования гарантирует, что ячейки EEPROM будут очищаться только тогда, когда это действительно необходимо.
Подробное описание операций очистки (EEPROM erase) и программирования дает понимание режимов программирования и их преимуществ. Использование драйвера из этого апноута может значительно увеличить быстродействие многих приложений, в которых используется EEPROM для энергонезависимого хранения параметров и флагов.
[Немного теории: как это работает]
Как устроена память EEPROM. Память EEPROM состоит из независимых ячеек, каждая представляет 1 бит. Принцип работы ячеек основан на технологии транзисторов с плавающим затвором: электрический заряд, захваченный затвором транзистора, определяет хранимый в ячейке логический уровень. Слегка упрощая, работу ячейки можно описать следующим образом: когда ячейка стирается (erase), заряд помещается на затвор и ячейка будет читаться как лог. 1 (состояние памяти по умолчанию). Программирование ячейки эквивалентно снятию разряда с затвора, что переводит логическое значение ячейки в 0. Можно запрограммировать (разрядить) только ту ячейку, которая ранее была стерта (заряжена).
Обратите внимание, что хотя к памяти EEPROM осуществляется доступ по байтам, биты все равно могут быть запрограммированы по отдельности. Поскольку только запрограммированные биты разряжены (находятся в состоянии лог. 0), оставшиеся незапрограммированными биты все еще остаются заряженными (лог. 1). Любой незапрограммированный бит может быть впоследствии запрограммирован. Таким образом, уже запрограммированный байт можно программировать без его предварительной очистки, в результате получится значение побитной операции AND между старым значением и новым (пока все биты в байте не обнулятся).
Режимы программирования EEPROM. Изначально в микроконтроллерах AVR не было выбираемых режимов программирования EEPROM, при этом операция записи в действительности является комбинацией очистки и программирования. Записываемый в память байт всегда очищается перед программированием нового значения, даже если не требуется стирать какие-либо биты. Например, когда программируется значение 0x00 в ячейку EEPROM, в которой уже содержится значение 0x0F, не нужно выполнять предварительную очистку байта. Достаточно было бы обнулить оставшиеся биты, потому что не требуется переводить значение битов из 0 в 1. Для этого случая операция очистки не даст никакого эффекта, она просто впустую потратит время и потребляемую энергию. Комбинированные операции очистки и программирования удваивают время выполнения по сравнению с простой операцией программирования.
Когда были разработаны AVR, в которых есть выбор режима программирования, например ATmega48/88/168, стало возможным разделить доступ на запись в EEPROM на отдельные операции очистки и программирования. Это уменьшит время обновления EEPROM на 50% в случаях, когда не требуется очистка. Доступные режимы программирования перечислены ниже в таблице 1.
Примечание: в этом документе слово "программирование" используется для описания обновления без очистки, и слово "обновление" используется для любой операции, которая изменит содержимое EEPROM.
Таблица 1. Режимы программирования EEPROM.
Режим |
Описание |
Время обновления |
0 |
Скомбинированы вместе стирание и программирование |
3.4 мс |
1 |
Только стирание |
1.8 мс |
2 |
Только программирование |
1.8 мс |
Режим программирования устанавливается путем записи битов EEPM1 и EEPM0 в регистре управления EEPROM (EEPROM Control Register, EECR). Режим по умолчанию при включении питания/сбросе - режим 0, так что этот режим совместим со старым программным обеспечением, не использующим режимы программирования EEPROM.
Эффективный доступ к EEPROM. Чтобы получить выгоду от использования режимов программирования, программное обеспечение EEPROM должно использовать отдельные режимы только для того, чтобы выполнять абсолютно необходимые действия, и не более того. Например, когда обновляется байт EEPROM, и при этом не требуется изменять какой-то из битов от 0 на 1, не требуется операция очистки (достаточно использовать режим 2).
Когда обновляются байты EEPROM, программное обеспечение должно сравнивать биты уже существующего значения с программируемой ячейке со значениями битов в новом байте, который следует записать, и по результату сравнения должно приниматься решение - какой из режимов программирования использовать. В зависимости от записываемых значений используются дополнительные циклы CPU для принятия решения, какой режим перевесит для сокращения среднего времени обновления.
[Реализация]
Этот апноут предоставляет маленькое тестовое приложение, чтобы показать как использовать режимы программирования. Исходный код реализует функции чтения и обновления EEPROM, и выполняет несколько обновлений EEPROM, чтобы продемонстрировать несколько режимов программирования. Подробно описывается только функция обновления EEPROM. См. документацию "source.doc" [4], где описана работа кода.
EEPROM_PutChar(). Это функция для обновления EEPROM. Она сравнивает старый байт в ячейке и его требуемое новое значение, и использует наиболее эффективный режим программирования для операции обновления. Алгоритм функции показан на рис. 1.
Рис. 1. Алгоритм EEPROM_PutChar.
В качестве альтернативного (упрощенного) варианта реализации можно выполнить побитную операцию AND старого и нового значение байта. Если результат равен новому значению, то требуется только операция программирования, очистка не нужна. Если результат отличается, то используется режим с комбинацией очистки и программирования. Это может несколько уменьшить затраты циклов ядра и размер кода, однако не даст выигрыша, когда старое и новое значения совпадают, или когда нужна только операция очистки.
Время выполнения. Для наиболее общего случая считается, что возможно использование в программе режима самопрограммирования. Однако это не всегда так, поэтому с помощью директивы #define компилятора языка C можно выбросить часть кода, относящегося в инструкции SPM (кто не понимает, о чем идет речь, см. [6]). Для получения подробных комментариев см. исходный код к апноуту AVR103 [5].
В таблице 2 показано время выполнения кода для случаев без оптимизации и максимальной оптимизации по скорости. Значения включают в себя инструкции вызова функции и инструкции возврата, и подразумевается, что перед вызовом предыдущие операции записи с EEPROM и с инструкцией SPM были завершены. Строка "Старый вариант записи EEPROM" относится к стандартной подпрограмме записи в EEPROM, которая не использует режимы программирования (пример такой записи можно найти в даташите на микроконтроллер).
Таблица 2. Время выполнения кода для разных режимов оптимизации в циклах CPU.
Операция |
Без оптимизации (1, 2) |
Max оптимизация по скорости (1, 2) |
Только стирание |
41 |
35 |
Только запись |
41 |
35 |
Очистка и запись |
41 |
35 |
Нет операции |
36 |
30 |
Старый вариант записи EEPROM |
26 |
24 |
Примечания (1): предполагается, что предыдущие операции записи EEPROM и SPM были завершены. (2): полное время выполнения см. в таблице 1.
Применение EEPROM_PutChar(). Эта реализация EEPROM_PutChar может заменить реализации, которые не используют режимы программирования (см. [2, 3]). Функция сама заботится о выборе наилучшего режима программирования, без внешнего участия. Например, AVR104 [3] может быть улучшен при использовании режимов программирования путем замены двух блоков в алгоритме на рис. 4 "Установить бит ..." кодом EEPROM_PutChar из этого апноута.
Во многих приложениях можно получить значительные выгоды при правильном планировании использования ресурсов EEPROM. Вам следует избегать смены битов с 0 на 1, если Вы можете это себе позволить. Например, хранилище параметров в EEPROM может быть улучшено кольцевым буфером, как это реализовано при использовании памяти FLASH в апноуте AVR105 [4]. Программирование и очистка ячеек памяти FLASH осуществляется очень похоже на аналогичные действия с ячейками памяти EEPROM.
[Ссылки]
1. AVR103: Using the EEPROM Programming Modes site:atmel.com. 2. AVR100: доступ к энергонезависимой памяти EEPROM. 3. AVR104: буферизированная запись в EEPROM с управлением по прерыванию. 4. AVR105: эффективное сохранение параметров в памяти FLASH. 5. 141229AVR103-AVR104-AVR105.zip - исходный код, документация. 6. AVR109: самопрограммирование AVR. |