Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вопросы по реализации бутлоадера
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
mempfis_
Всем добрый день.
Стоит задача написать бутлоадер для at91sam7s64.
Есть несколько ламерских вопросов по этому поводу.

1. Правильно ли я понимаю что для ARM бутлоадер это обычная программа (в отличии от AVR) которая может начинаться с какого угодно адреса?
2. Чтобы иметь возможность прошить flash собственно подпрограммы прошивки flash должны находится в оперативной памяти?
3. Если п.1 верный то где во flash лучше располагать бутлоадер (в начале или в конце)?
4. Как быть со стартапом приложения? Если я в бутлоадере инициализирую стеки, тактовый генератор и т.д. то можно ли исключить стартап из приложения и просто вызвать main? Или лучше произвести сброс переферии и вызвать приложение со стартапом?
5. Достаточно ли будет выделить в flash сегмент и размещать в нём основную программу или в startup и LowLevelInit() нужно будет както дополнительно учитывать что в МК живёт ещё и бутлоадер?

Теперь мои соображения по поводу бутлоадера - поправте если гдето буду не прав:
- Проект бутлоадера - обычная программа - т.е. создаю в IAR5.41 проект, подключаю стартап и LowLevelInint() в которых инициализируются стеки, тактовый генератор, VIC и т.д.
- В main бутлоадера настраиваю всю необходимую мне переферию (PIT, PIO, USB и т.д.).
- Перехожу в основной цикл прораммы в котором ожидаю команды с usb-терминала.
- Если приходит команда прошивки flash - прошиваю нужную страницу памяти в секции приложения.
- Если приходит команда запуска приложения - вызываю main приложения (это если можно не вставлять startup и LowLevelInit()) или прыгаю на адрес с которого начинается основная программа.

Спасибо всем кто ответит.

P.S. Также буду благодарен ссылкам на какие-либо проекты бутлоадеров для sam7s.
P.P.S. С сайта atmel скачал какойто проект но он для ARM9 и довольно запутанный и непонятный...
aaarrr
Цитата(mempfis_ @ Jul 29 2010, 12:28) *
1. Правильно ли я понимаю что для ARM бутлоадер это обычная программа (в отличии от AVR) которая может начинаться с какого угодно адреса?
3. Если п.1 верный то где во flash лучше располагать бутлоадер (в начале или в конце)?

Обычно процессор все-таки стартует с загрузчика, поэтому в начале.

Цитата(mempfis_ @ Jul 29 2010, 12:28) *
2. Чтобы иметь возможность прошить flash собственно подпрограммы прошивки flash должны находится в оперативной памяти?

Да.

Цитата(mempfis_ @ Jul 29 2010, 12:28) *
4. Как быть со стартапом приложения? Если я в бутлоадере инициализирую стеки, тактовый генератор и т.д. то можно ли исключить стартап из приложения и просто вызвать main? Или лучше произвести сброс переферии и вызвать приложение со стартапом?

Ну уж стеки точно стоит инициализировать заново, а с периферией смотрите сами, как удобнее.

Цитата(mempfis_ @ Jul 29 2010, 12:28) *
5. Достаточно ли будет выделить в flash сегмент и размещать в нём основную программу или в startup и LowLevelInit() нужно будет както дополнительно учитывать что в МК живёт ещё и бутлоадер?

Зависит от п.4

Цитата(mempfis_ @ Jul 29 2010, 12:28) *
Теперь мои соображения по поводу бутлоадера - поправте если гдето буду не прав:

В общем-то все правильно, только почему у загрузчика нет никакой самостоятельности в плане запуска программы?

В моем варианте загрузчик действовал по такому алгоритму:
1. Проверка состояния внешнего пина, если имеется нужный уровень - переходим к п.4
2. Проверка наличия сигнатуры по определенному адресу RAM, при совпадении переходим к п.4
3. Проверка CRC имеющейся во флеш программы, если все в порядке - запускаем ее на исполнение
4. Ждем загрузку
mempfis_
Спасибо за быстрый ответ.
В целом начинает проясняться стуктура проекта.

