MultiTimer使用及调整

原项目地址:GitHub - 0x1abin/MultiTimer: Software timers extend module for embedded

之前在项目上有利用一个硬件定时器,对多段代码执行时间进行测量,于是就去网上寻找一下是否有较为成熟的源码,就看到很多人在讨论MultiTimer,翻看一下代码确实简约高效,于是把它作为项目前后台系统任务添加方式,可以避免变量跨文件,有利于工程管理;

在实际使用过程,做了部分调整(不一定是优化),更贴合自己的使用目的:

1、因为前后台任务均是周期调用,我在原来定时器类增加周期调用属性;

2、因为为满足多个使用场景,修改为面向对象属性,支持定义多个定时器系统;

3、考虑多个线程时序问题,还要考虑运行时临界问题,由于该代码我仅在初始化使用,暂时不添加;

#include "MultiTimer.h"
#include <stdio.h>

/**
 * @brief 初始化定时器
 * @param timer 定时器上下文
 * @param ticksFunc 平台定时器回调函数
 * @return 0 成功,-1 失败
 */
int multiTimerInit(stTimerContext* timerHandle,uint64_t(*ticksFunc)(void))
{
    if(timerHandle == NULL || ticksFunc == NULL)
    {
        return -1; 
    }
    timerHandle->timerList = NULL;
    timerHandle->callback = ticksFunc;
    return 0;
}

/**
 * @brief 移除定时器
 * @param timer 要移除的定时器
 * @return 无
 */
static void removeTimer(stTimerContext* timerHandle,MultiTimer* timer) 
{
    MultiTimer** current = &timerHandle->timerList;
    while (*current) 
    {
        if (*current == timer) 
        {
            *current = timer->next;
            break;
        }
        current = &(*current)->next;
    }
}

/**
 * @brief 启动定时器
 * @param timer 要启动的定时器
 * @param timing 定时时间(单位:毫秒)
 * @param callback 定时器回调函数
 * @param userData 用户数据
 * @return 0 成功,-1 失败
 */
int multiTimerStart(stTimerContext* timerHandle, MultiTimer* timer, uint64_t timing, uint8_t isRepeat,  void (*callback)(MultiTimer*,void*), void* userData)
{
    if(timerHandle == NULL || timer == NULL || timing == 0 || callback == NULL)
    {
        return -1; 
    }
    removeTimer(timerHandle, timer);

	timer->Ctrl.bit.repeat = (isRepeat?1:0);
    timer->deadline = timerHandle->callback() + timing;
	timer->interval = timing;
    timer->callback = callback;
    timer->userData = userData;

    MultiTimer** current = &timerHandle->timerList;
    while (*current && ((*current)->deadline < timer->deadline)) 
    {
        current = &(*current)->next;
    }
    timer->next = *current;
    *current = timer;

    return 0;
}

/**
 * @brief 停止定时器
 * @param timer 要停止的定时器
 * @return 0 成功,-1 失败
 */
int multiTimerStop(stTimerContext* timerHandle, MultiTimer* timer) 
{
    removeTimer(timerHandle, timer); 
    return 0;
}

/**
 * @brief 等待下一个定时器事件
 * @return 距离下一个定时器事件的剩余时间(单位:毫秒),如果没有定时器事件,则返回0
 */
int multiTimerYield(stTimerContext* timerHandle) 
{
    if(timerHandle == NULL || timerHandle->timerList == NULL || timerHandle->callback == NULL)
    {
        return -1; 
    }
    uint64_t currentTicks = timerHandle->callback();
    MultiTimer* timer = timerHandle->timerList;
    MultiTimer** current = NULL;
    while(timer && (timer->deadline <= currentTicks))
    {
        if (timer->callback) 
        {
            timer->callback(timer, timer->userData);
        }
        if(timer->Ctrl.bit.repeat)
        {
            timer->deadline = currentTicks + timer->interval;
			removeTimer(timerHandle, timer);
			
			current = &timerHandle->timerList;
			while (*current && ((*current)->deadline < timer->deadline)) 
			{
				current = &(*current)->next;
			}
			timer->next = *current;
			*current = timer;
        }
        else
        {
            removeTimer(timerHandle, timer);
        }
        timer = timerHandle->timerList;;
    }
    return timer ? (int)(timer->deadline - currentTicks) : 0;
}
#ifndef __MULTITIMER_H__
#define __MULTITIMER_H__

#include <stdint.h>

