diff --git a/MultiTimer.c b/MultiTimer.c new file mode 100644 index 0000000..3a05af5 --- /dev/null +++ b/MultiTimer.c @@ -0,0 +1,108 @@ +#include "MultiTimer.h" +#include + +// Timer handle list head. +static MultiTimer* timerList = NULL; + +// Timer tick +static PlatformTicksFunction_t platformTicksFunction = NULL; + +/** + * @brief + * + * @param ticksFunc + * @return int + */ +int MultiTimerInstall(PlatformTicksFunction_t ticksFunc) +{ + platformTicksFunction = ticksFunc; + return 0; +} + +/** + * @brief Initializes the timer struct handle. + * @param handle: the timer handle strcut. + * @param timeout_cb: deadline callback. + * @param repeat: repeat interval time. + * @retval None + */ +int MultiTimerInit(MultiTimer* timer, uint32_t period, MultiTimerCallback_t cb, void* userData) +{ + if (!timer || !cb) { + return -1; + } + timer->callback = cb; + timer->userData = userData; + timer->period = period; + return 0; +} + +/** + * @brief Start the timer work, add the handle into work list. + * @param handle: target handle strcut. + * @param deadline: Set the start time. + * @retval 0: succeed. -1: already exist. + */ +int MultiTimerStart(MultiTimer* timer, uint32_t startTime) +{ + timer->deadline = platformTicksFunction() + startTime; + + // Insert timer. + MultiTimer** nextTimer = &timerList; + for (;; nextTimer = &(*nextTimer)->next) { + if (!*nextTimer) { + timer->next = NULL; + *nextTimer = timer; + break; + } + if (timer->deadline < (*nextTimer)->deadline) { + timer->next = *nextTimer; + *nextTimer = timer; + break; + } + } + + return 0; +} + +/** + * @brief Stop the timer work, remove the handle off work list. + * @param handle: target handle strcut. + * @retval None + */ +int MultiTimerStop(MultiTimer* timer) +{ + MultiTimer** nextTimer = &timerList; + + // Find and remove timer. + for (; *nextTimer; nextTimer = &(*nextTimer)->next) { + MultiTimer* entry = *nextTimer; + if (entry == timer) { + *nextTimer = timer->next; + break; + } + } + return 0; +} + +/** + * @brief main loop. + * @param None. + * @retval None + */ +void MultiTimerYield(void) +{ + MultiTimer* target = timerList; + for (; target; target = target->next) { + if (platformTicksFunction() >= target->deadline) { + if (target->period == 0) { + MultiTimerStop(target); + } else { + target->deadline = platformTicksFunction() + target->period; + } + target->callback(target, target->userData); + } else { + break; + } + } +} diff --git a/MultiTimer.h b/MultiTimer.h new file mode 100644 index 0000000..f33ecf1 --- /dev/null +++ b/MultiTimer.h @@ -0,0 +1,38 @@ +#ifndef _MULTI_TIMER_H_ +#define _MULTI_TIMER_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint64_t (*PlatformTicksFunction_t)(void); + +typedef struct MultiTimerHandle MultiTimer; + +typedef void (*MultiTimerCallback_t)(MultiTimer* timer, void* userData); + +struct MultiTimerHandle { + MultiTimer* next; + uint64_t deadline; + uint32_t period; + MultiTimerCallback_t callback; + void* userData; +}; + +int MultiTimerInstall(PlatformTicksFunction_t ticksFunc); + +int MultiTimerInit(MultiTimer* timer, uint32_t period, MultiTimerCallback_t cb, void* userData); + +int MultiTimerStart(MultiTimer* timer, uint32_t startTime); + +int MultiTimerStop(MultiTimer* timer); + +void MultiTimerYield(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/README.md b/README.md old mode 100755 new mode 100644 diff --git a/multi_timer.c b/multi_timer.c deleted file mode 100755 index 334d643..0000000 --- a/multi_timer.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2016 Zibin Zheng - * All rights reserved - */ - -#include -#include "multi_timer.h" - -//timer handle list head. -static struct Timer* head_handle = NULL; - -//Timer ticks -//static uint32_t _timer_ticks = (1 << 32)- 1000; // only for test tick clock overflow -static uint32_t _timer_ticks = 0; - -/** - * @brief Initializes the timer struct handle. - * @param handle: the timer handle strcut. - * @param timeout_cb: timeout callback. - * @param timeout: delay to start the timer. - * @param repeat: repeat interval time. - * @param arg: the input argument for timeout_cb fucntion. - * @retval None - */ -void timer_init(struct Timer* handle, void (*timeout_cb)(void *arg), \ - uint32_t timeout, uint32_t repeat, void *arg) -{ - // memset(handle, sizeof(struct Timer), 0); - handle->timeout_cb = timeout_cb; - handle->timeout = timeout; - handle->repeat = repeat; - handle->cur_ticks = _timer_ticks; - handle->cur_expired_time = handle->timeout; - handle->arg = arg; - //printf("cur_ticks: %u, cur_expired_time: %u, _timer_ticks: %u, timeout: %u\r\n", - // handle->cur_ticks, handle->cur_expired_time, _timer_ticks, timeout); -} - -/** - * @brief Start the timer work, add the handle into work list. - * @param btn: target handle strcut. - * @retval 0: succeed. -1: already exist. - */ -int timer_start(struct Timer* handle) -{ - struct Timer* target = head_handle; - - while(target) { - if(target == handle) { - return -1; //already exist. - } - target = target->next; - } - handle->next = head_handle; - head_handle = handle; - - return 0; -} - -/** - * @brief Stop the timer work, remove the handle off work list. - * @param handle: target handle strcut. - * @retval 0: succeed. -1: timer not exist. - */ -int timer_stop(struct Timer* handle) -{ - struct Timer** curr; - - for(curr = &head_handle; *curr;) { - struct Timer* entry = *curr; - if(entry == handle) { - *curr = entry->next; - //free(entry); - return 0; // found specified timer - } else { - curr = &entry->next; - } - } - - return 0; -} - -/** - * @brief main loop. - * @param None. - * @retval None - */ -void timer_loop(void) -{ - struct Timer* target; - - for(target = head_handle; target; target = target->next) { - /* - More detail on tick-clock overflow, please see https://blog.csdn.net/szullc/article/details/115332326 - */ - if(_timer_ticks - target->cur_ticks >= target->cur_expired_time) { - //printf("cur_ticks: %u, cur_expired_time: %u, _timer_ticks: %u\r\n", - // target->cur_ticks, target->cur_expired_time, _timer_ticks); - if(target->repeat == 0) { - timer_stop(target); - } else { - target->cur_ticks = _timer_ticks; - target->cur_expired_time = target->repeat; - } - target->timeout_cb(target->arg); - } - } -} - -/** - * @brief background ticks, timer repeat invoking interval nms. - * @param None. - * @retval None. - */ -void timer_ticks(void) -{ - _timer_ticks += CFG_TIMER_1_TICK_N_MS; -} diff --git a/multi_timer.h b/multi_timer.h deleted file mode 100755 index cb3e533..0000000 --- a/multi_timer.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2016 Zibin Zheng - * All rights reserved - */ - -#ifndef _MULTI_TIMER_H_ -#define _MULTI_TIMER_H_ - -#include -#include - -/* -It means 1 tick for 1ms. -Your can configurate for your tick time such as 5ms/10ms and so on. -*/ -#define CFG_TIMER_1_TICK_N_MS 1 - -typedef struct Timer { - uint32_t cur_ticks; /* Record current timer start tick */ - uint32_t cur_expired_time; /* Record current timer expired time */ - uint32_t timeout; /* Delay (xx ms) time to start tiemr */ - uint32_t repeat; /* Timer interval expired time (xx ms) */ - void * arg; /* Input argument for timeout_cb function */ - void (*timeout_cb)(void *arg); /* Timer expired callback function */ - struct Timer* next; /* Pointer to next timer */ -} Timer; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Initializes the timer struct handle. - * @param handle: the timer handle strcut. - * @param timeout_cb: timeout callback. - * @param timeout: delay to start the timer. - * @param repeat: repeat interval time. - * @param arg: the input argument for timeout_cb fucntion. - * @retval None - */ -void timer_init(struct Timer* handle, void(*timeout_cb)(void *arg), \ - uint32_t timeout, uint32_t repeat, void *arg); - -/** - * @brief Start the timer work, add the handle into work list. - * @param btn: target handle strcut. - * @retval 0: succeed. -1: already exist. - */ -int timer_start(struct Timer* handle); - -/** - * @brief Stop the timer work, remove the handle off work list. - * @param handle: target handle strcut. - * @retval 0: succeed. -1: timer not exist. - */ -int timer_stop(struct Timer* handle); - -/** - * @brief background ticks, timer repeat invoking interval nms. - * @param None. - * @retval None. - */ -void timer_ticks(void); - -/** - * @brief main loop. - * @param None. - * @retval None - */ -void timer_loop(void); - -#ifdef __cplusplus -} -#endif - -#endif