Реклама ⓘ
Главная » Микроконтроллеры
Призовой фонд
на апрель 2024 г.
1. 100 руб.
От пользователей

Реклама ⓘ

Особенности процесса самопрограммирования

С точки зрения самопрограммирования, FLASH-память программ разделена на две части. Такое разделение для ATmega8 приведено на рис.1. Это секция прикладной программы Application Section и секция загрузчика Boot Loader Section. Код загрузчика может выполняться только во второй секции. Размер Boot Loader Section на этапе программирования задается двумя битами конфигурации: BOOTSZ1 и BOOTSZ0. У ATmega8 он может составлять 128, 256, 512 и 1024 слова. Сброс конфигурационной ячейки BOOTRST на 0 заставит перенести вектор сброса, нормально расположенный по адресу 0, в самое начало загрузочной секции.

Разделение Flash-памяти у ATmega8
Рис.1 Разделение Flash-памяти у ATmega8

У большинства моделей FLASH-память также разделена по способу доступа на области RWW (Read-While-Write) и NRWW (No Read-While-Write). Различие между ними проявляется только на этапе программирования. В моменты модификации содержимого памяти программ доступ к секции RWW, посредством инструкций lpm, rjmp, rcall и др. запрещен, а их использование может привести к непредсказуемым последствиям. То же самое касается и прерываний, которые должны быть временно запрещены, или перемещены в секцию загрузчика. Размер NRWW всегда совпадает с наибольшим размером Boot Loader Section.

Память программ AVR имеет страничную организацию (размер страницы у разных моделей может составлять 32,64 или 128 слов). Поэтому взаимодействие с FLASH-памятью производится через внутренний буфер обмена. Во время записи, буфер сначала заполняется данными, а затем его содержимое целиком переносится в заданную страницу. Это приводит к небольшим затруднениям, когда, например, необходимо перезаписать только одно или несколько слов. В этом случае придется сначала переписать страницу в SRAM микроконтроллера, затем модифицировать необходимые байты и только потом перенести данные в буфер и произвести запись. Стирание памяти производится также по страницам. Запись страницы, без предварительного стирания, равно как и запись во время изменения памяти FLASH или EEPROM, - невозможна. Распределение памяти ATmega8 приведено на рис.2.

Адресация Flash-памяти при самопрограммировании
Рис.2 Адресация Flash-памяти при самопрограммировании

Самопрограммирование AVR происходит на двух уровнях. Тип операции задается битами управляющего РВВ SPMCR, а запуск самого процесса командой spm (Store Program Memory). Адресация данных производится с помощью указателя ZH:ZL. В случае ATmega8 биты Z12:Z6 регистра Z задают номер страницы (0…127), а биты Z5:Z1 определяют порядковый номер слова в пределах страницы (0…31). LSB Z0 всегда должен быть равен 0 (адресовать байты 16-разрядных слов нет необходимости). Сами данные, если они необходимы передаются/принимаются в регистровой паре R1:R0.

Активизация инструкции spm происходит в течении 4 машинных циклов после установки бита SPMEN (в некоторых моделях бит носит название SELFPRSEN) в регистре SPMCR. Другие биты SPMCR при совместном использовании с SPMEN, как было сказано выше, определяют род действия команды spm. Кроме того, бит SPMEN служит еще и признаком окончания операции. Он аппаратно сбрасывается на нуль в случае завершения необходимого действия, либо если в течении 4 циклов после его установки не была встречена команда spm. С учетом вышесказанного подпрограмма записи в регистр SPMCR должна выглядеть следующим образом (в R16 передается новое значение SPMCR):

do_spm: 
     in    R17,SPMCR ;ожидаем пока не закончится 
     brc  R17,SPMEN  ;предыдущая операция 
	 rjmp  do_spm
ds1: sbic  EECR,EEWE ;ожидаем пока не закончится 
	 rjmp  ds1       ;запись в EEPROM-память
	 out   SPMCR,R16 ;модифицируем регистр SPMCR
	 spm             ;в течении 4-х циклов выполняем команду spm
     ret

Стирание производится установкой битов SPMEN, PGERS в SPMCR и выполнением команды spm в течении четырех машинных циклов. Перед этим действием в регистре Z нужно занести номер страницы (регистры R1, R0 в этом процессе не участвуют):

	 ldi   R16,(1<< PGERS)|(1<< SPMEN) 
     rcall do_spm  ;стираем страницу
	 spm
     .

В результате стирания каждое слово в пределах страницы будут иметь значение 0xFFFF.

