项目中小型单片机跑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__ */