轻量级微型裸机任务调度组件

项目中小型单片机跑RTOS觉得有点大,自已整了一个轻量级的,感觉用的挺爽,分享给大家,直接上代码

#include "Tsk.h"
#include "main.h"
#include "SysConfig.h"

#pragma region 任务系统代码

typedef struct TskModl
{
	volatile uint8_t Num;
	FueTd d[tskNum];
	uint8_t state;
}TskModl;

static TskModl Tm;

//公用变量
static FueTd ftd;

/// <summary>
/// 初始化公用变量
/// </summary>
/// <param name=""></param>
/// <returns></returns>
FueTd* InitFd(void)
{
	memset(&ftd, 0, sizeof(FueTd));
	ftd.state = 1;
	return &ftd;
}

/// <summary>
/// 任务系统初始化
/// </summary>
/// <param name=""></param>
void Tsk_Init(void)
{
	if (Tm.state)
	{
		return;
	}
	memset(&Tm, 0, sizeof(TskModl));
	Tm.state = 1;
}

/// <summary>
/// 检测任务数
/// </summary>
/// <returns></returns>
static uint8_t InitTsk()
{
	if (!Tm.state)
	{
		Tsk_Init();
	}
	if (Tm.Num >= tskNum)
	{
		return tskNum;
	}
	return 0;
}

/// <summary>
/// 添加简易任务
/// 例当接收到串口数据时,将数据复制到申请的运态内存中,指定要处理的任务函数指针后,立即释放串口中断
/// </summary>
/// <param name="fu">任务指针</param>
/// <param name="d">数据指针</param>
/// <returns></returns>
void* TskAdd(void* fu, void* d)
{
	if (InitTsk())
	{
		return 0;
	}
	int i = 0;
	FueTd* f = 0;
	while (i < tskNum)
	{
		f = &Tm.d[i];
		if (!f->state)
		{
			if (d)
			{
				f->fues = fu;
				f->d = d;
			}
			else
			{
				f->fue = fu;
			}
			f->state = 1;
			Tm.Num++;
			return f;
		}
		i++;
	}
	return NULL;
}

/// <summary>
/// 添加标准任务
/// </summary>
/// <param name="d">任务结构体</param>
/// <returns></returns>
void* Tsk_Add(FueTd* d)
{
	if (InitTsk())
	{
		return 0;
	}
	int i = 0;
	FueTd* f = 0;
	while (i < tskNum)
	{
		f = &Tm.d[i];
		if (!f->state)
		{
			memcpy(f, d, sizeof(FueTd));
			if (!f->state)
			{
				f->state = 1;
			}
			if (!f->tim && f->setTim)
			{
				f->tim = HAL_GetTick() + f->setTim;
			}
			Tm.Num++;
			return f;
		}
		i++;
	}
	return 0;
}

/// <summary>
/// 任务执行函数,将它添加到 main 函数循环执行
/// 没有应用到系统中断及优先级等复杂技术,就是简单的循扫任务,要的就是简单吗
/// </summary>
/// <param name=""></param>
void To_Tsk(void)
{
	uint8_t i = 0;
	int num = Tm.Num;
	uint32_t state = 0;
	FueTd* f;
	sr.TskTim = HAL_GetTick();
	while (num > 0 && i < tskNum)
	{
		f = &Tm.d[i];
		if (f->state)
		{
			if (f->tim < sr.TskTim)
			{
				if (f->fues)
				{
					state = f->fues(f);
				}
				else
				{
					if (f->fue)
					{
						state = f->fue();
					}
					else
					{
						f->state = 0;
					}
				}
				if (!state)
				{
					memset(f, 0, sizeof(FueTd));
					Tm.Num--;
				}
				else
				{
					if (f->setTim)
					{
						f->tim = sr.TskTim + f->setTim;
					}
				}
			}
			num--;
		}
		i++;
	}
}

#pragma endregion

#pragma region 示例串口接收示例


/// <summary>
/// 接收处理
/// </summary>
/// <param name="v"></param>
/// <returns></returns>
static uint32_t ReceivingProcessing(void* v)
{
	FueTd* f = v;
	uint8_t* d = f->d;
	//处理数据D

	free(f->d);


	//如果返回1将不会销毁任务,正常不需要再执行任务时返回0
	return 0;

}

/// <summary>
/// 接收任务
/// </summary>
/// <param name="d"></param>
/// <param name="len"></param>
void  UART3_Receive(uint8_t* d, uint16_t len)
{
	if (len < 8)
	{
		return;
	}
	uint16_t* x = (uint16_t*)d;
	if (x[0] != len)
	{
		return;
	}
	uint8_t* t = malloc(len + 1);
	if (!t)
	{
		return;
	}
	t[len] = 0;
	memcpy(t, d, len);
	FueTd* f = InitFd();
	f->d = t;
	f->fues = ReceivingProcessing;
	f = Tsk_Add(f);
}

#pragma endregion

#pragma region 示例LED呼吸灯


static uint32_t LedFlashTsk(void* v)
{
	FueTd* f = v;
	f->state--;
	if (f->state % 2 == 0)
	{
		//LEDOff
	}
	else
	{
		//LEDOn
	}
	return f->state;
}

/// <summary>
/// LED呼吸灯
/// </summary>
/// <param name="tim">间隔</param>
/// <param name="num">闪烁次数</param>
void AddLedFlash(int tim, int num)
{

	FueTd* f = InitFd();
	f->setTim = tim;
	f->state = num * 2;
	f->fues = LedFlashTsk;
	Tsk_Add(f);
}


#pragma endregion

头文件

#ifndef __WEIREN_TSK_H__
#define __WEIREN_TSK_H__

#ifdef __cplusplus
extern "C" {
#endif

#include "stdint.h"
 
    #define  tskNum 32
 	
	typedef void Fu(void);

	typedef void Fus(void* arg);

	typedef uint32_t Fue(void);

	typedef uint32_t Fues(void* arg);

	typedef struct  FueTd
	{
		Fues* fues;

		Fue* fue;

		void* d;

		volatile uint32_t state;     //可以累加,但等于0时将被销毁

		uint32_t tim;    //任务执行时间

		uint16_t setTim;    //设置定时

	}FueTd;

	void Tsk_Init(void);
		
	void *TskAdd(void *fu, void *d);
	
	void *Tsk_Add(FueTd *d);

	void To_Tsk(void);

	FueTd *InitFd(void);
 
	
#ifdef __cplusplus
}
#endif
#endif /*__WEIREN_TSK_H__ */

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值