本帖最后由 pzsh 于 2021-8-31 13:41 编辑
最近在网上看到个TMT,简单的定时器调度系统~这不,我来看一下~
其实PIC18F16Q41的FLASH空间不小了,按道理移植RTOS都绰绰有余。
但是本质上都是定时器的调度~
不废话,先上MCC配置:
CLOCK(64M):
USART1(9600,N,8,1):
TIMER0(设置成1ms中断):
PIN(UART,LED,KEY):
编译生成代码:
加载TMT文件:
tmt.h(其中,进临界和出临界改成自己MCU对于的函数)
- /*
- * File: tmt.h
- * Author: Administrator
- *
- * Created on August 31, 2021, 9:45 AM
- */
- #ifndef TMT_H
- #define TMT_H
- #ifdef __cplusplus
- extern "C" {
- #endif
- /**
- * [url=home.php?mod=space&uid=247401]@brief[/url] 硬件平台相关的头文件,提供硬件运行的基本环境,一般是寄存器头文件。
- * [url=home.php?mod=space&uid=1543424]@Details[/url] The header files related to the hardware platform provide
- * the basic environment for hardware operation, generally
- * register header files..
- **/
- #include "../mcc_generated_files/mcc.h"
- /**
- * [url=home.php?mod=space&uid=247401]@brief[/url] 进入TMT临界区宏函数,需要关闭相关定时器的中断。
- * [url=home.php?mod=space&uid=1543424]@Details[/url] Enter the TMT critical section macro function.
- * It is necessary to turn off the interrupt of the related timer.
- * [url=home.php?mod=space&uid=536309]@NOTE[/url] 需要根据硬件平台,移植合适的关定时器中断代码。
- * It is necessary to transplant the appropriate off-timer
- * interrupt code according to the hardware platform.
- **/
- //#define ENTER_TMT_CRI_AREA() do{ __HAL_TIM_DISABLE_IT(&htim1,TIM_IT_UPDATE); }while(0) //32版本
- #define ENTER_TMT_CRI_AREA() do{ TMR0_StopTimer(); }while(0) //51版本
- /**
- * @brief 退出TMT临界区宏函数,需要打开相关定时器的中断。
- * @details Enter the TMT critical section macro function.
- * It is necessary to turn on the interrupt of the related timer.
- * [url=home.php?mod=space&uid=536309]@NOTE[/url] 需要根据硬件平台,移植合适的开定时器中断代码。
- * 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{ TMR0_StartTimer(); }while(0) //51版本
- /**
- * @brief TMT的变量类型重定义,如果有冲突,请配置为0。
- * @details The variable type of TMT 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 任务数量控制宏,用来确定TMT需要调度的最大任务数量。
- * @details The number of tasks control macro is used to
- * determine the maximum number of tasks that TMT
- * needs to schedule.
- **/
- #define TMT_TASK_NUM (8)
- /*-----------------------------------------------------------------------
- | DATA |
- -----------------------------------------------------------------------*/
- /**
- * @brief 任务的执行状态枚举体。
- * @details The execution status enumerator of the task.
- **/
- typedef enum
- {
- Task_Stop = 1, /*!< 停止运行状态。*/
- Task_Continue = !Task_Stop /*!< 继续运行状态。*/
- }TaskState_Type;
- /**
- * @brief TMT函数自检枚举体,指示函数是否正常执行。
- * TMT function self checks enumerator.
- * indicating whether the function is normally executed.
- ***/
- typedef enum
- {
- TMT_NOK= 1, /* Function self checking failed */
- TMT_OK = !TMT_NOK /* Function self checking successfed */
- }TMT_FunState_Type;
- /*-----------------------------------------------------------------------
- | API FUNCTION |
- -----------------------------------------------------------------------*/
- /**
- * @brief TMT初始化函数,注册相关元素。
- * @details The TMT initializes the function
- * and registers the associated elements.
- * @param None.
- * [url=home.php?mod=space&uid=266161]@return[/url] None.
- **/
- void TMT_Init(void);
- /**
- * @brief TMT的API操作函数结构体。
- * @details The TMT API manipulates the function structure.
- **/
- typedef struct
- {
- /**
- * @brief TMT更新任务调度tick时间。
- * @details TMT update task schedule tick time.
- * @param[in] None.
- * [url=home.php?mod=space&uid=266161]@return[/url] None.
- * @note 在定时器中断服务函数中调用。
- * Called in the timer interrupt service function.
- * [url=home.php?mod=space&uid=389923]@example[/url] TMT.Tick();
- **/
- void (*Tick) (void);
-
-
- /**
- * @brief TMT运行函数,是任务调度器。
- * @details TMT runs the function, which is the task scheduler.
- * @param[in] None.
- * @return None.
- * @note 在main函数的无限循环中调用。
- * Called in the infinite loop of main.
- * [url=home.php?mod=space&uid=389923]@example[/url] TMT.Run();
- **/
- void (*Run) (void);
-
-
- /**
- * @brief TMT创建一个任务函数。
- * @details TMT creates a task function.
- * @param[in] entry 任务函数入口指针.
- * A pointer function without formal parameters.
- * @param[in] setTime 任务调度的时间 task run time (ticks)
- * @return [TMT_OK]创建成功.Create successfully.
- * @return [TMT_NOK]创建失败. Create failed.
- * @note 在main函数的无限循环中调用。
- * Called in the infinite loop of main.
- * @example TMT.Create(enrty,500); //定时entry任务为500ticks调度一次
- **/
- TMT_FunState_Type (*Create) (void (*entry) (void), uint16_t setTime);
-
-
- /**
- * @brief TMT删除一个任务函数。
- * @details TMT creates a task function.
- * @param[in] entry 任务函数入口指针.
- * A pointer function without formal parameters.
- * @return [TMT_OK]删除成功.Delete successfully.
- * @return [TMT_NOK]删除失败. Delete failed.
- * @example TMT.Delete(enrty); //删除entry任务
- **/
- TMT_FunState_Type (*Delete) (void (*entry) (void));
-
-
- /**
- * @brief TMT控制一个任务的调度时间函数。
- * @details The TMT 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 [TMT_OK]修改成功.The modification was successful.
- * @return [TMT_NOK]修改失败.The modification was failed.
- * @example TMT.TimeCtrl(enrty,100); //修改entry任务为100ticks调度一次
- **/
- TMT_FunState_Type (*TimeCtrl) (void (*entry) (void), uint16_t setTime);
-
-
- /**
- * @brief TMT控制一个任务运行状态函数。
- * @details TMT controls a task running state function.
- * @param[in] entry 任务函数入口指针.
- * A pointer function without formal parameters.
- * @param[in] state 任务运行状态.Task running status
- * @return [TMT_OK]修改成功.The modification was successful.
- * @return [TMT_NOK]修改失败.The modification was failed.
- * @example TMT.RunCtrl(enrty,Task_Stop); //修改entry任务为停止运行.
- **/
- TMT_FunState_Type (*RunCtrl) (void (*entry) (void), TaskState_Type state);
- }TMT_Type;
- /**
- * @brief 对外声明的TMT操作函数结构体。
- * @details TMT operation function structure declared externally.
- * @note 所有需要被外部调用的函数,都包含在这个结构体中.
- * All functions that need to be called externally
- * are included in this structure.
- **/
- extern TMT_Type TMT;
- #ifdef __cplusplus
- }
- #endif
- #endif /* TMT_H */
TMT.C
- /*-----------------------------------------------------------------------
- | FILE DESCRIPTION |
- -----------------------------------------------------------------------*/
- /*----------------------------------------------------------------------
- - File name : TMT.c
- - Author : zeweni
- - Update date : 2020.06.26
- - Copyright(c) : 2020-2021 zeweni. All rights reserved.
- -----------------------------------------------------------------------*/
- /*------------------------------------------------------------------------
- | COPYRIGHT NOTICE |
- ------------------------------------------------------------------------*/
- /*
- * Copyright (C) 2021, zeweni (17870070675@163.com)
- * This file is part of task management time slice framework.
- * Abbreviated as TMT.
-
- * Task management time slice framework is free software: you can redist-
- * ribute it and/or modify it under the terms of the Apache-2.0 License.
- * Task management time slice framework is distributed in the hope that it
- * will be useful,but WITHOUT ANY WARRANTY; without even the implied
- * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * Apache-2.0 License for more details.
- * You should have received a copy of the Apache-2.0 License.Task management
- * time slice framework. If not, see <http://www.apache.org/licenses/>.
- **/
- /*-----------------------------------------------------------------------
- | INCLUDES |
- -----------------------------------------------------------------------*/
- #include "TMT.h"
- /*-----------------------------------------------------------------------
- | DATA |
- -----------------------------------------------------------------------*/
- /**
- * @brief 最大任务数量宏,再封装一层。
- * @details The maximum number of tasks is a macro,
- * and then one layer is encapsulated.
- **/
- #define TASKS_MAX TMT_TASK_NUM
- /**
- * @brief 定义TMT相关操作函数结构体。
- * @details Define the structure of the TMT related operation functions.
- **/
- TMT_Type TMT;
- /**
- * @brief TMT的类,包含公共和私有两个属性。
- * @details Class of TMT, containing both public and private properties.
- **/
- static struct Class
- {
- TMT_Type Public; /*!< 公共部分,对外开放的属性,具体定义在头文件。*/
-
- struct Private /*!< 私有部分,仅限本文件内调用。*/
- {
- struct
- {
- void (* Entry) (void); /*!< 任务函数入口指针。*/
- uint16_t TIMCount; /*!< 任务调度时间计数器。*/
- uint16_t SetTime; /*!< 任务设置的调度时间。*/
- uint8_t State; /*!< 任务运行状态。*/
- }Comp[TASKS_MAX];
-
- uint8_t Num; /*!< 已经创建的任务数量。*/
- }Private;
-
- }Object;
- /*-----------------------------------------------------------------------
- | FUNCTION |
- -----------------------------------------------------------------------*/
- /**
- * @brief TMT更新任务调度tick时间。
- * @details TMT update task schedule tick time.
- * @param[in] None.
- * @return None.
- **/
- static void TMT_Update_Tick_t(void)
- {
- uint8_t i;
- for(i = 0; i< Object.Private.Num; i++)
- {
- /* If time arrives */
- if(Object.Private.Comp[i].TIMCount > 0 )
- {
- Object.Private.Comp[i].TIMCount--;
- }
- }
- }
- /**
- * @brief TMT运行函数,是任务调度器。
- * @details TMT runs the function, which is the task scheduler.
- * @param[in] None.
- * @return None.
- **/
- static void TMT_Run_t(void)
- {
- uint8_t index;
- for(index = 0; index < Object.Private.Num; index++)
- {
- /* If time arrives */
- if(Object.Private.Comp[index].TIMCount == 0 && Object.Private.Comp[index].State != Task_Stop)
- {
- Object.Private.Comp[index].TIMCount = Object.Private.Comp[index].SetTime;
-
- /*
- To prevent process conflict,
- only one process can be executed in the same time period.
- */
- if(Object.Private.Comp[index].Entry != (void*)(0) )
- {
- Object.Private.Comp[index].Entry(); /* Run task */
- }
- }
- }
- }
- /**
- * @brief TMT创建一个任务函数。
- * @details TMT creates a task function.
- * @param[in] entry 任务函数入口指针.
- * A pointer function without formal parameters.
- * @param[in] setTime 任务调度的时间 task run time (ticks)
- * @return [TMT_OK]创建成功.Create successfully.
- * @return [TMT_NOK]创建失败. Create failed.
- **/
- static TMT_FunState_Type TMT_Create_t(void (*entry) (void),uint16_t setTime)
- {
- static uint8_t task_num = 0; /* Initialize to 0 */
- if(task_num < TASKS_MAX)
- {
- Object.Private.Comp[task_num].Entry = entry;
- Object.Private.Comp[task_num].SetTime = setTime;
- Object.Private.Comp[task_num].TIMCount = setTime;
- Object.Private.Comp[task_num].State = Task_Continue;
- task_num += 1;
- Object.Private.Num = task_num;
- return TMT_OK;
- }
- else
- {
- return TMT_NOK;
- }
- }
- /**
- * @brief TMT删除一个任务函数。
- * @details TMT creates a task function.
- * @param[in] entry 任务函数入口指针.
- * A pointer function without formal parameters.
- * @return [TMT_OK]删除成功.Delete successfully.
- * @return [TMT_NOK]删除失败. Delete failed.
- **/
- static TMT_FunState_Type TMT_Delete_t(void (*entry) (void))
- {
- uint8_t index;
- if(Object.Private.Num > 0)
- {
- ENTER_TMT_CRI_AREA();
-
- for(index = 0; index < Object.Private.Num; index++)
- {
- if(Object.Private.Comp[index].Entry == entry)
- {
- Object.Private.Num--;
- Object.Private.Comp[index].Entry = Object.Private.Comp[Object.Private.Num].Entry;
- Object.Private.Comp[index].SetTime = Object.Private.Comp[Object.Private.Num].SetTime;
- Object.Private.Comp[index].TIMCount = Object.Private.Comp[Object.Private.Num].TIMCount;
- Object.Private.Comp[index].State = Object.Private.Comp[Object.Private.Num].State;
- EXTI_TMT_CRI_AREA();
- return TMT_OK;
- }
- }
- }
- EXTI_TMT_CRI_AREA();
- return TMT_NOK;
- }
- /**
- * @brief TMT控制一个任务运行状态函数。
- * @details TMT controls a task running state function.
- * @param[in] entry 任务函数入口指针.
- * A pointer function without formal parameters.
- * @param[in] state 任务运行状态.Task running status
- * @return [TMT_OK]修改成功.The modification was successful.
- * @return [TMT_NOK]修改失败.The modification was failed.
- **/
- static TMT_FunState_Type TMT_RunCtrl_t(void (*entry)(void),TaskState_Type state)
- {
- uint8_t index;
- for(index = 0; index<Object.Private.Num; index++)
- {
- if(Object.Private.Comp[index].Entry == entry)
- {
- Object.Private.Comp[index].State = state;
- return TMT_OK;
- }
- }
- return TMT_NOK;
- }
- /**
- * @brief TMT控制一个任务的调度时间函数。
- * @details The TMT controls the scheduling time function of a task.
- * @param[in] *taskFunc (void) 任务函数入口指针.
- * A pointer function without formal parameters.
- * @param[in] setTime 任务调度的时间 task run time (ticks)
- * @return [TMT_OK]修改成功.The modification was successful.
- * @return [TMT_NOK]修改失败.The modification was failed.
- **/
- static TMT_FunState_Type TMT_TimeCtrl_t(void (*entry) (void),uint16_t setTime)
- {
- uint8_t index;
- for(index = 0; index< Object.Private.Num; index++)
- {
- if(Object.Private.Comp[index].Entry == entry)
- {
- Object.Private.Comp[index].TIMCount = setTime;
- Object.Private.Comp[index].SetTime = setTime;
- return TMT_OK;
- }
- }
- return TMT_NOK;
- }
- /**
- * @brief TMT初始化函数,注册相关元素。
- * @details The TMT initializes the function
- * and registers the associated elements.
- * @param None.
- * @return None.
- **/
- void TMT_Init(void)
- {
- Object.Public.Run = TMT_Run_t;
- Object.Public.Tick = TMT_Update_Tick_t;
- Object.Public.Create = TMT_Create_t;
- Object.Public.Delete = TMT_Delete_t;
- Object.Public.TimeCtrl = TMT_TimeCtrl_t;
- Object.Public.RunCtrl = TMT_RunCtrl_t;
- Object.Private.Num = 0;
-
- TMT = Object.Public;
- }
- /*-----------------------------------------------------------------------
- | END OF FLIE. (C) COPYRIGHT zeweni |
- -----------------------------------------------------------------------*/
在timer0中断函数里面添加TMT核心任务处理函数:
- #include "../TMT/tmt.h"
- volatile uint32_t mscnt=0;
- void TMR0_CallBack(void)
- {
- // Add your custom callback code here
- mscnt++;
- if(mscnt>=500)
- {
- //LED0_Toggle();
- mscnt=0;
- }
-
- TMT.Tick();
-
- if(TMR0_InterruptHandler)
- {
- TMR0_InterruptHandler();
- }
- }
在main函数里面新建2个任务,并运行(主要开总中断):
- #include "mcc_generated_files/mcc.h"
- #include "tmt/tmt.h"
- void TMT_Demo0(void)
- {
- LED0_Toggle();
- }
- uint8_t j=0;
- void TMT_Demo1(void)
- {
- printf("the j is %d!\r\n",j++);
- }
- /*
- Main application
- */
- void main(void)
- {
- uint8_t i=0;
- // Initialize the device
- SYSTEM_Initialize();
- // If using interrupts in PIC18 High/Low Priority Mode you need to enable the Global High and Low Interrupts
- // If using interrupts in PIC Mid-Range Compatibility Mode you need to enable the Global Interrupts
- // Use the following macros to:
- TMT_Init();
-
- TMT.Create(TMT_Demo0,500);
- TMT.Create(TMT_Demo1,500);
-
- // Enable the Global Interrupts
- INTERRUPT_GlobalInterruptEnable();
- // Disable the Global Interrupts
- //INTERRUPT_GlobalInterruptDisable();
- while (1)
- {
- // Add your application code
- //printf("the i is %d!\r\n",i++);
- // __delay_ms(300);
- TMT.Run();
- }
- }
下载,运行:
看串口输出端:
看板上LED:
虽然简单,但是很好的诠释了系统调度的流程,好了,今天就到这!
谢谢观看~
|