Не могли-бы Вы поянить вот эту фразу:
Цитата
Ну уж стеки точно стоит инициализировать заново

Обозначает ли это то что я должен компилировать приложение с подключённым стартапом и вызывать приложение из бутлоадера не с ф-ии main а начиная с начала секции приложения?

Цитата
В общем-то все правильно, только почему у загрузчика нет никакой самостоятельности в плане запуска программы?

Это для отладки запуск приложения по командам с терминала. А вообще предполагается проверка CRC секции приложения и если там всё ОК то автоматический запуск приложения.

dimka76
Цитата(mempfis_ @ Jul 29 2010, 12:28) *
P.S. Также буду благодарен ссылкам на какие-либо проекты бутлоадеров для sam7s.


http://microkontroller.ru/index.php?option...l&Itemid=55
mempfis_
Цитата(dimka76 @ Jul 29 2010, 11:57) *


Спасибо за ссылку. Проект под sam7s64 - это хорошо. Жаль только что под IAR 4.41. Но думаю разберусь smile.gif
aaarrr
Цитата(mempfis_ @ Jul 29 2010, 12:53) *
Обозначает ли это то что я должен компилировать приложение с подключённым стартапом и вызывать приложение из бутлоадера не с ф-ии main а начиная с начала секции приложения?

У приложения в любом случае должна быть точка входа, и эта точка будет не main. Помимо стеков есть еще копирование секций, инициализация переменных и ZI, и все это происходит до main. Так что стартап, хоть и в сокращенном виде, но должен присутствовать.

Кроме того, еще надо отдельно определиться с векторами и ремапом, т.к. тут возможны варианты.
mempfis_
Цитата
Помимо стеков есть еще копирование секций, инициализация переменных и ZI, и все это происходит до main. Так что стартап, хоть и в сокращенном виде, но должен присутствовать.

С этим понятно - вставлю startup

Цитата
Кроме того, еще надо отдельно определиться с векторами и ремапом, т.к. тут возможны варианты.

Вот тут мне не всё понятно но спрашивать буду когда дойдёт до этого дело.
Спасибо за консультации. Займусь общей организацией проекта smile.gif
sergeeff
Ну и если вы задумаете еще и на С++ постепенно перейти, то из startup'a надо будет еще вызывать конструкторы глобальных объектов. Так что без startup'a - никуда.

Другое дело, что они будут, скорее всего, разными для bootloader'a и прикладной программы.
mempfis_
Дошёл до того момента когда бутлоадер вот-вот уже будет реализован в первом приближении.
Встал вопрос о создании файла тестовой прошивки приложения для проверки работоспособности бутлоадера.

Появились вот какие вопросы:

1. Как заставить IAR 5.41 разместить код программы с адреса отличного от 0x100000?
Для своего процессора (sam7s64) использую приведённый ниже файл flash.icf
Павильно ли я понял что поменяв начальный и конечный адреса в выделенных жирным строках я чётко дам понять линкеру что код во flash надо размещать в этом диапазоне адресов? Достаточно ли будет этого чтобы сместить весь код приложения за область бутлоадера? Или нужно будет менять ещё какието параметры в этом файле?

CODE
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x100000;
define symbol __ICFEDIT_region_ROM_end__ = 0x10FFFF;

define symbol __ICFEDIT_region_RAM_start__ = 0x200000;
define symbol __ICFEDIT_region_RAM_end__ = 0x203FFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_startup__ = 0x100;
define symbol __ICFEDIT_size_vectors__ = 0x100;
define symbol __ICFEDIT_size_cstack__ = 0x1000;
define symbol __ICFEDIT_size_sysstack__ = 0x60;
define symbol __ICFEDIT_size_irqstack__ = 0x60;
define symbol __ICFEDIT_size_heap__ = 0x0;
/*-Exports-*/
export symbol __ICFEDIT_region_ROM_start__;
export symbol __ICFEDIT_region_ROM_end__;
export symbol __ICFEDIT_region_RAM_start__;
export symbol __ICFEDIT_region_RAM_end__;
export symbol __ICFEDIT_size_startup__;
export symbol __ICFEDIT_size_vectors__;
export symbol __ICFEDIT_size_cstack__;
export symbol __ICFEDIT_size_sysstack__;
export symbol __ICFEDIT_size_irqstack__;
export symbol __ICFEDIT_size_heap__;
/**** End of ICF editor section. ###ICF###*/

