基于时间片的简易任务调度器

依据时间片调度的原理以及根据github上开源项目TMT,将TMT重新按照自己的风格编写了一遍做出了如今的STS(简易任务调度器),并做出一点小小改动,如有兴趣可在github找到TMT开源项目用于学习。

头文件

/*
 * @Author: Qiu Weian
 * @Date: 2022-05-07 19:49:14
 * @LastEditors: Qiu Weian
 * @LastEditTime: 2022-05-08 15:24:26
 * @Description: 
 */
/*-----------------------------------------------------------------------
|                            FILE DESCRIPTION                           |
-----------------------------------------------------------------------*/
/*----------------------------------------------------------------------
  - File name     : stms.h
  - Author        : wan
  - Update date   : 2022.05.07                  
  -	Copyright(c)  : All rights reserved.
-----------------------------------------------------------------------*/
/*------------------------------------------------------------------------
|                            COPYRIGHT NOTICE                            |
------------------------------------------------------------------------*/
/*****
 * Statement:This is a simple task scheduler,basede on the open project TMT
 *           task manager on the github,rewire it with my own code style.
 * ***/




/*-----------------------------------------------------------------------
|                              TRANSPLANT                               |
-----------------------------------------------------------------------*/
#ifndef __STS_H_
#define __STS_H_

