STM32F7 - выполнить код из ОЗУ и прошить - PullRequest
0 голосов
/ 28 марта 2019

Я полагаю, что у меня есть проблема с моим скриптом компоновщика, но я не уверен, что это настоящий виновник здесь.

Фон:

Я использую 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 - нужен ли проект для запуска из ОЗУ? Опять же, иногда он отлично работает из оперативной памяти, а иногда нет.

1 Ответ

0 голосов
/ 05 июля 2019

Это закончилось проблемой с truestudio. Я не уверен, что это была конкретная версия, которую я использую, но при использовании функции отладки в truestudio, отладчик не будет последовательно программировать RAM.

Обходной путь должен использовать STM32CubeProg, но это означает отсутствие отладки.

Интересно, что простая настройка ссылки ST как внешнего инструмента работала без проблем. https://info.atollic.com/hubfs/AppNotes/st_link_utility_as_ext-tool.pdf

Код теперь запускается / выполняется из flash / ram и переходов между ними без проблем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...