ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Четверг
2 мая
1269404 Топик полностью
VVB (20.12.2022 08:51, просмотров: 204) ответил Dingo на Вы как-то подменили Internal Boot ROM?! Или вы так обозначили начальную часть прошивки в SPI(или где она у вас хранится)?
Этапы инициализации (из SPI Flash): 

1. boot ROM загружает заголовок, один или несколько секторов по 512 байт, по 1-битному интерфейсу, с тактовой 12 МГц, с выключенными кэшами. В адрес начала static RAM. При этом небольшие части другой static RAM используется в качестве стека и может быть испорчена (я проводил натурные эксперименты и не помню адреса и диапазоны; я как раз критическую секцию + CRC для восстановления работоспособности разместил в той части SRAM, которая не портится boot ROM)

2. boot ROM декодирует заголовок, определяет адрес загрузки в SDRAM, длину программы

3. boot ROM инициализирует PLL, если это указано стартапными контактами

4. boot ROM исполняет команды из заголовка (запись в какие-то регистры МК), или не исполняет (если их нет); поэтому если в заголовке инициализируется PLL, то можно игнорировать состояние стартапного контакта для выбора PLL/12MHz

5. boot ROM делает инициализацию JTAG аналогично п.4 (используя другой стартапный контакт); поэтому если в заголовке инициализируется JTAG, то можно игнорировать состояние стартапного контакта JTAG ON/OFF

6. boot ROM переносит пользовательскую программу из SPI в SDRAM (тут я не уверен; возможно, п.7 выполняется раньше)

7. boot ROM делает/не делает инициализацию WDT используя старапный контакт; поэтому если в заголовке инициализируется WDT, то надо быть уверенным в том, что период сброса WDT настроен время, на достаточное для копирования пользовательской программы

8. boot ROM передаёт исполнение на адрес запуска, при этом не подчищая static SRAM и ничего не делая с кэшами

9. начинается классическая инициализация подготовки окружения C/C++ (зависимая от применяемого инстумента разработки, она разная в gcc/armcc/iar)

10. в рамках инициализации окружения C до вызова main производится обнуление секции .bss

11. по-умолчанию включение кэшей в коде от Nuvoton bare-metal производится после вызова main, это значит, что обнуление .bss использует одну шину SDRAM без кэшей и поэтому очень долго


Самый первый выигрыш по времени: изменить п.9-10, добавив в пользовательскую программу в ассемблерный код обработки вектора сброса включение кэшей, это дало мне более чем 10-кратный выигрыш по времени с момента рестарта до момента запуска моей программы.

Второй потенциальный выигрыш (я не проверял): добавить п.5.5, в котором IP блок SPI будет настраиваться (через команды записи регистров МК в "заголовке") на 4-битный интерфейс, это должно сократить время вычитывания из SPI Flash. Но замеры осциллографом показали, что время вычитывания "по-умолчанию" (по 1-битному SPI) у меня сейчас около 200 мс, я пока не дёргаюсь, меня устраивает. Если надо быстрее -- буду делать.