#ifdef __cplusplus
extern "C" {
#endif

/* Includes -------------------------------------------------------------*/
/**
 * @brief     硬件平台(MCU)相关的头文件,提供硬件运行的基本环境,一般是寄存器头文件。
 * @details   The header files related to the hardware platform(MCU) provide 
 *            the basic environment for hardware operation, generally 
 *            register header files..
**/
//example:#include "reg52.h"

/* Defines --------------------------------------------------------------*/
/**
 * @brief     进入STS临界区宏函数,需要关闭相关定时器的中断。
 * @details   Enter the STS critical section macro function.
 *            It is necessary to turn off the interrupt of the related timer.
 * @note      需要根据硬件平台,移植合适的关定时器中断代码。
 *            It is necessary to transplant the appropriate off-timer 
 *            interrupt code according to the hardware platform.
**/
//ENTER_TMT_CRI_AREA()    do{ __HAL_TIM_DISABLE_IT(&htim1,TIM_IT_UPDATE); }while(0)  //32版本
//ENTER_TMT_CRI_AREA()    do{ IT0 = 0; }while(0) //51版本
#define       ENTER_STS_CRI_AREA() 

/**
 * @brief     退出STS临界区宏函数,需要打开相关定时器的中断。
 * @details   Enter the STS critical section macro function.
 *            It is necessary to turn on the interrupt of the related timer.
 * @note      需要根据硬件平台,移植合适的开定时器中断代码。
 *            It is necessary to transplant the appropriate on-timer 
 *            interrupt code according to the hardware platform.
 * 
**/
//#define       EXTI_TMT_CRI_AREA()     do{ __HAL_TIM_ENABLE_IT(&htim1,TIM_IT_UPDATE); }while(0) //32版本
//#define       EXTI_TMT_CRI_AREA()     do{ IT0 = 1; }while(0) //51版本
#define       EXTI_STS_CRI_AREA()

/**
 * @brief     STS的变量类型重定义,如果有冲突,请配置为0。
 * @details   The variable type of STS is redefined. 
 *            If there is a conflict, please configure it to 0..
**/
#if 		  (0)

	typedef  unsigned char   uint8_t; /*!<  8 bits */
	typedef  unsigned int   uint16_t; /*!< 16 bits */

#endif

/*-----------------------------------------------------------------------
|                                CONFIG                                 |
-----------------------------------------------------------------------*/

/**
 * @brief     任务数量控制宏,用来确定STS需要调度的最大任务数量。
 * @details   The number of tasks control macro is used to 
 *            determine the maximum number of tasks that STS
 *            needs to schedule.
**/
#define 	  STS_TASK_NUM  	 		(8)
/**
 * @brief     删除任务的风格,用来确定删除任务时是否按照创建任务的顺序排序,
 * 			  用来确定任务同样的时间片调度时确定任务调用顺序。
 * 			  1:按照创建任务顺序排序
 * 			  0:删除任务时将最后一位任务放入将被删除的任务的位置
 * @details   The style of deleting tasks is used to determine whether to delete 
 *            tasks in the order in which they were created, and to determine the
 *            order in which tasks are called when they are scheduled in the same
 * 			  time slice.
 * 			  1:Sort by task creation order
 * 			  0:When deleting a task, put the last task in the position of the task that will be deleted
**/
#define 	  STS_DELETE_TASK_STYLE		(0)


/*-----------------------------------------------------------------------
|                                 DATA                                  |
-----------------------------------------------------------------------*/

/**
 * @brief     任务的执行状态枚举体。
 * @details   The execution status enumerator of the task.
**/
typedef enum
{
  TASK_STOP     = 1,         /*!< 停止运行状态。*/
	TASK_RUN      = !TASK_STOP /*!< 继续运行状态。*/
} TASK_STATE_TYPE_E;

/**
  * @brief   STS函数自检枚举体,指示函数是否正常执行。
  *          STS function self checks enumerator. 
  *          indicating whether the function is normally executed.
***/
typedef enum
{
	FSC_FAIL     = 1,        /* Function self checking failed */
	FSC_SUCCESS  = !FSC_FAIL /* Function self checking successfed */ 
} FSC_STATE_TYPE_E; 

/* Externs --------------------------------------------------------------*/
/*-----------------------------------------------------------------------
|                             API FUNCTION                              |
-----------------------------------------------------------------------*/
/**
 * @brief   STS的API操作函数结构体。
 * @details The STS API manipulates the function structure.
**/
typedef struct
{
	/**
	 * @brief     STS更新任务调度tick时间。
	 * @details   STS update task schedule tick time.
	 * @param[in] None.
	 * @return    None.
	 * @note      在定时器中断服务函数中调用。
	 *            Called in the timer interrupt service function.
	 * @example   STS.Ticks();
	**/
	void (*Update_Tick) (void);
	
	
	/**
	 * @brief     STS运行函数,是任务调度器。
	 * @details   STS runs the function, which is the task scheduler.
	 * @param[in] None.
	 * @return    None.
	 * @note      在main函数的无限循环中调用。
	 *            Called in the infinite loop of main.
	 * @example   STS.Run();
	**/
	void (*Run) (void);
	
	
	/**
	 * @brief     STS创建一个任务函数。
	 * @details   STS creates a task function.
	 * @param[in] entry 任务函数入口指针.
	 *            A pointer function without formal parameters.
	 * @param[in] setTime 任务调度的时间 task run time (ticks)
	 * @return    [FSC_SUCCESS]创建成功.Create successfully.
	 * @return    [FSC_FAIL]创建失败.	Create failed.
	 * @note      在main函数的无限循环中调用。
	 *            Called in the infinite loop of main.
	 * @example   STS.Create(Entry,500); //定时Entry任务为500ticks调度一次
	**/	
	FSC_STATE_TYPE_E (*CreateTask) (void (*Entry) (void), uint16_t Set_Time);
	
	
	/**
	 * @brief     STS删除一个任务函数。
	 * @details   STS creates a task function.
	 * @param[in] entry 任务函数入口指针.
	 *            A pointer function without formal parameters.
	 * @return    [FSC_SUCCESS]删除成功.Delete successfully.
	 * @return    [FSC_FAIL]删除失败.	Delete failed.
	 * @example   STS.Delete(Enrty); //删除entry任务
	**/		
	FSC_STATE_TYPE_E (*DeleteTask) (void (*Entry) (void));
	
	
	/**
	 * @brief     STS控制一个任务的调度时间函数。
	 * @details   The STS controls the scheduling time function of a task.
	 * @param[in] entry 任务函数入口指针.
	 *            A pointer function without formal parameters.
	 * @param[in] setTime 任务调度的时间 task run time (ticks)
	 * @return    [FSC_SUCCESS]修改成功.The modification was successful.
	 * @return    [FSC_FAIL]修改失败.The modification was failed.
	 * @example   STS.Set_Task_Tick(Enrty,100); //修改entry任务为100ticks调度一次
	**/	
	FSC_STATE_TYPE_E (*Set_Task_Tick) (void (*Entry) (void), uint16_t Set_Time);
	
	
	/**
	 * @brief     STS控制一个任务运行状态函数。
	 * @details   STS controls a task running state function.
	 * @param[in] entry 任务函数入口指针.
	 *            A pointer function without formal parameters.
	 * @param[in] state 任务运行状态.Task running status
	 * @return    [FSC_SUCCESS]修改成功.The modification was successful.
	 * @return    [FSC_FAIL]修改失败.The modification was failed.
	 * @example   STS.Set_Task_RunState(Enrty,TASK_STOP); //修改entry任务为停止运行.
	**/		
	FSC_STATE_TYPE_E (*Set_Task_RunState) (void (*Entry) (void), TASK_STATE_TYPE_E State);
} STS_TYPE_S;

/**
 * @brief   STS初始化函数,注册相关元素。
 * @details The STS initializes the function 
 *          and registers the associated elements.
 * @param   None.
 * @return  None.
**/
extern void STS_Init(void);

/**
 * @brief   对外声明的STS操作函数结构体。
 * @details TMT operation function structure declared externally.
 * @note    所有需要被外部调用的函数,都包含在这个结构体中.
 *          All functions that need to be called externally 
 *          are included in this structure.
**/
extern STS_TYPE_S STS;

#ifdef __cplusplus
}
#endif

#endif /*__STS_H_*/



c文件

/*
 * @Author: Qiu Weian
 * @Date: 2022-05-07 19:49:14
 * @LastEditors: Qiu Weian
 * @LastEditTime: 2022-05-09 12:09:10
 * @Description: 
 */
/*-----------------------------------------------------------------------
|                            FILE DESCRIPTION                           |
-----------------------------------------------------------------------*/
/*----------------------------------------------------------------------
  - File name     : stms.h
  - Author        : wan
  - Update date   : 2022.05.07                  
  -	Copyright(c)  : All rights reserved.
-----------------------------------------------------------------------*/

/* Includes -------------------------------------------------------------*/
#include "sts.h"
/*-----------------------------------------------------------------------
|                                 DATA                                  |
-----------------------------------------------------------------------*/

/**
 * @brief     最大任务数量宏,再封装一层。
 * @details   The maximum number of tasks is a macro, 
 *            and then one layer is encapsulated.
**/
#define  TASKS_MAX       STS_TASK_NUM

STS_TYPE_S STS;

/**
 * @brief   STS的类,包含公共和私有两个属性。
 * @details Class of STS, containing both pbl and pvt properties.
**/
typedef struct 
{
    void     (*Entry) (void);    /*!< 任务函数入口指针。*/
    uint16_t Tim_Cnt;            /*!< 任务调度时间计数器。*/
    uint16_t Set_Time;           /*!< 任务设置的调度时间。*/
    uint8_t  State;              /*!< 任务运行状态。*/
} TASK_INFO_S;

typedef struct 
{
    TASK_INFO_S Tasks[TASKS_MAX];   /*!< 任务信息。*/
    uint8_t     Task_Num;           /*!< 已经创建的任务数量。*/
} STS_PRIVATE_TYPE_S;

typedef struct 
{
    STS_TYPE_S         public;      /*!< 公共部分,对外开放的属性,具体定义在头文件。*/
    STS_PRIVATE_TYPE_S private;     /*!< 私有部分,仅限本文件内调用。*/
} STS_OBJECT_S;

static STS_OBJECT_S STS_Object;     /*!< 创建内部对象,私有部分,仅限本文件内调用。*/

/*-----------------------------------------------------------------------
|                               FUNCTION                                |
-----------------------------------------------------------------------*/
/**
 * @brief     STS更新任务调度tick时间。
 * @details   STS update task schedule tick time.
 * @param[in] None.
 * @return    None.
**/
static void STS_Update_Tick(void)
{
    uint8_t i;
    for (i = 0; i < STS_Object.private.Task_Num; i++) 
    {
        /* If time arrives */
        if (STS_Object.private.Tasks[i].Tim_Cnt > 0)
        {
            STS_Object.private.Tasks[i].Tim_Cnt--;
        }
    }
}

/**
 * @brief     STS运行函数,是任务调度器。
 * @details   STS runs the function, which is the task scheduler.
 * @param[in] None.
 * @return    None.
**/
static void STS_Run(void)
{
    uint8_t i;
    for (i = 0; i < STS_Object.private.Task_Num; i++) 
    {
        /* If time arrives */
        if ((STS_Object.private.Tasks[i].Tim_Cnt == 0) && (STS_Object.private.Tasks[i].State != TASK_STOP))
        {
            STS_Object.private.Tasks[i].Tim_Cnt = STS_Object.private.Tasks[i].Set_Time;
            /* 
				To prevent process conflict, 
				only one process can be executed in the same time period.
			*/
            if (STS_Object.private.Tasks[i].Entry != (void *)(0)) 
            {
                STS_Object.private.Tasks[i].Entry();    /* Run the task once */
            }
        }
    }
}