define memory mem with size = 4G;
define region STA_region = mem:[from __ICFEDIT_region_ROM_start__ size __ICFEDIT_size_startup__];
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__+__ICFEDIT_size_startup__ to __ICFEDIT_region_ROM_end__];
define region VEC_region = mem:[from __ICFEDIT_region_RAM_start__ size __ICFEDIT_size_vectors__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__+__ICFEDIT_size_vectors__ to __ICFEDIT_region_RAM_end__];

define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block SYS_STACK with alignment = 8, size = __ICFEDIT_size_sysstack__ { };
define block IRQ_STACK with alignment = 8, size = __ICFEDIT_size_irqstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };

initialize by copy { readwrite };
initialize by copy { section .vectors };
do not initialize { section .noinit };

place in STA_region { section .cstartup };
place in ROM_region { readonly };
place in VEC_region { section .vectors };
place in RAM_region { readwrite, block IRQ_STACK, block SYS_STACK, block CSTACK, block HEAP };



2. Вопрос по стартапу.
Привожу стартап который я подключаю к проекту для бутлоадера (точнее для всех моих программ что стартуют с адреса во flash 0x100000).
Вопрос к знающим нужно ли в нём чтото менять чтобы использовать его для подключения к проекту который будет стартовать не с адреса 0x100000?
Сам я визуально ничего такого в нём не вижу поэтому надеюсь на помощь бывалых smile.gif

CODE
/*
IAR startup file for AT91SAM7S microcontrollers.
*/

MODULE ?cstartup

;; Forward declaration of sections.
SECTION IRQ_STACK:DATA:NOROOT(2)
SECTION CSTACK:DATA:NOROOT(3)

//------------------------------------------------------------------------------
// Headers
//------------------------------------------------------------------------------

#define __ASSEMBLY__
#include "board.h"

//------------------------------------------------------------------------------
// Definitions
//------------------------------------------------------------------------------

#define ARM_MODE_ABT 0x17
#define ARM_MODE_FIQ 0x11
#define ARM_MODE_IRQ 0x12
#define ARM_MODE_SVC 0x13
#define ARM_MODE_SYS 0x1F

#define I_BIT 0x80
#define F_BIT 0x40

//------------------------------------------------------------------------------
// Startup routine
//------------------------------------------------------------------------------

/*
Exception vectors
*/
SECTION .vectors:CODE:NOROOT(2)

PUBLIC resetVector
PUBLIC irqHandler

EXTERN Undefined_Handler
EXTERN SWI_Handler
EXTERN Prefetch_Handler
EXTERN Abort_Handler
EXTERN FIQ_Handler

ARM

__iar_init$$done: ; The interrupt vector is not needed
; until after copy initialization is done

resetVector:
; All default exception handlers (except reset) are
; defined as weak symbol definitions.
; If a handler is defined by the application it will take precedence.
LDR pc, =resetHandler ; Reset
LDR pc, Undefined_Addr ; Undefined instructions
LDR pc, SWI_Addr ; Software interrupt (SWI/SYS)
LDR pc, Prefetch_Addr ; Prefetch abort
LDR pc, Abort_Addr ; Data abort
B . ; RESERVED
LDR pc, =irqHandler ; IRQ
LDR pc, FIQ_Addr ; FIQ

Undefined_Addr: DCD Undefined_Handler
SWI_Addr: DCD SWI_Handler
Prefetch_Addr: DCD Prefetch_Handler
Abort_Addr: DCD Abort_Handler
FIQ_Addr: DCD FIQ_Handler