#ifdef __cplusplus  
extern "C" {  
#endif

typedef struct MultiTimer{
    struct MultiTimer* next;
	union{
		uint32_t all;
		struct{
			uint32_t repeat:1;
			uint32_t rev:31;
		}bit;
	}Ctrl;
    uint64_t deadline;
    uint64_t interval;
    void (*callback)(struct MultiTimer*, void*);
    void* userData;
}MultiTimer;

typedef struct{
    MultiTimer* timerList;
    uint64_t(*callback)(void);
}stTimerContext;


/**
 * @brief 初始化定时器
 * @param timer 定时器上下文
 * @param ticksFunc 平台定时器回调函数
 * @return 0 成功,-1 失败
 */
int multiTimerInit(stTimerContext* timerHandle,uint64_t(*ticksFunc)(void));

/**
 * @brief 移除定时器
 * @param timer 要移除的定时器
 * @return 无
 */
static void removeTimer(stTimerContext* timerHandle,MultiTimer* timer);

/**
 * @brief 启动定时器
 * @param timer 要启动的定时器
 * @param timing 定时时间(单位:毫秒)
 * @param callback 定时器回调函数
 * @param userData 用户数据
 * @return 0 成功,-1 失败
 */
int multiTimerStart(stTimerContext* timerHandle, MultiTimer* timer, uint64_t timing, 
				uint8_t isRepeat,  void (*callback)(MultiTimer*,void*), void* userData);

/**
 * @brief 停止定时器
 * @param timer 要停止的定时器
 * @return 0 成功,-1 失败
 */
int multiTimerStop(stTimerContext* timerHandle, MultiTimer* timer);

/**
 * @brief 等待下一个定时器事件
 * @return 距离下一个定时器事件的剩余时间(单位:毫秒),如果没有定时器事件,则返回0
 */
int multiTimerYield(stTimerContext* timerHandle);


#ifdef __cplusplus
} 
#endif

#endif

以下是搭好框架后,成果展示,是不是实现了类似RTOS任务调度操作?当然这仅是基于裸机,并没有任务调度,仅有时间片驱动的周期执行事件 

/**
 * @file Test.c
 * @author <NAME> (<EMAIL>)
 * @brief Test file for APL
 * @version 0.1
 * @date 2021-09-13
 */

#ifdef __cplusplus
extern "C" {
#endif

#include "TimerManage.h"
#include "BspGpio.h"

static MultiTimer taskLed1 = {0};
static MultiTimer taskLed2 = {0};
static MultiTimer taskLed3 = {0};


/**
 * @brief Led1任务回调函数
 * @param timer 定时器指针
 * @param user 用户数据
 */
static void taskLed1Callback(MultiTimer* timer, void* user)
{
    BspGpioSet(GPIO_PORT_C,GPIO_PIN_11,2);
}

/**
 * @brief Led2任务回调函数
 * @param timer 定时器指针
 * @param user 用户数据
 */
static void taskLed2Callback(MultiTimer* timer, void* user)
{
    BspGpioSet(GPIO_PORT_C,GPIO_PIN_10,2);
}

/**
 * @brief Led3任务回调函数
 * @param timer 定时器指针
 * @param user 用户数据
 */
static void taskLed3Callback(MultiTimer* timer, void* user)
{
    BspGpioSet(GPIO_PORT_D,GPIO_PIN_3,2);
}

/**
 * @brief 初始化Led
 * @return None
 */
void LedInit(void)
{
    //初始化Led
    BspGpioInit(GPIO_PORT_C,GPIO_PIN_11,GPIO_MODE_OUTPUT,GPIO_OUTPUT_OPEN_DRAIN,GPIO_SPEED_MEDIUM,GPIO_PULL_NONE);
    BspGpioInit(GPIO_PORT_C,GPIO_PIN_10,GPIO_MODE_OUTPUT,GPIO_OUTPUT_OPEN_DRAIN,GPIO_SPEED_MEDIUM,GPIO_PULL_NONE);
	BspGpioInit(GPIO_PORT_D,GPIO_PIN_3,GPIO_MODE_OUTPUT,GPIO_OUTPUT_OPEN_DRAIN,GPIO_SPEED_MEDIUM,GPIO_PULL_NONE);
    //添加Led1任务
    TimerManageMsAddTask(&taskLed1, 10, 1, taskLed1Callback, NULL);
    //添加Led2任务
    TimerManageMsAddTask(&taskLed2, 100, 1, taskLed2Callback, NULL);
	//添加Led3任务
    TimerManageMsAddTask(&taskLed3, 1000, 1, taskLed3Callback, NULL);
}





















#ifdef __cplusplus
}
#endif

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值