SuperTinyKernel™ RTOS 1.06.x
Lightweight, high-performance, deterministic, bare-metal C++ RTOS for resource-constrained embedded systems. MIT Open Source License.
Loading...
Searching...
No Matches
STK C Timer API

Pure C interface for stk::time::TimerHost and stk::time::TimerHost::Timer. More...

Collaboration diagram for STK C Timer API:

Topics

 STK C PeriodicTrigger API
 Pure C interface for stk::time::PeriodicTrigger.

Macros

#define STK_C_TIMER_MAX   (32U)
 Maximum number of concurrent stk_timer_t instances per core (default: 32). The total pool size is STK_C_TIMER_MAX × STK_C_CPU_COUNT slots, shared across all cores. When the pool is exhausted stk_timer_create() asserts in debug builds and returns NULL in release builds.
#define STK_C_TIMER_HANDLER_STACK_SIZE   (256U)
 Stack size of the timer handler, increase if your timers consume more (default: 256).

Typedefs

typedef struct stk_timerhost_t stk_timerhost_t
 Opaque handle to a TimerHost instance (one per CPU core).
typedef struct stk_timer_t stk_timer_t
 Opaque handle to a concrete timer managed by stk_timerhost_t.
typedef void(* stk_timer_callback_t) (stk_timerhost_t *host, stk_timer_t *timer, void *user_data)
 Timer expiration callback invoked from within the TimerHost handler task.

Functions

stk_timerhost_tstk_timerhost_get (uint8_t core_nr)
 Obtain the pre-allocated TimerHost for the given CPU core.
void stk_timerhost_init (stk_timerhost_t *host, stk_kernel_t *kernel, bool privileged)
 Initialize the TimerHost and register its internal tasks with the kernel.
bool stk_timerhost_shutdown (stk_timerhost_t *host)
 Gracefully shut down the TimerHost.
bool stk_timerhost_is_empty (const stk_timerhost_t *host)
 Return true when no timers are currently active on this host.
size_t stk_timerhost_get_size (const stk_timerhost_t *host)
 Return the number of currently active timers on this host.
int64_t stk_timerhost_get_time_now (const stk_timerhost_t *host)
 Return the last tick count snapshot maintained by the host's tick task.
stk_timer_tstk_timer_create (stk_timer_callback_t callback, void *user_data)
 Allocate a timer from the static pool.
void stk_timer_destroy (stk_timer_t *tmr)
 Return a timer handle back to the static pool.
bool stk_timer_start (stk_timerhost_t *host, stk_timer_t *tmr, uint32_t delay, uint32_t period)
 Start a timer.
bool stk_timer_stop (stk_timerhost_t *host, stk_timer_t *tmr)
 Stop a running timer.
bool stk_timer_reset (stk_timerhost_t *host, stk_timer_t *tmr)
 Reset a periodic timer's deadline (re-arm from now).
bool stk_timer_restart (stk_timerhost_t *host, stk_timer_t *tmr, uint32_t delay, uint32_t period)
 Atomically stop and re-start a timer.
bool stk_timer_start_or_reset (stk_timerhost_t *host, stk_timer_t *tmr, uint32_t delay, uint32_t period_ticks)
 Start the timer if inactive, or reset its deadline if already active and periodic.
bool stk_timer_set_period (stk_timerhost_t *host, stk_timer_t *tmr, uint32_t period_ticks)
 Change the period of a running periodic timer without affecting the current deadline.
bool stk_timer_is_active (const stk_timer_t *tmr)
 Check whether a timer is currently active (started and not yet expired/stopped).
uint32_t stk_timer_get_period (const stk_timer_t *tmr)
 Get the timer's reload period.
int64_t stk_timer_get_deadline (const stk_timer_t *tmr)
 Get the absolute expiration tick count of the timer's next deadline.
int64_t stk_timer_get_timestamp (const stk_timer_t *tmr)
 Get the tick count at which the timer last expired.
uint32_t stk_timer_get_remaining_ticks (const stk_timer_t *tmr)
 Get remaining ticks until next expiration.

Detailed Description

Macro Definition Documentation

