CH32V203: почему нельзя просто прочитать 64-битный SysTick и как это исправить

Микроконтроллер CH32V203 оснащен 64-битным аппаратным таймером SysTick, но чтение его значения может привести к неожиданным сбоям из-за особенностей архитектуры. Разбираемся, в чем проблема и как правильно работать с этим таймером.

CH32V203: почему нельзя просто прочитать 64-битный SysTick и как это исправить

Когда разработчик впервые сталкивается с микроконтроллером CH32V203, его приятно удивляет наличие 64-битного аппаратного таймера SysTick. Казалось бы, это огромное преимущество: точные временные замеры, длительные интервалы без переполнения. Однако на практике чтение этого таймера может превратиться в настоящую головную боль. Почему так происходит и как обойти подводные камни — разберем в этой статье.

Особенности 64-битного SysTick на CH32V203

CH32V203G6U6 — это микроконтроллер на ядре RISC-V, который выделяется среди конкурентов наличием 64-битного таймера SysTick. В отличие от стандартного 32-битного SysTick, который встречается в большинстве ARM-микроконтроллеров, здесь таймер имеет расширенную разрядность. Это позволяет отсчитывать гораздо более длительные промежутки времени без переполнения, что особенно полезно в системах реального времени и при измерении длительных интервалов.

Однако радость от аппаратного таймера быстро сменяется недоумением, когда разработчик пытается прочитать его текущее значение. Проблема заключается в том, что 64-битный таймер не может быть прочитан одной инструкцией. Микроконтроллер выдает значение двумя 32-битными словами: сначала младшую часть, затем старшую. Но между этими двумя чтениями таймер продолжает тикать, и если он переполнится в этот момент, старшая часть может оказаться некорректной. В результате получается «рваное» значение, которое невозможно использовать для точных расчетов.

Предыстория и контекст

Эта проблема не уникальна для CH32V203. Многие микроконтроллеры с 64-битными таймерами сталкиваются с аналогичной дилеммой. Например, в архитектуре ARM Cortex-M3 и M4 SysTick всегда 24-битный, и его чтение не вызывает проблем. Но когда производители добавляют 64-битные таймеры, они часто забывают предусмотреть механизм атомарного чтения. В CH32V203 это особенно актуально, так как таймер используется не только для задержек, но и для системного времени, от которого зависит работа всей операционной системы реального времени (RTOS).

Разработчики, работающие с CH32V203, быстро обнаружили, что простое чтение регистра SYSTCVR (Current Value Register) приводит к ошибкам в расчетах. Например, если прерывание происходит во время чтения, то данные могут быть искажены. Некоторые пытались решить проблему, отключая таймер на время чтения, но это приводит к потере точности и недопустимо в системах, где временные интервалы критичны.

Как правильно читать 64-битный SysTick?

Существует несколько подходов к решению этой проблемы. Самый простой способ — читать старшую часть, затем младшую, а затем снова старшую. Если старшая часть не изменилась, значит, чтение прошло корректно. Если изменилась, повторяем процедуру. Этот метод называется «двойное чтение» и широко применяется в программировании микроконтроллеров. Однако он требует аккуратности и может быть неэффективным, если таймер тикает очень быстро.

Более надежный способ — использовать аппаратную поддержку захвата таймера. В CH32V203 можно настроить таймер так, чтобы он захватывал значение в момент события, например, прерывания. Это гарантирует согласованность данных, но требует дополнительной настройки и использования дополнительных ресурсов.

Третий вариант — использовать 32-битный SysTick, если он доступен, и игнорировать 64-битное расширение. Но это лишает преимуществ длинных интервалов.

Технические подробности и сравнение с другими МК

Для сравнения, в микроконтроллерах STM32 с ядром Cortex-M7 SysTick также 24-битный, и чтение не вызывает проблем. В более новых архитектурах, например, в RISC-V, 64-битные таймеры встречаются чаще, и производители обычно предусматривают атомарное чтение. Например, в микроконтроллерах GD32VF103, также на RISC-V, проблема решена аппаратно: чтение 64-битного таймера происходит одной инструкцией.

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

Кого затронет и как

Эта проблема касается всех разработчиков, использующих CH32V203 в своих проектах. Особенно это критично для тех, кто пишет собственные драйверы или работает с RTOS, где системное время играет ключевую роль. Неправильное чтение таймера может привести к сбоям в планировании задач, ошибкам в тайм-аутах и даже к зависанию системы.

Для разработчиков из России и СНГ, которые активно используют китайские микроконтроллеры из-за их доступности, эта тема особенно актуальна. Многие проекты на CH32V203 создаются для промышленной автоматизации, интернета вещей и образовательных целей, и стабильность работы таймера критически важна.

Что будет дальше

Скорее всего, производитель WCH (Nanjing Qinheng Microelectronics) в будущих ревизиях микроконтроллера исправит эту особенность, добавив аппаратную поддержку атомарного чтения. Но пока этого не произошло, разработчикам приходится искать обходные пути. В сообществе уже обсуждаются возможные решения, и, вероятно, скоро появятся стандартные библиотеки, которые будут корректно работать с 64-битным SysTick.

Также стоит отметить, что проблема чтения 64-битных таймеров не ограничивается только CH32V203. Это общая проблема для многих микроконтроллеров, и разработчикам стоит быть внимательными при работе с такими таймерами, изучая документацию и ища известные проблемы.

Итог

64-битный SysTick на CH32V203 — это мощный инструмент, но его неправильное использование может привести к серьезным ошибкам. Понимание особенностей чтения этого таймера и применение правильных методов позволит избежать проблем и использовать все преимущества микроконтроллера. Следите за обновлениями от производителя и активно участвуйте в сообществах, чтобы быть в курсе новых решений.