Я полагаю, что у меня есть проблема с моим скриптом компоновщика, но я не уверен, что это настоящий виновник здесь.
Фон:
Я использую STM32F730 в проекте.У uC есть вспышка на 64 КБ и 256 КБ оперативной памяти.Из них 64K - это TCM, 192k - обычная RAM.Проект превысит 64 КБ внутренней флэш-памяти, поэтому я собираюсь запустить дополнительный код из ОЗУ.На плате есть внешняя флэш-память, поэтому при загрузке УК выполнит процедуру загрузки со встроенной флэш-памяти, которая считывает данные со встроенной флэш-памяти через SPI и сохраняет данные в нужном месте в ОЗУ.Эта часть работает, но только иногда.Флэш-память запрограммирована несколькими способами, но я уверен, что необходимый код находится там.Кроме того, моя ошибка возникает при запуске runnign от отладчика, а загрузка с флэш-памяти не выполняется.
Все проблемы будут касаться запуска из отладчика.В данный момент код не загружается с микросхемы.
У меня включены длинные вызовы функций, чтобы разрешить переход к ОЗУ, что решило одну проблему, которая возникла у меня, но не эту.
Проблема :
Иногда , код работает без нареканий при загрузке через отладчик.В других случаях код не работает вообще, и серьезные неисправности.Я не эксперт по встраиванию (я в основном занимаюсь проектированием печатных плат и ПЛИС), но мне удалось пройтись по сборке и найти странные вещи, которые вызывают проблему, но не то, почему проблема возникает.Мой текущий проект имеет драйвер IMU, загруженный в ОЗУ, и должен отправить данные обратно через USB CDC.Это работает, когда загружается полностью во флэш-памяти, но не всегда в оперативной памяти.Когда я включаю оптимизацию отладки, это работает, например, но никакая оптимизация не вызывает ошибку.
Я изменил свой компоновщик следующим образом:
/* Specify the memory areas */
MEMORY
{
TCM_RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K
CODE_RAM (xrw) : ORIGIN = 0x20010000, LENGTH = 64K
DATA_RAM (xrw) : ORIGIN = 0x20020000, LENGTH = 112K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 64K
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
/* NP 2019-03-15 - RAM Executable code should be linked to RAM */
/* NOTE: With code linked this way it WILL NOT RUN WITHOUT THE DEBUGGER OR BOOTLADED */
/* Any loaded code will be wiped from RAM on a power cycle. */
.coderam :
{
. = ALIGN(4);
__RAM_CODE_SECTION_START = .;
*(.text.imu*)
. = ALIGN(4);
__RAM_CODE_SECTION_END = .;
}>FLASH//CODE_RAM
/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH
Каждая функция драйвера imu начинается с imu *, поэтому я пытаюсь загрузить все функции imu в ОЗУ с помощью строки *(.text.imu*)
, Я пытался указать imu.o, но не смог выяснить правильный синтаксис после большого количества поисков, проб и ошибок. Я переключаюсь между хранением imu. * Во флэш-памяти и RAM по биту с комментариями. Обратите внимание, что когда я использую флэш-памятьон хранит его по адресу 0x0, почему это так? Я думаю, что это вопрос для начинающих, но я не понимаю, почему.
Проблема: я столкнулся с проблемой в функции инициализации, которая являетсяпервый вызов функции для фрагмента кода ОЗУ. Это фрагмент кода С:
uint8_t imu_init(void)
{
uint8_t retry_cnt = 0U;
imu_trans.device_csn_bank = IMU_CSN_BANK;
imu_trans.device_csn_pin = IMU_CSN_PIN;
imu_trans.device = DEVICE_IMU;
imu_trans.speed = SPI_SPEED_6_75MBIT;
imu_trans.rxBuf = imuRxBuf;
**Continues, but hard fault occurs earlier**
При просмотре сборки в моей функции инициализации при запуске из ОЗУ выполняется следующий код:
imu_init:
20010000: 0x000080b5 imu_init+0 push {r7, lr}
20010002: 0x000082b0 imu_init+2 sub sp, #8
20010004: 0x000000af imu_init+4 add r7, sp, #0
69 uint8_t retry_cnt = 0U;
20010006: 0x00000023 imu_init+6 movs r3, #0
20010008: 0x00000000 imu_init+8 movs r0, r0
71 imu_trans.device_csn_bank = IMU_CSN_BANK;
2001000a: 0x00001d4b imu_init+10 ldr r3, [pc, #116] ; (0x20010080 <imu_init+128>)
2001000c: 0x00000000 imu_init+12 movs r0, r0
2001000e: 0x00000060 imu_init+14 str r0, [r0, #0]
72 imu_trans.device_csn_pin = IMU_CSN_PIN;
20010010: 0x00fb7100 imu_init+16 ; <UNDEFINED> instruction: 0xfb000071
20010014: 0x0000001d imu_init+20 adds r0, r0, #4
20010016: 0x00004a5a imu_init+22 ldrh r2, [r1, r1]
73 imu_trans.device = DEVICE_IMU;
20010018: 0x0000001b imu_init+24 subs r0, r0, r4
2001001a: 0x00004b4f imu_init+26 ldr r7, [pc, #300] ; (0x20010148 <imu_process_vals+4>)
2001001c: 0x0000f400 imu_init+28 lsls r4, r6, #3
74 imu_trans.speed = SPI_SPEED_6_75MBIT;
Очевидно, что это жесткие ошибки на линии 20010010: 0x00fb7100 imu_init+16 ; <UNDEFINED> instruction: 0xfb000071
. Интересно (и вот что я не получаю), которого нет в шестнадцатеричном файле!?!
*snip*
:020000042001D9
:1000000080B582B000AF0023FB711D4B1D4A5A60C2
:100010001B4B4FF480721A80194B01221A72184B35
*snip*
Началотретьей линии - инструктажна!но браузер памяти показывает:
0x0000000020010000 B082B580 2300AF00 4B1D0000 .µ.°.¯.#...K
0x000000002001000C 60000000 0071FB00 5A4A1D00 ...`.ûq...JZ
Так что, похоже, что в оперативной памяти плохая инструкция, но почему !?Похоже, что 0x2001000C тоже поврежден, поскольку не соответствует шестнадцатеричному файлу.Сначала я думал, что что-то в моем процессе загрузки делает это, но это происходит, если я также установил точку останова в обработчике сброса, поэтому я не понимаю причину.Я думал, что это была коррупция SWD, но она всегда одинакова, поэтому я не уверен, что это тоже фактор.Первоначально я думал, что некоторые из этих инструкций были состояниями ожидания (mov r0, r0), но теперь я думаю, что это искаженные значения?
Неудивительно, что код при загрузке на флэш-память читается так же, как и шестнадцатеричный файл:
0x000000000800AEC4 B082B580 2300AF00 4B1D71FB 605A4A1D F44F4B1B 801A7280 .µ.°.¯.#ûq.K.JZ`.KOô.r..
0x000000000800AEDC 22014B19 4B18721A 729A2202 4A184B16 4B1560DA 611A4A17 .K.".r.K.".r.K.JÚ`.K.J.a
Итак, TL; DR: 1. Если я загружаю все во флэш-памяти, он работает нормально 2Если я загружаю драйвер imu в ОЗУ, а все остальное во флэш-памяти, то это приводит к сбоям 3. Если я включаю оптимизацию отладки -Og, она снова работает, но может переместить ошибку в другое место.
Любая помощь будет принята с благодарностью, я потратил около 30 часов, пытаясь заставить эту, казалось бы, простую вещь работать (и она сработала! Затем она прекратилась), и у меня заканчиваются идеи, чтобы попытаться,
Спасибо, Ник
РЕДАКТИРОВАТЬ
Я думаю, что мог бы проследить это немного дальше ... Я попытался загрузить тот же файл из утилиты ST link и просмотреть память, затем попытаться загрузить отладчик и просмотреть память.
Конечно, код, загружаемый отладчиком, отличается от кода, загружаемого утилитой ST Link. Код, загруженный утилитой ST link, работает должным образом - USB перечисляет и отправляет данные.
Я сделал сравнение, и все после второго адреса ОЗУ (все после 0x20010008) повреждено.
Так что это, возможно, проблема с настройкой отладчика? Я использую STlinkV3 через SWD - нужен ли проект для запуска из ОЗУ? Опять же, иногда он отлично работает из оперативной памяти, а иногда нет.