• 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;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    二、 任务管理器数据类型结构体

    
    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;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    三、获取系统运行的Tick、获取时差

    1. 系统时钟72MHZ,SysTick_Handler()嘀嗒定时器1ms中断
    
    #define SYSTICK_LOADVALUE       72000//(SystemCoreClock/1000U)
    #define CYCLES_PER_MICROSECOND  72//(SystemCoreClock/1000000U)
    
    /* 获取系统运行的Tick */
    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;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    四、查找任务

    在这里插入图片描述

    
    /* 查找任务 */
    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;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    五、注册任务

    在这里插入图片描述

    /* 注册任务 */
    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;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    六、设置、获取任务状态

    
    /* 设置任务状态 */
    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;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    七、设置任务运行周期时间

    
    /* 设置任务运行周期时间 */
    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;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    八、获取任务误差时间

    /* 获取任务误差时间 */
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    九、获取上一个任务

    /* 获取上一个任务 */
    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;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    十、查找任务

    
    /* 删除一个任务 */
    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; 
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    十一、获取处理器利用率 、任务运行时间

    
    #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
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    十二、运行任务管理

    
    /* 运行任务管理 */
    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;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    十三、初始化毫秒级任务管理器

    
    /* 初始化毫秒级任务管理器 */
    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
    	
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    十四、验证例程

    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);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    十五、主函数

    
    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());
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
  • 相关阅读:
    百度百科怎么修改词条内容?
    I Pa?sWorD(2023icpc网络预选赛)
    Apifox下载安装【官方版】
    对接京东平台的第一篇
    TL-Link WAR308路由器无线模式下一会有网一会无
    基于JAVA的网络通讯系统设计与实现(论文+系统)
    前端开发面试-css篇
    拉格朗日插值法的推导
    Refind多引导系统界面
    考试宝典——软件过程与管理重点知识总结_01
  • 原文地址:https://blog.csdn.net/Ceosat/article/details/126237366