Skip to content

Commit

Permalink
os_timer_sig: Implement the possibility to restart the timer relative…
Browse files Browse the repository at this point in the history
… to the moment of the previous triggering (#38)

* os_timer_sig: Implement the possibility to restart the timer relative to the moment of the previous triggering

* os_timer_sig: Implement the possibility to restart the one-shot timer relative to the moment of the previous triggering
  • Loading branch information
TheSomeMan authored Oct 2, 2023
1 parent ba67f58 commit b643932
Show file tree
Hide file tree
Showing 2 changed files with 210 additions and 36 deletions.
79 changes: 71 additions & 8 deletions include/os_timer_sig.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ typedef struct os_timer_sig_periodic_static_obj_t
void* stub2;
os_signal_num_e stub3;
os_delta_ticks_t stub4;
bool stub5;
TickType_t stub5;
bool stub6;
bool stub7;
bool stub8;
} os_timer_sig_periodic_static_obj_t;

typedef struct os_timer_sig_periodic_static_t
Expand All @@ -42,8 +44,9 @@ typedef struct os_timer_sig_one_shot_static_obj_t
void* stub2;
os_signal_num_e stub3;
os_delta_ticks_t stub4;
bool stub5;
TickType_t stub5;
bool stub6;
bool stub7;
} os_timer_sig_one_shot_static_obj_t;

typedef struct os_timer_sig_one_shot_static_t
Expand Down Expand Up @@ -170,6 +173,24 @@ os_timer_sig_periodic_start(os_timer_sig_periodic_t* const p_obj);
void
os_timer_sig_one_shot_start(os_timer_sig_one_shot_t* const p_obj);

/**
* @brief Set the new period for the timer (but do not start or restart it).
*
* @param p_obj Pointer to the os_timer_sig_periodic_t object instance.
* @param delay_ticks Period for the timer, specified in system ticks.
*/
void
os_timer_sig_periodic_set_period(os_timer_sig_periodic_t* const p_obj, const os_delta_ticks_t delay_ticks);

/**
* @brief Set the new period for the timer (but do not start or restart it).
*
* @param p_obj Pointer to the os_timer_sig_periodic_t object instance.
* @param delay_ticks Period for the timer, specified in system ticks.
*/
void
os_timer_sig_one_shot_set_period(os_timer_sig_one_shot_t* const p_obj, const os_delta_ticks_t delay_ticks);

/**
* @brief Restarts the periodic timer which sends the specified signal.
*
Expand Down Expand Up @@ -212,26 +233,68 @@ os_timer_sig_one_shot_restart_with_period(
const bool flag_reset_active_timer);

/**
* @brief Stop and restart the periodic timer which sends the specified signal from the current moment.
* @brief Updates the timestamp associated with a one-shot signal timer when the timer was triggered.
*
* This function is used to update the timestamp value associated with a one-shot signal timer
* when the timer was triggered. It takes a pointer to the `os_timer_sig_one_shot_t` object and
* updates the `timestamp` field with the specified system tick counter.
*
* @param p_obj Pointer to the `os_timer_sig_one_shot_t` object.
* @param timestamp The timestamp value to update.
*/
void
os_timer_sig_one_shot_update_timestamp_when_timer_was_triggered(
os_timer_sig_one_shot_t* const p_obj,
const TickType_t timestamp);

/**
* @brief Updates the timestamp associated with a periodic signal timer when the timer was triggered.
*
* This function is used to update the timestamp value associated with a periodic signal timer
* when the timer was triggered. It takes a pointer to the `os_timer_sig_periodic_t` object and
* updates the `timestamp` field with the specified system tick counter.
*
* @param p_obj Pointer to the `os_timer_sig_periodic_t` object.
* @param timestamp The timestamp value to update.
*/
void
os_timer_sig_periodic_update_timestamp_when_timer_was_triggered(
os_timer_sig_periodic_t* const p_obj,
const TickType_t timestamp);

