简易版-软件定时器

发布时间 2023-11-01 16:18:56作者: 星辰陪衬

main.c

#include <stdio.h>
#include <stdlib.h>
#include "sw_timer.h"
#include "windows.h"
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

void timer1(void *parameter)
{
	sw_timer_t *timer = parameter;
	printf("timer1 run %s ...\r\n",timer->user_data);
}



void timer2(void *parameter)
{
	sw_timer_t *timer = parameter;
	printf("timer2 run %s ...\r\n",timer->user_data);
}



void timer3(void *parameter)
{
	sw_timer_t *timer = parameter;
	printf("timer3 run %s ...\r\n",timer->user_data);
	sw_timer_set_pause(timer);
}

void timer4(void *parameter)
{
	sw_timer_t *timer = parameter;
	printf("timer4 run %s ...\r\n",timer->user_data);
	sw_timer_del(timer);
}


int main(int argc, char *argv[])
{
	sw_timer_t * timer;
	setbuf(stdout, NULL);
	timer = sw_timer_create(timer1,1000,6,"timer1");
	printf("timer = %p\r\n",timer);
	sw_timer_set_repeat_count(timer,10);
	timer = sw_timer_create(timer2,2000,3,"timer2");
	printf("timer = %p\r\n",timer);
	timer = sw_timer_create(timer3,3000,2,"timer3");
	printf("timer = %p\r\n",timer);
	timer = sw_timer_create(timer4,4000,8,"timer4");
	printf("timer = %p\r\n",timer);


	while(1)
	{
		sw_timer_handle();
		Sleep(10);
		sw_timer_tick(10);
		//printf("...\r\n");
	}
	
	return 0;
}

  

sw_timer.h

#ifndef __SW_TIMER_H__
#define __SW_TIMER_H__

#include "stdint.h"

#define TIMER_LIST_NUM_MAX      10


typedef void (*sw_timer_cb_t)(void *);

typedef struct
{
    uint32_t used;		/*  */
	uint32_t period; /**< How often the timer should run*/
    uint32_t priority;  /* 优先级 越小优先级越高*/
    uint32_t last_run; /**< next time the timer ran*/
    sw_timer_cb_t timer_cb; /**< Timer function*/
    void * user_data; /**< Custom user data*/
    int32_t repeat_count; /**< 1: One time;  -1 : infinity;  n>0: residual times*/
    uint32_t paused : 1;
}sw_timer_t;





sw_timer_t *sw_timer_create(sw_timer_cb_t timer_xcb, uint32_t period, uint32_t priority, void * user_data);
int sw_timer_del(sw_timer_t *timer);
int sw_get_timer_count(void);
void sw_timer_handle(void);

void sw_timer_set_ready(sw_timer_t * timer, void *user_data);
void sw_timer_set_pause(sw_timer_t *timer);
void sw_timer_set_repeat_count(sw_timer_t * timer, int32_t repeat_count);

void sw_timer_tick(uint32_t ms);



#endif //__SW_LIST_H__

  

sw_timer.c

#include "sw_timer.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"

#define timer_malloc(x)         malloc(x)
#define timer_free(p)           free(p)
#define timer_tick_get			sw_tick_get

#define T_LOG_USER         		printf
#define T_LOG_ERROR          	printf

#define TIMER_LIST_NUM_MAX		10


static sw_timer_t timer_list[TIMER_LIST_NUM_MAX] = {0};



static uint32_t time_space(uint32_t new,uint32_t old)
{
    uint32_t ret = 0;
    if(new > old)
    {
        ret = new -old;
    }
    else
    {
        ret = 0xFFFFFFFFU - old;
        ret += new;
    }
    return ret;
}

static uint32_t timer_tick = 0;
void sw_timer_tick(uint32_t ms)
{
	timer_tick += ms;
}

static uint32_t sw_tick_get(void)
{
	return timer_tick;
}

int sw_get_timer_count(void)
{
	int i=0;
	int cnt = 0;
	for(i=0;i<TIMER_LIST_NUM_MAX;i++)
	{
		if(timer_list[i].used == 1)
		{
			cnt++; 
		}
	}
	return cnt;
}


sw_timer_t *sw_timer_create(sw_timer_cb_t timer_xcb, uint32_t period, uint32_t priority, void * user_data)
{
	int i = 0,j = 0;
	if(sw_get_timer_count() >= TIMER_LIST_NUM_MAX)
	{
		T_LOG_ERROR("timer count >= TIMER_LIST_NUM_MAX");
		return NULL;
	}
	for(i=0;i<TIMER_LIST_NUM_MAX;i++)
	{
		if(timer_list[i].used == 1)
		{
			if(timer_list[i].priority > priority)
			{
				for(j=TIMER_LIST_NUM_MAX-2;j>=i;j--)
				{
					memcpy(&timer_list[j+1],&timer_list[j],sizeof(sw_timer_t));
				}
				break;
			}
		}
		else
		{
			break;
		}
	}
	timer_list[i].period = period;
	timer_list[i].priority = priority;
	timer_list[i].timer_cb = timer_xcb;
	timer_list[i].repeat_count = -1;
	timer_list[i].paused = 0;
	timer_list[i].last_run = timer_tick_get();
	timer_list[i].user_data = user_data;
	timer_list[i].used = 1;
	printf("timer[i] = %d\r\n",i);
	return &timer_list[i];
}

int sw_timer_del(sw_timer_t *timer)
{
	int i = 0,j = 0;
	for(i=0;i<TIMER_LIST_NUM_MAX;i++)
	{
		if(timer_list[i].used != 1)
		{
			return -1;
		}	
		if(&timer_list[i] == timer)
		{
			for(j=i;j<TIMER_LIST_NUM_MAX-1;j++)
			{
				memcpy(&timer_list[j],&timer_list[j+1],sizeof(sw_timer_t));
			}
			return 1;
		}
	}
	return -1;
}

void sw_timer_set_pause(sw_timer_t *timer)
{
	timer->paused = 1;
}

void sw_timer_set_repeat_count(sw_timer_t * timer, int32_t repeat_count)
{
	timer->repeat_count = repeat_count;
}

void sw_timer_set_ready(sw_timer_t * timer, void *user_data)
{
	timer->user_data = user_data;
	timer->paused = 0;
	timer->last_run = timer_tick_get() - timer->period - 1;
}


void sw_timer_handle(void)
{
	int i = 0;
	for(i=0;i<TIMER_LIST_NUM_MAX;i++)
	{
		if(timer_list[i].used != 1)
		{
			break;
		}
		if(timer_list[i].paused != 0)
		{
			continue;
		}
		if(timer_list[i].repeat_count == 0)
		{
			continue;
		}
		
		if(time_space(timer_tick_get(),timer_list[i].last_run) >= timer_list[i].period)
		{
			if(timer_list[i].repeat_count > 0)
			{
				timer_list[i].repeat_count --;
			}
			timer_list[i].timer_cb(&timer_list[i]);
			timer_list[i].last_run = timer_tick_get();
		}	
	}
}