Skip to content

Commit 9f8a782

Browse files
Added API for ThreadX timers (#344)
1 parent 46f4196 commit 9f8a782

2 files changed

Lines changed: 228 additions & 0 deletions

File tree

threadX/inc/u_tx_timers.h

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#pragma once
2+
3+
// clang-format off
4+
5+
#include "tx_api.h"
6+
#include <stdint.h>
7+
#include <stdbool.h>
8+
9+
typedef enum {
10+
ONESHOT, /* Timer runs once. */
11+
PERIODIC /* Timer runs periodically based on the 'duration' setting. */
12+
} timer_type_t;
13+
14+
typedef struct {
15+
/* PUBLIC: Thread Configuration Settings */
16+
/* Set these when defining an instance of this struct. */
17+
const CHAR *name; /* Name of the timer. */
18+
VOID (*callback)(ULONG); /* Callback to be ran when the timer expires. */
19+
ULONG duration; /* The time until the timer expires (in ticks). */
20+
ULONG callback_input; /* Optional setting. Input for the callback function. Just set to '0' if you don't need to use. */
21+
timer_type_t type; /* Type of timer. See 'timer_type_t'. */
22+
bool auto_activate; /* Whether or not the timer should auto-activate. */
23+
24+
/* PRIVATE: Internal implementation - DO NOT ACCESS DIRECTLY */
25+
/* (should only be accessed by functions in u_tx_timers.c) */
26+
TX_TIMER TX_TIMER_; /* The actual timer instance. */
27+
} timer_t;
28+
29+
/**
30+
* @brief Initializes a ThreadX timer.
31+
*
32+
* @param timer Pointer to the timer to initialize.
33+
*/
34+
int timer_init(timer_t* timer);
35+
36+
/**
37+
* @brief Starts a ThreadX timer.
38+
*
39+
* @param timer Pointer to the timer to start.
40+
*/
41+
int timer_start(timer_t* timer);
42+
43+
/**
44+
* @brief Stops a ThreadX timer. If the timer is already deactivated, this function will have no effect.
45+
*
46+
* @param timer Pointer to the timer to stop.
47+
*/
48+
int timer_stop(timer_t* timer);
49+
50+
/**
51+
* @brief Resets a ThreadX timer back to its starting position. Does not automatically start the timer after resetting (use timer_restart() for that).
52+
*
53+
* @param timer Pointer to the timer to reset.
54+
*/
55+
int timer_reset(timer_t* timer);
56+
57+
/**
58+
* @brief Restarts a timer.
59+
*
60+
* @param timer Pointer to the timer to restart.
61+
*/
62+
int timer_restart(timer_t* timer);
63+
64+
/**
65+
* @brief Gets the remaining number of ticks until the timer's expiration.
66+
*
67+
* @param timer Pointer to the timer.
68+
* @param remaining Buffer to store the information.
69+
*/
70+
int timer_getRemainingTicks(timer_t* timer, uint32_t *remaining);
71+
72+
// clang-format on

threadX/src/u_tx_timers.c

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
#include "u_tx_timers.h"
2+
#include "u_tx_debug.h"
3+
4+
// clang-format off
5+
6+
/* Check if a timer is active. */
7+
int _is_timer_active(timer_t* timer, bool* active) {
8+
/* Get the active indication. */
9+
UINT is_active;
10+
int status = tx_timer_info_get(&timer->TX_TIMER_, (CHAR**)TX_NULL, &is_active, (ULONG*)TX_NULL, (ULONG*)TX_NULL, (TX_TIMER**)TX_NULL);
11+
if(status != TX_SUCCESS) {
12+
PRINTLN_ERROR("Failed to call tx_timer_info_get (Status: %d/%s, Timer: %s).", status, tx_status_toString(status), timer->name);
13+
return U_ERROR;
14+
}
15+
16+
/* Check the indication. */
17+
if(is_active == TX_TRUE) {
18+
*active = true;
19+
} else {
20+
*active = false;
21+
}
22+
23+
return U_SUCCESS;
24+
}
25+
26+
/* Initializes a timer. */
27+
int timer_init(timer_t* timer) {
28+
/* Set reschedule ticks setting. */
29+
ULONG reschedule_ticks;
30+
if(timer->type == ONESHOT) {
31+
reschedule_ticks = 0; // If it's a one-shot timer, don't reschedule the timer.
32+
} else {
33+
reschedule_ticks = timer->duration; // If it's a periodic timer, set the timer to go off every 'duration' ticks.
34+
}
35+
36+
/* Set auto-activate setting. */
37+
UINT auto_activate;
38+
if(timer->auto_activate) {
39+
auto_activate = TX_AUTO_ACTIVATE; // The timer will start automatically at initialization.
40+
} else {
41+
auto_activate = TX_NO_ACTIVATE; // The timer must be manually started after initialization.
42+
}
43+
44+
/* Create the timer. */
45+
int status = tx_timer_create(&timer->TX_TIMER_, (CHAR*)timer->name, timer->callback, timer->callback_input, timer->duration, reschedule_ticks, auto_activate);
46+
if(status != TX_SUCCESS) {
47+
PRINTLN_ERROR("Failed to create timer (Status: %d/%s, Timer: %s).", status, tx_status_toString(status), timer->name);
48+
return U_ERROR;
49+
}
50+
51+
/* Return successful. */
52+
PRINTLN_INFO("Ran Timer::init() (Timer: %s).", timer->name);
53+
return U_SUCCESS;
54+
}
55+
56+
/* Starts a timer. */
57+
int timer_start(timer_t* timer) {
58+
/* Get active status. */
59+
bool is_active = false;
60+
int status = _is_timer_active(timer, &is_active);
61+
if(status != U_SUCCESS) {
62+
PRINTLN_ERROR("Failed to get the activation status of a timer (Timer: %s).", timer->name);
63+
return U_ERROR;
64+
}
65+
66+
/* Check active status. */
67+
if(is_active) {
68+
PRINTLN_ERROR("Tried to start a timer that is already active (Timer: %s).", timer->name);
69+
return U_ERROR;
70+
}
71+
72+
/* Activate the timer. */
73+
status = tx_timer_activate(&timer->TX_TIMER_);
74+
if(status != TX_SUCCESS) {
75+
PRINTLN_ERROR("Failed to call tx_timer_activate() (Status: %d/%s, Timer: %s).", status, tx_status_toString(status), timer->name);
76+
return U_ERROR;
77+
}
78+
79+
return U_SUCCESS;
80+
}
81+
82+
/* Stops a timer. If the timer is already deactivated, this function will have no effect. */
83+
int timer_stop(timer_t* timer) {
84+
/* Deactivate the timer. */
85+
int status = tx_timer_deactivate(&timer->TX_TIMER_);
86+
if(status != TX_SUCCESS) {
87+
PRINTLN_ERROR("Failed to call tx_timer_deactivate() (Status: %d/%s, Timer: %s).", status, tx_status_toString(status), timer->name);
88+
return U_ERROR;
89+
}
90+
return U_SUCCESS;
91+
}
92+
93+
/* Resets a timer back to its starting position. Does not automatically start the timer after resetting (use Timer::restart() for that.) */
94+
int timer_reset(timer_t* timer) {
95+
/* Deactivate the timer. */
96+
int status = tx_timer_deactivate(&timer->TX_TIMER_);
97+
if(status != TX_SUCCESS) {
98+
PRINTLN_ERROR("Failed to call tx_timer_deactivate() (Status: %d/%s, Timer: %s).", status, tx_status_toString(status), timer->name);
99+
return U_ERROR;
100+
}
101+
102+
/* Set reschedule ticks setting. */
103+
ULONG reschedule_ticks;
104+
if(timer->type == ONESHOT) {
105+
reschedule_ticks = 0; // If it's a one-shot timer, don't reschedule the timer.
106+
}
107+
else {
108+
reschedule_ticks = timer->duration; // If it's a periodic timer, set the timer to go off every 'duration' ticks.
109+
}
110+
111+
/* Change the timer. */
112+
status = tx_timer_change(&timer->TX_TIMER_, timer->duration, reschedule_ticks);
113+
if(status != TX_SUCCESS) {
114+
PRINTLN_ERROR("Failed to call tx_timer_change() (Status: %d/%s, Timer: %s).", status, tx_status_toString(status), timer->name);
115+
return U_ERROR;
116+
}
117+
118+
return U_SUCCESS;
119+
}
120+
121+
/* Restarts a timer. */
122+
int timer_restart(timer_t* timer) {
123+
/* Reset the timer. */
124+
int status = timer_reset(timer);
125+
if(status != U_SUCCESS) {
126+
PRINTLN_ERROR("Failed to call timer_reset() when restarting timer (Timer: %s).", timer->name);
127+
return U_ERROR;
128+
}
129+
130+
/* Start the timer. */
131+
status = timer_start(timer);
132+
if(status != U_SUCCESS) {
133+
PRINTLN_ERROR("Failed to call timer_start() when restarting timer (Timer: %s).", timer->name);
134+
return U_ERROR;
135+
}
136+
137+
return U_SUCCESS;
138+
}
139+
140+
/* Gets the remaining number of ticks until the timer's expiration. */
141+
int timer_getRemainingTicks(timer_t* timer, uint32_t* remaining) {
142+
/* Get the remaining ticks status. */
143+
ULONG remaining_ticks;
144+
int status = tx_timer_info_get(&timer->TX_TIMER_, (CHAR**)TX_NULL, (UINT*)TX_NULL, &remaining_ticks, (ULONG*)TX_NULL, (TX_TIMER**)TX_NULL);
145+
if(status != TX_SUCCESS) {
146+
PRINTLN_ERROR("Failed to call tx_timer_info_get (Status: %d/%s, Timer: %s).", status, tx_status_toString(status), timer->name);
147+
return U_ERROR;
148+
}
149+
150+
/* Set the remaining ticks. */
151+
*remaining = (uint32_t)(remaining_ticks);
152+
153+
return U_SUCCESS;
154+
}
155+
156+
// clang-format on

0 commit comments

Comments
 (0)