/**
* @brief Stop and restart the periodic timer which sends the specified signal.
*
* If the timer wasn't initially active, it will initiate it.
* For already active timers, the function stops it and restarts from the current moment.
* This function will restart the timer from the last time it was triggered (or from the current moment).
* For already active timers, the function stops it and then calculates the next trigger time.
* If the time since the last activation exceeds the configured period, the timer will be triggered immediately
* and the signal will be sent and a timer with the specified period will be activated.
* If the time elapsed since the last actuation is less than the configured period, the timer will be configured
* for the remaining time, and after it is triggered, it will be reconfigured for the specified period.
*
* @param p_obj Pointer to the os_timer_sig_periodic_t object instance.
* @param flag_restart_from_current_moment If true, then restart the timer from the current moment.
*/
void
os_timer_sig_periodic_relaunch(os_timer_sig_periodic_t* const p_obj);
os_timer_sig_periodic_relaunch(os_timer_sig_periodic_t* const p_obj, bool flag_restart_from_current_moment);

/**
* @brief Stop and restart the one-shot timer which sends the specified signal from the current moment.
* @brief Stop and restart the one-shot timer which sends the specified signal.
*
* If the timer wasn't initially active, it will initiate it.
* For already active timers, the function stops it and restarts from the current moment.
* This function will restart the timer from the last time it was triggered (or from the current moment).
* For already active timers, the function stops it and then calculates the next trigger time.
* If the time since the last activation exceeds the configured period, the timer will be triggered immediately
* and the signal will be sent, but the one-shot timer will not be activated.
* If the time elapsed since the last actuation is less than the configured period, the timer will be configured
* for the remaining time, and after it is triggered.
*
* @param p_obj Pointer to the os_timer_sig_one_shot_t object instance.
* @param flag_restart_from_current_moment If true, then restart the timer from the current moment.
*/
void
os_timer_sig_one_shot_relaunch(os_timer_sig_one_shot_t* const p_obj);
os_timer_sig_one_shot_relaunch(os_timer_sig_one_shot_t* const p_obj, const bool flag_restart_from_current_moment);

