[PIC®/AVR®/dsPIC®产品] 【CuriosityNano测评报告】+PIC18F16Q41 轻量级定时器调度

[复制链接]
7537|15
 楼主| qjp1988113 发表于 2021-8-31 10:18 | 显示全部楼层 |阅读模式
本帖最后由 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对于的函数)
  1. /*
  2. * File:   tmt.h
  3. * Author: Administrator
  4. *
  5. * Created on August 31, 2021, 9:45 AM
  6. */

  7. #ifndef TMT_H
  8. #define        TMT_H

  9. #ifdef        __cplusplus
  10. extern "C" {
  11. #endif

  12. /**
  13. * [url=home.php?mod=space&uid=247401]@brief[/url]     硬件平台相关的头文件,提供硬件运行的基本环境,一般是寄存器头文件。
  14. * [url=home.php?mod=space&uid=1543424]@Details[/url]   The header files related to the hardware platform provide
  15. *            the basic environment for hardware operation, generally
  16. *            register header files..
  17. **/
  18. #include  "../mcc_generated_files/mcc.h"


  19. /**
  20. * [url=home.php?mod=space&uid=247401]@brief[/url]     进入TMT临界区宏函数,需要关闭相关定时器的中断。
  21. * [url=home.php?mod=space&uid=1543424]@Details[/url]   Enter the TMT critical section macro function.
  22. *            It is necessary to turn off the interrupt of the related timer.
  23. * [url=home.php?mod=space&uid=536309]@NOTE[/url]      需要根据硬件平台,移植合适的关定时器中断代码。
  24. *            It is necessary to transplant the appropriate off-timer
  25. *            interrupt code according to the hardware platform.
  26. **/
  27. //#define       ENTER_TMT_CRI_AREA()    do{ __HAL_TIM_DISABLE_IT(&htim1,TIM_IT_UPDATE); }while(0)  //32版本
  28. #define       ENTER_TMT_CRI_AREA()    do{ TMR0_StopTimer(); }while(0) //51版本

  29. /**
  30. * @brief     退出TMT临界区宏函数,需要打开相关定时器的中断。
  31. * @details   Enter the TMT critical section macro function.
  32. *            It is necessary to turn on the interrupt of the related timer.
  33. * [url=home.php?mod=space&uid=536309]@NOTE[/url]      需要根据硬件平台,移植合适的开定时器中断代码。
  34. *            It is necessary to transplant the appropriate on-timer
  35. *            interrupt code according to the hardware platform.
  36. **/
  37. //#define       EXTI_TMT_CRI_AREA()     do{ __HAL_TIM_ENABLE_IT(&htim1,TIM_IT_UPDATE); }while(0) //32版本
  38. #define       EXTI_TMT_CRI_AREA()     do{ TMR0_StartTimer(); }while(0) //51版本


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

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

  47. #endif

  48. /*-----------------------------------------------------------------------
  49. |                                CONFIG                                 |
  50. -----------------------------------------------------------------------*/

  51. /**
  52. * @brief     任务数量控制宏,用来确定TMT需要调度的最大任务数量。
  53. * @details   The number of tasks control macro is used to
  54. *            determine the maximum number of tasks that TMT
  55. *            needs to schedule.
  56. **/
  57. #define           TMT_TASK_NUM           (8)


  58. /*-----------------------------------------------------------------------
  59. |                                 DATA                                  |
  60. -----------------------------------------------------------------------*/


  61. /**
  62. * @brief     任务的执行状态枚举体。
  63. * @details   The execution status enumerator of the task.
  64. **/
  65. typedef enum
  66. {
  67.     Task_Stop = 1,   /*!< 停止运行状态。*/
  68.         Task_Continue = !Task_Stop /*!< 继续运行状态。*/
  69. }TaskState_Type;


  70. /**
  71.   * @brief   TMT函数自检枚举体,指示函数是否正常执行。
  72.   *          TMT function self checks enumerator.
  73.   *          indicating whether the function is normally executed.
  74. ***/
  75. typedef enum
  76. {
  77.         TMT_NOK= 1,     /* Function self checking failed */
  78.         TMT_OK = !TMT_NOK /* Function self checking successfed */
  79. }TMT_FunState_Type;


  80. /*-----------------------------------------------------------------------
  81. |                             API FUNCTION                              |
  82. -----------------------------------------------------------------------*/

  83. /**
  84. * @brief   TMT初始化函数,注册相关元素。
  85. * @details The TMT initializes the function
  86. *          and registers the associated elements.
  87. * @param   None.
  88. * [url=home.php?mod=space&uid=266161]@return[/url]  None.
  89. **/
  90. void TMT_Init(void);


  91. /**
  92. * @brief   TMT的API操作函数结构体。
  93. * @details The TMT API manipulates the function structure.
  94. **/
  95. typedef struct
  96. {
  97.         /**
  98.          * @brief     TMT更新任务调度tick时间。
  99.          * @details   TMT update task schedule tick time.
  100.          * @param[in] None.
  101.          * [url=home.php?mod=space&uid=266161]@return[/url]    None.
  102.          * @note      在定时器中断服务函数中调用。
  103.          *            Called in the timer interrupt service function.
  104.          * [url=home.php?mod=space&uid=389923]@example[/url]   TMT.Tick();
  105.         **/
  106.         void (*Tick) (void);
  107.         
  108.         
  109.         /**
  110.          * @brief     TMT运行函数,是任务调度器。
  111.          * @details   TMT runs the function, which is the task scheduler.
  112.          * @param[in] None.
  113.          * @return    None.
  114.          * @note      在main函数的无限循环中调用。
  115.          *            Called in the infinite loop of main.
  116.          * [url=home.php?mod=space&uid=389923]@example[/url]   TMT.Run();
  117.         **/
  118.         void (*Run) (void);
  119.         
  120.         
  121.         /**
  122.          * @brief     TMT创建一个任务函数。
  123.          * @details   TMT creates a task function.
  124.          * @param[in] entry 任务函数入口指针.
  125.          *            A pointer function without formal parameters.
  126.          * @param[in] setTime 任务调度的时间 task run time (ticks)
  127.          * @return    [TMT_OK]创建成功.Create successfully.
  128.          * @return    [TMT_NOK]创建失败.        Create failed.
  129.          * @note      在main函数的无限循环中调用。
  130.          *            Called in the infinite loop of main.
  131.          * @example   TMT.Create(enrty,500); //定时entry任务为500ticks调度一次
  132.         **/        
  133.         TMT_FunState_Type (*Create) (void (*entry) (void), uint16_t setTime);
  134.         
  135.         
  136.         /**
  137.          * @brief     TMT删除一个任务函数。
  138.          * @details   TMT creates a task function.
  139.          * @param[in] entry 任务函数入口指针.
  140.          *            A pointer function without formal parameters.
  141.          * @return    [TMT_OK]删除成功.Delete successfully.
  142.          * @return    [TMT_NOK]删除失败.        Delete failed.
  143.          * @example   TMT.Delete(enrty); //删除entry任务
  144.         **/               
  145.         TMT_FunState_Type (*Delete) (void (*entry) (void));
  146.         
  147.         
  148.         /**
  149.          * @brief     TMT控制一个任务的调度时间函数。
  150.          * @details   The TMT controls the scheduling time function of a task.
  151.          * @param[in] entry 任务函数入口指针.
  152.          *            A pointer function without formal parameters.
  153.          * @param[in] setTime 任务调度的时间 task run time (ticks)
  154.          * @return    [TMT_OK]修改成功.The modification was successful.
  155.          * @return    [TMT_NOK]修改失败.The modification was failed.
  156.          * @example   TMT.TimeCtrl(enrty,100); //修改entry任务为100ticks调度一次
  157.         **/        
  158.         TMT_FunState_Type (*TimeCtrl) (void (*entry) (void), uint16_t setTime);
  159.         
  160.         
  161.         /**
  162.          * @brief     TMT控制一个任务运行状态函数。
  163.          * @details   TMT controls a task running state function.
  164.          * @param[in] entry 任务函数入口指针.
  165.          *            A pointer function without formal parameters.
  166.          * @param[in] state 任务运行状态.Task running status
  167.          * @return    [TMT_OK]修改成功.The modification was successful.
  168.          * @return    [TMT_NOK]修改失败.The modification was failed.
  169.          * @example   TMT.RunCtrl(enrty,Task_Stop); //修改entry任务为停止运行.
  170.         **/               
  171.         TMT_FunState_Type (*RunCtrl) (void (*entry) (void), TaskState_Type state);
  172. }TMT_Type;


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


  181. #ifdef        __cplusplus
  182. }
  183. #endif

  184. #endif        /* TMT_H */

TMT.C
  1. /*-----------------------------------------------------------------------
  2. |                            FILE DESCRIPTION                           |
  3. -----------------------------------------------------------------------*/
  4. /*----------------------------------------------------------------------
  5.   - File name     : TMT.c
  6.   - Author        : zeweni
  7.   - Update date   : 2020.06.26                  
  8.   -        Copyright(c)  : 2020-2021 zeweni. All rights reserved.
  9. -----------------------------------------------------------------------*/
  10. /*------------------------------------------------------------------------
  11. |                            COPYRIGHT NOTICE                            |
  12. ------------------------------------------------------------------------*/
  13. /*
  14. * Copyright (C) 2021, zeweni (17870070675@163.com)

  15. * This file is part of task management time slice framework.
  16. * Abbreviated as TMT.

  17. * Task management time slice framework is free software: you can redist-
  18. * ribute it and/or modify it under the terms of the Apache-2.0 License.

  19. * Task management time slice framework is distributed in the hope that it
  20. * will be useful,but WITHOUT ANY WARRANTY; without even the implied  
  21. * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * Apache-2.0 License for more details.

  23. * You should have received a copy of the Apache-2.0 License.Task management
  24. * time slice framework. If not, see <http://www.apache.org/licenses/>.
  25. **/
  26. /*-----------------------------------------------------------------------
  27. |                               INCLUDES                                |
  28. -----------------------------------------------------------------------*/
  29. #include "TMT.h"
  30. /*-----------------------------------------------------------------------
  31. |                                 DATA                                  |
  32. -----------------------------------------------------------------------*/

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


  39. /**
  40. * @brief   定义TMT相关操作函数结构体。
  41. * @details Define the structure of the TMT related operation functions.
  42. **/
  43. TMT_Type TMT;


  44. /**
  45. * @brief   TMT的类,包含公共和私有两个属性。
  46. * @details Class of TMT, containing both public and private properties.
  47. **/
  48. static struct Class
  49. {
  50.         TMT_Type Public;  /*!< 公共部分,对外开放的属性,具体定义在头文件。*/
  51.         
  52.         struct Private   /*!< 私有部分,仅限本文件内调用。*/
  53.         {
  54.                 struct
  55.                 {
  56.                         void (* Entry) (void); /*!< 任务函数入口指针。*/
  57.                         uint16_t TIMCount;     /*!< 任务调度时间计数器。*/
  58.                         uint16_t SetTime;      /*!< 任务设置的调度时间。*/
  59.                         uint8_t State;         /*!< 任务运行状态。*/
  60.                 }Comp[TASKS_MAX];
  61.                
  62.                 uint8_t Num;   /*!< 已经创建的任务数量。*/
  63.         }Private;
  64.         
  65. }Object;

  66. /*-----------------------------------------------------------------------
  67. |                               FUNCTION                                |
  68. -----------------------------------------------------------------------*/

  69. /**
  70. * @brief     TMT更新任务调度tick时间。
  71. * @details   TMT update task schedule tick time.
  72. * @param[in] None.
  73. * @return    None.
  74. **/
  75. static void TMT_Update_Tick_t(void)
  76. {
  77.         uint8_t i;
  78.         for(i = 0; i< Object.Private.Num; i++)
  79.     {
  80.                  /* If time arrives */
  81.         if(Object.Private.Comp[i].TIMCount > 0 )
  82.         {
  83.             Object.Private.Comp[i].TIMCount--;
  84.         }
  85.         }        
  86. }

  87. /**
  88. * @brief     TMT运行函数,是任务调度器。
  89. * @details   TMT runs the function, which is the task scheduler.
  90. * @param[in] None.
  91. * @return    None.
  92. **/
  93. static void TMT_Run_t(void)
  94. {
  95.         uint8_t index;
  96.         for(index = 0; index < Object.Private.Num; index++)
  97.         {
  98.                  /* If time arrives */
  99.                 if(Object.Private.Comp[index].TIMCount == 0 && Object.Private.Comp[index].State != Task_Stop)
  100.                 {
  101.                         Object.Private.Comp[index].TIMCount = Object.Private.Comp[index].SetTime;
  102.                         
  103.                         /*
  104.                                 To prevent process conflict,
  105.                                 only one process can be executed in the same time period.
  106.                         */
  107.                         if(Object.Private.Comp[index].Entry != (void*)(0) )
  108.                         {
  109.                                 Object.Private.Comp[index].Entry();  /* Run task */
  110.                         }
  111.                 }
  112.         }
  113. }


  114. /**
  115. * @brief     TMT创建一个任务函数。
  116. * @details   TMT creates a task function.
  117. * @param[in] entry 任务函数入口指针.
  118. *            A pointer function without formal parameters.
  119. * @param[in] setTime 任务调度的时间 task run time (ticks)
  120. * @return    [TMT_OK]创建成功.Create successfully.
  121. * @return    [TMT_NOK]创建失败.        Create failed.
  122. **/        
  123. static TMT_FunState_Type TMT_Create_t(void (*entry) (void),uint16_t setTime)
  124. {        
  125.     static uint8_t task_num = 0; /* Initialize to 0 */
  126.         if(task_num < TASKS_MAX)
  127.         {
  128.                 Object.Private.Comp[task_num].Entry = entry;
  129.                 Object.Private.Comp[task_num].SetTime = setTime;
  130.                 Object.Private.Comp[task_num].TIMCount = setTime;
  131.                 Object.Private.Comp[task_num].State = Task_Continue;
  132.                 task_num += 1;
  133.                 Object.Private.Num = task_num;
  134.                 return TMT_OK;
  135.         }
  136.         else
  137.         {
  138.                 return TMT_NOK;        
  139.         }               
  140. }


  141. /**
  142. * @brief     TMT删除一个任务函数。
  143. * @details   TMT creates a task function.
  144. * @param[in] entry 任务函数入口指针.
  145. *            A pointer function without formal parameters.
  146. * @return    [TMT_OK]删除成功.Delete successfully.
  147. * @return    [TMT_NOK]删除失败.        Delete failed.
  148. **/        
  149. static TMT_FunState_Type TMT_Delete_t(void (*entry) (void))
  150. {        
  151.     uint8_t index;
  152.     if(Object.Private.Num > 0)
  153.     {
  154.         ENTER_TMT_CRI_AREA();
  155.                
  156.         for(index = 0; index < Object.Private.Num; index++)
  157.         {
  158.             if(Object.Private.Comp[index].Entry == entry)
  159.             {
  160.                     Object.Private.Num--;
  161.                     Object.Private.Comp[index].Entry = Object.Private.Comp[Object.Private.Num].Entry;
  162.                     Object.Private.Comp[index].SetTime = Object.Private.Comp[Object.Private.Num].SetTime;
  163.                     Object.Private.Comp[index].TIMCount = Object.Private.Comp[Object.Private.Num].TIMCount;
  164.                     Object.Private.Comp[index].State = Object.Private.Comp[Object.Private.Num].State;
  165.                     EXTI_TMT_CRI_AREA();
  166.                     return TMT_OK;
  167.             }
  168.         }
  169.     }
  170.     EXTI_TMT_CRI_AREA();
  171.     return TMT_NOK;
  172. }


  173. /**
  174. * @brief     TMT控制一个任务运行状态函数。
  175. * @details   TMT controls a task running state function.
  176. * @param[in] entry 任务函数入口指针.
  177. *            A pointer function without formal parameters.
  178. * @param[in] state 任务运行状态.Task running status
  179. * @return    [TMT_OK]修改成功.The modification was successful.
  180. * @return    [TMT_NOK]修改失败.The modification was failed.
  181. **/        
  182. static TMT_FunState_Type TMT_RunCtrl_t(void (*entry)(void),TaskState_Type state)
  183. {
  184.         uint8_t index;
  185.         for(index = 0; index<Object.Private.Num; index++)
  186.         {
  187.                 if(Object.Private.Comp[index].Entry == entry)
  188.                 {
  189.                     Object.Private.Comp[index].State = state;
  190.                         return TMT_OK;
  191.                 }
  192.         }
  193.         return TMT_NOK;
  194. }


  195. /**
  196. * @brief     TMT控制一个任务的调度时间函数。
  197. * @details   The TMT controls the scheduling time function of a task.
  198. * @param[in] *taskFunc (void) 任务函数入口指针.
  199. *            A pointer function without formal parameters.
  200. * @param[in] setTime 任务调度的时间 task run time (ticks)
  201. * @return    [TMT_OK]修改成功.The modification was successful.
  202. * @return    [TMT_NOK]修改失败.The modification was failed.
  203. **/        
  204. static TMT_FunState_Type TMT_TimeCtrl_t(void (*entry) (void),uint16_t setTime)
  205. {        
  206.         uint8_t index;
  207.         for(index = 0; index< Object.Private.Num; index++)
  208.         {
  209.                 if(Object.Private.Comp[index].Entry == entry)
  210.                 {
  211.                         Object.Private.Comp[index].TIMCount = setTime;
  212.                         Object.Private.Comp[index].SetTime = setTime;
  213.                         return TMT_OK;
  214.                 }
  215.         }
  216.         return TMT_NOK;
  217. }


  218. /**
  219. * @brief   TMT初始化函数,注册相关元素。
  220. * @details The TMT initializes the function
  221. *          and registers the associated elements.
  222. * @param   None.
  223. * @return  None.
  224. **/
  225. void TMT_Init(void)
  226. {
  227.         Object.Public.Run = TMT_Run_t;
  228.         Object.Public.Tick = TMT_Update_Tick_t;
  229.         Object.Public.Create = TMT_Create_t;
  230.         Object.Public.Delete = TMT_Delete_t;
  231.         Object.Public.TimeCtrl = TMT_TimeCtrl_t;
  232.         Object.Public.RunCtrl = TMT_RunCtrl_t;
  233.         Object.Private.Num = 0;
  234.         
  235.         TMT = Object.Public;
  236. }

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



