Главная » Микроконтроллеры
Призовой фонд
на март 2017 г.
1. UNI-T UT-39C
Паяльник
2. Тестер компонентов LCR-T4
Паяльник
3. 100 руб.
От пользователей

Перенос программы между разными моделями

Иногда может возникнуть необходимость в переносе программы с одной модели AVR на другую. Если под рукой находится исходный текст, то в этом нет ни какой проблемы. Другое дело, когда в распоряжении имеется только 16-тиричный hex-файл. В этом случае можно воспользоваться описанным ниже способом, затратив лишь немного времени на доработку программы.

Сразу необходимо оговорится, что подобное возможно только в том случае, если перенос программного обеспечения производится на микроконтроллер с объемом FLASH-памяти превышающем исходный, как минимум в два раза. Модели должны быть также совместимы на уровне РВВ, используемых в программе. В значительной степени все вышесказанное относится, например, к моделям ATmega8535, ATmega16, ATmega32 и др. В дальнейшем все примеры будут относиться к переносу программы с ATmega8535 на ATmega16.

Выполнение кода, предназначенного для ATmega8535, в адресном пространстве модели ATmega16
Рис.1 Выполнение кода, предназначенного для ATmega8535,
в адресном пространстве модели ATmega16

Непосредственному выполнению программного кода в адресном пространстве нового процессора помешают два обстоятельства. Первое из них это несоответствие между таблицами векторов прерывания. В пределах целого семейства не существует двух микроконтроллеров, у которых адреса векторов совпадают. Кроме того и размеры самих таблиц у всех моделей различны. Вторая, значительно более серьезная проблема, проявляется в искаженном действии инструкций rjmp k, rcall k, brbs k, brbc k и всех остальных, осуществляющих относительные переходы (относительно текущего значения программного счетчика) в памяти программ. Понять это можно, если взглянуть на рис.1. На нем изображено адресное пространство памяти программ микроконтроллеров ATmega8535 и ATmega16. Допустим, что в слове программ под номером 0x0E00 встретится инструкция rjmp PC+0x0400. К программному счетчику при этом будет добавлено смещение 0x0400, в результате чего произойдет относительный переход по новому адресу. Очевидно, что этим адресом будет являться 0x0E00+0x0400 = 0x0200. Переполнение 0x1000 у 12-разрядного программного счетчика программ ATmega8535 будет отброшено. Совсем иначе обстоит дело с микроконтроллером ATmega16, у которого на борту расположено 8192 16-разрядных слова программ и, соответственно, 13-битный счетчик команд. Переполнение в этом случае не произойдет и после перехода rjmp PC+0x0400 программа продолжит свое выполнение с команды по адресу 0x1200. Функционирование устройства будет нарушено.

Проблема с несоответствием векторов прерываний решается достаточно легко. У AVR-микроконтроллеров положения вектора сброса и таблицы прерываний могут быть перемещены в область загрузчика

       .cseg
       .org  LARGEBOOTSTART

    jmp   initial    ;начало основной прграммы 
	jmp   0x0001     ;внешнее прерывание 0 ATmega8535
	jmp   0x0002     ;внешнее прерывание 1 ATmega8535
	jmp   0x0003     ;совпадение TCNT2 и OCR2 ATmega8535
	jmp   0x0004     ;переполнение TCNT2 ATmega8535
	jmp   0x0005     ;захват в ICP1  ATmega8535
	jmp   0x0006     ;совпадение TCNT1 и OCR1A ATmega8535
	jmp   0x0007     ;совпадение TCNT1 и OCR1B ATmega8535
	jmp   0x0008     ;переполнение TCNT1 ATmega8535
	jmp   0x0009     ;переполнение TCNT0 ATmega8535
	jmp   0x000A     ;прерывание от модуля SPI ATmega8535
	jmp   0x000B     ;получение байта по USART ATmega8535
	jmp   0x000C     ;опустошение UDR в USART ATmega8535
	jmp   0x000D     ;передача байта по USART ATmega8535
	jmp   0x000E     ;прерывание от АЦП ATmega8535
	jmp   0x000F     ;завершение записи в EEPROM ATmega8535
	jmp   0x0010     ;прерывание от компаратора ATmega8535
	jmp   0x0011     ;прерывание от модуля TWI ATmega8535
	jmp   0x0012     ;внешнее прерывание 2 ATmega8535
	jmp   0x0013     ;совпадение TCNT0 и OCR0 ATmega8535
	jmp   0x0014     ;завершение выполнения spm ATmega8535

initial:
    ldi   R16,1 << IVCE ;таблицу векторов прерывания	
    out   GICR,R16    ;переносим в область загрузчика
	ldi   R16,1 << IVSEL
	out   GICR,R16
	jmp   0           ;переходим на начало программы

Для этого необходимо сбросить FUSE-бит BOOTRST. Биты BOOTSZ1: BOOTSZ0 будут определять размер Boot Loader Section (см. разд. Самопрограммирование AVR). В данном примере BOOTSZ1:BOOTSZ0=00 (размер загрузочной секции 1024 слова, сброс по адресу LARGEBOOTSTART=0x1C00). 

Таким образом, каждый раз после запуска устройства программа будет стартовать по адресу 0x1C00 и начинаться с метки initial. Последовательность следующих пяти команд фиксирует таблицу векторов прерывания в области загрузчика и передает управление на начало основной программы с нулевого адреса.

Допустим, в ходе работы устройства в основной программе возникает прерывание от переполнения таймера-счетчика 0. Процессор перейдет на обработчик прерывания по адресу 0x1C12, что соответствует положению вектора прерывания от таймера 0 для модели ATmega16. Слово программ 0x1C12 должно содержать инструкцию перехода на адрес соответствующего вектора в основной программе для модели ATmega8535 (в данном случае jmp 0x0009). Тоже самое касается и всех остальных векторов из области загрузчика. 

Теперь рассмотрим, как можно исправить действия различного рода инструкций относительного перехода. Для этого все свободные адреса с 0x1000 по 0x1FFF в памяти программ ATmega16 “забиваются” командами вызова подпрограммы new_adr:

     .cseg   
	 .org 0x1000
   .

    rcall new_adr 
    rcall new_adr
    rcall new_adr
    .

      .org  0x1800

new_adr:
    push  R16
    in    R16,SREG
    push  R16
    push  ZH
    push  ZL
    in    ZH,SPH
    in    ZL,SPL
    ldd   R16,Z+6
    subi  R16,low(0x1001)
    std   Z+6,R16
    ldd   R16,Z+5
    sbci  R16,high(0x1001)
    std   Z+5,R16
    pop   ZL
    pop   ZH
    pop   R16
    out   SREG,R16
    pop   R16
    ret
       
    rcall new_adr 
    rcall new_adr
   .
    rcall new_adr

Смысл подпрограммы new_adr заключается в следующем. Когда возникнет  ошибочный переход в запрещенное адресное пространство, например, переход по адресу 0x1200 вместо 0x0200, то после вызова rcall new_adr адрес возврата 0x1201 (возврат на следующую команду) будет сохранен в стеке. В теле new_adr этот адрес (размещается в SRAM) подлежит коррекции. В нашем случае из него нужно вычесть смещение 0x1001. После завершения new_adr программа продолжит свое выполнение не с команды по адресу PC = 0x1201, а с нового места PC = 0x1201 - 0x1001 = 0x0200.

Подпрограмма new_adr должна находится по адресу 0x1800, чтобы быть в пределах досягаемости инструкций rcall k (±2047 слов).

В файле m8535to16.asm находится полный текст программы, а в m8535to16.hex, соответственно исполняемый код. Если возникнет необходимость в переносе программы с ATmega8535 на ATmega16, то в любом текстовом редакторе к исходному hex-файлу нужно присоединить файл m8535to16.hex и загрузить новую прошивку в микроконтроллер (установки FUSE-битов BOOTSZ1:BOOTSZ0=00, BOOTRST=0):

:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ;файл предназначенный 
:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ;для ATmega8535
 ̣̣̣̣̣̣̣̣ 
 ̣̣̣̣̣̣̣̣
:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
:00000001FF                                 ;удаление строки окончания файла!

             +

:020000020000FC                             ;добавление к исходному hex-файлу
:10200000FFD7FED7FDD7FCD7FBD7FAD7F9D7F8D73C ;файла m8535to16.hex
:10201000F7D7F6D7F5D7F4D7F3D7F2D7F1D7F0D76C
 ̣̣̣̣̣̣̣̣ 
 ̣̣̣̣̣̣̣̣
:103FE0000FD80ED80DD80CD80BD80AD809D808D8B5
:103FF00007D806D805D804D803D802D801D800D8E5
:00000001FF

С очень большой вероятностью модифицированная программа успешно заработает на новой модели. Правда такая доработка накладывает и ряд ограничений. Переход, в случае попадания в запрещенный диапазон адресов, будет длиться на 37 циклов дольше и потребует в стеке дополнительных 8 б. Вызов каждого прерывания будет отложен на 2 цикла. И, конечно, каждый переход из основной программы в область 0x1000…0x1FFF обязательно должен попадать на инструкцию rcall new_adr.

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

Теги:

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

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

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

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

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

Статью еще никто не комментировал. Вы можете стать первым.
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется напряжение?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

AVR-программатор USB ASP
AVR-программатор USB ASP
Квадрокоптер Syma X11 200 Вт усилитель класса D на IRS2092
вверх