diff --git a/Makefile b/Makefile index 2be11d6..87314ae 100755 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ INC += -I$(IDIR) TARGET = $(BIN_PATH)/test C_SRCS += examples/test_linux.c -C_SRCS += multi_timer.c +C_SRCS += MultiTimer.c OBJ := $(patsubst %.c,%.o,$(filter %.c,$(addprefix $(SRC_PATH)/,$(C_SRCS)))) TARGET_OBJ := $(addprefix $(OBJ_PATH)/,$(OBJ)) diff --git a/MultiTimer.c b/MultiTimer.c index 394372d..75de835 100644 --- a/MultiTimer.c +++ b/MultiTimer.c @@ -7,46 +7,18 @@ 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) +int MultiTimerStart(MultiTimer* timer, uint32_t timing, MultiTimerCallback_t callback, void* userData) { - if (!timer || !cb) { + if (!timer || !callback) { 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) -{ MultiTimer** nextTimer = &timerList; - /* Remove the existing target timer. */ for (; *nextTimer; nextTimer = &(*nextTimer)->next) { if (timer == *nextTimer) { @@ -55,8 +27,10 @@ int MultiTimerStart(MultiTimer* timer, uint32_t startTime) } } - /* New deadline time. */ - timer->deadline = platformTicksFunction() + startTime; + /* Init timer. */ + timer->deadline = platformTicksFunction() + timing; + timer->callback = callback; + timer->userData = userData; /* Insert timer. */ for (nextTimer = &timerList;; nextTimer = &(*nextTimer)->next) { @@ -74,15 +48,9 @@ int MultiTimerStart(MultiTimer* timer, uint32_t startTime) 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; @@ -94,29 +62,25 @@ int MultiTimerStop(MultiTimer* timer) return 0; } -/** - * @brief main loop. - * @param None. - * @retval None - */ -void MultiTimerYield(void) +int MultiTimerYield(void) { MultiTimer** nextTimer = &timerList; - for (; *nextTimer; nextTimer = &(*nextTimer)->next) { MultiTimer* entry = *nextTimer; /* Sorted list, just process with the front part. */ if (entry->deadline > platformTicksFunction()) { - return; + return (int)(entry->deadline - platformTicksFunction()); } /* remove expired timer from list */ *nextTimer = entry->next; - if (entry->period) { - MultiTimerStart(entry, entry->period); - } + /* call callback */ if (entry->callback) { entry->callback(entry, entry->userData); } + if (entry->next == NULL) { + return 0; + } } + return 0; } diff --git a/MultiTimer.h b/MultiTimer.h index f33ecf1..60eb45f 100644 --- a/MultiTimer.h +++ b/MultiTimer.h @@ -16,20 +16,43 @@ typedef void (*MultiTimerCallback_t)(MultiTimer* timer, void* userData); struct MultiTimerHandle { MultiTimer* next; uint64_t deadline; - uint32_t period; MultiTimerCallback_t callback; void* userData; }; +/** + * @brief Platform ticks function. + * + * @param ticksFunc ticks function. + * @return int 0 on success, -1 on error. + */ int MultiTimerInstall(PlatformTicksFunction_t ticksFunc); -int MultiTimerInit(MultiTimer* timer, uint32_t period, MultiTimerCallback_t cb, void* userData); - -int MultiTimerStart(MultiTimer* timer, uint32_t startTime); - +/** + * @brief Start the timer work, add the handle into work list. + * + * @param timer target handle strcut. + * @param timing Set the start time. + * @param callback deadline callback. + * @param userData user data. + * @return int 0: success, -1: fail. + */ +int MultiTimerStart(MultiTimer* timer, uint32_t timing, MultiTimerCallback_t callback, void* userData); + +/** + * @brief Stop the timer work, remove the handle off work list. + * + * @param timer target handle strcut. + * @return int 0: success, -1: fail. + */ int MultiTimerStop(MultiTimer* timer); -void MultiTimerYield(void); +/** + * @brief Check the timer expried and call callback. + * + * @return int The next timer expires. + */ +int MultiTimerYield(void); #ifdef __cplusplus } diff --git a/examples/main.c b/examples/main.c deleted file mode 100755 index e5a7c03..0000000 --- a/examples/main.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "multi_timer.h" - -struct Timer timer1; -struct Timer timer2; - -void timer1_callback(void *arg) -{ - printf("timer1 timeout! arg: %p\r\n", arg); -} - -void timer2_callback(void *arg) -{ - printf("timer2 timeout! arg: %p\r\n", arg); -} - -int main(void) -{ - timer_init(&timer1, timer1_callback, 1000, 1000, NULL); //1s loop - timer_start(&timer1); - - timer_init(&timer2, timer2_callback, 50, 0, NULL); //50ms delay - timer_start(&timer2); - - while(1) { - timer_loop(); - } - - return 0; -} - -void HAL_SYSTICK_Callback(void) -{ - timer_ticks(); //1ms ticks -} \ No newline at end of file diff --git a/examples/test_linux.c b/examples/test_linux.c index d9618e3..30ff5ad 100755 --- a/examples/test_linux.c +++ b/examples/test_linux.c @@ -1,92 +1,45 @@ #include -#include #include #include -#include -#include +#include "../MultiTimer.h" -#include "../multi_timer.h" +MultiTimer timer1; +MultiTimer timer2; +MultiTimer timer3; -#define LOG_TIMESTAMP_FORMAT "[%Y-%m-%d %H:%M:%S]" -#define LOG_TIMESTAMP_LEN 21 -#define MS_TIMESTAMP_LEN 5 - -int32_t printf_timestamp(const char *msg, ...) +uint64_t PlatformTicksGetFunc(void) { - char content[1024] = {0}; - time_t time_write; - struct tm tm_Log; - struct timeval t; - uint32_t len = 0; - va_list vl_list; - - time_write = time(NULL); - localtime_r(&time_write, &tm_Log); - strftime((char *)&content[len], sizeof(content) - len - 1, LOG_TIMESTAMP_FORMAT, &tm_Log); - len = strlen(&content[len]); - - /* .msec] */ - gettimeofday(&t, NULL); - len--; // min a ']' char - snprintf((char*)&content[len], sizeof(content) - len, ".%03d]", (int)(t.tv_usec / 1000)); - len += MS_TIMESTAMP_LEN; - - va_start(vl_list, msg); - vsnprintf((char *)&content[len], sizeof(content) - len - 1, (const char *)msg, vl_list); - va_end(vl_list); - - printf("%s", content); - - return 0; + struct timespec current_time; + clock_gettime(CLOCK_MONOTONIC, ¤t_time); + return (uint64_t)((current_time.tv_sec * 1000) + (current_time.tv_nsec / 1000000)); } -void signalHandler(int signo) +void exampleTimer1Callback(MultiTimer* timer, void *userData) { - switch(signo) - { - case SIGALRM: - timer_ticks(); - //printf_timestamp("Caught the SIGALRM signal every 1ms !\n"); - break; - } + printf("[T:%012ld] Timer:%p callback-> %s.\r\n", PlatformTicksGetFunc(), timer, (char*)userData); + MultiTimerStart(timer, 1000, exampleTimer1Callback, userData); } -struct Timer timer1; -struct Timer timer2; - -void timer1_callback(void *arg) +void exampleTimer2Callback(MultiTimer* timer, void *userData) { - printf_timestamp("timer1 timeout! arg: %p\r\n", arg); + printf("[T:%012ld] Timer:%p callback-> %s.\r\n", PlatformTicksGetFunc(), timer, (char*)userData); } -void timer2_callback(void *arg) +void exampleTimer3Callback(MultiTimer* timer, void *userData) { - printf_timestamp("timer2 timeout! arg: %p\r\n", arg); + printf("[T:%012ld] Timer:%p callback-> %s.\r\n", PlatformTicksGetFunc(), timer, (char*)userData); + MultiTimerStart(timer, 4567, exampleTimer3Callback, userData); } -int main(void) +int main(int argc, char *argv[]) { - printf_timestamp("%s start ...\r\n", __func__); - - signal(SIGALRM, signalHandler); - - struct itimerval new_value, old_value; - new_value.it_value.tv_sec = 0; // should be 0x00 !!! - new_value.it_value.tv_usec = 1; // non-zero is OK !!! - new_value.it_interval.tv_sec = 0; - new_value.it_interval.tv_usec = 1000 * CFG_TIMER_1_TICK_N_MS; // 1ms - setitimer(ITIMER_REAL, &new_value, &old_value); + MultiTimerInstall(PlatformTicksGetFunc); - timer_init(&timer1, timer1_callback, 4000, 1000, &timer1); // start timer after 4s - timer_start(&timer1); + MultiTimerStart(&timer1, 1000, exampleTimer1Callback, "1000ms CYCLE timer"); + MultiTimerStart(&timer2, 5000, exampleTimer2Callback, "5000ms ONCE timer"); + MultiTimerStart(&timer3, 3456, exampleTimer3Callback, "3456ms delay start, 4567ms CYCLE timer"); - timer_init(&timer2, timer2_callback, 0, 5000, &timer2); // start timer right now - timer_start(&timer2); - - while(1) { - /* Maybe some sleep time is needed to avoid running CPU all the time. */ - timer_loop(); + while (1) { + MultiTimerYield(); } - - return 0; -} +} \ No newline at end of file