◆ STK_C_TIMER_HANDLER_STACK_SIZE

#define STK_C_TIMER_HANDLER_STACK_SIZE   (256U)

Stack size of the timer handler, increase if your timers consume more (default: 256).

Definition at line 55 of file stk_c_time.h.

◆ STK_C_TIMER_MAX

#define STK_C_TIMER_MAX   (32U)

Maximum number of concurrent stk_timer_t instances per core (default: 32). The total pool size is STK_C_TIMER_MAX × STK_C_CPU_COUNT slots, shared across all cores. When the pool is exhausted stk_timer_create() asserts in debug builds and returns NULL in release builds.

Note
Increase if your application needs more simultaneous timers.

Definition at line 48 of file stk_c_time.h.

Typedef Documentation

◆ stk_timer_callback_t

typedef void(* stk_timer_callback_t) (stk_timerhost_t *host, stk_timer_t *timer, void *user_data)

Timer expiration callback invoked from within the TimerHost handler task.

Parameters
[in]hostTimerHost that fired the timer.
[in]timerThe timer that expired.
[in]user_dataOpaque pointer supplied at timer creation time.
Warning
Must not call blocking kernel services (e.g. stk_mutex_lock with a non-zero timeout) unless the handler task stack is large enough.

Definition at line 77 of file stk_c_time.h.

◆ stk_timer_t

typedef struct stk_timer_t stk_timer_t

Opaque handle to a concrete timer managed by stk_timerhost_t.

Definition at line 68 of file stk_c_time.h.

◆ stk_timerhost_t

typedef struct stk_timerhost_t stk_timerhost_t

Opaque handle to a TimerHost instance (one per CPU core).

Definition at line 64 of file stk_c_time.h.

Function Documentation

◆ stk_timer_create()

stk_timer_t * stk_timer_create ( stk_timer_callback_t callback,
void * user_data )

Allocate a timer from the static pool.

Parameters
[in]callbackFunction to call when the timer expires (must not be NULL).
[in]user_dataOpaque pointer forwarded to callback on expiration.
Returns
Timer handle, or NULL if the pool is exhausted (STK_C_TIMER_MAX × STK_C_CPU_COUNT slots total).
Note
The returned handle is valid until stk_timer_destroy() is called. It must not be active (i.e. not currently started) when destroyed.
The pool is shared across all CPU cores. Total capacity is STK_C_TIMER_MAX * STK_C_CPU_COUNT.

Definition at line 196 of file stk_c_time.cpp.

197{
198 STK_ASSERT(callback != nullptr);
199
201
202 stk_timer_t *result = nullptr;
203
204 for (uint32_t i = 0U; i < STK_C_TIMERS_TOTAL; ++i)
205 {
206 if (!s_Timers[i].busy)
207 {
208 s_Timers[i].busy = true;
209 s_Timers[i].timer.handle.Initialize(callback, user_data);
210 result = &s_Timers[i].timer;
211 break;
212 }
213 }
214
215 // pool exhausted, you must increase STK_C_TIMER_MAX
216 STK_ASSERT(result != nullptr);
217
218 return result;
219}
#define STK_ASSERT(e)
Runtime assertion. Halts execution if the expression e evaluates to false.
Definition stk_defs.h:409
#define STK_C_TIMERS_TOTAL
static struct TimerSlot s_Timers[(STK_C_TIMER_MAX *STK_C_CPU_COUNT)]
RAII-style low-level synchronization primitive for atomic code execution. Used as building brick for ...
Definition stk_sync_cs.h:54

References s_Timers, STK_ASSERT, and STK_C_TIMERS_TOTAL.

◆ stk_timer_destroy()

void stk_timer_destroy ( stk_timer_t * tmr)

Return a timer handle back to the static pool.

Parameters
[in]tmrTimer handle.
Warning
The timer must have been stopped (or never started) before calling this. Destroying an active timer is a programming error and triggers an assertion.

Definition at line 221 of file stk_c_time.cpp.

