Июл 112013
 

Основное предназначение flash памяти микроконтроллера – хранение кода программы. Именно отсюда извлекаются команды, которые затем выполняются ядром микроконтроллера. Весь алгоритм поведения микроконтроллера, каким его придумал разработчик программы, то, каким образом микроконтроллер реагирует на внешние воздействия, настройка всех периферийных модулей и т.д. – все это хранится во встроенной flash памяти. Целью нескольких последующих статей является более подробное знакомство со структурой и возможностями встроенной flash памяти, а также основными методами, позволяющими выполнять действия с этой областью памяти. Стирание и программирование всей памяти программ или отдельных ячеек, регистры конфигурации flash памяти, различные варианты защиты от доступа к этой области памяти и т.д. – все это будет изложено далее. Для удобства восприятия информация будет разделена на несколько частей. Первая часть является обзорной и в ней будет рассмотрена структура flash памяти некоторых серий микроконтроллеров из семейства STM32 с ядром Cortex-M3.

Основной объем встроенной flash памяти занимает, конечно же, область, предназначенная для хранения кода программы, но кроме нее есть часть памяти, предназначенная для других целей. Сама память программ разделена на фрагменты меньшего размера, число этих фрагментов и их размер зависит от серии микроконтроллера. Структура flash памяти будет рассмотрена на примере микроконтроллеров серий STM32F100–F103 и STM32L1xx, поскольку это наиболее распространенные и популярные типы.

Если пока не привязываться к конкретному семейству, то в общем виде структуру flash памяти можно представить состоящей из следующих областей:

Main memory — память программ. Содержит основной код программы, который исполняется ядром микроконтроллера. Эта область разделена на страницы определенного размера, количество и размер страниц зависит от типа микроконтроллера и размера его памяти программ. Кроме того, для некоторых микроконтроллеров область памяти программ кроме страниц может быть поделена еще и на несколько секторов. Сектор содержит какое-то число страниц определенного размера. В другом секторе размер страниц может отличаться.

EEPROM – энергонезависимая перепрограммируемая область памяти. Из всех вышеперечисленных серий имеется только в микроконтроллерах низкопотребляющей серии STM32L1xx. Обычно используется для хранения пользовательских данных, различных настроек устройства, т.е. всего того, что не должно потеряться при отключении питания или сбросе микроконтроллера. Хоть это также область flash памяти, но имеет некоторые отличия от области памяти программ. Эта область памяти будет рассмотрена в одной из следующих частей.

Information block содержит две области памяти: System memory и Option bytes.

System memory – это область загрузчика. Позволяет программировать микроконтроллер через внешний интерфейс (для вышеперечисленных семейств — USART). К этой области пользователь не имеет доступа, производитель «прошивает» в нее встроенный загрузчик при производстве микроконтроллера. Поэтому стереть или повредить данные в этой области случайными действиями невозможно.

Option bytes – область памяти, где устанавливается защита от записи/чтения отдельных страниц памяти программ, а также некоторые другие пользовательские настройки.

И в самом конце расположены регистры интерфейса flash памяти (FLITF — Flash memory interface).

На рисунках ниже приведена структура flash памяти для различных типов микроконтроллеров.

STM32F100 (medium-density value line devices)

STM32F100_Flash module organization (medium-density value line devices)

STM32F10x (high-density devices)

STM32F10x_Flash module organization (high-density devices)

STM32L1xx (medium density devices)

STM32L1xx_Flash module organization (medium density devices)

Всеми операциями записи/чтения «рулит» отдельный модуль – контроллер записи и чтения flash памяти FPEC (Flash Program/Erase Controller).

Микроконтроллеры с наибольшим размером памяти выделяются тем, что имеют по два банка памяти программ. Это позволяет хранить в микроконтроллере две версии прошивки, программировать один из банков памяти, в то время как второй является рабочим и в нем выполняется программа. К сожалению, практически попробовать эти возможности мне не приходилось, поэтому не могу рассказать подробней. Итак, вот структура микроконтроллеров XL-density STM32F101-103 и high-density STM32L1xx:

STM32F10x XL-density Flash module organization

STM32F10x_XL-density Flash module organization

STM32L1xx Flash module organization (high density devices)

STM32L1xx_Flash module organization (high density devices)

Как видно из последней таблицы, у микроконтроллеров high-density STM32L1xx кроме двойного банка памяти программ продублированы и все остальные области flash памяти, а именно EEPROM, область загрузчика и Option Bytes. В обеих таблицах для семейства STM32L1xx отсутствуют регистры интерфейса flash памяти. На самом деле они есть и никуда не делись, но почему-то именно в этих таблицах из документации они не приведены.

Для начала, думаю, пока хватит. В следующий раз рассмотрим процедуры программирования и стирания в области памяти программ, а также способы защиты и регистры flash интерфейса.

 Posted by at 22:40  Tagged with: ,

  8 Responses to “STM32. FLASH память. Структура”

  1. Оооо как я рад !!! у меня столько вопросов, и проблем, буду следить.

  2. Как можно создать адресацию EEPROM в заголовочном файле. Вот грабли на которые я наткнулся: в заголовочном файле .h сначала объявил указатели и им присвоил адреса вот примерно так
    1.Мысля:
    uint16_t *ModBusAddr = (uint16_t *)0x08080000;
    в каком то .с файле вызов функции чтения EEPROM
    uint16_t ReadEEPROM(uint16_t *addr) { // функция чтения EEPROM принимающая адрес указателя, и возвращающая uint16_t
    uint16_t *ptr;
    uint16_t result;
    ptr = (uint16_t *)(addr);
    result = *ptr;
    return result;
    }
    Вот грабли №1: Keil выдал ошибку что множественное объявление «ModBusAddr » , оказывается можно только объявить переменные в .h но присвоить значения можно только в .с файлах.

    2. Мысля
    Решил адресацию EEPROM xthtp #define
    #define ModBusAddr 0
    в таком случае функция чтения EEPROM приняла вид
    uint16_t ReadEEPROM(uint16_t addr) { // функция чтения EEPROM принимающая позицию в памяти , и возвращающая uint16_t
    uint16_t *ptr;
    uint16_t result;
    ptr = (uint16_t *)(eepromADR + addr ); // где #define eepromADDR 0x08080000
    result = *ptr;
    return result;
    }
    вот грабли №2: Да все работает, но во первых придется рассчитать каждый short, int, переменную в адресном пространстве EEPROM и задавать последовательность 0,1,2,3,4 и т п
    Например для
    #define ModBusAddr 0 //так в голове держу 0x08080000 , выделю два байта для этой переменной
    #define ModBusFunc 2 // так в голове держу 0x08080002 выделю два байта для этой переменной
    и т д.
    Вот еще проблема функция uint16_t ReadEEPROM(uint16_t addr) имеет тип uint16 что принимаемый что возвращаемый, как быть если я хочу выделить для одной переменной например только байт, для другой два байта, а с float что делать ?
    Тоже подумал и решил так создам Шаблон функции которая будет принимать различные типы данных и в зависимости от этого читать определенное количество байт с EEPROM/

    template
    eeType ReadEEPROM( eeType addr ); // но Keil выдал ошибку на этом месте «unknown type name template»

    Проошу помощи, каким образом Вы распределяете память и как описаны функции чтения и записи в EEPROM

  3. В конце что то ошибка вот ТАК ВЕРНЕЕ
    template
    eeType ReadEEPROM ( eeType addr );

  4. блин не печатается тут template «»»

    • Все вопросы в общем по языку С. А краткий ответ тут не дашь никак, да и полно источников, где все разжевано подробно, лучше к ним обратиться. Например, у Кернигана и Ритчи почитать, как никак это авторы языка.
      А по EEPROM будет статья, но только для STM32L, не более. Пока времени нет, да и настроя, лето все же :)

  5. Хотелось бы узнать, а предвидятся статьи по работе с линкером ?!