diff --git a/.gitignore b/.gitignore index 167bed0..4a9aa90 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.vscode *.o *.out test diff --git a/MultiTimer.c b/MultiTimer.c index f0419fb..947e35e 100644 --- a/MultiTimer.c +++ b/MultiTimer.c @@ -1,11 +1,6 @@ #include "MultiTimer.h" #include -#define MULTIMER_MAX_TIMEOUT 0x7fffffff - -/* Check if timer's expiry time is greater than time and care about uint32_t wraparounds */ -#define CHECK_TIME_LESS_THAN(t, compare_to) ( (((uint32_t)((t)-(compare_to))) > MULTIMER_MAX_TIMEOUT) ? 1 : 0 ) - /* Timer handle list head. */ static MultiTimer* timerList = NULL; @@ -18,9 +13,9 @@ int MultiTimerInstall(PlatformTicksFunction_t ticksFunc) return 0; } -int MultiTimerStart(MultiTimer* timer, uint32_t timing, MultiTimerCallback_t callback, void* userData) +int MultiTimerStart(MultiTimer* timer, uint64_t timing, MultiTimerCallback_t callback, void* userData) { - if (!timer || !callback || timing > MULTIMER_MAX_TIMEOUT / 2 ) { + if (!timer || !callback ) { return -1; } MultiTimer** nextTimer = &timerList; @@ -72,7 +67,7 @@ int MultiTimerYield(void) MultiTimer* entry = timerList; for (; entry; entry = entry->next) { /* Sorted list, just process with the front part. */ - if (CHECK_TIME_LESS_THAN(platformTicksFunction(), entry->deadline)) { + if (platformTicksFunction() < entry->deadline) { return (int)(entry->deadline - platformTicksFunction()); } /* remove expired timer from list */ @@ -83,4 +78,5 @@ int MultiTimerYield(void) entry->callback(entry, entry->userData); } } + return 0; } diff --git a/MultiTimer.h b/MultiTimer.h index 3ae6671..a36fd0f 100644 --- a/MultiTimer.h +++ b/MultiTimer.h @@ -29,7 +29,7 @@ extern "C" { #endif -typedef uint32_t (*PlatformTicksFunction_t)(void); +typedef uint64_t (*PlatformTicksFunction_t)(void); typedef struct MultiTimerHandle MultiTimer; @@ -37,7 +37,7 @@ typedef void (*MultiTimerCallback_t)(MultiTimer* timer, void* userData); struct MultiTimerHandle { MultiTimer* next; - uint32_t deadline; + uint64_t deadline; MultiTimerCallback_t callback; void* userData; }; @@ -59,7 +59,7 @@ int MultiTimerInstall(PlatformTicksFunction_t ticksFunc); * @param userData user data. * @return int 0: success, -1: fail. */ -int MultiTimerStart(MultiTimer* timer, uint32_t timing, MultiTimerCallback_t callback, void* userData); +int MultiTimerStart(MultiTimer* timer, uint64_t timing, MultiTimerCallback_t callback, void* userData); /** * @brief Stop the timer work, remove the handle off work list. diff --git a/README.md b/README.md index 907c181..2e61bdf 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ MultiTimer 是一个软件定时器扩展模块,可无限扩展你所需的定 1. 配置系统时间基准接口,安装定时器驱动; ```c -uint32_t PlatformTicksGetFunc(void) +uint64_t PlatformTicksGetFunc(void) { /* Platform implementation */ } @@ -24,7 +24,7 @@ MultiTimer timer1; 3. 设置定时时间,超时回调处理函数, 用户上下指针,启动定时器; ```c -int MultiTimerStart(&timer1, uint32_t timing, MultiTimerCallback_t callback, void* userData); +int MultiTimerStart(&timer1, uint64_t timing, MultiTimerCallback_t callback, void* userData); ``` 4. 在主循环调用定时器后台处理函数 @@ -43,11 +43,9 @@ int main(int argc, char *argv[]) ## 功能限制 1.定时器的时钟频率直接影响定时器的精确度,尽可能采用1ms/5ms/10ms这几个精度较高的tick; -2.定义应用定时器时,最大定时不可以超过 UINT32_MAX / 4; +2.定时器的回调函数内不应执行耗时操作,否则可能因占用过长的时间,导致其他定时器无法正常超时; -3.定时器的回调函数内不应执行耗时操作,否则可能因占用过长的时间,导致其他定时器无法正常超时; - -4.由于定时器的回调函数是在 MultiTimerYield 内执行的,需要注意栈空间的使用不能过大,否则可能会导致栈溢出。 +3.由于定时器的回调函数是在 MultiTimerYield 内执行的,需要注意栈空间的使用不能过大,否则可能会导致栈溢出。 ## Examples @@ -63,11 +61,11 @@ MultiTimer timer1; MultiTimer timer2; MultiTimer timer3; -uint32_t PlatformTicksGetFunc(void) +uint64_t PlatformTicksGetFunc(void) { struct timespec current_time; clock_gettime(CLOCK_MONOTONIC, ¤t_time); - return (uint32_t)((current_time.tv_sec * 1000) + (current_time.tv_nsec / 1000000)); + return (uint64_t)((current_time.tv_sec * 1000) + (current_time.tv_nsec / 1000000)); } void exampleTimer1Callback(MultiTimer* timer, void *userData) diff --git a/examples/test_linux.c b/examples/test_linux.c index d945b34..9b91182 100644 --- a/examples/test_linux.c +++ b/examples/test_linux.c @@ -7,27 +7,27 @@ MultiTimer timer1; MultiTimer timer2; MultiTimer timer3; -uint32_t PlatformTicksGetFunc(void) +uint64_t PlatformTicksGetFunc(void) { struct timespec current_time; clock_gettime(CLOCK_MONOTONIC, ¤t_time); - return (uint32_t)((current_time.tv_sec * 1000) + (current_time.tv_nsec / 1000000)); + return (uint64_t)((current_time.tv_sec * 1000) + (current_time.tv_nsec / 1000000)); } void exampleTimer1Callback(MultiTimer* timer, void *userData) { - printf("[T:%010d] Timer:%p callback-> %s.\r\n", PlatformTicksGetFunc(), timer, (char*)userData); + printf("[%012ld] Timer:%p callback-> %s.\r\n", PlatformTicksGetFunc(), timer, (char*)userData); MultiTimerStart(timer, 1000, exampleTimer1Callback, userData); } void exampleTimer2Callback(MultiTimer* timer, void *userData) { - printf("[T:%010d] Timer:%p callback-> %s.\r\n", PlatformTicksGetFunc(), timer, (char*)userData); + printf("[%012ld] Timer:%p callback-> %s.\r\n", PlatformTicksGetFunc(), timer, (char*)userData); } void exampleTimer3Callback(MultiTimer* timer, void *userData) { - printf("[T:%010d] Timer:%p callback-> %s.\r\n", PlatformTicksGetFunc(), timer, (char*)userData); + printf("[%012ld] Timer:%p callback-> %s.\r\n", PlatformTicksGetFunc(), timer, (char*)userData); MultiTimerStart(timer, 4567, exampleTimer3Callback, userData); }