222{
223 STK_ASSERT(tmr != nullptr);
224
225 // destroying an active timer is a programming error
226 STK_ASSERT(!tmr->handle.IsActive());
227
229
230 bool found = false;
231
232 for (uint32_t i = 0U; ((i < STK_C_TIMERS_TOTAL) && !found); ++i)
233 {
234 if (s_Timers[i].busy && (&s_Timers[i].timer == tmr))
235 {
236 tmr->handle.Reset();
237 s_Timers[i].busy = false;
238 found = true;
239 }
240 }
241
242 // timer not found in the pool: indicates a double-free or corruption
243 STK_ASSERT(found);
244}
bool IsActive() const
Check whether the timer is currently active.
CTimerWrapper handle

References stk_timer_t::handle, stk::time::TimerHost::Timer::IsActive(), CTimerWrapper::Reset(), s_Timers, STK_ASSERT, and STK_C_TIMERS_TOTAL.

Here is the call graph for this function:

◆ stk_timer_get_deadline()

int64_t stk_timer_get_deadline ( const stk_timer_t * tmr)

Get the absolute expiration tick count of the timer's next deadline.

Parameters
[in]tmrTimer handle.
Returns
Absolute deadline (ticks). Meaningful only when the timer is active.

Definition at line 331 of file stk_c_time.cpp.

332{
333 STK_ASSERT(tmr != nullptr);
334
335 return static_cast<int64_t>(tmr->handle.GetDeadline());
336}
Ticks GetDeadline() const
Get the absolute time in ticks at which the timer will expire.

References stk::time::TimerHost::Timer::GetDeadline(), stk_timer_t::handle, and STK_ASSERT.

Here is the call graph for this function:

◆ stk_timer_get_period()

uint32_t stk_timer_get_period ( const stk_timer_t * tmr)

Get the timer's reload period.

Parameters
[in]tmrTimer handle.
Returns
Period in ticks, or 0 for a one-shot timer.

Definition at line 324 of file stk_c_time.cpp.

325{
326 STK_ASSERT(tmr != nullptr);
327
328 return tmr->handle.GetPeriod();
329}
uint32_t GetPeriod() const
Get the reload period of the timer.

References stk::time::TimerHost::Timer::GetPeriod(), stk_timer_t::handle, and STK_ASSERT.

Here is the call graph for this function:

◆ stk_timer_get_remaining_ticks()

uint32_t stk_timer_get_remaining_ticks ( const stk_timer_t * tmr)

Get remaining ticks until next expiration.

Parameters
[in]tmrTimer handle.
Returns
Remaining ticks, or 0 if already expired or not active.
Note
Computed from the last value written by the host's tick task - may be up to one tick-task wake cycle stale.

Definition at line 345 of file stk_c_time.cpp.

346{
347 STK_ASSERT(tmr != nullptr);
348
349 return tmr->handle.GetRemainingTicks();
350}
uint32_t GetRemainingTicks() const
Get remaining ticks until the timer next expires.

References stk::time::TimerHost::Timer::GetRemainingTicks(), stk_timer_t::handle, and STK_ASSERT.

Here is the call graph for this function:

◆ stk_timer_get_timestamp()

int64_t stk_timer_get_timestamp ( const stk_timer_t * tmr)

Get the tick count at which the timer last expired.

Parameters
[in]tmrTimer handle.
Returns
Expiration timestamp (ticks). Zero if the timer has never fired.

Definition at line 338 of file stk_c_time.cpp.

339{
340 STK_ASSERT(tmr != nullptr);
341
342 return static_cast<int64_t>(tmr->handle.GetTimestamp());
343}
Ticks GetTimestamp() const
Get the tick count at which the timer last expired.

References stk::time::TimerHost::Timer::GetTimestamp(), stk_timer_t::handle, and STK_ASSERT.

Here is the call graph for this function:

◆ stk_timer_is_active()

bool stk_timer_is_active ( const stk_timer_t * tmr)

Check whether a timer is currently active (started and not yet expired/stopped).

Parameters
[in]tmrTimer handle.
Returns
true if the timer is active.
Note
Advisory - may change immediately after the call.

Definition at line 317 of file stk_c_time.cpp.

