Главная

Главная

Сообщество

Сообщество

Форум

Форум

STM32

STM32

Электроника

Электроника

Raspberry Pi

Raspberry Pi

Файлы SVD для STM32. Удобная отладка регистров под STM32CubeIDE.

Все, кто пользовался отладкой на уровне регистров под STM32CubeIDE, замечал, что список регистров идёт вразнобой, без какой-либо логики. Например, список для типичного STM32F407xx выглядит таким образом, здесь у нас порты ввода/вывода:

Это у нас UART/USART:

Это таймеры:

Как видим, все устройства идут не по порядку, а вразнобой. И это ещё цветочки. Есть МК, где всё это перемешано ещё хуже, и приходится искать, где и что у нас находится. Кроме этого, если присмотреться, есть периферия, которой на данном кристалле вообще нет. Такой подход очень неудобен и мешает отладке.

С первого взгляда может показаться, что нет никакой логики, но посмотрев даташит, раздел распределения памяти, можно увидеть, что таблица периферии повторяет порядок следования регистров в отладчике. Я задавал вопрос фирме ST, какого ... так сделано. Мне ответили, что у них работы много, а людей мало, вам надо, вы и занимайтесь этим. Ну я и занялся. Для этого нужно всего ничего, найти файл вот по этому пути в каталоге с установленной STM32CubeIDE:

/plugin/com.st.stm32cube.ide.mcu.productdb.debug/resources/cmsis/STMicroelectronics_CMSIS_SVD/STM32F407.svd

Затем я скопировал его в каталог, где у меня находятся все драйвера данного кристалла, назвал STM32F407_main.svd и, первым делом, отсортировал всю периферию. Получил вот такой порядок:

Т. е. я разбил по группам и сделал сортировку в группе, группы получились такие:

  • аналоговая периферия
  • порты ввода/вывода
  • таймеры
  • внешние интерфейсы
  • остальное

В каждой группе периферия идёт примерно в том порядке, в каком она идёт в STM32CubeMX.

Дальше я скопировал получившийся файл в тот же каталог с именем, схожим с маркировкой кристалла. В моём случае - STM32F407VET.svd - и грохнул там упоминание о периферии, которой нет на этом кристалле. Грохнул не всё, в разделе "Остальное" остались описания регистров, с которыми было лень возиться. Теперь список периферии выглядит так:

Ушла часть портов GPIO и так, по мелочи. А теперь о том, что это за файл и как устроен. Подключается файл здесь:

Выбираем слева "CMSIS-SVD Settings" и кнопкой "Browse" выбираем нужный нам файл. Структура файла такова - первым идёт заголовок, он нам неинтересен, и менять его не стоит. А интересует нас всё, что заключено между тегами <peripherals> ... <peripherals>.

Здесь и находится описание периферии, регистров и битов регистров:

<peripherals>  
    <peripheral>                                                   <!--Ветка описания одного устройства-->
      <name>RCC</name>                                             <!--Имя устройства-->
      <description>Reset and clock control</description>           <!--Описание, (для чего оно)-->
      <groupName>RCC</groupName>                                   <!--Группа к которой относится устройство-->
      <baseAddress>0x40023800</baseAddress>                        <!--Стартовый адрес в памяти-->
      <addressBlock>                                               <!--Занимаемое адресное пространство-->
        <offset>0x0</offset>                                       <!--Смещение от базового адреса-->
        <size>0x400</size>                                         <!--Размер занимаемого блока-->
        <usage>registers</usage>                                   <!--Используется регистрами-->
      </addressBlock>
      <interrupt>                                                  <!--Блок прерывания-->
        <name>RCC</name>                                           <!--Имя прерывания-->
        <description>RCC global interrupt</description>            <!--Описание-->
        <value>5</value>                                           <!--Номер вектора прерывания-->
      </interrupt>
      <registers>                                                  <!--Регистры-->
        <register>
          <name>CR</name>                                          <!--Имя регистра-->
          <displayName>CR</displayName>                            <!--Имя показываемое в списке-->
          <description>clock control register</description>
          <addressOffset>0x0</addressOffset>                       <!--Смещение от базового адреса-->
          <size>0x20</size>                                        <!--Количество занимаемых бит-->
          <resetValue>0x00000083</resetValue>                      <!--Значение при сбросе-->
          <fields>                                                 <!--Блок полей-->
            <field>                                                <!--Поле-->
              <name>PLLI2SRDY</name>                               <!--Имя поля-->
              <description>PLLI2S clock ready flag</description>   <!--Описание-->
              <bitOffset>27</bitOffset>                            <!--Смещение поля относительно начала регистра-->
              <bitWidth>1</bitWidth>                               <!--Количество бит в поле-->
              <access>read-only</access>                           <!--Способ доступа-->
            </field>
            <field>
            ...
            </field>
          </fields>
        </register>
        <register>
        ...
        </register>
      <registers>
    </peripheral>
    <peripheral>
    ...
    </peripheral>
  </pepherals>

Получается такая картина: файл разделён на блоки ограниченные тегами <peripheral> ... </peripheral>. В этих тегах описываются конкретные периферийные устройства. Далее идёт заголовок периферийного устройства, где указывается его базовый адрес в адресном пространстве МК, прерывания, если они есть, их именование в системе и номер вектора.

Далее тегами <register> ... </register> описываются все регистры, которые принадлежат данной периферии. Сколько регистров, столько и блоков. Каждый блок имеет также заголовок, в котором описывается имя регистра, смещение относительно базового адреса самого периферийного устройства, количество активных битов, значение при сбросе.

Теперь идут теги <field> ... </field> - в них идёт описание конкретных битов. Опять же имя, описание, смещение относительно адреса данного регистра, количество битов занимаемых полем и способ доступа: чтение, запись, чтение/запись и т. д.

Все данные структуры повторяются столько раз, сколько периферийных устройств присутствует в данном микроконтроллере.

Теперь о нюансах... Если несколько периферийных устройств имеют одинаковую структуру, каждое из них не описывается отдельно. Просто описывается одно, а другие описываются со ссылкой на предыдущее.

<peripheral derivedFrom="GPIOC">              <!--GPIOD-->
  <name>GPIOD</name>
  <baseAddress>0X40020C00</baseAddress>
</peripheral>

Например GPIOC и GPIOD имеют одинаковую структуру, но разный базовый адрес. Описываем GPIOC, а у GPIOD ссылаемся на структуру GPIOC - <peripheral derivedFrom="GPIOC">, и указываем только новый базовый адрес - <baseAddress>0X40020C00</baseAddress>. Главное, чтобы периферия, на которую ссылаемся, была описана раньше.

Вот в принципе и всё, выкладываю набор проектов и файлов: STM32Lib. Здесь у нас каталог для предыдущих статей, но немного видоизменённый, добавились SVD-файлы для контроллеров, на которые мне нужно было срочно их сделать. Все каталоги CMSIS из проектов я перенёс сюда для уменьшения размера проектов. Позже я расскажу подробнее, что именно изменилось.

guest
0 комментариев
Старые
Новые
Обзор конфиденциальности

На этом сайте используются файлы cookie, что позволяет нам обеспечить наилучшее качество обслуживания пользователей. Информация о файлах cookie хранится в вашем браузере и выполняет такие функции, как распознавание вас при возвращении на наш сайт и помощь нашей команде в понимании того, какие разделы сайта вы считаете наиболее интересными и полезными.