软件定时器实现-方法1
本文介绍了软件定时器的一种实现方法,该方法摘自git上面的实现,具体链接忘了。
缺点:使用起来比较复杂, 如果需要再次触发, 需要重新设置。
方法如下:
//multi_timer.c
#include "multi_timer.h" #include <stdio.h> /* Timer handle list head. */ static MultiTimer* timerList = NULL; /* Timer tick */ static PlatformTicksFunction_t platformTicksFunction = NULL; int MultiTimerInstall(PlatformTicksFunction_t ticksFunc) { platformTicksFunction = ticksFunc; return 0; } int MultiTimerStart(MultiTimer* timer, uint64_t timing, MultiTimerCallback_t callback, void* userData) { if (!timer || !callback ) { return -1; } MultiTimer** nextTimer = &timerList; /* Remove the existing target timer. */ for (; *nextTimer; nextTimer = &(*nextTimer)->next) { if (timer == *nextTimer) { *nextTimer = timer->next; /* remove from list */ break; } } /* Init timer. */ timer->deadline = platformTicksFunction() + timing; timer->callback = callback; timer->userData = userData; /* Insert timer. */ for (nextTimer = &timerList;; nextTimer = &(*nextTimer)->next) { if (!*nextTimer) { timer->next = NULL; *nextTimer = timer; break; } if (timer->deadline < (*nextTimer)->deadline) { timer->next = *nextTimer; *nextTimer = timer; break; } } return 0; } 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; } int MultiTimerYield(void) { MultiTimer* entry = timerList; for (; entry; entry = entry->next) { /* Sorted list, just process with the front part. */ if (platformTicksFunction() < entry->deadline) { return (int)(entry->deadline - platformTicksFunction()); } /* remove expired timer from list */ timerList = entry->next; /* call callback */ if (entry->callback) { entry->callback(entry, entry->userData); } } return 0; }
/* * Copyright (c) 2021 0x1abin * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef _MULTI_TIMER_H_ #define _MULTI_TIMER_H_ #include <stdint.h> #ifdef __cplusplus extern "C" { #endif typedef uint32_t (*PlatformTicksFunction_t)(void); typedef struct MultiTimerHandle MultiTimer; typedef void (*MultiTimerCallback_t)(MultiTimer* timer, void* userData); struct MultiTimerHandle { MultiTimer* next; uint64_t deadline; 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); /** * @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, uint64_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); /** * @brief Check the timer expried and call callback. * * @return int The next timer expires. */ int MultiTimerYield(void); #ifdef __cplusplus } #endif #endif
//main.c, 用于测试
//消框定时器
static void __app_multi_timer_proc( MultiTimer* timer, void *userData );
#define TIMER_TEST __app_multi_timer_proc
MultiTimer TmTest;
unsigned char timer_ms=1000;
//获取系统时间1ms
uint32_t PlatformTicksGetFunc(void)
{
// struct timespec current_time;
// clock_gettime(CLOCK_MONOTONIC, ¤t_time);
// return (uint64_t)((current_time.tv_sec * 1000) + (current_time.tv_nsec / 1000000));
return GetSysTick1MsCnt();
}
void __app_multi_timer_proc( MultiTimer* timer, void *userData )
{
unsigned int param = (unsigned int )userData;
printf( "multi timer :%d\n",param );
//如果需要轮询执行,需要再次调用MultiTimerStart
MultiTimerStart( &TmTest, timer_ms, TIMER_TEST, (void *)param )
}
int main() { //初始化软件定时器 MultiTimerInstall(PlatformTicksGetFunc);
unsigned int param = 0;
//设置一个软件定时器
MultiTimerStart( &TmTest, timer_ms, TIMER_TEST, (void *)param )
while(1)
{
//软件定时器处理逻辑
MultiTimerYield();
}
}