318{
319 STK_ASSERT(tmr != nullptr);
320
321 return tmr->handle.IsActive();
322}

References stk_timer_t::handle, stk::time::TimerHost::Timer::IsActive(), and STK_ASSERT.

Here is the call graph for this function:

◆ stk_timer_reset()

bool stk_timer_reset ( stk_timerhost_t * host,
stk_timer_t * tmr )

Reset a periodic timer's deadline (re-arm from now).

Parameters
[in]hostTimerHost managing the timer.
[in]tmrTimer handle. Must be active and periodic (period != 0).
Returns
true on success, false if preconditions are not met or the command queue is full.

Definition at line 275 of file stk_c_time.cpp.

276{
277 STK_ASSERT(host != nullptr);
278 STK_ASSERT(tmr != nullptr);
279
280 return host->handle.Reset(tmr->handle);
281}
bool Reset(Timer &tmr)
Reset periodic timer's deadline.

References stk_timer_t::handle, stk_timerhost_t::handle, stk::time::TimerHost::Reset(), and STK_ASSERT.

Here is the call graph for this function:

◆ stk_timer_restart()

bool stk_timer_restart ( stk_timerhost_t * host,
stk_timer_t * tmr,
uint32_t delay,
uint32_t period )

Atomically stop and re-start a timer.

Unlike calling stk_timer_stop() + stk_timer_start(), this operation is atomic with respect to the tick task: the timer cannot fire between the implicit stop and re-start. Consumes only one command queue slot.

Parameters
[in]hostTimerHost managing the timer.
[in]tmrTimer handle (active or inactive).
[in]delayInitial delay in ticks before the first expiration.
[in]periodReload period in ticks (0 = one-shot).
Returns
true on success, false if the command queue is full.

Definition at line 283 of file stk_c_time.cpp.

284{
285 STK_ASSERT(host != nullptr);
286 STK_ASSERT(tmr != nullptr);
287
288 // refresh host association before timer can fire
289 tmr->handle.SetHostHandle(host);
290
291 return host->handle.Restart(tmr->handle, delay, period);
292}
bool Restart(Timer &tmr, uint32_t delay, uint32_t period=0)
Atomically stop and re-start timer.
void SetHostHandle(stk_timerhost_t *host_handle)

References stk_timer_t::handle, stk_timerhost_t::handle, stk::time::TimerHost::Restart(), CTimerWrapper::SetHostHandle(), and STK_ASSERT.

Here is the call graph for this function:

◆ stk_timer_set_period()

bool stk_timer_set_period ( stk_timerhost_t * host,
stk_timer_t * tmr,
uint32_t period_ticks )

Change the period of a running periodic timer without affecting the current deadline.

The new period takes effect on the next reload after the current deadline fires. To apply immediately, follow with stk_timer_reset().

Parameters
[in]hostTimerHost managing the timer.
[in]tmrTimer handle. Must be active and periodic.
[in]period_ticksNew reload period in ticks. Must be non-zero.
Returns
true on success, false if preconditions are not met or the command queue is full.

Definition at line 305 of file stk_c_time.cpp.

306{
307 STK_ASSERT(host != nullptr);
308 STK_ASSERT(tmr != nullptr);
309
310 return host->handle.SetPeriod(tmr->handle, period_ticks);
311}
bool SetPeriod(Timer &tmr, uint32_t period)
Change the period of a running periodic timer without affecting its current deadline.

References stk_timer_t::handle, stk_timerhost_t::handle, stk::time::TimerHost::SetPeriod(), and STK_ASSERT.

Here is the call graph for this function:

◆ stk_timer_start()

bool stk_timer_start ( stk_timerhost_t * host,
stk_timer_t * tmr,
uint32_t delay,
uint32_t period )

Start a timer.

Parameters
[in]hostTimerHost that will manage this timer.
[in]tmrTimer handle. Must not already be active.
[in]delayInitial delay in ticks before the first expiration.
[in]periodReload period in ticks. Pass 0 for a one-shot timer.
Returns
true on success, false if the timer is already active or the command queue is full.

Definition at line 253 of file stk_c_time.cpp.

