Полная версия этой страницы:
Bootloader или загрузчик
Anatrulij
Apr 24 2009, 10:06
Расскажите какие функции выполняет встроенный bootloader и как написать свой(и где он будет находиться). (ядро LPC2468/78)
З.Ы. когда на форумах вспоминуют про Bootloader и про загрузчик - то имеют ввиду одно и тоже?
HARMHARM
Apr 24 2009, 10:14
Цитата(Anatrulij @ Apr 24 2009, 13:06)

Расскажите какие функции выполняет встроенный bootloader и как написать свой(и где он будет находиться). (ядро LPC2468/78)
Уйму раз на форуме писали.
Например
здесь и
здесь. Пооиск - рулииит. Для google используйте тэг:
Код
site:electronix.ru
Цитата
З.Ы. когда на форумах вспоминуют про Bootloader и про загрузчик - то имеют ввиду одно и тоже?
Да.
Anatrulij
Apr 24 2009, 14:17
В данных ссылках я не увидел где конкретно находиться системный(или как он там называется) загружчик(по какому адресу) и как он влияет на работу программы(что он вообще делает, если я сам пишу загрузчик).
И провильно ли я понял: в самом начале я прошиваю программу(bootloader), а уже эта программа(если надо) по нужным адресам записывает другую программу(основную)?
HARMHARM
Apr 24 2009, 14:52
Цитата(Anatrulij @ Apr 24 2009, 17:17)

В данных ссылках я не увидел где конкретно находиться системный(или как он там называется) загружчик(по какому адресу) и как он влияет на работу программы(что он вообще делает, если я сам пишу загрузчик).
Где поместите, там и будет. Обычно в начале флеша. Практически - никак не влияет. Обычно загрузчик только обновляет основную программу. Загрузчик запускается по включению питания или по переходу из основной программы.
Цитата
И провильно ли я понял: в самом начале я прошиваю программу(bootloader), а уже эта программа(если надо) по нужным адресам записывает другую программу(основную)?
Провильно. Впрочем, можно склеить их на этапе hex-файлов, и прошивать вместе (при первой прошивке пустого контроллера).
Anatrulij
Apr 24 2009, 15:31
Я под системным загрузчиком имел в виду загрузчик который идет вместе с контроллером - прошитый там навсегда(а может и нет)? Есть ли такой(где то здесь на форуме упоминали об таком)?
Сергей Борщ
Apr 24 2009, 21:19
Цитата(Anatrulij @ Apr 24 2009, 18:31)

Есть ли такой(где то здесь на форуме упоминали об таком)?
Есть такой. И описан он не на форуме, а (неожиданно, правда?) в LPC24xx User Manual, раздел: LPC24XX Flash memory programming firmware.
Anatrulij
Apr 24 2009, 21:26
А по какому адресу он расположен, и какие его функции?
Сергей Борщ
Apr 24 2009, 22:29
Цитата(Anatrulij @ Apr 25 2009, 00:26)

А по какому адресу он расположен, и какие его функции?
Это все описано в том самом мануале. Сомневаюсь, что кто-то из участников форума захочет перевести его для вас.
Anatrulij
Apr 28 2009, 11:02
На этом этапе мне пока все понятно.
Как я понял загрузчики - однотипные програмки.
Копнем теперь глубже - реализация загрузчика. Каким образом мне проверять есть ли во флеше рабочая прошивка?
Сергей Борщ
Apr 28 2009, 11:26
Цитата(Anatrulij @ Apr 28 2009, 14:02)

Копнем теперь глубже - реализация загрузчика. Каким образом мне проверять есть ли во флеше рабочая прошивка?
Посчитать ее контрольную сумму.
Anatrulij
Apr 28 2009, 11:42
Из загрузчика я считаю контрольную сумму записанной во флеше программы, а потом сравниваю ее с контрольной суммой до этого посчитаную (и где-то записаной во флеше). Правильно ли я понял?
HARMHARM
Apr 28 2009, 12:11
Цитата(Anatrulij @ Apr 28 2009, 14:42)

