|
LPC4337, свой загрузчик. Инициализация SDRAM, мешает работе приложения |
|
|
|
May 24 2018, 06:39
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
Цитата Если после приёма прошивки (и записи её во флешь с установленным флажком "имеется новая прошивка") выполняется Ваш программный сброс, загрузчик делает как Вы написали и переходит к пункту 2 вашего списка.... и в этот момент происходит случайный сброс (например - сработал супервизор питания из-за помехи по питанию). Что получится? Да - прошивка не обновится уже никогда. laughing.gif Есть у меня bootloader-ы, которые выходят из коматоза в любом случае, главное подать питание. Там да, все сделано на энергонезависимом флаге. Я говорил о более-менее простых бутах, на основе которого можно делать хороший загрузчик. Цитата пункт 2 замечаний: Видимо Вы меня не совсем поняли. Из пользовательского ПО я перехожу в bootloader вызовом NVIC_SystemReset(). Поэтому мне не интересно, в каком режиме находится сейчас процессор и что он там выполняет. Цитата Так что такой метод передачи управления загрузчику допустим разве что в настольно-наколенных поделках. Теперь тоже так считаете? Цитата Вы писали о передаче управления бутлоадеру без сброса Нет, я писал Цитата Ровно как и ничего не мешает инициализировать указатель стека и перейти сразу на приложение явно. что контекстно подразумевает, что мы находимся в загрузчике. Речь шла о передаче управления из загрузчика в основную программу. Итого: из приложения в загрузчик - NVIC_SystemReset(), из загрузчика в приложение - как указал выше JumpToApplication(). Это просто как вариант. Я не говорю что у меня все такие загрузчики. Надежные летают щас даже
|
|
|
|
|
May 24 2018, 07:01
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(Arlleex @ May 24 2018, 07:58)  Код void HW_JumpToApplication(void) { unsigned int pFunction = *((volatile unsigned int *)(APPLICATION_BASE_ADDRESS + 4)); void (*UserApplication)(void) = (void (*)())pFunction; __set_MSP(*(volatile unsigned int *)APPLICATION_BASE_ADDRESS); UserApplication(); return; } Мне больше нравится вот так: Код void jump_to_app(void) { static const uint16_t code[] = { 0x1d01, // adds r1, r0, #4 0x6800, // ldr r0, [r0, #0] 0x4685, // mov sp, r0 0x6809, // ldr r1, [r1, #0] 0x4708 // bx r1 }; ((void (*)(int))code)(APP_BASE); }
|
|
|
|
|
May 24 2018, 07:20
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
Цитата Мне больше нравится вот так: А какие плюшки от этого? Вообще конечно из Си-кода менять MSP/PSP не есть комильфо, но с другой стороны не вижу криминала, если в функцию перехода на приложение не передавать никаких параметров. Цитата 0x1d01, // adds r1, r0, #4 0x6800, // ldr r0, [r0, #0] 0x4685, // mov sp, r0 0x6809, // ldr r1, [r1, #0] 0x4708 // bx r1 Страшно  И не будь тут комментариев, показалось бы ужасным костылем  Ведь функцию по сути можно было написать чисто на ассемблере (хоть в отдельном .s файле, либо внутри Си-функции инлайн-ассемблером).
|
|
|
|
|
May 24 2018, 08:04
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(scifi @ May 24 2018, 10:01)  Мне больше нравится вот так: .h: Код #define PFLASH_BEGIN_C 0x08000000 //адрес начала внутренней флешь МК (кэшированная область) #define FW_WORK_BEGIN 0x00020000 //смещение рабочего ПО (FIRMWARE_TARGET_WORK) относительно начала флешь extern "C" void StartWorkFw(); .cpp (в бутлоадере): Код //деинит/reset использованной в буте периферии и старт рабочего ПО IntCpuDis(); FaultCpuDis(); IntDisAll(); //отключение тактирования периферии SCU.CCU.CGAT[0].SET = B0 | B1 | B2 | B3 | B4 | B7 | B8 | B9 | B10 | B11 | B16; SCU.CCU.CGAT[1].SET = B0 | B3 | B4 | B5 | B6 | B7 | B8; SCU.CCU.CGAT[2].SET = B1 | B2 | B4 | B5 | B6 | B7 | B10; SCU.CCU.CGAT[3].SET = B2; MPUoff(); StartWorkFw(); .asm: Код SECTION .text:CODE:NOROOT(2) THUMB PUBLIC StartWorkFw StartWorkFw: LDR R0, =PFLASH_BEGIN_C + FW_WORK_BEGIN LDRD R1, R2, [R0] MOV SP, R1 BX R2 LTORG
|
|
|
|
|
May 24 2018, 08:13
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
Цитата(jcxz @ May 24 2018, 12:04)  .asm: Код SECTION .text:CODE:NOROOT(2) THUMB PUBLIC StartWorkFw StartWorkFw: LDR R0, =PFLASH_BEGIN_C + FW_WORK_BEGIN LDRD R1, R2, [R0] MOV SP, R1 BX R2 LTORG Ну в общем на вкус и цвет, как говорится. А таблицу векторов где смещаете, кстати? Тоже где-то в boot-е или в основном приложении в начале?
|
|
|
|
|
May 24 2018, 08:36
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(jcxz @ May 24 2018, 11:04)  Код SECTION .text:CODE:NOROOT(2) THUMB PUBLIC StartWorkFw StartWorkFw: LDR R0, =PFLASH_BEGIN_C + FW_WORK_BEGIN LDRD R1, R2, [R0] MOV SP, R1 BX R2 LTORG Точно! Код void jump_to_app(void) { static const uint16_t code[] = { 0xc806, // ldmia r0!, {r1, r2} 0x468d, // mov sp, r1 0x4710 // bx r2 }; ((void (*)(int))code)(APP_BASE); } Этот код будет работать и на Cortex-M0, в отличие от.
|
|
|
|
|
May 28 2018, 12:22
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
Цитата(scifi @ May 28 2018, 15:05)  Поправлю сам себя. Последний штрих: Код void jump_to_app(void) { static const uint16_t code[] = { 0xc806, // ldmia r0!, {r1, r2} 0x468d, // mov sp, r1 0x4710 // bx r2 }; ((void (*)(int))(1 + (int)code))(APP_BASE); } ИМХО, лишнее. Компилятор вроде сам это контролирует (я про режим Thumb). На ассемблере да, надо следить. P.S. Может, ошибаюсь.
|
|
|
|
|
May 28 2018, 12:52
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
Цитата(scifi @ May 28 2018, 15:46)  Не лишнее. При тестировании вскрылось. Пардон. Я вычитывал слово по нужному адресу, а там было слово из таблицы векторов прерываний (вектор сброса) - а там уже в младшем бите установлена единица. Интересно, а считается ли Ваш способ наглядным примером самомодифицирующегося кода?
Сообщение отредактировал Arlleex - May 28 2018, 12:54
|
|
|
|
|
May 28 2018, 14:42
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
Да нет, не запутался. Говорю же что ошибся насчёт лишней установки младшего бита. Признаю, что устанавливать нужно его. А насчёт СМК - слышал, но не встречался, поэтому и подумал, а почему бы коду, копирующего самого себя и передающего управление функции в ОЗУ не называться СМК. Вот и все. Поправьте, если не прав. А, у вас же static const... Все во Flash разместится...
Сообщение отредактировал Arlleex - May 28 2018, 17:57
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|