257{
258 STK_ASSERT(host != nullptr);
259 STK_ASSERT(tmr != nullptr);
260
261 // refresh host association before timer can fire
262 tmr->handle.SetHostHandle(host);
263
264 return host->handle.Start(tmr->handle, delay, period);
265}
bool Start(Timer &tmr, uint32_t delay, uint32_t period=0)
Start timer.

References stk_timer_t::handle, stk_timerhost_t::handle, CTimerWrapper::SetHostHandle(), stk::time::TimerHost::Start(), and STK_ASSERT.

Here is the call graph for this function:

◆ stk_timer_start_or_reset()

bool stk_timer_start_or_reset ( stk_timerhost_t * host,
stk_timer_t * tmr,
uint32_t delay,
uint32_t period_ticks )

Start the timer if inactive, or reset its deadline if already active and periodic.

Collapses the common pattern:

else stk_timer_start(host, t, delay, period);
bool stk_timer_start(stk_timerhost_t *host, stk_timer_t *tmr, uint32_t delay, uint32_t period)
Start a timer.
bool stk_timer_is_active(const stk_timer_t *tmr)
Check whether a timer is currently active (started and not yet expired/stopped).
bool stk_timer_reset(stk_timerhost_t *host, stk_timer_t *tmr)
Reset a periodic timer's deadline (re-arm from now).

into a single atomic operation, eliminating the TOCTOU race. If the timer is active but one-shot, no action is taken.

Parameters
[in]hostTimerHost managing the timer.
[in]tmrTimer handle (active or inactive).
[in]delayInitial delay in ticks (used only when starting).
[in]period_ticksReload period in ticks (used only when starting, 0 = one-shot).
Returns
true on success, false if the command queue is full.

Definition at line 294 of file stk_c_time.cpp.

295{
296 STK_ASSERT(host != nullptr);
297 STK_ASSERT(tmr != nullptr);
298
299 // refresh host association (harmless if timer is already active on host)
300 tmr->handle.SetHostHandle(host);
301
302 return host->handle.StartOrReset(tmr->handle, delay, period_ticks);
303}
bool StartOrReset(Timer &tmr, uint32_t delay, uint32_t period=0)
Start timer if inactive, or reset its deadline if already active and periodic.

References stk_timer_t::handle, stk_timerhost_t::handle, CTimerWrapper::SetHostHandle(), stk::time::TimerHost::StartOrReset(), and STK_ASSERT.

Here is the call graph for this function:

◆ stk_timer_stop()

bool stk_timer_stop ( stk_timerhost_t * host,
stk_timer_t * tmr )

Stop a running timer.

Parameters
[in]hostTimerHost managing the timer.
[in]tmrTimer handle. Must be currently active.
Returns
true on success, false if the timer is not active or the command queue is full.

Definition at line 267 of file stk_c_time.cpp.

268{
269 STK_ASSERT(host != nullptr);
270 STK_ASSERT(tmr != nullptr);
271
272 return host->handle.Stop(tmr->handle);
273}
bool Stop(Timer &tmr)
Stop running timer.

References stk_timer_t::handle, stk_timerhost_t::handle, STK_ASSERT, and stk::time::TimerHost::Stop().

Here is the call graph for this function:

◆ stk_timerhost_get()

stk_timerhost_t * stk_timerhost_get ( uint8_t core_nr)

Obtain the pre-allocated TimerHost for the given CPU core.

Parameters
[in]core_nrCPU core index (0 … STK_C_CPU_COUNT-1).
Returns
TimerHost handle, or NULL if core_nr is out of range.
Note
The host instance exists in static storage; do not free it.

Definition at line 141 of file stk_c_time.cpp.

142{
143 stk_timerhost_t *result = nullptr;
144
145 if (core_nr < STK_C_CPU_COUNT)
146 {
147 result = &s_TimerHosts[core_nr];
148 }
149
150 return result;
151}
static stk_timerhost_t s_TimerHosts[STK_C_CPU_COUNT]
#define STK_C_CPU_COUNT
Number of kernel instances / CPU cores supported (default: 1).
Definition stk_c.h:60

