Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Простой вопрос по ICC: goto на абсолютный адрес
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
SKov
Надо из прикладной программы прыгнуть на начало бутлоадера, который уже прошит (его нет в тексте текущей программы.)
Т.е. бутлоадер сначала загружает прикладную программу в младшие адреса, потом прикладная программа начинает работать и в какой-то момент может решить, что ей надо перезагрузиться.
Т.е. ей надо как-то снова передать управление на известный абсолютный адрес, с которого начинается бутлоадер.
Как это на Си в ICC AVR.?
_Артём_
Цитата(SKov @ Apr 12 2007, 23:01) *
Надо из прикладной программы прыгнуть на начало бутлоадера, который уже прошит (его нет в тексте текущей программы.)
Т.е. бутлоадер сначала загружает прикладную программу в младшие адреса, потом прикладная программа начинает работать и в какой-то момент может решить, что ей надо перезагрузиться.
Т.е. ей надо как-то снова передать управление на известный абсолютный адрес, с которого начинается бутлоадер.
Как это на Си в ICC AVR.?


Напимер так:
Код
    asm("rjmp 0xE000");
defunct
или так:

typedef void func(void);
...

((func *)0xE000)();
Сергей Борщ
Цитата(SKov @ Apr 12 2007, 22:01) *
Как это на Си в ICC AVR.?
На любом Си: (void(*)())(0xC00)(); Только надо разобраться в чем ICC хочет адрес - в байтах или словах.
rumit2000
я в ICC AVR пишу

asm ("jmp 0x7e00");
Dima_Ag
Цитата(Сергей Борщ @ Apr 13 2007, 02:48) *
На любом Си: (void(*)())(0xC00)(); Только надо разобраться в чем ICC хочет адрес - в байтах или словах.



К сожалению, на ICC такая конструкция не работает, поскольку у этого компилятора есть особенности в косвенном вызове функций.
Все косвенные вызовы происходят через обращение к таблице указателей на эти функции,
а число в Вашем примере 0xC00 - это будет адрес не ФУНКЦИИ, а её УКАЗАТЕЛЯ в таблице.
Поэтому такой вызов не сработает.

Данный момент подробно описано в хелпе в разделе Function Pointers.

Для перехода на адрес 0xC00 видимо, кроме ассемблера, вариантов нет.
SKov
Цитата(Dima_Ag @ Apr 13 2007, 11:07) *
...
Для перехода на адрес 0xC00 видимо, кроме ассемблера, вариантов нет.


Всем спасибо. Последний уточняющий вопрос, если можно.
Бутлоадер я писал на WinAVR и там наступил на грабли,
которые сейчас хочется избежать.
Там в make файле адрес начала бутлоадера должен быть указан в байтах
(BOOTBLOCKSTARTADDRESS = 0x1800) для 1к-загрузчика Меги88, а совсем не в словах ,
как , например, при прошивке кода бутлоадера через STK-500 мне надо
было выбрать соответствующий адрес для бутлоадера 0хс00.
К сожалению, на ассемблере писал для AVR-ов очень давно, почти все забыл,
поэтому прошу уточнить адрес для rjmp в моем случае.
Спасибо.
defunct
Цитата(SKov @ Apr 13 2007, 11:34) *
поэтому прошу уточнить адрес для rjmp в моем случае.

Откройте даташит, посмотрите сколько памяти у чипа в байтах.
Адресом будет (FLASHSIZE(в байтах) >> 1) - BOOTSIZE(в словах).
BOOTSIZE определяется настройками фузов. Тоже смотрите в даташите.
Dima_Ag
Цитата(SKov @ Apr 13 2007, 13:34) *
прошу уточнить адрес для rjmp в моем случае.
Спасибо.


Здесь есть важный момент - RJMP - Relative jump - относительный переход, т.е. переход произойдёт по адресу PC + k +1. Иными словами, k будет зависеть от того, в каком участке программы мы хотим вызвать бутлоадер.
Лучше использовать инструкцию JMP - это Direct Jump на адрес, но такая инструкция не поддерживается в Атмега 88.
Выход - правильнее использовать ijmp - indirect jump, т.е. в регистр Z загрузить адрес перехода.
Эта команда сработает корректно в любом участке программы. Адрес перехода, естественно, загружается в "словах". Более подробное описание ijmp есть в хелпе к АВРАСМ.
Dopler
Цитата(defunct @ Apr 13 2007, 13:11) *
Откройте даташит, посмотрите сколько памяти у чипа в байтах.
Адресом будет (FLASHSIZE(в байтах) >> 1) - BOOTSIZE(в словах).
BOOTSIZE определяется настройками фузов. Тоже смотрите в даташите.


Я думаю в этом случае лучше пользоваться объявлениями от Атмел:

Код
; ***** BOOTLOADER DECLARATIONS ******************************************
.equ    NRWW_START_ADDR    = 0xc00
.equ    NRWW_STOP_ADDR    = 0xfff
.equ    RWW_START_ADDR    = 0x0
.equ    RWW_STOP_ADDR    = 0xbff
.equ    PAGESIZE    = 32
.equ    FIRSTBOOTSTART    = 0xf80
.equ    SECONDBOOTSTART    = 0xf00
.equ    THIRDBOOTSTART    = 0xe00
.equ    FOURTHBOOTSTART    = 0xc00
.equ    SMALLBOOTSTART    = FIRSTBOOTSTART
.equ    LARGEBOOTSTART    = FOURTHBOOTSTART
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.