Запись страницы происходит в три этапа: стирание, заполнение данными страничного буфера обмена и, непосредственно, выполнение команды записи. При заполнении буфера каждое 16-разрядное слово заносится в регистровую пару R1:R0 и копируется в буфер установкой бита SPMEN в SPMCR и командой spm. В указателе Z при этом должен находиться номер страницы и текущий адрес слова. После подготовки буфера производится запись страницы посредством установки битов SPMEN, PGWRT в SPMCR и выполнением инструкции spm в течении четырех машинных циклов:

      .dseg             ;32 слова для записи во FLASH-память
   page_buffer: .byte 2*PAGESIZE 
    
      .сseg
      .
      ldi   R16,(1<< PGERS)|(1<< SPMEN) ;стираем страницу
      rcall do_spm  ;стираем страницу
      ldi   YH,high(page_buffer) ;заносим в указатель Y адрес
      ldi   YL,low(page_buffer)  ;начала буфера для записи
      ldi   R17,PAGESIZE  ;инициализируем счетчик слов
 pf1: ld    R0,Y+  
      ld    R1,Y+ 
 	  ldi   R16,1<< SPMEN 
      rcall do_spm  ;копируем слово из R1:R0 в буфер
	  adiw  ZH:ZL,2 ;устанавливаем адрес следующего слова
	  dec   R17     
	  brne  pf1  ;переносим в страничный буфер все 32 слова
      subi  ZL,PAGESIZE ;восстанавливаем адрес страницы
      sbci  ZH,0
      ldi   R16,(1<< PGWRT)|(1<< SPMEN) 
	  rcall do_spm  ;записываем страницу
      .

Считать память программ, если это необходимо, можно с помощью инструкций lpm/elpm. Однако чтение из Boot Loader Section имеет одну важную особенность: доступ к данным, находящимся в области RWW, после операции стирания/записи страницы FLASH-памяти блокируется. Для разрешения чтения необходимо установить в регистре SPMCR биты SPMEN и RWWSRE и в течении четырех циклов выполнить команду spm:

        .dseg             ;32 слова для чтения из FLASH-памяти
   page_buffer: .byte 2*PAGESIZE   
        
        .сseg
      .
      ldi   R16,(1<< RWWSRE)|(1<< SPMEN) ;разрешаем доступ к RWW
      rcall do_spm  
      ldi   YH,high(page_buffer) ;заносим в указатель Y адрес
      ldi   YL,low(page_buffer)  ;начала буфера для чтения
      ldi   R17,PAGESIZE  ;инициализируем счетчик слов
 rf1: lpm   R16,Z+ 
      st    Y+,R16
	  lpm   R16,Z+
      st    Y+,R16
	  dec   R18  
	  brne  rf1 ;считываем в буфер все 32 слова
	  .

Кроме FLASH-памяти загрузчик может обращаться также к пространству байтов конфигурации и ячеек защиты микроконтроллера. Перед их считыванием в регистр Z нужно занести адрес байта (0x0000 – младший байт конфигурации, 0x0003 – старший байт конфигурации, 0x0002 – дополнительный байт конфигурации, если он имеется, 0x0001 – байт, содержащий ячейки защиты). Затем в РВВ SPMCR необходимо установить биты SPMEN и BLBSET и в течении трех машинных циклов считать содержимое выбранного байта командой lpm:

       clr   ZH ;устанавливаем адрес младшего байта конфигурации
       clr   ZL 

       ldi   R17,(1<< BLBSET)|(1<< SPMEN)
       out   SPMCR,R17 
	   lpm   R16,Z ;считываем младший байт конфигурации в R16
	   .
       clr   ZH ;устанавливаем адрес старшего байта конфигурации
	   ldi   ZL,3
       ldi   R17,(1<< BLBSET)|(1<< SPMEN)
       out   SPMCR,R17 
	   lpm   R16,Z ;считываем старший байт конфигурации в R16	 
       .
       clr   ZH ;устанавливаем адрес байта ячеек защиты
       ldi   ZL,1
       ldi   R17,(1<< BLBSET)|(1<< SPMEN)
       out   SPMCR,R17 
	   lpm   R16,Z ;считываем содержимое ячеек защиты в R16
       .

Изменять такие аппаратные настройки, как частота, тип генератора, положение вектора сброса и т.д., boot-loader, к сожалению, не может. Модификация FUSE-битов не из области прикладной программы, не из области загрузчика невозможна. Зато имеется возможность влиять на ячейки защиты BLB12,BLB11,BLB02, BLB01. Для их программирования в регистре Z необходимо указать адрес байта ячеек защиты 0x0001, занести в R0, данные для записи, установить в SPMCR биты SPMEN и BLBSET и в течении четырех циклов выполнить команду spm:

       clr   ZH ;устанавливаем адрес байта ячеек защиты
	   ldi   ZL,1
       ldi   R16,~((1<< BLB12)|(1<< BLB11)|(1<< BLB02)|(1<< BLB01))
       mov   R0,R16 ;полная блокировка инструкций lpm и spm  
       ldi   R16,(1<< BLBSET)|(1<< SPMEN)
       rcall do_spm	 
       .

Перейти к следующей части:

Теги:

Котов Игорь Юрьевич Опубликована: 2012 г. 0 0
Я собрал 0 0
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 0 Проголосовало: 0 чел.

Комментарии (1) | Я собрал (0) | Подписаться

0
sim900d #
Спасибо тебе большое Игорь Юрьевич. Очень выручил.
Ответить
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется электрическое сопротивление?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

Pickit 2 - USB-программатор PIC-микроконтроллеров
Pickit 2 - USB-программатор PIC-микроконтроллеров
Набор для сборки - УНЧ 2х60 Вт на TDA7294 Паяльная станция Hakko 936
вверх