Переопределение начального значения указателя стека для stm32f3 - PullRequest
0 голосов
/ 09 марта 2020

У меня есть плата обнаружения stm32f303, и я пытаюсь понять процесс компоновки и перемещения. Я собираю и запускаю этот пример здесь: https://github.com/mblythe86/stm32f3-discovery-basic-template

Значение указателя стека сброса определено в таблице векторов в скрипте установки Device / startup_stm32f30x.s. Исходное значение: 0x2000A000 (ie. Начальный адрес SRAM + 32K). Единственные другие вещи, которые я вижу, которые выделены для SRAM, это разделы .data и .bss:

 2 .data         0000004c  20000000  08000e94  00020000  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  3 .bss          00000040  2000004c  08000ee0  0002004c  2**2
                  ALLOC

Так что (игнорируя стек) все с адреса 0x2000008 c - 0x40000000 должно быть свободно для использовать SRAM?

Я пытаюсь уменьшить начальное значение указателя стека на 32 байта (с 0x2000A000 до 0x20009FD0) в сценарии запуска, и мы компилируем и запускаем все нормально.

Я пытаюсь увеличить начальное значение указателя стека на 32 байта (с 0x2000A000 до 0x2000A020), и все перестает работать.

Запуск GDB и разрыв функции SystemInit, разборка, вызывающая проблему, выглядит следующим образом:

08000c18 <SystemInit>:
 8000c18:   b580        push    {r7, lr}
 8000c1a:   af00        add r7, sp, #0
 8000c1c:   4a1f        ldr r2, [pc, #124]  ; (8000c9c <SystemInit+0x84>)
 8000c1e:   4b1f        ldr r3, [pc, #124]  ; (8000c9c <SystemInit+0x84>)
 8000c20:   f8d3 3088   ldr.w   r3, [r3, #136]  ; 0x88

в этот момент мы запускаем какое-то исключение и переходим к WWDG_IRQHandler. Значение r3 в инструкции ldr.w равно 0xe000ed00, что является чем-то на шине периферийного устройства?

Меня сбивает с толку то, что этот раздел кода и все адреса регистров и памяти идентичен в оригинальной версии, которая работает (за исключением значения указателя стека, конечно), включая доступ к памяти ldr.w в 0xe000ed00 + 0x88. Есть идеи, что здесь происходит? Есть ли что-то еще, управляющее указателем начального стека, кроме таблицы векторов?

1 Ответ

0 голосов
/ 10 марта 2020

Мои советы.

  1. Загрузите немного более удобную среду разработки с приличным отладчиком GUI. Например, atolli c studio.

  2. Прекратить использование найденных где-нибудь на net «шаблонов». В этом используется библиотека prehistori c SPL - больше не поддерживается STM. Используйте CubeMx для генерации шаблонов проектов.

  3. у вас 48 КБ ОЗУ, но разделены на две разные области памяти. 40k SRAM (0x20000000 - 0x2000A000) и ОЗУ CCM (0x10000000 - 0x10002000)

  4. Согласно пункту 3. последний адрес SRAM равен 0x2000A000, поэтому при размещении стека по адресу 0x2000A020 - вы мгновенно оказаться в обработчике HardHault. (Это не WDG, так как при запуске все HF обрабатываются одной функцией)

  5. Вы также можете поместить стек в RAM CCM.

  6. Это самая простая конфигурация - ядра ARM имеют 2 стека, используемых пользователем, и привилегированный код.

  7. Стек не должен быть в конце области памяти. Я часто стараюсь поставить его в начале. Когда стек переполняется, он вызывает HF, давая мне шанс принять меры. Если стек находится в конце ОЗУ, он может молча переполниться, перезаписывая данные, хранящиеся в ОЗУ

  8. Всегда читать полную документацию. Техническое описание, справочное руководство и руководство по программированию

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