Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Bootloader для Mega48
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
_Артём_
Вечер добрый.
Есть задача под М48 и нужно при этом иметь возможность обновления программы.
Посмотрел документ от атмела (AVR112: TWI Bootloader for devices without boot section).
Реализовано так:
1. Переход на бут происходит с адреса 0 (раздельных областей для программы и загрузчика нет).
2. Выход из загрузчика:
Код
void (*FuncPtr) (void) = (void (*)(void)) ((LAST_INTVECT_ADDRESS + 2) / 2);    // Set up function pointer to address after last interrupt vector.
  FuncPtr ();


То есть точка входа для основной программы - это первый адрес после таблицы векторов. Но можно ли быть уверенным что это всегда так (для IAR)?
И ещё: насколько универсальны фунции самопрограммирования использованные в appn (ProcessPageErase, ProcessPageUpdate, Erase_One_Page)?Будут ли они работать на M8, M88? Кто-нибудь ими пользовался?
_Артём_
Ещё вопрос: как лучше организовать переход на старт программы (вариант с переходом на первую команду после векторов почему-то не проходит).

Делаю так:
1. Определяю сегмент в коде
Код
-Z(CODE)START_SEGMENT=B50-B60


И функцию перехода:
Код
__root void StartAplication(void)@"START_SEGMENT"
{
    asm("ldi R30, 0x12");
    asm("ldi R31, 0x03");
    asm("ijmp");
}



В буте
Код
        asm("ldi R30, 0xA8");
        asm("ldi R31, 0x05");
        asm("ijmp");


Есть ещё какие-то варианты?
Artem_Petrik
ИМХО наиболее прямой подход - переписать cstartup под себя.
_Артём_
Цитата(Artem_Petrik @ Mar 31 2012, 22:23) *
ИМХО наиболее прямой подход - переписать cstartup под себя.

Каким образом?
Это и непонятно.
Идеи нужны...
Artem_Petrik
Цитата(_Артём_ @ Mar 31 2012, 22:26) *
Каким образом?
Это и непонятно.
Идеи нужны...

Ну самым обычным: находите, где в ИАРе лежит cstartup.asm (или как его там .a90? дома ИАР не стоит), копируете его к себе в папку с проектом, подключаете в проект (теперь вместо стандартного, будет использоваться он), и правите его как душе угодно.
_Артём_
Цитата(Artem_Petrik @ Mar 31 2012, 22:31) *
Ну самым обычным: находите, где в ИАРе лежит cstartup.asm (или как его там .a90? дома ИАР не стоит), копируете его к себе в папку с проектом, подключаете в проект (теперь вместо стандартного, будет использоваться он), и правите его как душе угодно.


Подключил startup и добавил в него:
Код
    MODULE    ?START
    COMMON  START_SEGMENT:CODE:ROOT(1)

        EXTERN  ?C_STARTUP
        PUBLIC  ?APP_START_VECT

?APP_START_VECT:
    XJMP    ?C_STARTUP

    END

demiurg_spb
Цитата(_Артём_ @ Mar 27 2012, 20:16) *
Код
void (*FuncPtr) (void) = (void (*)(void)) ((LAST_INTVECT_ADDRESS + 2) / 2);    // Set up function pointer to address after last interrupt vector.
  FuncPtr ();

можно короче:
Код
    (*(void(*)(void))(BOOTLOADER_START_ADDRESS/2))();  // div 2 is to convert byte to word addressing mode for icall


Цитата(_Артём_ @ Mar 27 2012, 20:16) *
То есть точка входа для основной программы - это первый адрес после таблицы векторов. Но можно ли быть уверенным что это всегда так (для IAR)?
Я бы не стал на это полагаться, ибо при отсутствии обработчиков точка входа может быть расположена и поверх векторов. Кто знает что разработчики там наоптимизируют в следующий раз. Я думаю что точка входа должна быть определена линкеру и вам соответственно тоже, посмотрите внимательно на скрипт там же по вектору ресета осуществляется переход по какому-то адресу и этот адрес наверняка определён в виде какого-то имени вот его и стоит использовать.

Цитата(_Артём_ @ Mar 27 2012, 20:16) *
И ещё: насколько универсальны фунции самопрограммирования использованные в appn (ProcessPageErase, ProcessPageUpdate, Erase_One_Page)?Будут ли они работать на M8, M88? Кто-нибудь ими пользовался?
Я использую аналогичный интерфейс от gcc и никаких граблей не замечал. Так что стоит попробовать чтобы не изобретать велосипед.
Сергей Борщ
Когда-то писал простейший загрузчик для М48. Полез искать - никаких следов sad.gif Идея была простая: загрузчик не использовал прерываний. Писался в начало флеша, в таблице векторов на всех векторах, кроме RESET стояли RJMP . + <размер загрузчика> В скрипте линкера было указано, что приложение размещается со следующей за загрузчиком страницы. Приложение писалось как обычный проект, просто при линковке указывался другой адрес начала флеша. В скрипте загрузчика адрес старта приложения объявлялся как адрес первого вектора в таблице приложений. Далее все просто:
CODE
extern void Application();

void test()
{
   .....
   Application();
}
Artem_Petrik
Цитата(_Артём_ @ Apr 1 2012, 22:53) *
Подключил startup и добавил в него:
Код
    MODULE    ?START
    COMMON  START_SEGMENT:CODE:ROOT(1)

        EXTERN  ?C_STARTUP
        PUBLIC  ?APP_START_VECT

?APP_START_VECT:
    XJMP    ?C_STARTUP

    END

Так заработало?
Если линкеру правильно указать куда нужно ложить этот START_SEGMENT, то все должно работать. Ну и там, где раньше этот " XJMP ?C_STARTUP " стоял, нужно переход на бут прописать.
Я бы попробвал сделать то же, но без объявления спец сегмента, а как нибудь через ASEG и указанием
Код
ORG   LAST_INTVECT_ADDRESS + 2

чтоб лишний раз в скрипт линкера не лезть, а можно было просто подключить свой cstartup.asm и все. Но это надо пробовать, я сейчас всех тонкостей в этом деле не помню.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.