При подготовке этого материала я использовал несколько ресурсов в дополнение к руководству пользователя семейства микроконтроллеров и паспорта на микроконтроллер, одним из наиболее полезных источников был msp430 Flash Memory Characteristics.

Нам бы очень хотелось сохранить наши калибровки тактового генератора по двум причинам. Хотелось бы иметь возможность использования их в будущем, но так же хотелось бы сделать это, не используя довольно-таки ограниченные ресурсы самого микроконтроллера для самокалибровки. Кроме того, возможно потребуется применение в приложениях, в которых не предполагается кварцевых резонаторов, подключенных к устройству. (Возможно мы могли бы выполнить калибровку в нашем ланчпаде с установленным кристаллом, а затем перенести микроконтроллер с сохранёнными значениями калибровки в памяти). Программирование флэш-памяти в msp430 несложно, но есть некоторые вещи, которые должны быть выполнены определённым образом для защиты устройства. Процесс программирования станет более понятным, когда мы поймём, как работает флэш-память.

Описание Флэш.

 

1 бит на NOR-флэш-транзисторе с карманом для хранения заряда.

Флэш-память в msp430, называющаяся NOR-флэш (в отличие от NAND-флэш, которая работает например в вашем типичном USB флэш-накопителе). Она работает за счёт захвата заряда в изолированной области, так называемый, «плавающий затвор». Заряд в плавающем затворе изменяет состояние транзистора и определяет значение считываемого бита. Заряд выполняет работу переключателя, положительный заряд открывает путь электронам, «замыкает» ключ и мы читаем логическую единицу. Отрицательный заряд держит ключ разомкнутым, и мы читаем логический ноль.

Когда мы стираем флэш-память, каждый бит переключается в состояние, при котором затвор заряжен положительно. Таким образом, значение «пустого» бита всегда будет читаться как единица; байт стёртой флэш-памяти будет читаться как 0xFF. Можно запрограммировать бит в «0» с применением высокого управляющего напряжения на затворе, которое заставит стечь заряд с плавающего затвора на исток. В результате отрицательный заряд на плавающем затворе сохранится пока не произойдёт какой-нибудь физический эффект наподобие квантового туннелирования, который принимается за 100 лет для перезаписи бита. (При температуре 25° C типичное время жизни NOR-флэш — около 1000 лет!) К счастью, способность генерировать это высокое напряжение встроего в контроллер флэш-периферии msp430, поэтому мы в состоянии запрограммировать флэш-память до тех пор, пока напряжение на нашём контроллере по крайней мере 2,2В.

Флэш-память в msp430 организована по частям, называемым сегментами. Основная часть памяти делится на сегменты по 512 байт. (Это означает, что существуют 4 сегмента в основной памяти как для g2211, так для g2231, в каждом из которых по 2КБ) Каждый сегмент делится на блоки по 64 байта. Кроме того, более 512 байт, входящие в каждый msp430, делится на сегменты либо по 64, либо по 128 байт (один или 2 блока соответственно). Эти сегменты составляют часть информационной памяти контроллера. Контроллеры серии Value Line, которые поставляются с Launchpad, имеют 4 сегмента памяти по 64 байта каждый и называются сегменты A-D.

Физическая структура ячеек очень важна для нас, так как имеет прямое отношение к тому, как мы с ней работаем. Прежде всего, когда мы стираем флэш-память, мы можем стереть только весь сегмент за один раз. Это означает, что в то время, когда мы должны изменить в одной ячейке ноль на единицу, должна быть стёрта каждая ячейка в сегменте. Когда мы программируем флэш-память, высокое напряжение подаётся через весь блок, даже если мы программируем только одну ячейку. Это напряжение вызывает стресс для ячеек флэш, поэтому мы не можем превышать указанное «суммарное время программирования», обычно — 10мс. Очистка освобождает от стремма, и по сути сбрасывает наш совокупный таймер в 0. Эти оговорки влияют на нашу скорость программирования и на то, как часто должен быть стёрт блок.