/**
 * @brief     STS创建一个任务函数。
 * @details   STS creates a task function.
 * @param[in] entry 任务函数入口指针.
 *            A pointer function without formal parameters.
 * @param[in] set_time 任务调度的时间 task run time (ticks)
 * @return    [FSC_SUCCESS]创建成功.Create successfully.
 * @return    [FSC_FAIL]创建失败.	Create failed.
**/	
static FSC_STATE_TYPE_E STS_CreateTask(void (*Entry) (void), uint16_t Set_Time)
{
    if (Entry == (void*)(0)) return FSC_FAIL;
    if (STS_Object.private.Task_Num < TASKS_MAX)
    {
        STS_Object.private.Tasks[STS_Object.private.Task_Num].Entry = Entry;
        STS_Object.private.Tasks[STS_Object.private.Task_Num].Set_Time = Set_Time;
        STS_Object.private.Tasks[STS_Object.private.Task_Num].State = TASK_RUN;
        STS_Object.private.Tasks[STS_Object.private.Task_Num].Tim_Cnt = Set_Time;
        STS_Object.private.Task_Num++;
        return FSC_SUCCESS;

    } 
    else
    {
        return FSC_FAIL;
    } 
}

/**
 * @brief     STS删除一个任务函数。
 * @details   STS creates a task function.
 * @param[in] entry 任务函数入口指针.
 *            A pointer function without formal parameters.
 * @return    [FSC_SUCCESS]删除成功.Delete successfully.
 * @return    [FSC_FAIL]删除失败.	Delete failed.
**/
FSC_STATE_TYPE_E STS_DeleteTask(void (*Entry) (void))
{
    #if (STS_DELETE_TASK_STYLE == 1)
    uint8_t i,j,index;
    TASK_INFO_S TasksTempInfo[TASKS_MAX] = {0}; 
    #elif (STS_DELETE_TASK_STYLE == 0) 
    uint8_t i;
    #endif
    if (STS_Object.private.Task_Num > 0) 
    {
        ENTER_STS_CRI_AREA();
        for (i = 0; i < STS_Object.private.Task_Num; i++)
        {
            if (STS_Object.private.Tasks[i].Entry == Entry) 
            {
            #if (STS_DELETE_TASK_STYLE == 1) 
                //record the task information after the task to be deleted
                index = i;
                for (j = 0;j < (STS_Object.private.Task_Num-index-1);j++)           
                {
                    TasksTempInfo[j].Entry = STS_Object.private.Tasks[index+1+j].Entry;
                    TasksTempInfo[j].Set_Time = STS_Object.private.Tasks[index+1+j].Set_Time;
                    TasksTempInfo[j].State = STS_Object.private.Tasks[index+1+j].State;
                    TasksTempInfo[j].Tim_Cnt = STS_Object.private.Tasks[index+1+j].Tim_Cnt;
                }
                //delete the task that needs to be deleted, and move the task behind it one space forward
                for (j = 0; j < (STS_Object.private.Task_Num-index-1);j++)
                {
                    STS_Object.private.Tasks[index+j].Entry =  TasksTempInfo[j].Entry;
                    STS_Object.private.Tasks[index+j].Set_Time = TasksTempInfo[j].Set_Time;
                    STS_Object.private.Tasks[index+j].State = TasksTempInfo[j].State;
                    STS_Object.private.Tasks[index+j].Tim_Cnt = TasksTempInfo[j].Tim_Cnt;
                }
                //clear the last task information after the task is moved forward to 0
                STS_Object.private.Tasks[STS_Object.private.Task_Num].Entry = (void*)(0);
                STS_Object.private.Tasks[STS_Object.private.Task_Num].Set_Time = 0;
                STS_Object.private.Tasks[STS_Object.private.Task_Num].State = TASK_STOP;
                STS_Object.private.Tasks[STS_Object.private.Task_Num].Tim_Cnt = 0;
                STS_Object.private.Task_Num--;
            #elif (STS_DELETE_TASK_STYLE == 0)
                //put the last task information in the position of the task that will be deleted
                STS_Object.private.Task_Num--;
                STS_Object.private.Tasks[i].Entry = STS_Object.private.Tasks[STS_Object.private.Task_Num].Entry;
                STS_Object.private.Tasks[i].Set_Time = STS_Object.private.Tasks[STS_Object.private.Task_Num].Set_Time;
                STS_Object.private.Tasks[i].State = STS_Object.private.Tasks[STS_Object.private.Task_Num].State;
                STS_Object.private.Tasks[i].Tim_Cnt= STS_Object.private.Tasks[STS_Object.private.Task_Num].Tim_Cnt;
            #endif 
                EXTI_STS_CRI_AREA();
                return FSC_SUCCESS;
            }
        }
        EXTI_STS_CRI_AREA();
    }
    EXTI_STS_CRI_AREA();
    return FSC_FAIL;
}

/**
 * @brief     STS控制一个任务运行状态函数。
 * @details   STS controls a task running state function.
 * @param[in] entry 任务函数入口指针.
 *            A pointer function without formal parameters.
 * @param[in] state 任务运行状态.Task running status
 * @return    [FSC_SUCCESS]修改成功.The modification was successful.
 * @return    [FSC_FAIL]修改失败.The modification was failed.
**/	
FSC_STATE_TYPE_E STS_Set_Task_Tick(void (*Entry) (void), uint16_t Set_Time)
{
    uint8_t i;
    for (i = 0; i < STS_Object.private.Task_Num; i++)
    {
        if (STS_Object.private.Tasks[i].Entry == Entry)
        {
            STS_Object.private.Tasks[i].Set_Time = Set_Time;
            return FSC_SUCCESS;
        }
    }
    return FSC_FAIL;
}


/**
 * @brief     STS控制一个任务运行状态函数。
 * @details   STS controls a task running state function.
 * @param[in] entry 任务函数入口指针.
 *            A pointer function without formal parameters.
 * @param[in] state 任务运行状态.Task running status
 * @return    [FSC_SUCCESS]修改成功.The modification was successful.
 * @return    [FSC_FAIL]修改失败.The modification was failed.
**/	
FSC_STATE_TYPE_E STS_Set_Task_RunState(void (*Entry) (void), TASK_STATE_TYPE_E State)
{
    uint8_t i;
    for (i = 0; i < STS_Object.private.Task_Num; i++)
    {
        if (STS_Object.private.Tasks[i].Entry == Entry)
        {
            STS_Object.private.Tasks[i].State = State;
            return FSC_SUCCESS;
        }
    }
    return FSC_FAIL;
}

/**
 * @brief   STS初始化函数,注册相关元素。
 * @details The STS initializes the function 
 *          and registers the associated elements.
 * @param   None.
 * @return  None.
**/
void STS_Init(void)
{
    STS_Object.public.CreateTask        = STS_CreateTask;
    STS_Object.public.DeleteTask        = STS_DeleteTask;
    STS_Object.public.Run               = STS_Run;
    STS_Object.public.Set_Task_RunState = STS_Set_Task_RunState;
    STS_Object.public.Set_Task_Tick     = STS_Set_Task_Tick;
    STS_Object.public.Update_Tick       = STS_Update_Tick;
	STS_Object.private.Task_Num         = 0;
    STS = STS_Object.public;
}

/*-----------------------------------------------------------------------
|                   END OF FLIE.  (C) COPYRIGHT zeweni                  |
-----------------------------------------------------------------------*/


说明

ENTER_STS_CRI_AREA()
EXTI_STS_CRI_AREA()
//进入/退出临街区域,作用用于一些不希望被中断打断的代码区域,因为这段代码的数据不希望被中断所修改。
//原TMT中只是关闭了定时器中断,但是遇到有其他中断也会修改数据时,最好的办法是将总中断关闭,这个地方需要移植。
#if 		  (0)
	//用于内部文件的变量定义,方便移植
	typedef  unsigned char   uint8_t; /*!<  8 bits */
	typedef  unsigned int   uint16_t; /*!< 16 bits */

#endif
//任务的最大数量,依据项目情况而定。
#define 	  STS_TASK_NUM  	 		(8)
//删除任务的方式,
//定义为1:将会按照创建任务的顺序删除,比如有0->1->2->3->4时,需要删除2,那么删除之后会成为0->1->3->4
//定义为0:会将最后一个任务移动至删除的任务的位置,如:0->1->2>->3->4,删除2,会变成0->1->4->3
#define 	  STS_DELETE_TASK_STYLE		(0)
//移植时需要将STS.Update_Tick();放入定时器中断中,然后STS便会以这个时间基准来进行调度
void STS.Update_Tick();
//之后进行初始化然后在死循环中调用STS调度器即可
int main()
{
	USE_USART_Init(115200);
	USE_TIM_Init(7199,10);
	STS_Init();
	STS.CreateTask(Printf_100ms, 100);
	STS.CreateTask(Printf_200ms, 100);
	while(1)
	{
		STS.Run();
	}
}

以上纯属个人见解,有误之处还望大家指正。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值