Top.Mail.Ru

Файлы 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 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x