/**
* @brief Stop the periodic timer which sends the specified signal.
Expand Down
167 changes: 139 additions & 28 deletions src/os_timer_sig.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ struct os_timer_sig_periodic_t
os_signal_t* p_signal;
os_signal_num_e sig_num;
os_delta_ticks_t period_ticks;
TickType_t last_tick_when_timer_was_triggered;
bool is_static;
volatile bool is_active;
bool flag_need_to_restart;
};

_Static_assert(
Expand All @@ -33,6 +35,7 @@ struct os_timer_sig_one_shot_t
os_signal_t* p_signal;
os_signal_num_e sig_num;
os_delta_ticks_t period_ticks;
TickType_t last_tick_when_timer_was_triggered;
bool is_static;
volatile bool is_active;
};
Expand All @@ -48,7 +51,13 @@ os_timer_sig_cb_periodic(ATTR_UNUSED os_timer_periodic_t* p_timer, void* p_arg)
{
return;
}
os_timer_sig_periodic_t* p_obj = p_arg;
os_timer_sig_periodic_t* p_obj = p_arg;
p_obj->last_tick_when_timer_was_triggered = xTaskGetTickCount();
if (p_obj->flag_need_to_restart)
{
p_obj->is_active = os_timer_periodic_restart(p_obj->p_timer, p_obj->period_ticks);
p_obj->flag_need_to_restart = false;
}
if (p_obj->is_active)
{
os_signal_send(p_obj->p_signal, p_obj->sig_num);
Expand All @@ -62,7 +71,8 @@ os_timer_sig_cb_one_shot(ATTR_UNUSED os_timer_one_shot_t* p_timer, void* p_arg)
{
return;
}
os_timer_sig_one_shot_t* p_obj = p_arg;
os_timer_sig_one_shot_t* p_obj = p_arg;
p_obj->last_tick_when_timer_was_triggered = xTaskGetTickCount();
if (p_obj->is_active)
{
p_obj->is_active = false;
Expand All @@ -83,12 +93,14 @@ os_timer_sig_periodic_create(
{
return NULL;
}
p_obj->p_signal = p_signal;
p_obj->sig_num = sig_num;
p_obj->period_ticks = period_ticks;
p_obj->is_static = false;
p_obj->is_active = false;
p_obj->p_timer = os_timer_periodic_create(p_timer_name, period_ticks, &os_timer_sig_cb_periodic, p_obj);
p_obj->p_signal = p_signal;
p_obj->sig_num = sig_num;
p_obj->period_ticks = period_ticks;
p_obj->last_tick_when_timer_was_triggered = xTaskGetTickCount() - period_ticks;
p_obj->is_static = false;
p_obj->is_active = false;
p_obj->flag_need_to_restart = false;
p_obj->p_timer = os_timer_periodic_create(p_timer_name, period_ticks, &os_timer_sig_cb_periodic, p_obj);
if (NULL == p_obj->p_timer)
{
os_timer_sig_periodic_delete(&p_obj);
Expand All @@ -110,11 +122,13 @@ os_timer_sig_periodic_create_static(
{
os_timer_sig_periodic_t* const p_obj = (os_timer_sig_periodic_t*)&p_timer_sig_mem->obj_mem;

p_obj->p_signal = p_signal;
p_obj->sig_num = sig_num;
p_obj->period_ticks = period_ticks;
p_obj->is_static = true;
p_obj->is_active = false;
p_obj->p_signal = p_signal;
p_obj->sig_num = sig_num;
p_obj->period_ticks = period_ticks;
p_obj->last_tick_when_timer_was_triggered = xTaskGetTickCount() - period_ticks;
p_obj->is_static = true;
p_obj->is_active = false;
p_obj->flag_need_to_restart = false;

p_obj->p_timer = os_timer_periodic_create_static(
&p_timer_sig_mem->os_timer_mem,
Expand All @@ -138,12 +152,13 @@ os_timer_sig_one_shot_create(
{
return NULL;
}
p_obj->p_signal = p_signal;
p_obj->sig_num = sig_num;
p_obj->period_ticks = period_ticks;
p_obj->is_static = false;
p_obj->is_active = false;
p_obj->p_timer = os_timer_one_shot_create(p_timer_name, period_ticks, &os_timer_sig_cb_one_shot, p_obj);
p_obj->p_signal = p_signal;
p_obj->sig_num = sig_num;
p_obj->period_ticks = period_ticks;
p_obj->last_tick_when_timer_was_triggered = xTaskGetTickCount() - period_ticks;
p_obj->is_static = false;
p_obj->is_active = false;
p_obj->p_timer = os_timer_one_shot_create(p_timer_name, period_ticks, &os_timer_sig_cb_one_shot, p_obj);
if (NULL == p_obj->p_timer)
{
os_timer_sig_one_shot_delete(&p_obj);
Expand All @@ -165,11 +180,12 @@ os_timer_sig_one_shot_create_static(
{
os_timer_sig_one_shot_t* const p_obj = (os_timer_sig_one_shot_t*)&p_timer_sig_mem->obj_mem;

p_obj->p_signal = p_signal;
p_obj->sig_num = sig_num;
p_obj->period_ticks = period_ticks;
p_obj->is_static = true;
p_obj->is_active = false;
p_obj->p_signal = p_signal;
p_obj->sig_num = sig_num;
p_obj->period_ticks = period_ticks;
p_obj->last_tick_when_timer_was_triggered = xTaskGetTickCount() - period_ticks;
p_obj->is_static = true;
p_obj->is_active = false;

p_obj->p_timer = os_timer_one_shot_create_static(
&p_timer_sig_mem->os_timer_mem,
Expand Down Expand Up @@ -260,6 +276,26 @@ os_timer_sig_one_shot_start(os_timer_sig_one_shot_t* const p_obj)
os_timer_one_shot_start(p_obj->p_timer);
}

void
os_timer_sig_periodic_set_period(os_timer_sig_periodic_t* const p_obj, const os_delta_ticks_t delay_ticks)
{
if (NULL == p_obj)
{
return;
}
p_obj->period_ticks = delay_ticks;
}

void
os_timer_sig_one_shot_set_period(os_timer_sig_one_shot_t* const p_obj, const os_delta_ticks_t delay_ticks)
{
if (NULL == p_obj)
{
return;
}
p_obj->period_ticks = delay_ticks;
}

void
os_timer_sig_periodic_restart_with_period(
os_timer_sig_periodic_t* const p_obj,
Expand Down Expand Up @@ -299,27 +335,102 @@ os_timer_sig_one_shot_restart_with_period(
}

void
os_timer_sig_periodic_relaunch(os_timer_sig_periodic_t* const p_obj)
os_timer_sig_one_shot_update_timestamp_when_timer_was_triggered(
os_timer_sig_one_shot_t* const p_obj,
const TickType_t timestamp)
{
p_obj->last_tick_when_timer_was_triggered = timestamp;
}

void
os_timer_sig_periodic_update_timestamp_when_timer_was_triggered(
os_timer_sig_periodic_t* const p_obj,
const TickType_t timestamp)
{
p_obj->last_tick_when_timer_was_triggered = timestamp;
}

void
os_timer_sig_periodic_relaunch(os_timer_sig_periodic_t* const p_obj, bool flag_restart_from_current_moment)
{
if (NULL == p_obj)
{
return;
}
p_obj->is_active = false;
os_timer_periodic_stop(p_obj->p_timer);
p_obj->is_active = os_timer_periodic_restart(p_obj->p_timer, p_obj->period_ticks);

int32_t delta_ticks = (int32_t)p_obj->period_ticks;
const TickType_t cur_tick = xTaskGetTickCount();
if (flag_restart_from_current_moment)
{
os_timer_sig_periodic_update_timestamp_when_timer_was_triggered(p_obj, cur_tick);
}
else
{
const os_delta_ticks_t elapsed_ticks = cur_tick - p_obj->last_tick_when_timer_was_triggered;

delta_ticks = (int32_t)(p_obj->period_ticks - elapsed_ticks);
}
if (delta_ticks > 0)
{
if (delta_ticks == (int32_t)p_obj->period_ticks)
{
p_obj->flag_need_to_restart = false;
p_obj->is_active = os_timer_periodic_restart(p_obj->p_timer, p_obj->period_ticks);
}
else
{
p_obj->flag_need_to_restart = true;
p_obj->is_active = os_timer_periodic_restart(p_obj->p_timer, delta_ticks);
}
}
else
{
p_obj->flag_need_to_restart = false;
p_obj->is_active = os_timer_periodic_restart(p_obj->p_timer, p_obj->period_ticks);
os_timer_periodic_simulate(p_obj->p_timer);
}
}

void
os_timer_sig_one_shot_relaunch(os_timer_sig_one_shot_t* const p_obj)
os_timer_sig_one_shot_relaunch(os_timer_sig_one_shot_t* const p_obj, const bool flag_restart_from_current_moment)
{
if (NULL == p_obj)
{
return;
}
p_obj->is_active = false;
os_timer_one_shot_stop(p_obj->p_timer);
p_obj->is_active = os_timer_one_shot_restart(p_obj->p_timer, p_obj->period_ticks);

int32_t delta_ticks = (int32_t)p_obj->period_ticks;
const TickType_t cur_tick = xTaskGetTickCount();
if (flag_restart_from_current_moment)
{
os_timer_sig_one_shot_update_timestamp_when_timer_was_triggered(p_obj, cur_tick);
}
else
{
const os_delta_ticks_t elapsed_ticks = cur_tick - p_obj->last_tick_when_timer_was_triggered;

delta_ticks = (int32_t)(p_obj->period_ticks - elapsed_ticks);
}
if (delta_ticks > 0)
{
if (delta_ticks == (int32_t)p_obj->period_ticks)
{
p_obj->is_active = os_timer_one_shot_restart(p_obj->p_timer, p_obj->period_ticks);
}
else
{
p_obj->is_active = os_timer_one_shot_restart(p_obj->p_timer, delta_ticks);
}
}
else
{
p_obj->is_active = true;
os_timer_one_shot_simulate(p_obj->p_timer);
}
}

void
Expand Down

0 comments on commit b643932

Please sign in to comment.