STM32F103xx毫秒级任务管理器、调度器(动态任务创建的方式实现
一、 任务数据类型结构体
typedef void(* TaskFunction)(void);
#pragma pack(1)
typedef struct MsecTask
{
TaskFunction TaskCallback;
uint8_t State;
uint32_t PeriodTimes;
uint32_t PrevTimes;
uint32_t CostTimes;
uint32_t ErrorTimes;
struct MsecTask * pNextTask;
}MsecTask_Typedef, * MsecTask_Typedef_t;
二、 任务管理器数据类型结构体
typedef struct MsecTaskManager
{
MsecTask_Typedef * pTaskHead;
MsecTask_Typedef * pTaskTail;
MsecTask_Typedef * (* Register)(struct MsecTaskManager * taskManager, TaskFunction taskCallback, uint32_t tims_ms, uint8_t state);
void (* Running)(struct MsecTaskManager * taskManager, uint32_t tick);
uint8_t (* SetTaskPeriodTime)(struct MsecTaskManager * taskManager, TaskFunction taskCallback, uint32_t tims_ms);
uint8_t (* GetTaskState)(struct MsecTaskManager * taskManager, TaskFunction taskCallback);
uint8_t (* SetTaskState)(struct MsecTaskManager * taskManager, TaskFunction taskCallback, uint8_t state);
uint32_t (* GetTaskErrorTimes)(struct MsecTaskManager * taskManager, TaskFunction taskCallback);
MsecTask_Typedef * (* FindTask)(struct MsecTaskManager * taskManager, TaskFunction taskCallback);
MsecTask_Typedef * (* GetPrevTask)(struct MsecTaskManager * taskManager, MsecTask_Typedef * task);
uint8_t (* DeleteTask)(struct MsecTaskManager * taskManager, TaskFunction taskCallback);
#if ( MTM_MCU_USE_RATIO_ENABLE > 0 )
uint8_t (* GetMicroProcessorUseRatio)(struct MsecTaskManager * taskManager);
uint32_t (* GetTaskRunningTimes)(struct MsecTaskManager * taskManager, TaskFunction taskCallback);
uint32_t TaskRunTotalTimes;
#endif
}MsecTaskManager_Typedef, * MsecTaskManager_Typedef_t;
三、获取系统运行的Tick、获取时差
- 系统时钟72MHZ,SysTick_Handler()嘀嗒定时器1ms中断
#define SYSTICK_LOADVALUE 72000
#define CYCLES_PER_MICROSECOND 72
static uint32_t ulGetSystemTick(void)
{
extern __IO uint32_t uwTick;
return (uwTick * 1000 + (SYSTICK_LOADVALUE-SysTick->VAL)/CYCLES_PER_MICROSECOND);
}
static uint32_t ulGetTickDifference(uint32_t curTick, uint32_t preTick)
{
uint32_t diffTick = 0;
if (curTick >= preTick)
{
diffTick = curTick - preTick;
}
else
{
diffTick = 0xFFFFFFFF - preTick + 1;
diffTick += curTick;
}
return diffTick;
}
四、查找任务
static MsecTask_Typedef * pStuTaskManager_FindTask(struct MsecTaskManager * taskManager, TaskFunction taskCallback)
{
MsecTask_Typedef * nowTask = NULL;
MsecTask_Typedef * resTask = NULL;
nowTask = taskManager->pTaskHead;
while(nowTask != NULL)
{
if (nowTask->TaskCallback == taskCallback)
{
resTask = nowTask;
break;
}
nowTask = nowTask->pNextTask;
}
return resTask;
}
五、注册任务
static MsecTask_Typedef * pStuTaskManager_Register(struct MsecTaskManager * taskManager, TaskFunction taskCallback, uint32_t tims_ms, uint8_t state)
{
MsecTask_Typedef * task = NULL;
task = taskManager->FindTask(taskManager, taskCallback);
if (task != NULL)
{
task->State = state;
task->PrevTimes = ulGetSystemTick();
task->PeriodTimes = tims_ms;
return task;
}
task = (MsecTask_Typedef *)malloc(sizeof(MsecTask_Typedef));
if (task == NULL)
{
return NULL;
}
task->CostTimes = 0;
task->ErrorTimes = 0;
task->pNextTask = NULL;
task->State = state;
task->PeriodTimes = tims_ms;
task->TaskCallback = taskCallback;
task->PrevTimes = ulGetSystemTick();
if (taskManager->pTaskHead == NULL)
{
taskManager->pTaskHead = task;
}
else
{
taskManager->pTaskTail->pNextTask = task;
}
taskManager->pTaskTail = task;
return task;
}
六、设置、获取任务状态
static uint8_t ubTaskManager_SetTaskState(struct MsecTaskManager * taskManager, TaskFunction taskCallback, uint8_t state)
{
MsecTask_Typedef * memTask = NULL;
memTask = taskManager->FindTask(taskManager, taskCallback);
if (memTask == NULL)
{
return 1;
}
memTask->State = state;
return 0;
}
static uint8_t ubTaskManager_GetTaskState(struct MsecTaskManager * taskManager, TaskFunction taskCallback)
{
MsecTask_Typedef * memTask = NULL;
uint8_t taskState = 0xFF;
memTask = taskManager->FindTask(taskManager, taskCallback);
if (memTask == NULL)
{
return 1;
}
taskState = memTask->State;
return taskState;
}
七、设置任务运行周期时间
uint8_t ubTaskManager_SetTaskPeriodTime(struct MsecTaskManager * taskManager, TaskFunction taskCallback, uint32_t tims_ms)
{
MsecTask_Typedef * memTask = NULL;
memTask = taskManager->FindTask(taskManager, taskCallback);
if (memTask == NULL)
{
return 1;
}
memTask->PeriodTimes = tims_ms;
return 0;
}
八、获取任务误差时间
static uint32_t ulTaskManager_GetTaskErrorTimes(struct MsecTaskManager * taskManager, TaskFunction taskCallback)
{
MsecTask_Typedef * memTask = NULL;
uint32_t errorTimes = 0;
memTask = taskManager->FindTask(taskManager, taskCallback);
if (memTask == NULL)
{
return 0xFFFFFFFFUL;
}
errorTimes = memTask->ErrorTimes;
return errorTimes;
}
九、获取上一个任务
static MsecTask_Typedef * pStuTaskManager_GetPrevTask(struct MsecTaskManager * taskManager, MsecTask_Typedef * task)
{
MsecTask_Typedef * nowTask = NULL;
MsecTask_Typedef * resTask = NULL;
nowTask = taskManager->pTaskHead;
while (1)
{
if (nowTask == NULL)
{
break;
}
if (nowTask->pNextTask == task)
{
resTask = nowTask;
break;
}
nowTask = nowTask->pNextTask;
}
return resTask;
}
十、查找任务
uint8_t ubTaskManager_DeleteTask(struct MsecTaskManager * taskManager, TaskFunction taskCallback)
{
MsecTask_Typedef * memTask = NULL;
MsecTask_Typedef * prevTask = NULL;
MsecTask_Typedef * nextTask = NULL;
memTask = taskManager->FindTask(taskManager, taskCallback);
if (memTask == NULL)
{
return 1;
}
prevTask = taskManager->GetPrevTask(taskManager, memTask);
nextTask = memTask->pNextTask;
if((prevTask == NULL) && (nextTask == NULL))
{
taskManager->pTaskHead = taskManager->pTaskTail = NULL;
}
else if((prevTask == NULL) && (nextTask != NULL))
{
taskManager->pTaskHead = nextTask;
}
else if((prevTask != NULL) && (nextTask == NULL))
{
taskManager->pTaskTail = prevTask;
prevTask->pNextTask = NULL;
}
else if((prevTask != NULL) && (nextTask != NULL))
{
prevTask->pNextTask = nextTask;
}
else
{
return 2;
}
free(memTask);
memTask = NULL;
return 0;
}
十一、获取处理器利用率 、任务运行时间
#if ( MTM_MCU_USE_RATIO_ENABLE > 0 )
static uint8_t usTaskManager_GetMicroProcUseRatio(struct MsecTaskManager * taskManager)
{
static uint32_t startTick = 0;
uint8_t useRatio = 0;
useRatio = taskManager->TaskRunTotalTimes / (ulGetSystemTick() - startTick);
if (useRatio > 100)
{
useRatio = 100;
}
taskManager->TaskRunTotalTimes = 0;
startTick = ulGetSystemTick();
return useRatio;
}
static uint32_t ulTaskManager_GetTaskRunTimes(struct MsecTaskManager * taskManager, TaskFunction taskCallback)
{
MsecTask_Typedef * memTask = NULL;
uint32_t takeTimes = 0;
memTask = taskManager->FindTask(taskManager, taskCallback);
if (memTask == NULL)
{
return 0;
}
takeTimes = memTask->CostTimes;
return takeTimes;
}
#endif
十二、运行任务管理
static void vTaskManager_Running(struct MsecTaskManager * taskManager, uint32_t tick)
{
MsecTask_Typedef * nowTask = NULL;
uint32_t diffTick = 0;
nowTask = taskManager->pTaskHead;
while (1)
{
if (nowTask == NULL)
{
break;
}
if ((nowTask->State) && (nowTask->TaskCallback != NULL))
{
diffTick = ulGetTickDifference(tick, nowTask->PrevTimes);
if (diffTick >= nowTask->PeriodTimes)
{
nowTask->ErrorTimes = diffTick - nowTask->PeriodTimes;
nowTask->PrevTimes = tick;
#if ( MTM_MCU_USE_RATIO_ENABLE > 0 )
uint32_t startTick = ulGetSystemTick();
nowTask->TaskCallback();
nowTask->CostTimes = ulGetTickDifference(ulGetSystemTick(), startTick);
taskManager->TaskRunTotalTimes += nowTask->CostTimes;
#else
nowTask->TaskCallback();
#endif
}
}
nowTask = nowTask->pNextTask;
}
}
十三、初始化毫秒级任务管理器
void vInit_MsecTaskManager(MsecTaskManager_Typedef * taskManager)
{
taskManager->pTaskHead = NULL;
taskManager->pTaskTail = NULL;
taskManager->Running = vTaskManager_Running;
taskManager->FindTask = pStuTaskManager_FindTask;
taskManager->Register = pStuTaskManager_Register;
taskManager->DeleteTask = ubTaskManager_DeleteTask;
taskManager->SetTaskState = ubTaskManager_SetTaskState;
taskManager->GetTaskState = ubTaskManager_GetTaskState;
taskManager->GetPrevTask = pStuTaskManager_GetPrevTask;
taskManager->GetTaskErrorTimes = ulTaskManager_GetTaskErrorTimes;
taskManager->SetTaskPeriodTime = ubTaskManager_SetTaskPeriodTime;
#if ( MTM_MCU_USE_RATIO_ENABLE > 0 )
taskManager->GetTaskRunningTimes = ulTaskManager_GetTaskRunTimes;
taskManager->GetMicroProcessorUseRatio = usTaskManager_GetMicroProcUseRatio;
#endif
}
十四、验证例程
static void vTask1_Demo(void)
{
HAL_GPIO_TogglePin(USER_LED0_GPIO_Port, USER_LED0_Pin);
}
static void vTask2_Demo(void)
{
HAL_GPIO_TogglePin(USER_LED0_GPIO_Port, USER_LED6_Pin);
}
static void vTask3_Demo(void)
{
HAL_GPIO_TogglePin(USER_LED0_GPIO_Port, USER_LED2_Pin);
}
static void vDebug_Demo(void)
{
uint32_t takeTimer[3] = {0};
uint32_t errorTimer[3] = {0};
takeTimer[0] = AppMsecTaskManager.GetTaskRunningTimes(&AppMsecTaskManager, vTask1_Demo);
takeTimer[1] = AppMsecTaskManager.GetTaskRunningTimes(&AppMsecTaskManager, vTask2_Demo);
takeTimer[2] = AppMsecTaskManager.GetTaskRunningTimes(&AppMsecTaskManager, vTask3_Demo);
errorTimer[0] = AppMsecTaskManager.GetTaskErrorTimes(&AppMsecTaskManager, vTask1_Demo);
errorTimer[1] = AppMsecTaskManager.GetTaskErrorTimes(&AppMsecTaskManager, vTask2_Demo);
errorTimer[2] = AppMsecTaskManager.GetTaskErrorTimes(&AppMsecTaskManager, vTask3_Demo);
printf("Name Period Take Error\r\n");
printf("Task1 %-8d %-8d %d\r\n", 1000, takeTimer[0] , errorTimer[0]);
printf("Task2 %-8d %-8d %d\r\n", 500, takeTimer[1] , errorTimer[1]);
printf("Task3 %-8d %-8d %d\r\n", 200, takeTimer[2] , errorTimer[2]);
}
void vRegister_Task(void)
{
AppMsecTaskManager.Register(&AppMsecTaskManager, vTask1_Demo, 1000, 1);
AppMsecTaskManager.Register(&AppMsecTaskManager, vTask2_Demo, 500, 1);
AppMsecTaskManager.Register(&AppMsecTaskManager, vTask3_Demo, 2000, 1);
AppMsecTaskManager.Register(&AppMsecTaskManager, vDebug_Demo, 5000, 1);
}
十五、主函数
int main(void)
{
HAL_Init();
SystemClock_Config();
SystemCoreClockUpdate();
MX_GPIO_Init();
MX_USART1_UART_Init();
printf("Init USART OK...\r\n");
vInit_MsecTaskManager(&AppMsecTaskManager);
printf("Msec Task Manager OK...\r\n");
vRegister_Task();
while (1)
{
AppMsecTaskManager.Running(&AppMsecTaskManager, HAL_GetTick());
}
}