Из загрузчика я считаю контрольную сумму записанной во флеше программы, а потом сравниваю ее с контрольной суммой до этого посчитаную (и где-то записаной во флеше). Правильно ли я понял?
Да, конечно. Удобно положить контрольную сумму сразу после тела программы.
Anatrulij
Apr 28 2009, 12:49
HARMHARM >> Да, конечно. Удобно положить контрольную сумму сразу после тела программы.
А от куда загрузчик знает где конец программы?
Сергей Борщ
Apr 28 2009, 16:48
Цитата(Anatrulij @ Apr 28 2009, 15:49)

А от куда загрузчик знает где конец программы?
Есть несколько путей:
1) Он может считать контрольную сумму всей доступной приложению памяти. В последней ячейке будет контрольная сумма.
2) В приложении по заранее оговоренному адресу хранится его размер.
Anatrulij
Apr 29 2009, 13:07
А где в стартапе указано адрес начала программы, адрес начала бутлоадера?
я нашел вот такой код:
Код
Vectors LDR PC, Reset_Addr
LDR PC, Undef_Addr
LDR PC, SWI_Addr
LDR PC, PAbt_Addr
LDR PC, DAbt_Addr
NOP ; Reserved Vector
; LDR PC, IRQ_Addr
LDR PC, [PC, #-0x0120] ; Vector from VicVectAddr
LDR PC, FIQ_Addr
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
DCD 0 ; Reserved Address
IRQ_Addr DCD IRQ_Handler
FIQ_Addr DCD FIQ_Handler
Undef_Handler B Undef_Handler
SWI_Handler B SWI_Handler
PAbt_Handler B PAbt_Handler
DAbt_Handler B DAbt_Handler
IRQ_Handler B IRQ_Handler
FIQ_Handler B FIQ_Handler
но ни где больше переменные не упоминаються(то есть нет присвоения им каких-либо значений)
З.Ы. а есть описание кода в стартапе или описание того, как грамотно сделать стартап?
HARMHARM
Apr 29 2009, 13:21
Цитата(Anatrulij @ Apr 29 2009, 16:07)

А где в стартапе указано адрес начала программы, адрес начала бутлоадера?
З.Ы. а есть описание кода в стартапе или описание того, как грамотно сделать стартап?
В стартапе указан адрес инструкции, которую станет выполнять микроконтроллер. А у что там будет - бутлоадер или приложение - решать вам.
Это:
Код
Vectors LDR PC, Reset_Addr
первая инструкция, которую выполнит контроллер. Загрузка из Reset_Addr значения Reset_Handler в счетчик команд, по сути безусловный переход. Vectors это просто метка.
Это:
Код
Reset_Addr DCD Reset_Handler
Описание входной точки программы. Reset_Handler подставит линкер при сборке. Reset_Addr это метка.
Инструкции как таковой я не видел. Хорошо сделаный стартап выкладывал Zltigo
здесь. Правда, там много и того, что для вас будет лишним пока.
Anatrulij
Apr 29 2009, 13:57
А линкер это тоже отдельный фалик прикрученный к проекту?
HARMHARM
Apr 29 2009, 14:08
Цитата(Anatrulij @ Apr 29 2009, 16:57)

А линкер это тоже отдельный фалик прикрученный к проекту?
Wiki.Файлик, прикрученный к проекту - это скрипт линкера. У IAR 4 это .xcl, у 5 .icf.
Вообще-то это все есть в документации к IAR.
Anatrulij
Apr 29 2009, 14:15
я пишу на Keil
HARMHARM
Apr 29 2009, 14:18
Цитата(Anatrulij @ Apr 29 2009, 17:15)

я пишу на Keil
Телепатов нет...
У Keil тоже есть документация...
defunct
Apr 29 2009, 14:25
Цитата(Anatrulij @ Apr 29 2009, 17:15)

я пишу на Keil
для RVDS компилятора - см scatter file (.sct)
Anatrulij
Apr 30 2009, 05:41
defunct>>для RVDS компилятора - см scatter file (.sct)
Смотрел я этот файл. вот его содержание:
LR_IROM1 0x00000000 0x00080000 { ; load region size_region
ER_IROM1 0x00000000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x40000000 0x00010000 { ; RW data
.ANY (+RW +ZI)
}
}
ER_IROM1 0x00000000 0x00080000 - значит что с адреса 0x00080000 начинается выполнение моей программи?
А где написано чему равна переменная Reset_Addr?
sergeeff
Apr 30 2009, 05:55
А Reset_Addr - это метка первой команды вашего bootloader'a. Вы для начала разобрались с тем, с какого адреса стартует ваш процессор? Как устроена таблица векторов прерываний? С самими командами ассемблера?
Вообще полезно для начала детально изучить startup файл на предмет того, как он устроен.
Anatrulij
Apr 30 2009, 06:01
Цитата(sergeeff @ Apr 30 2009, 08:55)

Вообще полезно для начала детально изучить startup файл на предмет того, как он устроен.
Вот я и начал детально изучать startup файл
Anatrulij
Apr 30 2009, 09:24
Что-то я не могу найти в Кейле, где указывается с какого адреса начинается моя программа.
HARMHARM
Apr 30 2009, 11:36
Цитата(Anatrulij @ Apr 30 2009, 12:24)

Что-то я не могу найти в Кейле, где указывается с какого адреса начинается моя программа.
А зачем вам это понадобилось? Кроме того есть разница - начало программы и точка входа...
В любом случае - начало программы определяется в scatter file, точку входа линкер подставит сам когда все скомпонует.
Anatrulij
Apr 30 2009, 11:42
А где в scatter file указан адрес начала программи
HARMHARM
Apr 30 2009, 14:12
Цитата(Anatrulij @ Apr 30 2009, 14:42)

А где в scatter file указан адрес начала программи
Я мало понимаю в Keil, но кажется что строка
Код
ER_IROM1 0x00000000 0x00080000
указывает что линкер может разместить программу в этом диапазоне...
Скорее всего с адреса 0 и разместит.
Если хотите знать точно - смотрите в лог линкера.
Anatrulij
Apr 30 2009, 14:33
А как с бутлоадера передать управление на загруженную программу, а с программы (по необходимости) назад на бутлоадер?
HARMHARM
Apr 30 2009, 18:49
Цитата(Anatrulij @ Apr 30 2009, 17:33)

А как с бутлоадера передать управление на загруженную программу, а с программы (по необходимости) назад на бутлоадер?
С бутоладера - примерно так:
Код
extern __noreturn void switch_to_application();
ClearWDT();
__disable_interrupt();
switch_to_application();
При этом в ключах линкера объявлен символ (для IAR):
Код
-Dswitch_to_application=00018010
Естественно, есть соглашение (моё с самим собой), что по адресу 0х00018010 находится точка входа в приложение.
Из приложения в бутлоадер тоже можно так делать, но я предпочитаю отравить внутренний watchdog неправильной последовательностью.
Anatrulij
May 1 2009, 07:32
А для Keil?
sergeeff
May 1 2009, 10:15
Цитата(Anatrulij @ May 1 2009, 10:32)

А для Keil?
Не надо придумывать себе проблемы там, где их нет.
В любом С компиляторе:
Код
typedef void (*pt2Function)(void);
pt2Function BootCall = (pt2Function)0x1000; // адрес, куда надо перейти
BootCall(); // собственно переход
Anatrulij
May 1 2009, 10:50
После окончания работы функции, куда передается управление, или можно указать адрес функции main загруженной бутлоадером основной программы? Тогда возникает еще вопрос - main начинается с первого байта прошивки?
sergeeff
May 1 2009, 11:11
Цитата(Anatrulij @ May 1 2009, 13:50)

После окончания работы функции, куда передается управление, или можно указать адрес функции main загруженной бутлоадером основной программы? Тогда возникает еще вопрос - main начинается с первого байта прошивки?
Вы продумайте организацию работы вашего устройства. Что и в каком порядке инициализируется. Чтобы нормально стартовала ваша прикладная программа, т.е. main() к моменту ее вызова надо, чтобы были инициализированы все необходимые hardware-устройства (по крайней мере так принято), инициализирован сегмент bss, может быть скопирован сегмент данных data из FLASH в RAM, вызваны конструкторы глобальных объектов (в случае использования С++), инициализирована таблица прерываний.
Так что помозгуйте кто (bootloader или прикладная программа) что из этого списка и в какой последовательности инициализирует - и вперед.
Anatrulij
May 2 2009, 11:25
Цитата(sergeeff @ May 1 2009, 14:11)

Так что помозгуйте кто (bootloader или прикладная программа) что из этого списка и в какой последовательности инициализирует - и вперед.
Сразу будет записываться бутлоадер, а он же, по необходимости, будет обновлять основную прошивку.
я просто еще не знаю как это все правильно организовуется.
Мне так и не ответили на вопрос: После окончания работы функции, куда передается управление, или можно указать адрес функции main загруженной бутлоадером основной программы? Тогда возникает еще вопрос - main начинается с первого байта прошивки?
HARMHARM
May 2 2009, 11:53
Цитата(Anatrulij @ May 2 2009, 14:25)

я просто еще не знаю как это все правильно организовуется.
Есть несколько разных вариантов...
Цитата
Мне так и не ответили на вопрос: После окончания работы функции, куда передается управление, или можно указать адрес функции main загруженной бутлоадером основной программы? Тогда возникает еще вопрос - main начинается с первого байта прошивки?
Работы какой функции?
Можно указать на main основной программы, если вы решили проводить всю инициализацию в загрузчике, и не используете C++.
main начнется там, где его расположит линкер. Можно в принципе расположить main с первого байта прошивки, однако обычно в начале прошивки лежит её описание и векторы точек входа. То есть напрмер версия прошивки, длина прошивки, потом точки входа в приложение, в SWI, в FIQ, еще куда-нибудь.
Anatrulij
May 2 2009, 12:10
Цитата(HARMHARM @ May 2 2009, 14:53)

Есть несколько разных вариантов...
Можете описать данные варианты.
Если есть примерчик, выложите пожалуйста.
HARMHARM
May 3 2009, 19:27
Цитата(Anatrulij @ May 2 2009, 15:10)

Можете описать данные варианты.
Если есть примерчик, выложите пожалуйста.
Читайте
тему, там есть ссылки...
Anatrulij
May 4 2009, 11:38
Спасибо за ссылку. Сложновато пока для меня. может у кого то есть по проще? или где-то по этапам расписано, что и как делать.
Цитата(Anatrulij @ May 4 2009, 14:38)

или где-то по этапам расписано, что и как делать.
Значит так. Для начала Вы пропустили самый первый этап - нужно хоть чего-то достичь относительно самостоятельно. Например, написать моргающий светодиод и уж точно самостоятельно досконально разобраться как это и комплятор работают.
Anatrulij
May 4 2009, 12:08
Цитата(zltigo @ May 4 2009, 14:48)

Значит так. Для начала Вы пропустили самый первый этап - нужно хоть чего-то достичь относительно самостоятельно. Например, написать моргающий светодиод и уж точно самостоятельно досконально разобраться как это и комплятор работают.
Мигание светодиодом - это уже пройденный этам.
Щас поставил перед собой задачу - написать бутлоадер, который прошивает во флеш основную программу через CAN.
С чем разобрался: могу писать во флеш посредством IAP(с разположением секторов и прочее - понятно), с СAN-ном тоже знаком не плохо.
Решил, что бутлоадер будет разположен в нулевом (если не хватит, то и в первом) секотрах. При старет будет проверяться есть ли рабочая прошивка, если есть - то прыгаем на нее, в противном случае ждем данных с CAN. По каманде из основной прошивки можно пригнуть на бутлоадер. Так же будет несколько команд по которым будет возвращаться номер прошивки и прочие нужные мне данные - Вот не знаю пока как это все реализовать, с чего начать???
sergeeff
May 7 2009, 08:53
Никак не могу понять, что же вам не понятно? Сами же все внятно описали, где-что будет лежать и что должно делать. Ну так и реализовывайте!
Anatrulij
May 7 2009, 11:38
Цитата(sergeeff @ May 7 2009, 11:53)

Никак не могу понять, что же вам не понятно? Сами же все внятно описали, где-что будет лежать и что должно делать. Ну так и реализовывайте!
я как раз не знаю как это реализовать
sergeeff
May 7 2009, 18:01
Для начала, считайте, что у вас пока одна единственная задача, имеющая собственный main(). У этой задачи есть low_level_init() - инициализация необходимого по-минимуму железа (CAN, в частности) и в main() - какой-нибудь "Hello world". Все это должно лежать в нулевом секторе flash. Когда все это заработает - это 80% успеха.
Anatrulij
May 7 2009, 19:34
Цитата(sergeeff @ May 7 2009, 21:01)

Для начала, считайте, что у вас пока одна единственная задача, имеющая собственный main(). У этой задачи есть low_level_init() - инициализация необходимого по-минимуму железа (CAN, в частности) и в main() - какой-нибудь "Hello world". Все это должно лежать в нулевом секторе flash. Когда все это заработает - это 80% успеха.
Ок. Спасибо.
Сергей Борщ
May 8 2009, 07:34
Цитата(Anatrulij @ May 7 2009, 14:38)

я как раз не знаю как это реализовать
Посмотрите, как это реализовывали до вас. Вот, например,
AVR231:AES Bootloader. Да, он для совершенно другого процессора, но описание достаточно подробное, а в С-коде разобраться нетрудно.
Anatrulij
Jun 12 2009, 07:32
Был отвлечен другим делом, теперь можно вернуться к загузчику.
Цитата(Сергей Борщ @ May 8 2009, 10:34)

Посмотрите, как это реализовывали до вас. Вот, например,
AVR231:AES Bootloader. Да, он для совершенно другого процессора, но описание достаточно подробное, а в С-коде разобраться нетрудно.
Спасибо за ссылку. Посмотрел.
Логику бутлоадера я понял, теперь дело в реализации, но еще не до конца понял как передается управление на основную(прошитую) программу
Anatrulij
Jun 12 2009, 08:35
В IAP указано что можно писать до 4kB, а как быть с секторами которые "важут" 32kB?
SasaVitebsk
Jun 12 2009, 10:54
Цитата(Anatrulij @ Jun 12 2009, 11:35)

В IAP указано что можно писать до 4kB, а как быть с секторами которые "важут" 32kB?
Не совсем понятно о чём вы. Если про запись блоками по 32кб, то набираете эти 32к мелкими блоками и записываете.
Anatrulij
Jun 12 2009, 11:08
Цитата(SasaVitebsk @ Jun 12 2009, 13:54)

Не совсем понятно о чём вы. Если про запись блоками по 32кб, то набираете эти 32к мелкими блоками и записываете.
Извените, если не правельно задал вопрос - переформирую его.
в команде записи во флеш указываешь в какой сектор и сколько писать, так как размер 10 - 21 секторов 31кБ, а в команде можно указать не более 4 кБ, как мне записать остальные данные в этот сектор.
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.