inventor 0 28 марта, 2022 Опубликовано 28 марта, 2022 · Жалоба хочу сделать загрузчик по адресу 0x800000 st32L496 пока загрузчик не написан т.о. сама прога должна быть с адреса 0x8000000 + 0x4000 Вопрос такой, где, в каком месте мне нужно перенести вектора, чтобы программа работала файл для линкера такой: _Min_Heap_Size = 0x8000; /* required amount of heap */ _Min_Stack_Size = 0x800; /* required amount of stack */ /* Memories definition */ MEMORY { RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K FLASH (rx) : ORIGIN = 0x8000000 + 0x4000, LENGTH = 0xFC000 /*1024K - 0x4000 */ } захожу в SystemInit() и ставлю SCB->VTOR = 0x8000000 + 0x4000; /* Vector Table Relocation in Internal FLASH */ если запускаю из студии - все работает, если просто включением питания, то нет где я что то сделал неверно или не дописал? чую что этот SCB->VTOR должен быть где то в стартовом ассемблерной файле после назначения адреса стека и перед прыжком на SystemInit. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 28 марта, 2022 Опубликовано 28 марта, 2022 · Жалоба 1 час назад, inventor сказал: где я что то сделал неверно или не дописал? В командном файле компоновщика не поместили таблицу векторов прерываний в нужное место (0x8000000 + 0x4000 или куда там вам надо). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 28 марта, 2022 Опубликовано 28 марта, 2022 · Жалоба 3 часа назад, inventor сказал: и ставлю SCB->VTOR = 0x8000000 + 0x4000; /* Vector Table Relocation in Internal FLASH */ Это должен делать ваш загрузчик, вместо которого у вас пустое место. Напишите простейшую заглушку, которая будет писать VTOR, заполнять указатель стека содержимым ячейки 0x8004000 и передавать управление по адресу, указанному в ячейке 0x8004004. Да, можно VTOR прописывать и в самой программе, но как-то это кривововато выглядит. Ваша студия перед запуском загружает в PC адрес, указанный директивой ENTRY() скрипта компоновщика - поэтому при запуске из студии все работает. Правда непонятно, что при запуске из студии заносится в указатель стека. 1 час назад, jcxz сказал: В командном файле компоновщика не поместили таблицу векторов прерываний в нужное место Это необязательно - в таблице хранятся абсолютные адреса, от перемещения они не изменятся. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
inventor 0 29 марта, 2022 Опубликовано 29 марта, 2022 · Жалоба то есть в загрузчике сделать нечто подобное: /* Disable all interrupts */ RCC->CIR = 0x00000000; SCB->VTOR = APP_ADDRESS; __set_MSP(*(uint32_t *) APP_ADDRESS); __DMB(); (*((pfunc *) (APP_ADDRESS + 4))) (); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 30 марта, 2022 Опубликовано 30 марта, 2022 · Жалоба Да, примерно так. Только лучше это оформить ассемблерной вставкой, чтобы компилятор не напихал туда лишних команд работы со стеком. Я делаю так: __attribute__((noreturn)) inline void start_application(uintptr_t msp_init, void (*pc)()) { // start application, need asm inline to avoid stack corruption between MSR and BLX asm volatile ( "msr\tmsp, %[MSP]\n" "\tblx\t%[PC]\n" : : [MSP] "r" (msp_init) , [PC] "r" (pc) : ); __builtin_unreachable(); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 190 30 марта, 2022 Опубликовано 30 марта, 2022 · Жалоба 35 минут назад, Сергей Борщ сказал: __attribute__((noreturn)) inline void start_application(...) { ... } Допускаю, что здесь не совсем корректно выбран атрибут noreturn. Скорее, naked нужен. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 30 марта, 2022 Опубликовано 30 марта, 2022 · Жалоба Почему же? Возврата из этой функции нет, значит компилятор вправе выкинуть весь ненужный код (восстановление стека, возврат из функции) после нее. Смысла в naked тоже не вижу - пусть компилятор делает все то, что считает нужным. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 190 30 марта, 2022 Опубликовано 30 марта, 2022 · Жалоба 6 минут назад, Сергей Борщ сказал: Возврата из этой функции нет, значит компилятор вправе выкинуть весь ненужный код (восстановление стека, возврат из функции) после нее... На малых уровнях оптимизации noreturn, все-таки, не гарантирует отсутствие операций со стеком (прологи и эпилоги). Например, Keil, -O0, ARM Compiler 6.12 __attribute__((noreturn)) void noreturn_func(u32 i) { __asm("str r0, [r1]"); while(1); } 75: void noreturn_func(u32 i) { 0x08000E68 B082 SUB sp,sp,#0x08 0x08000E6A 4601 MOV r1,r0 0x08000E6C 9001 STR r0,[sp,#0x04] 76: __asm("str r0, [r1]"); 0x08000E6E 6008 STR r0,[r1,#0x00] 77: while(1); 0x08000E70 9100 STR r1,[sp,#0x00] 0x08000E72 E7FF B 0x08000E74 __attribute__((naked)) void naked_func(u32 i) { __asm("str r0, [r1]"); __asm("loop: b loop"); } 69: void naked_func(u32 i) { 70: __asm("str r0, [r1]"); 0x08000E64 6008 STR r0,[r1,#0x00] 71: __asm("loop: b loop"); 72: } 73: 0x08000E66 E7FE B 0x08000E66 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 30 марта, 2022 Опубликовано 30 марта, 2022 · Жалоба Я бы спросил: "Зачем именно MSR MSP, ... ?" Ведь корректным будет обеспечить, чтобы на момент старта приложения, активным был MSP (и вообще все условия работы CPU должны быть как после RESET). А тогда достаточно: MOV SP, ... что короче. Хотя это конечно и не существенно.... Например у меня аналогичное действие: .asm: SECTION .text:CODE:NOROOT(2) THUMB PUBLIC StartWorkFw StartWorkFw: LDR R0, =PFLASH_BEGIN_C + FW_WORK_BEGIN LDMIA R0!, {R1, R2} MOV SP, R1 BX R2 LTORG где: (PFLASH_BEGIN_C + FW_WORK_BEGIN) - это адрес начала образа запускаемого кода (начало таблицы векторов прерываний). И на входе в эту функцию, все прерывания должны быть запрещены. Вызов: extern "C" void StartWorkFw(); StartWorkFw(); PS: Лучше бы заострить внимание ТСа на необходимости выполнения вышеозвученного требования: Все условия работы CPU должны быть как после RESET Т.е. - режим работы CPU, состояние регистров управления CPU (регистр CONTROL, NVIC, MPU и др.), состояние периферии (вся периферия, использованная в загрузчике, должна быть сброшена/переведена в исходное состояние). Чтобы потом не наступать на неожиданные грабли, когда с загрузчиком и без оного, прикладное приложение работает по-разному. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 190 30 марта, 2022 Опубликовано 30 марта, 2022 · Жалоба 2 минуты назад, jcxz сказал: Чтобы потом не наступать на неожиданные грабли, когда с загрузчиком и без оного, прикладное приложение работает по-разному. Некий признак в NOINIT-регионе ОЗУ + повторный сброс (ручной или по WDT). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 30 марта, 2022 Опубликовано 30 марта, 2022 · Жалоба 2 минуты назад, Arlleex сказал: Некий признак в NOINIT-регионе ОЗУ + повторный сброс (ручной или по WDT). А во всех МК это возможно? Например: в некоторых продвинутых МК (Infineon например) есть опция "Контроль чётности ОЗУ". Если включить её и выполнить чтение ОЗУ (в которое после RESET-а и до этого момента ещё не было выполнено ни одной записи), то получим Exception. Да, конечно, можно отключить этот контроль и прочитать, но может есть МК, в которых такой контроль неотключаем? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 30 марта, 2022 Опубликовано 30 марта, 2022 · Жалоба 11 минут назад, Arlleex сказал: Некий признак в NOINIT-регионе ОЗУ (RCC->CSR & RCC_CSR_SFTRSTF) ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 190 30 марта, 2022 Опубликовано 30 марта, 2022 · Жалоба 9 минут назад, Сергей Борщ сказал: (RCC->CSR & RCC_CSR_SFTRSTF) ? Ну да. В STM32 использую этот флажок периферии, а в каких-то проектах дополнительно делаю мониторинг кодового слова в ОЗУ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 30 марта, 2022 Опубликовано 30 марта, 2022 · Жалоба 2 минуты назад, Сергей Борщ сказал: (RCC->CSR & RCC_CSR_SFTRSTF) ? Если так делать, то невозможно будет перейти из основного приложения в загрузчик. Когда например основное приложение получило прошивку и хочет передать её загрузчику для обновления. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 190 30 марта, 2022 Опубликовано 30 марта, 2022 · Жалоба 1 минуту назад, jcxz сказал: Если так делать, то невозможно будет перейти из основного приложения в загрузчик. NVIC_SystemReset(). Опять же, в случае, если приложение может генерировать программный сброс только для входа в этот самый прошиватор. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться