Прыжки в bootloader и обратно

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Аватара пользователя
_dark
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт апр 26, 2012 14:30:40
Откуда: под Москвой

Прыжки в bootloader и обратно

Сообщение _dark »

Написал bootloader для Mega128 - работает. Как и положено запускается при старте, отвечает - все ОК.
По команде выходит в основную программу то же нормально. Вот кусок кода (команда сбрасывает FBoot).

int main(void)
{
MCUCR = (1<<IVCE);
MCUCR = (1<<IVSEL);
...
if(!FBoot){
FBoot = 0;
MCUCR = (1<<IVCE);
MCUCR = (0<<IVSEL);
asm("jmp 0x0000");
}
return 0;
}

Основная прога тоже работает, но вот переход в bootloader не идет, хоть ты тресни, ни как не пойму почему...
Вот кусок основной проги:

int main(void)
{
...
if(FBoot){
asm ("jmp 0x1E000");
}
return 0;
}

Причем при просмотре в эмуляторе (работаю в связке WinAVR+AVRStudio 4.19) jmp 0x1E000 проходит верно (на адрес 0x0F000, bootsector = 8k) и сам bootloader грузится в эмуляторе туда же и на симуляторе выполняется верно, но реально загрузчик после перехода не работает. Причем не работает сама прога boot-a, а не прерывания.

Всю голову уже сломал, где засада не могу сообразить, может кто из форумчан пнет в нужном направлении?
Реклама
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Re: Прыжки в bootloader и обратно

Сообщение Kavka »

А что есть у вас FBoot?
Т.к. загрузчик и основная прога это совершенно разные самодостаточные программы, то знает ли одна о FBoot другой (независимо от направления).
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Реклама
Аватара пользователя
_dark
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт апр 26, 2012 14:30:40
Откуда: под Москвой

Re: Прыжки в bootloader и обратно

Сообщение _dark »

FBoot хотя и имеют одно имя конечно же независимые переменные в boot и в основной программе, собственно это флаги которые управляют только сотоянием данной программы, точнее указывают можно ли из нее выйти.

Наверное вот так будет понятнее

int main_boot(void)
{
FBoot = 1;
MCUCR = (1<<IVCE);
MCUCR = (1<<IVSEL);
...
if(!FBoot){
MCUCR = (1<<IVCE);
MCUCR = (0<<IVSEL);
asm("jmp 0x0000");
}
return 0;
}
здесь FBoot сбрасывается по команде из UART

int main(void)
{
FBoot = 0;
...
if(FBoot){
asm ("jmp 0x1E000");
}
return 0;
}
здесь FBoot своя локальная переменная, FBoot устанавливается по команде из UART

Собственно дело не в них, а в том, что main_boot() не выполняется вообще после команды asm ("jmp 0x1E000")

Есть подозрение, что состояние каких то регистров после инициализации основной программы не дают работать main_boot(), т.к. они не сброшены после перехода.

ЗЫ
В проекте задествована внешняя XRAM и основная программа ее использует, а boot нет.
Вроде сбрасываю инициализацию XRAM
MCUCR &= ~(1<<SRE); - не помогает...
впрочем похоже всетаки остается где то проинициализированная переферия или разрешенные прерывания, а векторов этих в boot-е нет... пошел писать заглушки....
....
Аватара пользователя
_dark
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт апр 26, 2012 14:30:40
Откуда: под Москвой

Re: Прыжки в bootloader и обратно

Сообщение _dark »

В общем так и есть, проблема в открытых прерываниях.
Поставил затычки и все заработало. Вопрос снят.

Для тех кто будет писать универсальный Boot - принудительно блокируйте все прерывания которые вам не нужны! даже если вы их не инициализировали.

Особенное СПАСИБО и связку воблы ARV :beer: , это его пост в ЧАВО о неэквивалетности аппарного RESET и программного сброса послал мысли в правильном направлении!

ЗЫ
Kavka спасибо что отозвались.
Реклама
Эиком - электронные компоненты и радиодетали
mackerel
Открыл глаза
Сообщения: 70
Зарегистрирован: Пт янв 30, 2009 18:02:40

Re: Прыжки в bootloader и обратно

Сообщение mackerel »

"Для тех кто будет писать универсальный Boot - принудительно блокируйте все прерывания которые вам не нужны! даже если вы их не инициализировали."
Вообще-то одна из настроек яровского компилятора, насколько я помню, это дефолтовое заполнение таблицы векторов прерываний кодами возврата?
Реклама
Аватара пользователя
_dark
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт апр 26, 2012 14:30:40
Откуда: под Москвой

Re: Прыжки в bootloader и обратно

Сообщение _dark »

mackerel писал(а):Вообще-то одна из настроек яровского компилятора, насколько я помню, это дефолтовое заполнение таблицы векторов прерываний кодами возврата?


Зависит от компилятора, а так как в данном случае у меня GCC (WinAVR), то он (цитирую букварь от ARV) "При разработке программ не исключена ситуация, когда случайно будет сгенерировано прерывание, для которого нет назначенного обработчика (ситуация «баг программы»). По умолчанию компилятор генерирует код, который в этом случае приведет к переходу на адрес 0х0000, т.е. поведение кода равносильно сбросу микроконтроллера."

На сколько я понимаю, в моем случае вектора уже переопределены на 0xF000 и поэтому все "улетает" в никуда.

Лечится это может и объявлением bad-прерывания
ISR(BADISR_vect){return;}
но я (ИМХО) предпочитаю делать по возможности без платформозависимых библиотек, т.е. выключить неиспользуемые boot-ом прерывания и заодно выключить ненужную перифирию.
Реклама
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»