При типичных используемых нами скоростях (от 257 до 476 кГц) мы можем запрограммировать целый блок дважды. (Заметим, что в данном случае «программирование» не означает, что мы можем записать любое значение, — мы лишь можем изменить 1 на 0 дважды. Чтобы изменить 0 на 1, мы вынуждены очищать целый сегмент…) Мы не можем однако запрограммировать один и тот же байт много раз, даже если мы не программируем любой другой байт в блоке. По правилам, если мы достигаем 10мс времени программирования или пишите один и тот же байт два раза, блок (и, следовательно, весь сегмент для основной памяти) должны быть стёрты. Это на самом деле непросто, особенно если мы хотим использовать основную память для хранения наших калибровок. По этой причине я рекомендовал бы использовать информационные сегменты для хранения чего угодно, но за пределами фактической программы в устройстве. Процесс, который мы должны будем выполнить, будет включать чтение всего содержимого блока в буфер (в оперативной памяти), стирать информацию по сегментам, менять необходимое значение в буфере и переписывать буфер в сегменте. (похоже, что это намного больше требует, чем мы привыкли в использовании флэш-накопителей, но в действительности и там и там происходит всё то же самое. Компьютер просто делает фантастичекую скрытую работу, поэтому нам не приходится беспокоиться об этом.)

 Описание Флэш.

Несколько слов о различных сегментах: сегменты B-D имеют свои достоинства. Так, сегмент А специально отведён Texas Instruments для хранения информации, сохраняющейся независимо от любых изменения при программировании. Например в этом сегменте хранятся заводские калибровки. В результате этот сегмент заблокирован, и вам придётся установить бит разрешения записи перед выполнением любой инструкции, стирания или программирования этого сегмента. Вдобавок, для обеспечения целостности данных, хранящихся в сегменте А, одно слово (2 байта) пишутся как контрольная сумма, про которую я расскажу в ближайшее время. Если вы что-либо измените в сегменте, вычисление  контрольной суммы не удастся. Некоторые программы полагаются на это, так что если вы действительно должны что-то изменить в этом сегменте, вы должны быть готовы иметь дело с последствиями. Ну по крайней мере быть готовы пересчитать контрольную сумму. Для наших целей в этом уроке мы будем использовать сегмент B вместо этого, но мы будем программировать его почти таким же образом для сохранения структуры сегмента. Таким образом вы сможете выбрать сегмент А для хранения своих калибровок, где они и должны быть.

Давайте посмотрим, как поместить в сегмент А данные. Запустите отладчик в CCS; не имеет значения, какой код вы используете, мы даже не будем запускать программу. Мы хотим перейти в режим отладки. Оказавшись в режиме отладки, в виде по умолчанию справа будет панель со вкладками для разборки кода и памяти, именно вкладка памяти покажет содержимое флэш-памяти устройства. (если этого окна не видно, вы можете найти его, выбрав Window-show view-memory.) Информация о памяти находится (как указано в спецификации) от адреса 0x1000 к 0x10FF. Вы можете использовать это окно для просмотра диапазона, или можете сохранить определённую область памяти в текстовый файл. для этого нажмите кнопку «сохранить», перейдите к файлу, в который требуется сохранить данные, введите начальный адрес 0x10c0 и длину 0x20. (В примечании указано, что нужно давать длину в словах; слово 16 бит в msp430, так что 0x20 (32) слова в сегменте 64 байт.)

Например вывод из моего g2231. Первая строка определяет, из какой части памяти сохранён дамп. Первая строка содержит одно слово - оно определяется из двух байтов по адресам 0x10C0 и 0x10C1. Примем к сведению, что младший адрес слова относится к младшему разряду байта (LSB,   младший бит), в то время как старший адрес означает старший байт. Последняя строка имеет 32-е слово с адресов 0x10FE (LSB) и 0x10FF (MSB). Большая часть памяти в сегменте А, очевидно, чистая, так как большинство записей содержать 0xFFFF. (помните, после стирания флэш-памяти, считывается логическая единица) Есть несколько запрограммированных слов, разберём значения каждого из них. В руководстве пользователя семейства микроконтроллеров x2xx (текущая версия на момент написания статьи slau144h), перейдём к главе о TLV, раздел 24. TLV означает "TagLengthValue", - "тег-длина-значение", используются в микроконтроллерах семейства MSP430x2xx для хранения информации. В принципе - первое слово - указание размера памяти, выделенной для определённого типа данных и определение типа хранящихся данных. В таблице 24-1 приведён пример того, как это происходит. Первое слово в сегменте хранит значение контрольной суммы. Обратим внимание, что контрольная сумма вычисляется как дополнение к побитовому XOR. Если вы начинаете со следующего слова, делаете XOR его с третьим словом и так далее, добавляя в конце контрольную сумму, должен получиться ноль. Что-то вроде того:

1
2
3
4
5
6
7
8
9
10
 int chksum = 0;
 char passed;
 int *i;
 for (i=(int *)0x10C2; i<(int *)0x1100; i++) {
 chksum ^= *i;
 }
 if (chksum + *(int *)0x10C0 == 0)
 passed = 1;
 else
 passed = 0;
