libxr
Embedded C++ framework for bare-metal, RTOS and Linux
Loading...
Searching...
No Matches
mspm0_timebase.cpp
1#include "mspm0_timebase.hpp"
2
3using namespace LibXR;
4
6{
7 ConfigureWrapRange(static_cast<uint64_t>(UINT32_MAX) * 1000ULL + 999ULL, UINT32_MAX);
8 // SysTick 中断必须能抢占 LibXR 驱动的中断(优先级 1)。
9 // The SysTick interrupt must preempt the interrupts of the LibXR drivers (priority 1).
10 NVIC_SetPriority(SysTick_IRQn, 0U);
11 DL_SYSTICK_enableInterrupt();
12 SetReady();
13}
14
15namespace
16{
17struct SysTickSnapshot
18{
19 uint32_t milliseconds;
20 uint32_t period;
21 uint32_t value;
22};
23
24// 只在快照期间屏蔽中断;不读取会清除 COUNTFLAG 的 CTRL。
25// Mask IRQs only for the snapshot; do not read CTRL and consume COUNTFLAG.
26// BSP 必须在下一次回绕前处理 SysTick;一个 pending 位不能记录多次回绕。
27// The BSP must service SysTick before another wrap; one pending bit is not a counter.
28SysTickSnapshot ReadSysTickSnapshot()
29{
30 const uint32_t primask = __get_PRIMASK();
31 __disable_irq();
32
33 SysTickSnapshot snapshot{MSPM0Timebase::sys_tick_ms, DL_SYSTICK_getPeriod(), 0U};
34 uint32_t pending_before;
35 uint32_t pending_after;
36 do
37 {
38 pending_before = SCB->ICSR & SCB_ICSR_PENDSTSET_Msk;
39 snapshot.value = DL_SYSTICK_getValue();
40 pending_after = SCB->ICSR & SCB_ICSR_PENDSTSET_Msk;
41 } while (pending_before != pending_after);
42
43 if (pending_after != 0U)
44 {
45 ++snapshot.milliseconds;
46 }
47 __set_PRIMASK(primask);
48 return snapshot;
49}
50} // namespace
51
53{
54 const auto snapshot = ReadSysTickSnapshot();
55 // VAL == 0 是回绕/初次装载边界,不再叠加一个完整周期。
56 // VAL == 0 is the wrap/initial-load boundary, not an additional full period.
57 const uint32_t elapsed = snapshot.value == 0U ? 0U : snapshot.period - snapshot.value;
58 return MicrosecondTimestamp(static_cast<uint64_t>(snapshot.milliseconds) * 1000ULL +
59 static_cast<uint64_t>(elapsed) * 1000ULL / snapshot.period);
60}
61
63{
64 return ReadSysTickSnapshot().milliseconds;
65}
67{
68 // 只有 SysTick 中断写入;C++20 弃用 volatile 的 ++,改为显式读改写。
69 // Only the SysTick interrupt writes it; C++20 deprecates ++ on volatile, so read and
70 // write explicitly.
72}
73void MSPM0Timebase::Sync(uint32_t ticks) { MSPM0Timebase::sys_tick_ms = ticks; }
74
75extern "C" void SysTick_Handler(void) // NOLINT
76{
78}
static volatile uint32_t sys_tick_ms
SysTick 毫秒计数器。 SysTick millisecond counter.
MSPM0Timebase()
构造函数 / Constructor
static void OnSysTickInterrupt()
SysTick 中断入口辅助函数。 Helper called from the SysTick interrupt path.
static void Sync(uint32_t ticks)
同步毫秒计数器。 Synchronize the millisecond counter.
微秒时间戳 / Microsecond timestamp
毫秒时间戳 / Millisecond timestamp
static void ConfigureWrapRange(uint64_t max_valid_us, uint32_t max_valid_ms) noexcept
配置时间戳回绕上界。 Configure the timestamp wraparound limits.
Definition timebase.hpp:95
static void SetReady(bool ready=true) noexcept
设置时间基就绪状态。 Set the timebase ready flag.
Definition timebase.hpp:85
static MicrosecondTimestamp GetMicroseconds()
获取当前时间的微秒级时间戳。 Gets the current timestamp in microseconds.
static MillisecondTimestamp GetMilliseconds()
获取当前时间的毫秒级时间戳。 Gets the current timestamp in milliseconds.
LibXR 命名空间 / LibXR namespace.
Definition ch32_can.hpp:14