/*
Handles incoming interrupt requests by branching to the corresponding
handler, as defined in the AIC. Supports interrupt nesting.
*/
irqHandler:
/* Save interrupt context on the stack to allow nesting */
SUB lr, lr, #4
STMFD sp!, {lr}
MRS lr, SPSR
STMFD sp!, {r0, lr}

/* Write in the IVR to support Protect Mode */
LDR lr, =AT91C_BASE_AIC
LDR r0, [r14, #AIC_IVR]
STR lr, [r14, #AIC_IVR]

/* Branch to interrupt handler in Supervisor mode */
MSR CPSR_c, #ARM_MODE_SYS
STMFD sp!, {r1-r3, r4, r12, lr}
MOV lr, pc
BX r0
LDMIA sp!, {r1-r3, r4, r12, lr}
MSR CPSR_c, #ARM_MODE_IRQ | I_BIT

/* Acknowledge interrupt */
LDR lr, =AT91C_BASE_AIC
STR lr, [r14, #AIC_EOICR]

/* Restore interrupt context and branch back to calling code */
LDMIA sp!, {r0, lr}
MSR SPSR_cxsf, lr
LDMIA sp!, {pc}^


/*
After a reset, execution starts here, the mode is ARM, supervisor
with interrupts disabled.
Initializes the chip and branches to the main() function.
*/
SECTION .cstartup:CODE:NOROOT(2)

PUBLIC resetHandler
EXTERN LowLevelInit
EXTERN ?main
REQUIRE resetVector
ARM

resetHandler:

/* Set pc to actual code location (i.e. not in remap zone) */
LDR pc, =label

/* Perform low-level initialization of the chip using LowLevelInit() */
label:
LDR r0, =LowLevelInit
LDR r4, =SFE(CSTACK)
MOV sp, r4
MOV lr, pc
BX r0

/* Set up the interrupt stack pointer. */
MSR cpsr_c, #ARM_MODE_IRQ | I_BIT | F_BIT ; Change the mode
LDR sp, =SFE(IRQ_STACK)

/* Set up the SYS stack pointer. */
MSR cpsr_c, #ARM_MODE_SYS | F_BIT ; Change the mode
LDR sp, =SFE(CSTACK)

/* Branch to main() */
LDR r0, =?main
MOV lr, pc
BX r0

/* Loop indefinitely when program is finished */
loop4:
B loop4

END
aaarrr
Цитата(mempfis_ @ Aug 12 2010, 12:04) *
Достаточно ли будет этого чтобы сместить весь код приложения за область бутлоадера? Или нужно будет менять ещё какието параметры в этом файле?

На первый взгляд достаточно.

Цитата(mempfis_ @ Aug 12 2010, 12:04) *
Вопрос к знающим нужно ли в нём чтото менять чтобы использовать его для подключения к проекту который будет стартовать не с адреса 0x100000?

Да в общем-то ничего не надо. Разве что это можно убрать:
Код
        /* Set pc to actual code location (i.e. not in remap zone) */
        LDR     pc, =label


Только проверьте, правильно ли выполняется remap в LowLevelInit (проверяется ли текущее состояние перед переключением).
Exeland
Я тоже занят написанием загрузчика. А как заставить Keil разместить код программы с N-го адреса Флеш?
aaarrr
Цитата(Exeland @ Aug 16 2010, 14:18) *
Я тоже занят написанием загрузчика. А как заставить Keil разместить код программы с N-го адреса Флеш?

Как и в любом другом компиляторе - попросить об этом линкер. Лучше руками прописать scatter.
Exeland
Я с линкером не работал. Можете дать кусочек кода с пояснением.
aaarrr
Цитата(Exeland @ Aug 16 2010, 14:27) *
Я с линкером не работал. Можете дать кусочек кода с пояснением.

Есть два пути:
1. (неправильный, но работать будет) Просто переставьте расположение памяти на вкладке Target, scatter-файл сгенерирует среда
2. Прочитать в мануале про линкер, написать scatter самостоятельно
Второй путь можно сократить, если взять готовый файл из п.1 и исправить его, попутно сверяясь с мануалом.
mempfis_
Цитата(aaarrr @ Aug 12 2010, 15:15) *
На первый взгляд достаточно.


Сегодня всё проверил - приложение вызванное из загрузчика запустилось и работает как положено smile.gif
Спасибо за помощь smile.gif
Wano
Цитата(Exeland @ Aug 16 2010, 13:27) *
Я с линкером не работал. Можете дать кусочек кода с пояснением.


1)убрать галку на Use Memory Layout form Target Dialog на вкладке линкера и нажать Edit дабы отобразился скаттер , которым до этого собирали.
2)
Код
LR_IROM1 0x00000000 0x00038000  {   ; load region size_region
  ER_IROM1 0x00000000 0x00038000  { ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }.....
}

первые цифры в секции и есть начало куда ляжет RESET(statrup) и тд. Выбирать начало сверяясь (как сказал aaarrr) с шитом. Вторая цифра размер секции. http://www.keil.com/support/man/docs/armli...nk_cchfgafb.htm
Exeland
Поменял в Target Diolog адреса, грузится если pc=Start_Adress сделать. Прыжком с загрузчика грузится, если только не инициализировать в загрузчике периферию. Видимо придется отключать переферию перед прыжком.
Exeland
Хотя нет все работает. rolleyes.gif
Прыжок на ПО делаю так, если кому интересно:
Код
#define FW_start_adrs       0x08001c01 // Адрес размещения прошивки главной программы (должен быть нечетн. для STM323)
void (* GO_to_Start)() = (void(*)())FW_start_adrs; // Псевдофункция
...
GO_to_Start();// Прыгаем на адрес начала ПО
...

Wano
Цитата(Exeland @ Aug 17 2010, 09:16) *
Поменял в Target Diolog адреса, грузится если pc=Start_Adress сделать. Прыжком с загрузчика грузится, если только не инициализировать в загрузчике периферию. Видимо придется отключать переферию перед прыжком.


Лучше руками. Вектора сначала , а код где хотим. Прилепил примерчик , размещать исполняемый код можно куда угодно,а стартовать с векторов.
Exeland
Еще один вопрос. Необходимо разместить константы (Контрольную сумму, версию прошивки и ее размер)по заданному адресу Flash. Как это можно сделать?
aaarrr
Цитата(Exeland @ Aug 17 2010, 13:42) *
Как это можно сделать?

Можно предложить несколько способов:
1. Вбить необходимые константы в стартапе, адрес которого априори известен
2. Сделать фиксированную секцию
3. Не делать фиксированную область, а создать структуру с сигнатурой для поиска
Я бы рекомендовал первый или последний способы.
skripach
Цитата
3. Не делать фиксированную область, а создать структуру с сигнатурой для поиска

Размер сигнатуры и что в её качестве использовать? Сейчас 8 байт взятых с потолка.
aaarrr
Думаю, восьми байт как раз достаточно. Если "потолком" служил генератор псевдослучайной последовательности, то сгодится.
skripach
Цитата
Если "потолком" служил генератор псевдослучайной последовательности, то сгодится.

так и есть
Exeland
Цитата(aaarrr @ Aug 17 2010, 14:26) *
Можно предложить несколько способов:
1. Вбить необходимые константы в стартапе, адрес которого априори известен

Не могли бы вы привести пример в виде кусочка кода.
Wano
Цитата(Exeland @ Aug 19 2010, 08:41) *
Не могли бы вы привести пример в виде кусочка кода.


если в KEIL-е

в основной проге глобально const char text[] __attribute__((at(0x00001000)))={"прошивка такая-то"};

в загрузчике смотрим:
const char * text;
text = (const char*)0x00001000;

Ну или структуру сделать, как сказал aaarrr
TU-104
Цитата(mempfis_ @ Aug 16 2010, 19:44) *
Сегодня всё проверил - приложение вызванное из загрузчика запустилось и работает как положено sm.gif
Спасибо за помощь sm.gif

КАК у вас это получилось?! Вы даже про вектора не спрашивали в этой ветке. Или у вас основное приложение работает без прерываний?

Цитата(mempfis_ @ Jul 29 2010, 15:31) *
Вот тут мне не всё понятно но спрашивать буду когда дойдёт до этого дело.

А можно мне спросить, что нужно сделать с этими векторами?
У меня похожий контроллер, AT91SAM7X256:
ROM: 0x00100000-0x0013FFFF, RAM : 0x00200000-0x0020FFFF
После старта, на нулевой адрес отображается флэш.
После ремапа с нулевого адреса видна ОЗУ.

К примеру, беру 2 одинаковых проекта (под IAR 6) работающих "мигалок". Оба со своими стартапами (которые мне пока вообще не понять)
1й будет бутлоадером, будет лежать в начале флеш.
В нем пишу так:
Код
    
#define PROG_JUMP_ADDRESS    (0x00110000)
  //запрет всех прерываний
AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF;
//запуск основной программы(выход из bootloader)
work_start_address = (void(*)(void))PROG_JUMP_ADDRESS;
work_start_address();

В нем же, в этом тестовом примере в low_level_init сделан ремап RAM.
_________________________________

Беру 2й проект, ставлю в Linker-> Options:
Код
define symbol __ICFEDIT_intvec_start__ = 0x00110000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x00110000;

Загружаю стандартной самбой 1й бинарник с адреса 100000, второй с адреса 110000. Дергаю питание.
Запускается 1я мигалка, прыгает на 0х110000, запускается вторая мигалка(рабочая). Вижу отладочный текст в консоли, все ОК. Но рабочая программа доходит видимо до первого прерывания и виснет.

Что нужно сделать еще?
Заранее спасибо за ответы.



TU-104
Добавил копирование первых 64 байт прошивки в начало ОЗУ.
0х00110000 -> 0х00
Код
    
    unsigned int *adrram20 = (unsigned int *) AT91C_ISRAM;
    unsigned int *adrflash10 = (unsigned int *) AT91C_IFLASH;

adrflash10 += 0x00010000/4;
for (i=0; i<0x10; i++){
  TRACE_INFO(" 0x%08x = 0x%08x    0x%08x = 0x%08x  \n\r", adrflash10, *adrflash10, adrram20 , *adrram20);  
  *adrram20 = *adrflash10;
  adrram20++;
  adrflash10++;
}

Указал в опциях линкера старт РАМ 0х00200040.

Что-то я еще не сделал...
ar__systems
Я расскажу как я делал. (1788)

И приложение, и проект, существуют как полностью независимые приложения. соответвенно можно загрузить в чип одно приложение, и все будет работать. Можно загрузить бутлоадер также отдельно, и он тоже будет работать самостоятельно. Бутлоадер ожидает увидеть приложение по определенному адресу, и если оно там есть, выполняет переход туда, там происходит полная инициализация всего, т.к. приложение не ждет никакой поддержки бутлоадера.

При совместном использовании БЛ заменяет собой некую заглушку которая предусмотрена в приложении, которая по сути всего лишь осуществляет переход из 0 в начала startup приложения.

Преимуществ у такого подхода много, как минимум - отладка не осложняется никакими бутлоадерами и его не надо как-то особо собирать для отладки.

Обновление бутлоадера не предусмотрено, БЛ выполняется прямо из флеша.
toweroff
Цитата(ar__systems @ Feb 21 2014, 02:07) *
БЛ выполняется прямо из флеша.

а записи приложения во флеш это не мешает?
ar__systems
Цитата(toweroff @ Feb 20 2014, 17:10) *
а записи приложения во флеш это не мешает?

Нет, не мешает.... а как это могло бы мешать?
TU-104
Цитата(ar__systems @ Feb 21 2014, 04:07) *
При совместном использовании БЛ заменяет собой некую заглушку которая предусмотрена в приложении, которая по сути всего лишь осуществляет переход из 0 в начала startup приложения.

вот еще больше запутался
RabidRabbit
Как было сделано у меня (AT91SAM7S32): бутлоадер (написанный на ассемблере, размер ограничен 0x400) при старте копирует себя в ОЗУ, выполняет REMAP, выполняет переход по адресу в ОЗУ
Код
    ldr        PC, =(0x200000 + continueEntry - 0x100000)
continueEntry
; enable main oscillator and PLL
, настраивает тактирование и прочее, включает PIO контроллер, по состоянию двух пинов решает, пытаться запустить приложение или перейти в ожидание команд через DBGU. В случае попытки запуска бутлоадер проверяет (по фиксированному адресу во флэш) размер и контрольную сумму приложения, если проверка прошла, копирует векторы (из известного места во флэш) в адрес 0x20 (туда ведь уже отмаплено ОЗУ) и делает ldr PC, =0 (переход по вектору сброса). При любой ошибке следует переход на ожидание команд через DBGU). Команд всего 2 - "hello" и передача прошивки. Прошивка передаётся блоками размером со страницу флэша (в данном случае 128 байт), очередной полученный блок бутлоадер записывает во флэш, после чего отправляет подтверждение. После окончания загрузки следует попытка запуска приложения.
Само приложение построено с "дыркой" в начале рамером 0x400 - размер таблицы переходов + слово (размер приложения) + слово (контрольная сумма). При передаче бутлоадеру используется самописная программа, которая загружает бинарник в память, записывает на место размер и контрольную сумму, и потом с адреса 0x400 передаёт всё остальное постранично бутлоадеру. Соответственно при старте приложения тактирование уже настроено, можно заниматься более полезными делами.
На всякий случай начало бутлоадера:
CODE

