Arlleex 183 24 мая, 2018 Опубликовано 24 мая, 2018 · Жалоба Если после приёма прошивки (и записи её во флешь с установленным флажком "имеется новая прошивка") выполняется Ваш программный сброс, загрузчик делает как Вы написали и переходит к пункту 2 вашего списка.... и в этот момент происходит случайный сброс (например - сработал супервизор питания из-за помехи по питанию). Что получится? Да - прошивка не обновится уже никогда. laughing.gif Есть у меня bootloader-ы, которые выходят из коматоза в любом случае, главное подать питание. Там да, все сделано на энергонезависимом флаге. Я говорил о более-менее простых бутах, на основе которого можно делать хороший загрузчик. пункт 2 замечаний: Видимо Вы меня не совсем поняли. Из пользовательского ПО я перехожу в bootloader вызовом NVIC_SystemReset(). Поэтому мне не интересно, в каком режиме находится сейчас процессор и что он там выполняет. Так что такой метод передачи управления загрузчику допустим разве что в настольно-наколенных поделках. Теперь тоже так считаете? :rolleyes: Вы писали о передаче управления бутлоадеру без сброса Нет, я писал Ровно как и ничего не мешает инициализировать указатель стека и перейти сразу на приложение явно. что контекстно подразумевает, что мы находимся в загрузчике. Речь шла о передаче управления из загрузчика в основную программу. Итого: из приложения в загрузчик - NVIC_SystemReset(), из загрузчика в приложение - как указал выше JumpToApplication(). Это просто как вариант. Я не говорю что у меня все такие загрузчики. Надежные летают щас даже :rolleyes: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 24 мая, 2018 Опубликовано 24 мая, 2018 · Жалоба 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); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 24 мая, 2018 Опубликовано 24 мая, 2018 · Жалоба Мне больше нравится вот так: А какие плюшки от этого? Вообще конечно из Си-кода менять MSP/PSP не есть комильфо, но с другой стороны не вижу криминала, если в функцию перехода на приложение не передавать никаких параметров. 0x1d01, // adds r1, r0, #4 0x6800, // ldr r0, [r0, #0] 0x4685, // mov sp, r0 0x6809, // ldr r1, [r1, #0] 0x4708 // bx r1 Страшно :biggrin: И не будь тут комментариев, показалось бы ужасным костылем :rolleyes: Ведь функцию по сути можно было написать чисто на ассемблере (хоть в отдельном .s файле, либо внутри Си-функции инлайн-ассемблером). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 24 мая, 2018 Опубликовано 24 мая, 2018 · Жалоба А какие плюшки от этого? Работает везде, используется только стандартный Си. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 24 мая, 2018 Опубликовано 24 мая, 2018 · Жалоба Мне больше нравится вот так: .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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 24 мая, 2018 Опубликовано 24 мая, 2018 · Жалоба .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-е или в основном приложении в начале? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 24 мая, 2018 Опубликовано 24 мая, 2018 · Жалоба 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, в отличие от. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 24 мая, 2018 Опубликовано 24 мая, 2018 · Жалоба Ну в общем на вкус и цвет, как говорится. А таблицу векторов где смещаете, кстати? Тоже где-то в boot-е или в основном приложении в начале? само запускаемое приложение программирует всю периферию как ему надо. Бутлоадер только обеспечивает чтобы после него регистры периферии были в изначальном состоянии. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 28 мая, 2018 Опубликовано 28 мая, 2018 · Жалоба Точно! ... Этот код будет работать и на Cortex-M0, в отличие от. Поправлю сам себя. Последний штрих: 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); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 28 мая, 2018 Опубликовано 28 мая, 2018 · Жалоба Поправлю сам себя. Последний штрих: 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. Может, ошибаюсь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 28 мая, 2018 Опубликовано 28 мая, 2018 · Жалоба ИМХО, лишнее. Компилятор вроде сам это контролирует (я про режим Thumb). На ассемблере да, надо следить. P.S. Может, ошибаюсь. Не лишнее. При тестировании вскрылось. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 28 мая, 2018 Опубликовано 28 мая, 2018 (изменено) · Жалоба Не лишнее. При тестировании вскрылось. Пардон. Я вычитывал слово по нужному адресу, а там было слово из таблицы векторов прерываний (вектор сброса) - а там уже в младшем бите установлена единица. Интересно, а считается ли Ваш способ наглядным примером самомодифицирующегося кода? Изменено 28 мая, 2018 пользователем Arlleex Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 28 мая, 2018 Опубликовано 28 мая, 2018 · Жалоба Пардон. Я вычитывал слово по нужному адресу, а там было слово из таблицы векторов прерываний (вектор сброса) - а там уже в младшем бите установлена единица. Интересно, а считается ли Ваш способ наглядным примером самомодифицирующегося кода? Мне кажется, вы запутались :wacko: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 28 мая, 2018 Опубликовано 28 мая, 2018 (изменено) · Жалоба Да нет, не запутался. Говорю же что ошибся насчёт лишней установки младшего бита. Признаю, что устанавливать нужно его. А насчёт СМК - слышал, но не встречался, поэтому и подумал, а почему бы коду, копирующего самого себя и передающего управление функции в ОЗУ не называться СМК. Вот и все. Поправьте, если не прав. А, у вас же static const... Все во Flash разместится... Изменено 28 мая, 2018 пользователем Arlleex Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться