#include <cstdint>
#include <cstdio>
// Timebase A: SysTick (1 kHz)
struct SysTickTimer {
static std::uint32_t ticks() {
return 100;
}
static std::uint32_t freq_hz() {
return 1000;
}
};
// Timebase B: RTC (32 Hz)
struct RtcTimer {
static std::uint32_t ticks() {
return 4;
}
static std::uint32_t freq_hz() {
return 32;
}
};
/**
* Scheduler Class
* Uses a Template parameter to define the hardware timebase.
* This ensures that the math is resolved for the specific type provided.
*/
template<typename Timer>
class Scheduler {
public:
std::uint32_t elapsed_ms() const {
// Calculation: (ticks * 1000) / frequency
return (Timer::ticks() * 1000U) / Timer::freq_hz();
}
};
/**
* Build-Time Selection
* In a production environment, this alias would be swapped
* based on the target hardware build configuration.
*/
using ActiveTimer = SysTickTimer;
int main() {
// By passing 'ActiveTimer' (SysTickTimer), we satisfy the template requirement.
// If you were to write 'Scheduler<> scheduler', it would fail to compile.
// If you omit the type entirely 'Scheduler scheduler', it fails to compile.
Scheduler<ActiveTimer> scheduler;
std::printf("elapsed_ms=%u\n",
static_cast<unsigned>(scheduler.elapsed_ms()));
return 0;
}
Expected Output
elapsed_ms=100