在timer0中断函数里面添加TMT核心任务处理函数:
  1. #include "../TMT/tmt.h"
  2. volatile uint32_t mscnt=0;

  3. void TMR0_CallBack(void)
  4. {
  5.     // Add your custom callback code here
  6.     mscnt++;
  7.     if(mscnt>=500)
  8.     {
  9.         //LED0_Toggle();
  10.         mscnt=0;
  11.     }
  12.    
  13.     TMT.Tick();
  14.    
  15.     if(TMR0_InterruptHandler)
  16.     {
  17.         TMR0_InterruptHandler();
  18.     }
  19. }
在main函数里面新建2个任务,并运行(主要开总中断):

  1. #include "mcc_generated_files/mcc.h"
  2. #include "tmt/tmt.h"



  3. void TMT_Demo0(void)
  4. {
  5.         LED0_Toggle();
  6. }

  7. uint8_t j=0;
  8. void TMT_Demo1(void)
  9. {
  10.         printf("the j is %d!\r\n",j++);
  11. }

  12. /*
  13.                          Main application
  14. */
  15. void main(void)
  16. {
  17.     uint8_t i=0;
  18.     // Initialize the device
  19.     SYSTEM_Initialize();

  20.     // If using interrupts in PIC18 High/Low Priority Mode you need to enable the Global High and Low Interrupts
  21.     // If using interrupts in PIC Mid-Range Compatibility Mode you need to enable the Global Interrupts
  22.     // Use the following macros to:

  23.     TMT_Init();
  24.         
  25.         TMT.Create(TMT_Demo0,500);
  26.         TMT.Create(TMT_Demo1,500);
  27.    
  28.     // Enable the Global Interrupts
  29.     INTERRUPT_GlobalInterruptEnable();

  30.     // Disable the Global Interrupts
  31.     //INTERRUPT_GlobalInterruptDisable();

  32.     while (1)
  33.     {
  34.         // Add your application code
  35.         //printf("the i is %d!\r\n",i++);
  36.         // __delay_ms(300);
  37.         TMT.Run();
  38.     }
  39. }
