Upgrade 2.0.
parent
2e5223c645
commit
1dc788f79f
@ -0,0 +1,108 @@
|
|||||||
|
#include "MultiTimer.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef _MULTI_TIMER_H_
|
||||||
|
#define _MULTI_TIMER_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#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
|
||||||
@ -1,118 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2016 Zibin Zheng <znbin@qq.com>
|
|
||||||
* All rights reserved
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#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;
|
|
||||||
}
|
|
||||||
@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2016 Zibin Zheng <znbin@qq.com>
|
|
||||||
* All rights reserved
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _MULTI_TIMER_H_
|
|
||||||
#define _MULTI_TIMER_H_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
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
|
|
||||||
Loading…
Reference in New Issue