; exception vectors - начало бутлоадера
exception_block_start
ldr pc, Reset_Addr
ldr pc, Undef_Addr
ldr pc, SWI_Addr
ldr pc, PAbt_Addr
ldr pc, DAbt_Addr
nop
ldr pc, [pc, #-0xF20] ; go to by IRQ vector
ldr pc, [pc, #-0xF20] ; go to by FIQ vector
exception_vectors
; address map for exeption vectors - сюда копируются векторы приложения
Reset_Addr
DCD Reset_Handler
Undef_Addr
DCD Undef_Handler
SWI_Addr
DCD SWI_Handler
PAbt_Addr
DCD PAbt_Handler
DAbt_Addr
DCD DAbt_Handler
exception_block_end

И начало приложения:
CODE

; exception vectors
exVectorsStart
ldr pc, Reset_Addr
ldr pc, Undef_Addr
ldr pc, SWI_Addr
ldr pc, PAbt_Addr
ldr pc, DAbt_Addr
nop
ldr pc, [pc, #-0xF20] ; go to by IRQ vector
ldr pc, [pc, #-0xF20] ; go to by FIQ vector
exVectorsEnd
; место для загрузчика
SPACE (0x400 - (exVectorsEnd - exVectorsStart))
; место для размещения данных загрузчика
SPACE 8
; address map for exeption vectors
exTableStart
Reset_Addr
DCD Reset_Handler
Undef_Addr
DCD Undef_Handler
SWI_Addr
DCD SWI_Handler
PAbt_Addr
DCD PAbt_Handler
DAbt_Addr
DCD DAbt_Handler
exTableEnd
toweroff
Цитата(ar__systems @ Feb 21 2014, 05:06) *
Нет, не мешает.... а как это могло бы мешать?

Цитата
37.3.2.6Interrupts during IAP
The on-chip flash memory is not accessible during IAP operations. When the user
application code starts executing, the interrupt vectors from the user flash area are active.
The user should either disable interrupts, or ensure that user interrupt vectors are active in
RAM and that the interrupt handlers reside in RAM, before making an IAP call (see
Section 5.4 “Vector table remapping”). The IAP code does not use or disable interrupts.
ar__systems
так прерывания выключил, и все ок
toweroff
Цитата(ar__systems @ Feb 21 2014, 21:03) *
так прерывания выключил, и все ок

ну эт да sm.gif
а можно не заморачиваться - разместил в RAM и забыл
TU-104
а все-таки подскажите, как запустить приложение с другого адреса... с рабочими прерываниями
Ведь оно работает... но без прерываний. Или ткните, где еще почитать.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.