MultiTimer开源定时器(多任务回调)----链表分析
·
/*
* Copyright (c) 2016 https://blog.csdn.net/Wekic
* All rights reserved
*/
#ifndef _MULTI_TIMER_H_
#define _MULTI_TIMER_H_
#include "stdint.h"
#include "stddef.h"
typedef struct Timer {
uint32_t timeout; //超时时间
uint32_t repeat; //重置时间
void (*timeout_cb)(void); //回调任务函数
struct Timer* next; //下一个任务
}Timer;
#ifdef __cplusplus
extern "C" {
#endif
void timer_init(struct Timer* handle, void(*timeout_cb)(), uint32_t timeout, uint32_t repeat);
int timer_start(struct Timer* handle);
void timer_stop(struct Timer* handle);
void timer_ticks(void);
void timer_loop(void);
// void timer_again(struct Timer* handle);
// void timer_set_repeat(struct Timer* handle, uint32_t repeat);
#ifdef __cplusplus
}
#endif
#endif
/*
* Copyright (c) 2020 https://blog.csdn.net/Wekic
* All rights reserved
*/
#include "multi_timer.h"
//timer handle list head.
static struct Timer* head_handle = NULL;
//Timer ticks
static uint32_t _timer_ticks = 0;
/**
* @brief Initializes the timer struct handle.
* @param handle: the timer handle strcut.
* @param timeout_cb: timeout callback.
* @param repeat: repeat interval time.
* @retval None
*/
//定时器回调任务初始化
void timer_init(struct Timer* handle, void(*timeout_cb)(), uint32_t timeout, uint32_t repeat)
{
// memset(handle, sizeof(struct Timer), 0);
handle->timeout_cb = timeout_cb; //回调块
handle->timeout = _timer_ticks + timeout; //设置超时时间
handle->repeat = repeat; //设置回调时间
}
/**
* @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 None
*/
//删除任务块
void 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);
}
//偏移下一个回调块
else{
curr = &entry->next;
}
}
}
/**
* @brief main loop.
* @param None.
* @retval None
*/
//任务链表检查
void timer_loop()
{
struct Timer* target;
//循环 (1.得到链表头 2.判断下一个是否为空 3.继续下一个)
for(target=head_handle; target; target=target->next) {
//超出时间
if(_timer_ticks >= target->timeout) {
//重载为0,去掉这个定时任务
if(target->repeat == 0) {
timer_stop(target);
}
//设置下一次超时时间
else {
target->timeout = _timer_ticks + target->repeat;
}
//运行回调函数
target->timeout_cb();
}
}
}
/**
* @brief background ticks, timer repeat invoking interval 1ms.
* @param None.
* @retval None.
*/
//提供时间基准
void timer_ticks()
{
_timer_ticks++;
}
README.md
# MultiTimer
## 简介
MultiTimer 是一个软件定时器扩展模块,可无限扩展你所需的定时器任务,取代传统的标志位判断方式, 更优雅更便捷地管理程序的时间触发时序。
## 使用方法
1.先申请一个定时器管理handle
```
struct Timer timer1;
```
2.初始化定时器对象,注册定时器回调处理函数,设置定时时间(ms),循环定时触发时间
```
timer_init(struct Timer* handle, void(*timeout_cb)(), uint32_t timeout, uint32_t repeat);
```
3.启动定时器
```
timer_start(&timer1);
```
4.设置1ms的硬件定时器循环调用 *timer_ticks()* 以提供时间基准
```
void HAL_SYSTICK_Callback(void)
{
timer_ticks();
}
```
5.在主循环调用定时器后台处理函数
```
int main()
{
...
while(1) {
...
timer_loop();
}
}
```
## Examples
```
#include "multi_timer.h"
struct Timer timer1;
struct Timer timer2;
void timer1_callback()
{
printf("timer1 timeout!\r\n");
}
void timer2_callback()
{
printf("timer2 timeout!\r\n");
}
int main()
{
timer_init(&timer1, timer1_callback, 1000, 1000); //1s loop
timer_start(&timer1);
timer_init(&timer2, timer2_callback, 50, 0); //50ms delay
timer_start(&timer2);
while(1) {
timer_loop();
}
}
void HAL_SYSTICK_Callback(void)
{
timer_ticks(); //1ms ticks
}
```
## Examples
```
#include "multi_timer.h"
struct Timer timer1;
struct Timer timer2;
void timer1_callback()
{
printf("timer1 timeout!\r\n");
}
void timer2_callback()
{
printf("timer2 timeout!\r\n");
}
int main()
{
timer_init(&timer1, timer1_callback, 1000, 1000); //1s loop (1S定时任务)
timer_start(&timer1);
timer_init(&timer2, timer2_callback, 50, 0); //50ms delay (50ms调用)
timer_start(&timer2);
while(1) {
timer_loop();
}
}
void HAL_SYSTICK_Callback(void)
{
timer_ticks(); //1ms ticks
}
```
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)