Маленькое замечание: Я пока не до конца освоил работу с указателями, я работаю над этим в рамках подготовки к следующему курсу. Если в этом коде есть ошибка, я её исправлю. А теперь я думаю о нём исключительно как о псевдокоде. Теперь, когда мы понимаем, как организованы сегменты памяти, давайте посмотрим на то, что внутри. Используем моё устройство, значение моей контрольной суммы 0xB22C. Это означает, что ближайшие 0x26 записей (38 байт) имеют вид 0xFE. Смотрим таблицу 24-2, видим, что 0xFE относится к "TAG_EMPTY", то есть, ближайшие 38 байт (или 19 слов) не используются. Конечно же, ближайшие 19 строк - 0xFFFF. Следующая строка содержит запись: 0x1010. Следующие 0x10 записей (16 байт или 8 слов) имеют тип 0x10, не указанных в руководстве пользователя семейства. Я задал вопрос поддержке Texas Instruments, чтобы узнать об этом. В любом случае, каждая запись пустая. Следующая запись - это 0x0201, это значит, что есть одно слово типа "TAG_DCO_30"  Здесь у нас хранится значение калибровочной константы тактового генератора для комнатной температуры и напряжения питания 3В (заметим, что значение питания самого ланчпада составляет 3,3В, и помните, что другое напряжение питания сильно влияет на тактовый генератор!) Здесь только одна запись, которую мы уже знаем, она соответствует CALBC1_1MHZ (0x86) и CALDCO_1MHZ (0xC4) в соответствии с данными на g2231.

Упражнение для читателя: Используя ваш дамп памяти, рассчитать контрольную сумму Сегмента А и сравнить её со значением в адресной строке 0x10C0. подсказка: XOR 0xFFFF дважды не имеет никакого эффекта; чётное число этих линий может быть проигнорировано. При добавлении к сохранённым значениям контрольной суммы у вас получается ноль? посчитайте дополнение  к ~(контрольная сумма)+1  и сравните его с сохранённым значением.

 

Подготовка к ручной калибровке тактового генератора (DCO)

Цель нашего кода — получить ручное значение калибровки для частоты 7. 3278 МГц и сохранить его в СегментВ, используя стандартные примеры кода для TLV от TI.  (Вы можете сделать это и в СегментА если хотите, но не забывайте, что мы используем нестандартное значение частоты генератора) СегментВ находится в памяти контроллера в диапазоне адресов от  0x1080 до 0x10BF. Организация того, как мы будем записывать это:

Тут ошибка на картинке, должно быть 0X38FE, я поправлю это позднее.


Мы используем кварц для поиска калибровочного значения для частоты 7.3278 Мгц. Для этого значения посчитаем контрольную сумму:
chksum = 0x38FE ^ 0x0201 ^ {calibration values}
       = 0x3AFF ^ {calibration values}
То, что мы сохраним по адресу 0x1080, будет ~chksum + 1.

Далее, мы стираем СегментВ, и записываем по адресам:

  • 0x1080: два комплементарных значения контрольной суммы
  • 0x1082: 0x38FE
  • 0x10BC: 0x0201
  • 0x10BE: 0x{CALBC1}{CALDCO}
Этот урок получился весьма длинным. В следующем уроке мы ознакомимся с регистрами msp430 и разберём, как записать информацию в память.
Упражнение для читателя: Серия «Value Line» микроконтроллеров поставляется со стандартными калибровочными значениями для частот: 8 MHz, 12 MHz, and 16 MHz. В главе о TLV описания семейства мы видим, что положения этих калибровок стандартизовано для СегментаА, и обозначены как CAL_16MHz, CAL_12MHz, CAL_8MHz, CAL_1MHz. В данных СегментаА для серии «Value Line» не оставлено места для трёх других калибровок, так что выходит, что структура сегментов должна быть смещена. Если мы хотим добавить эти данные без потери структуры, как мы должны установить сегменты? Нарисуйте таблицу для карты структцры сегментов, используя этот урок и покажите, как посчитать новое значение контрольной суммы на основе этой таблицы.

* Структуры TLV (TagLengthValue — тег-длина-значение) используются в микроконтроллерах семейства MSP430x2xx для представления информации, зависящей от устройства, такой как калибровочные значения. Эти структуры располагаются в сегменте A информационной секции флэш-памяти. Аппаратно-зависимые реализации данных структур описываются в справочной документации на конкретные модели.

источник

поделиться:
  • Добавить ВКонтакте заметку об этой странице
  • Мой Мир
  • Facebook
  • Twitter
  • LiveJournal
  • В закладки Google
  • Яндекс.Закладки
  • БобрДобр
  • Сто закладок
  • Blogger
  • Блог Я.ру
  • Одноклассники