下载,运行:
看串口输出端:

看板上LED:

虽然简单,但是很好的诠释了系统调度的流程,好了,今天就到这!
谢谢观看~

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
pzsh 发表于 2021-8-31 13:41 | 显示全部楼层
看flash和RAM配置,的确跑个RTOS没问题
51xlf 发表于 2021-9-3 21:30 | 显示全部楼层
能够一直RT-Thead吗?        
i1mcu 发表于 2021-9-3 21:30 | 显示全部楼层
这个芯片多大的flash呢   
pmp 发表于 2021-9-3 21:31 | 显示全部楼层
可以直接配置生成RTOS代码 ?      
mmbs 发表于 2021-9-3 21:31 | 显示全部楼层
主要是RAM和flash决定的。     
1988020566 发表于 2021-9-3 21:31 | 显示全部楼层
有移植成功的教程吗?      
lzbf 发表于 2021-9-3 21:32 | 显示全部楼层
PIC18F16Q41的FLASH空间很大吗   
houjiakai 发表于 2021-9-3 21:32 | 显示全部楼层
这个是官网申请的板子吗   
youtome 发表于 2021-9-3 21:32 | 显示全部楼层
定时器中断函数            
cemaj 发表于 2021-9-3 21:32 | 显示全部楼层
TMT是什么?      
jimmhu 发表于 2021-9-3 21:32 | 显示全部楼层
定时器的调度具体含义是什么   
1988020566 发表于 2021-9-3 21:32 | 显示全部楼层
期待楼主分享详细的移植教程。   
 楼主| qjp1988113 发表于 2021-9-4 19:04 | 显示全部楼层
houjiakai 发表于 2021-9-3 21:32
这个是官网申请的板子吗

是的
 楼主| qjp1988113 发表于 2021-9-4 19:28 | 显示全部楼层
i1mcu 发表于 2021-9-3 21:30
这个芯片多大的flash呢

64K FLASH,4K RAM
littlelida 发表于 2021-9-14 15:28 | 显示全部楼层
TMT是什么东西?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

111

主题

627

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部