References s_TimerHosts, and STK_C_CPU_COUNT.

◆ stk_timerhost_get_size()

size_t stk_timerhost_get_size ( const stk_timerhost_t * host)

Return the number of currently active timers on this host.

Parameters
[in]hostTimerHost handle.
Returns
Advisory active timer count (may change immediately after the call).

Definition at line 178 of file stk_c_time.cpp.

179{
180 STK_ASSERT(host != nullptr);
181
182 return host->handle.GetSize();
183}
size_t GetSize() const
Return number of currently active timers.

References stk::time::TimerHost::GetSize(), stk_timerhost_t::handle, and STK_ASSERT.

Here is the call graph for this function:

◆ stk_timerhost_get_time_now()

int64_t stk_timerhost_get_time_now ( const stk_timerhost_t * host)

Return the last tick count snapshot maintained by the host's tick task.

Parameters
[in]hostTimerHost handle.
Returns
Tick count (may be one tick-task wake cycle stale).

Definition at line 185 of file stk_c_time.cpp.

186{
187 STK_ASSERT(host != nullptr);
188
189 return static_cast<int64_t>(host->handle.GetTimeNow());
190}
Ticks GetTimeNow() const
Get current time.

References stk::time::TimerHost::GetTimeNow(), stk_timerhost_t::handle, and STK_ASSERT.

Here is the call graph for this function:

◆ stk_timerhost_init()

void stk_timerhost_init ( stk_timerhost_t * host,
stk_kernel_t * kernel,
bool privileged )

Initialize the TimerHost and register its internal tasks with the kernel.

Parameters
[in]hostTimerHost handle obtained via stk_timerhost_get().
[in]kernelKernel instance the timer tasks will be added to.
[in]privilegedIf true the internal handler tasks run in privileged mode, otherwise they run in user mode.
Note
Must be called before stk_kernel_start() and before any stk_timer_* operations on this host.

Definition at line 153 of file stk_c_time.cpp.

156{
157 STK_ASSERT(host != nullptr);
158 STK_ASSERT(kernel != nullptr);
159
161 (privileged ? ACCESS_PRIVILEGED : ACCESS_USER));
162}
@ ACCESS_USER
Unprivileged access mode (access to some hardware is restricted, see CPU manual for details)....
Definition stk_common.h:43
@ ACCESS_PRIVILEGED
Privileged access mode (access to hardware is fully unrestricted).
Definition stk_common.h:44
void InitializeTimerHost(stk_kernel_t *kernel, stk::time::TimerHost *th, EAccessMode amode)
Definition stk_c.cpp:64

References stk::ACCESS_PRIVILEGED, stk::ACCESS_USER, stk_timerhost_t::handle, stk::interop_c_helper::InitializeTimerHost(), and STK_ASSERT.

Here is the call graph for this function:

◆ stk_timerhost_is_empty()

bool stk_timerhost_is_empty ( const stk_timerhost_t * host)

Return true when no timers are currently active on this host.

Parameters
[in]hostTimerHost handle.
Returns
Advisory empty flag (may change immediately after the call).

Definition at line 171 of file stk_c_time.cpp.

172{
173 STK_ASSERT(host != nullptr);
174
175 return host->handle.IsEmpty();
176}
bool IsEmpty() const
Return true if no timers are currently active.

References stk_timerhost_t::handle, stk::time::TimerHost::IsEmpty(), and STK_ASSERT.

Here is the call graph for this function:

◆ stk_timerhost_shutdown()

bool stk_timerhost_shutdown ( stk_timerhost_t * host)

Gracefully shut down the TimerHost.

Parameters
[in]hostTimerHost handle.
Returns
true on success, false if the internal command queue is full.
Note
All active timers are stopped. After shutdown the host must not be used.

Definition at line 164 of file stk_c_time.cpp.

165{
166 STK_ASSERT(host != nullptr);
167
168 return host->handle.Shutdown();
169}
bool Shutdown()
Shutdown host instance. All timers are stopped and removed from the host.

References stk_timerhost_t::handle, stk::time::TimerHost::Shutdown(), and STK_ASSERT.

Here is the call graph for this function: