你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【安富莱STM32F407之uCOS-III教程】第11章 μCOS-III内核函数分析

[复制链接]
baiyongbin2009 发布时间:2014-12-24 19:55
特别说明:
1.  本教程是安富莱电子原创。
2.  安富莱STM32F407开发板资料已经全部开源,开源地址:地址链接

3.  当前共配套300多个实例,4套用户手册。

第11章  μCOS-III内核函数分析

    本期教程开始分析μCOS-III的内核函数,源码的分析采用先对源码进行注释,然后讲解函数实现的功能和相关的原理分析,最后是举一个例子(如果这个函数是供外部函数调用的)。内核函数很重要,是学习任务管理,任务间通信机制的基础。希望初学的同学认真学习,这部分应该算是μCOS-III的核心代码。
    11.1 系统配置文件
    11.2 源码文件
    11.3 μCOS-III初始化
    11.4 μCOS-III启动
    11.5 获取系统版本
    11.6 空闲任务
    11.7 临界段
    11.8 安全关键IEC61508
    11.9 任务切换
    11.10 调度锁
    11.11 Round-Robin调度
    11.12 总结

11.1  系统配置文件
    下面先简单说明下μCOS-III中几个配置文件的作用,方便分析源码的时候查看,配置文件主要有以下几个:
11.1.png

11.1.1      lib_cfg.h配置文件
    lib_cfg.h文件内容如下:
  1. /*
  2. *********************************************************************************************************
  3. *                                               MODULE
  4. *********************************************************************************************************
  5. */

  6. #ifndef  LIB_CFG_MODULE_PRESENT
  7. #define  LIB_CFG_MODULE_PRESENT

  8. /*
  9. *********************************************************************************************************
  10. *                                          uC/LIB CONFIGURATION
  11. *********************************************************************************************************
  12. */

  13. #define  LIB_MEM_CFG_ARG_CHK_EXT_EN     DEF_ENABLED
  14.                                          /*   DEF_DISABLED     Argument check DISABLED       */
  15.                                          /*   DEF_ENABLED      Argument check ENABLED        */

  16. #define  LIB_MEM_CFG_OPTIMIZE_ASM_EN    DEF_ENABLED
  17.                                          /*   DEF_DISABLED     Assembly-optimized function(s) DISABLED   */
  18.                                          /*   DEF_ENABLED      Assembly-optimized function(s) ENABLED    */

  19. #define  LIB_MEM_CFG_ALLOC_EN           DEF_ENABLED
  20.                                          /*   DEF_DISABLED     Memory allocation DISABLED    */
  21.                                          /*   DEF_ENABLED      Memory allocation ENABLED     */

  22. #define  LIB_MEM_CFG_HEAP_SIZE          23u * 1024u     /* Configure Heap Memory Size  */

  23. /*
  24. *********************************************************************************************************
  25. *                                             MODULE END
  26. *********************************************************************************************************
  27. */

  28. #endif<span lang="EN-US" style="text-indent: 21.2pt; line-height: 12pt; font-size: 9pt; font-family: 新宋体; background-color: rgb(255, 255, 255);">  </span><span lang="EN-US" style="text-indent: 21.2pt; line-height: 12pt; font-family: 微软雅黑, sans-serif; background-color: rgb(255, 255, 255);">              </span>
复制代码
    lib_cfg.h是用于给uC/LIB做配置的头文件。如果程序中使用uC/LIB的话,需要调用函数Mem_Init()进行初始化。
11.1.2      os_cfg.h配置文件
   os_cfg.h文件中的内容如下:
  1. #ifndef OS_CFG_H
  2. #define OS_CFG_H


  3. /* ---------------------------- MISCELLANEOUS -------------------------- */
  4. #define OS_CFG_APP_HOOKS_EN             1u   /* Enable (1) or Disable (0) application specific hooks  */
  5. #define OS_CFG_ARG_CHK_EN               1u   /* Enable (1) or Disable (0) argument checking           */
  6. #define OS_CFG_CALLED_FROM_ISR_CHK_EN   1u   /* Enable (1) or Disable (0) check for called from ISR   */
  7. #define OS_CFG_DBG_EN                   1u   /* Enable (1) debug code/variables                       */
  8. #define OS_CFG_ISR_POST_DEFERRED_EN     0u   /* Enable (1) or Disable (0) Deferred ISR posts          */
  9. #define OS_CFG_OBJ_TYPE_CHK_EN          1u   /* Enable (1) or Disable (0) object type checking        */
  10. #define OS_CFG_TS_EN                    1u   /* Enable (1) or Disable (0) time stamping               */

  11. #define OS_CFG_PEND_MULTI_EN  1u   /* Enable (1) or Disable (0) code generation for multi-pend feature   */

  12. #define OS_CFG_PRIO_MAX       64u  /* Defines the maximum number of task priorities (see OS_PRIO data type) */

  13. #define OS_CFG_SCHED_LOCK_TIME_MEAS_EN  0u   /* Include code to measure scheduler lock time           */
  14. #define OS_CFG_SCHED_ROUND_ROBIN_EN     0u   /* Include code for Round-Robin scheduling               */
  15. #define OS_CFG_STK_SIZE_MIN            64u   /* Minimum allowable task stack size                     */


  16. /* ----------------------------- EVENT FLAGS --------------------------- */
  17. #define OS_CFG_FLAG_EN          1u   /* Enable (1) or Disable (0) code generation for EVENT FLAGS   */
  18. #define OS_CFG_FLAG_DEL_EN      1u   /* Include code for OSFlagDel()                                */
  19. #define OS_CFG_FLAG_MODE_CLR_EN 1u   /* Include code for Wait on Clear EVENT FLAGS                  */
  20. #define OS_CFG_FLAG_PEND_ABORT_EN 1u /* Include code for OSFlagPendAbort()                          */


  21. /* -------------------------- MEMORY MANAGEMENT ------------------------ */
  22. #define OS_CFG_MEM_EN           1u   /* Enable (1) or Disable (0) code generation for MEMORY MANAGER  */


  23. /* --------------------- MUTUAL EXCLUSION SEMAPHORES ------------------- */
  24. #define OS_CFG_MUTEX_EN                 1u   /* Enable (1) or Disable (0) code generation for MUTEX   */
  25. #define OS_CFG_MUTEX_DEL_EN             1u   /* Include code for OSMutexDel()                         */
  26. #define OS_CFG_MUTEX_PEND_ABORT_EN      1u   /* Include code for OSMutexPendAbort()                   */


  27. /* --------------------------- MESSAGE QUEUES -------------------------- */
  28. #define OS_CFG_Q_EN                     1u   /* Enable (1) or Disable (0) code generation for QUEUES  */
  29. #define OS_CFG_Q_DEL_EN                 1u   /* Include code for OSQDel()                             */
  30. #define OS_CFG_Q_FLUSH_EN               1u   /* Include code for OSQFlush()                           */
  31. #define OS_CFG_Q_PEND_ABORT_EN          1u   /* Include code for OSQPendAbort()                       */


  32. /* ----------------------------- SEMAPHORES ---------------------------- */
  33. #define OS_CFG_SEM_EN                   1u   /* Enable (1) or Disable (0) code generation for SEMAPHORES */
  34. #define OS_CFG_SEM_DEL_EN               1u   /* Include code for OSSemDel()                              */
  35. #define OS_CFG_SEM_PEND_ABORT_EN        1u   /* Include code for OSSemPendAbort()                        */
  36. #define OS_CFG_SEM_SET_EN               1u   /* Include code for OSSemSet()                              */


  37. /* -------------------------- TASK MANAGEMENT -------------------------- */
  38. #define OS_CFG_STAT_TASK_EN             1u   /* Enable (1) or Disable(0) the statistics task   */
  39. #define OS_CFG_STAT_TASK_STK_CHK_EN     1u   /* Check task stacks from statistic task          */

  40. #define OS_CFG_TASK_CHANGE_PRIO_EN      1u   /* Include code for OSTaskChangePrio()            */
  41. #define OS_CFG_TASK_DEL_EN              1u   /* Include code for OSTaskDel()                   */
  42. #define OS_CFG_TASK_Q_EN                1u   /* Include code for OSTaskQXXXX()                 */
  43. #define OS_CFG_TASK_Q_PEND_ABORT_EN     1u   /* Include code for OSTaskQPendAbort()            */
  44. #define OS_CFG_TASK_PROFILE_EN          1u   /* Include variables in OS_TCB for profiling      */
  45. #define OS_CFG_TASK_REG_TBL_SIZE        1u   /* Number of task specific registers              */
  46. #define OS_CFG_TASK_SEM_PEND_ABORT_EN   1u   /* Include code for OSTaskSemPendAbort()               */
  47. #define OS_CFG_TASK_SUSPEND_EN          1u   /* Include code for OSTaskSuspend() and OSTaskResume() */


  48. /* -------------------------- TIME MANAGEMENT -------------------------- */
  49. #define OS_CFG_TIME_DLY_HMSM_EN         1u   /* Include code for OSTimeDlyHMSM()                   */
  50. #define OS_CFG_TIME_DLY_RESUME_EN       1u   /* Include code for OSTimeDlyResume()                 */


  51. /* ------------------------- TIMER MANAGEMENT -------------------------- */
  52. #define OS_CFG_TMR_EN         1u   /* Enable (1) or Disable (0) code generation for TIMERS      */
  53. #define OS_CFG_TMR_DEL_EN     1u   /* Enable (1) or Disable (0) code generation for OSTmrDel()  */

  54. #endif
复制代码
    这个配置文件比较的重要,主要用于μCOS-III源码中相关函数的配置。

收藏 评论23 发布时间:2014-12-24 19:55

举报

23个回答
baiyongbin2009 回答时间:2014-12-24 19:58:39
(续)11.1  系统配置文件
11.1.3      os_cfg_app.h配置文件
os_cfg_app.h文件的内容如下:
  1. #ifndef OS_CFG_APP_H
  2. #define OS_CFG_APP_H

  3. /*
  4. ***********************************************************************************************************
  5. *                                            CONSTANTS
  6. ***********************************************************************************************************
  7. */

  8. /* --------------------- MISCELLANEOUS ------------------ */
  9. #define  OS_CFG_MSG_POOL_SIZE            100u       /* Maximum number of messages                        */
  10. #define  OS_CFG_ISR_STK_SIZE             256u       /* Stack size of ISR stack (number of CPU_STK elements) */
  11. #define  OS_CFG_TASK_STK_LIMIT_PCT_EMPTY  10u       /* Stack limit position in percentage to empty       */


  12. /* ---------------------- IDLE TASK --------------------- */
  13. #define  OS_CFG_IDLE_TASK_STK_SIZE       128u            /* Stack size (number of CPU_STK elements)    */


  14. /* ------------------ ISR HANDLER TASK ------------------ */
  15. #define  OS_CFG_INT_Q_SIZE                10u            /* Size of ISR handler task queue             */
  16. #define  OS_CFG_INT_Q_TASK_STK_SIZE      128u            /* Stack size (number of CPU_STK elements)    */

  17. /* ------------------- STATISTIC TASK ------------------- */
  18. #define  OS_CFG_STAT_TASK_PRIO     (OS_CFG_PRIO_MAX - 2u) /* Priority                                */
  19. #define  OS_CFG_STAT_TASK_RATE_HZ         10u             /* Rate of execution (10 Hz Typ.)          */
  20. #define  OS_CFG_STAT_TASK_STK_SIZE       128u             /* Stack size (number of CPU_STK elements) */


  21. /* ------------------------ TICKS ----------------------- */
  22. #define  OS_CFG_TICK_RATE_HZ            1000u   /* Tick rate in Hertz (10 to 1000 Hz)                   */
  23. #define  OS_CFG_TICK_TASK_PRIO             1u   /* Priority                                             */
  24. #define  OS_CFG_TICK_TASK_STK_SIZE       128u   /* Stack size (number of CPU_STK elements)              */
  25. #define  OS_CFG_TICK_WHEEL_SIZE           16u   /* Number of 'spokes' in tick wheel                     */

  26. /* ----------------------- TIMERS ----------------------- */
  27. #define  OS_CFG_TMR_TASK_PRIO      (OS_CFG_PRIO_MAX - 2u)   /* Priority                                 */
  28. #define  OS_CFG_TMR_TASK_RATE_HZ          10u               /* Rate for timers (10 Hz Typ.)             */
  29. #define  OS_CFG_TMR_TASK_STK_SIZE        128u               /* Stack size (number of CPU_STK elements)  */
  30. #define  OS_CFG_TMR_WHEEL_SIZE            17u               /* Number of 'spokes' in timer wheel        */

  31. #endif
复制代码
    这个文件主要是内核任务的配置,包括中断管理任务,空闲任务,统计任务,嘀嗒定时器任务已经定时器任务。
11.1.4      app_cfg.h配置文件
app_cfg.h文件夹中的内容如下:
  1. #ifndef  APP_CFG_MODULE_PRESENT
  2. #define  APP_CFG_MODULE_PRESENT


  3. /*
  4. *********************************************************************************************************
  5. *                                            TASK PRIORITIES
  6. *********************************************************************************************************
  7. */

  8. #define  APP_CFG_TASK_START_PRIO                              2u
  9. #define  APP_CFG_TASK_UPDATE_PRIO                             3u
  10. #define  APP_CFG_TASK_COM_PRIO                                4u
  11. #define  APP_CFG_TASK_USER_IF_PRIO                            5u
  12. #define  APP_CFG_TASK_GUI_PRIO                        (OS_CFG_PRIO_MAX - 4u)
  13. #define  APP_CFG_TASK_GUIRefresh_PRIO                 (OS_CFG_PRIO_MAX - 4u)

  14. /*
  15. *********************************************************************************************************
  16. *                                            TASK STACK SIZES
  17. *                             Size of the task stacks (# of OS_STK entries)
  18. *********************************************************************************************************
  19. */

  20. #define  APP_CFG_TASK_START_STK_SIZE                      1024u
  21. #define  APP_CFG_TASK_UPDATE_STK_SIZE                     1024u
  22. #define  APP_CFG_TASK_COM_STK_SIZE                        1024u
  23. #define  APP_CFG_TASK_USER_IF_STK_SIZE                    1024u
  24. #define  APP_CFG_TASK_GUI_STK_SIZE                        1024u
  25. #define  APP_CFG_TASK_GUIRefresh_STK_SIZE                 1024u

  26. #endif
复制代码
    这个文件主要用于用户任务的配置。

baiyongbin2009 回答时间:2014-12-24 19:59:09
(续)11.1  系统配置文件
11.1.5       cpu_cfg.h配置文件
    cpu_cfg.h文件中的内容如下:
  1. #ifndef CPU_CFG_MODULE_PRESENT
  2. #define CPU_CFG_MODULE_PRESENT


  3. /*
  4. *********************************************************************************************************
  5. * CPU NAME CONFIGURATION
  6. *
  7. * Note(s) : (1) Configure CPU_CFG_NAME_EN to enable/disable CPU host name feature :
  8. *
  9. * (a) CPU host name storage
  10. * (b) CPU host name API functions
  11. *
  12. * (2) Configure CPU_CFG_NAME_SIZE with the desired ASCII string size of the CPU host name,
  13. * including the terminating NULL character.
  14. *
  15. * See also 'cpu_core.h GLOBAL VARIABLES Note #1'.
  16. *********************************************************************************************************
  17. */

  18. /* Configure CPU host name feature (see Note #1) : */
  19. #define CPU_CFG_NAME_EN DEF_ENABLED
  20. /* DEF_DISABLED CPU host name DISABLED */
  21. /* DEF_ENABLED CPU host name ENABLED */

  22. /* Configure CPU host name ASCII string size ... */
  23. #define CPU_CFG_NAME_SIZE 16 /* ... (see Note #2). */

  24. /*
  25. *********************************************************************************************************
  26. * CPU TIMESTAMP CONFIGURATION
  27. *
  28. * Note(s) : (1) Configure CPU_CFG_TS_xx_EN to enable/disable CPU timestamp features :
  29. *
  30. * (a) CPU_CFG_TS_32_EN enable/disable 32-bit CPU timestamp feature
  31. * (b) CPU_CFG_TS_64_EN enable/disable 64-bit CPU timestamp feature
  32. *
  33. * (2) (a) Configure CPU_CFG_TS_TMR_SIZE with the CPU timestamp timer's word size :
  34. *
  35. * CPU_WORD_SIZE_08 8-bit word size
  36. * CPU_WORD_SIZE_16 16-bit word size
  37. * CPU_WORD_SIZE_32 32-bit word size
  38. * CPU_WORD_SIZE_64 64-bit word size
  39. *
  40. * (b) If the size of the CPU timestamp timer is not a binary multiple of 8-bit octets
  41. * (e.g. 20-bits or even 24-bits), then the next lower, binary-multiple octet word
  42. * size SHOULD be configured (e.g. to 16-bits). However, the minimum supported word
  43. * size for CPU timestamp timers is 8-bits.
  44. *
  45. * See also 'cpu_core.h FUNCTION PROTOTYPES CPU_TS_TmrRd() Note #2a'.
  46. *********************************************************************************************************
  47. */

  48. /* Configure CPU timestamp features (see Note #1) : */
  49. #define CPU_CFG_TS_32_EN DEF_ENABLED
  50. #define CPU_CFG_TS_64_EN DEF_DISABLED
  51. /* DEF_DISABLED CPU timestamps DISABLED */
  52. /* DEF_ENABLED CPU timestamps ENABLED */

  53. /* Configure CPU timestamp timer word size ... */
  54. /* ... (see Note #2) : */
  55. #define CPU_CFG_TS_TMR_SIZE CPU_WORD_SIZE_32


  56. /*
  57. *********************************************************************************************************
  58. * CPU INTERRUPTS DISABLED TIME MEASUREMENT CONFIGURATION
  59. *
  60. * Note(s) : (1) (a) Configure CPU_CFG_INT_DIS_MEAS_EN to enable/disable measuring CPU's interrupts
  61. * disabled time :
  62. *
  63. * (a) Enabled, if CPU_CFG_INT_DIS_MEAS_EN #define'd in 'cpu_cfg.h'
  64. *
  65. * (b) Disabled, if CPU_CFG_INT_DIS_MEAS_EN NOT #define'd in 'cpu_cfg.h'
  66. *
  67. * See also 'cpu_core.h FUNCTION PROTOTYPES Note #1'.
  68. *
  69. * (b) Configure CPU_CFG_INT_DIS_MEAS_OVRHD_NBR with the number of times to measure &
  70. * average the interrupts disabled time measurements overhead.
  71. *
  72. * Recommend a single (1) overhead time measurement, even for instruction-cache-enabled
  73. * CPUs, since critical sections are NOT typically called within instruction-cached loops.
  74. * Thus a single non-cached/non-averaged time measurement is a more realistic overhead
  75. * for the majority of non-cached interrupts disabled time measurements.
  76. *
  77. * See also 'cpu_core.c CPU_IntDisMeasInit() Note #3a'.
  78. *********************************************************************************************************
  79. */

  80. #if 0 /* Configure CPU interrupts disabled time ... */
  81. #define CPU_CFG_INT_DIS_MEAS_EN /* ... measurements feature (see Note #1a). */
  82. #endif

  83. /* Configure number of interrupts disabled overhead ... */
  84. #define CPU_CFG_INT_DIS_MEAS_OVRHD_NBR 1u /* ... time measurements (see Note #1b). */

  85. /*
  86. *********************************************************************************************************
  87. * CPU COUNT ZEROS CONFIGURATION
  88. *
  89. * Note(s) : (1) (a) Configure CPU_CFG_LEAD_ZEROS_ASM_PRESENT to define count leading zeros bits
  90. * function(s) in :
  91. *
  92. * (1) 'cpu_a.asm', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/
  93. * 'cpu_cfg.h' to enable assembly-optimized function(s)
  94. *
  95. * (2) 'cpu_core.c', if CPU_CFG_LEAD_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/
  96. * 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise
  97. *
  98. * (b) Configure CPU_CFG_TRAIL_ZEROS_ASM_PRESENT to define count trailing zeros bits
  99. * function(s) in :
  100. *
  101. * (1) 'cpu_a.asm', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT #define'd in 'cpu.h'/
  102. * 'cpu_cfg.h' to enable assembly-optimized function(s)
  103. *
  104. * (2) 'cpu_core.c', if CPU_CFG_TRAIL_ZEROS_ASM_PRESENT NOT #define'd in 'cpu.h'/
  105. * 'cpu_cfg.h' to enable C-source-optimized function(s) otherwise
  106. *********************************************************************************************************
  107. */

  108. #if 1 /* Configure CPU count leading zeros bits ... */
  109. #define CPU_CFG_LEAD_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1a). */
  110. #endif

  111. #if 0 /* Configure CPU count trailing zeros bits ... */
  112. #define CPU_CFG_TRAIL_ZEROS_ASM_PRESENT /* ... assembly-version (see Note #1b). */
  113. #endif

  114. /*
  115. *********************************************************************************************************
  116. * MODULE END
  117. *********************************************************************************************************
  118. */

  119. #endif /* End of CPU cfg module include. */
复制代码
    这个文件里面主要是uC/CPU相关的配置。
baiyongbin2009 回答时间:2014-12-24 20:00:19
11.2  源码文件
    μCOS-III中的源码主要包含如下文件:
11.2.png
                              
    上面截图中是μCOS-III相关的源码文件,后面的几期教程就是把这几个文件讲清楚。本期教程主要是讲解os_core文件中的相关函数。学期源码前还有看一下os_type.h文件中的内容(主要是变量的类型,这个一定得了解下):
  1. /*
  2. ***********************************************************************************************************
  3. *                                                 INCLUDE HEADER FILES
  4. ***********************************************************************************************************
  5. */

  6. typedef   CPU_INT16U      OS_CPU_USAGE; /* CPU Usage 0..10000                     <16>/32 */

  7. typedef   CPU_INT32U      OS_CTR;       /* Counter,                                    32 */

  8. typedef   CPU_INT32U      OS_CTX_SW_CTR; /* Counter of context switches,               32 */

  9. typedef   CPU_INT32U      OS_CYCLES;    /* CPU clock cycles,                                   <32>/64 */

  10. typedef   CPU_INT32U      OS_FLAGS;     /* Event flags,                                      8/16/<32> */

  11. typedef   CPU_INT32U      OS_IDLE_CTR;  /* Holds the number of times the idle task runs,       <32>/64 */

  12. typedef   CPU_INT16U      OS_MEM_QTY;   /* Number of memory blocks,                            <16>/32 */
  13. typedef   CPU_INT16U      OS_MEM_SIZE;  /* Size in bytes of a memory block,                    <16>/32 */

  14. typedef   CPU_INT16U      OS_MSG_QTY;   /* Number of OS_MSGs in the msg pool,                  <16>/32 */
  15. typedef   CPU_INT16U      OS_MSG_SIZE;  /* Size of messages in number of bytes,                <16>/32 */

  16. typedef   CPU_INT08U      OS_NESTING_CTR; /* Interrupt and scheduler nesting,                  <8>/16/32 */

  17. typedef   CPU_INT16U      OS_OBJ_QTY;     /* Number of kernel objects counter,                   <16>/32 */
  18. typedef   CPU_INT32U      OS_OBJ_TYPE;    /* Special flag to determine object type,                   32 */

  19. typedef   CPU_INT16U      OS_OPT;         /* Holds function options                              <16>/32 */

  20. typedef   CPU_INT08U      OS_PRIO;        /* Priority of a task,                               <8>/16/32 */

  21. typedef   CPU_INT16U      OS_QTY;         /* Quantity                                            <16>/32 */

  22. typedef   CPU_INT32U      OS_RATE_HZ;     /* Rate in Hertz                                            32 */

  23. typedef   CPU_INT32U      OS_REG;         /* Task register                                     8/16/<32> */
  24. typedef   CPU_INT08U      OS_REG_ID;      /* Index to task register                            <8>/16/32 */

  25. typedef   CPU_INT32U      OS_SEM_CTR;     /* Semaphore value                                     16/<32> */

  26. typedef   CPU_INT08U      OS_STATE;       /* State variable                                    <8>/16/32 */

  27. typedef   CPU_INT08U      OS_STATUS;      /* Status                                            <8>/16/32 */

  28. typedef   CPU_INT32U      OS_TICK;        /* Clock tick counter                                  <32>/64 */
  29. typedef   CPU_INT16U      OS_TICK_SPOKE_IX; /* Tick wheel spoke position                         8/<16>/32 */

  30. typedef   CPU_INT16U      OS_TMR_SPOKE_IX; /* Timer wheel spoke position                        8/<16>/32 */
复制代码


baiyongbin2009 回答时间:2014-12-24 20:03:29
11.3  μCOS-III初始化
    下面开始讲解os_core.c文件中的函数,这个文件里面的函数比较多,为了方便大家更好的学习这个文件中的相关函数,这里对其进行了分类,先从μCOS-III的初始化开始讲解。
11.3.1      初始化
    根据前面os_cfg.h文件中的配置,用户可以配置程序中需要执行的函数。μCOS-III的初始化函数OSInit()中涉及的全局变量和函数的初始化比较多,这里将其汇总一下,下面是全局变量的初始化:
全局变量
初始值
变量说明
OSIntNestingCtr
0
中断嵌套的层数(0~250)
OSRunning
  
OS_STATE_OS_STOPPED
  
系统是否开始运行标志
OSSchedLockNestingCtr
0
调用了调度锁的嵌套层数
OSTCBCurPtr
  
0
  
指向当前正在运行任务控制块指针
OSTCBHighRdyPtr
0
指向最高优先级就绪任务控制块指针
OSPrioCur
  
0
  
当前正在运行的任务优先级
OSPrioHighRdy
0
具有最高优先级别的就绪任务的优先级
OSPrioSaved
  
0
  
保存任务优先级
OSSchedLockTimeBegin
0
使用调度锁起始时间
OSSchedLockTimeMax
  
0
  
调度器被锁的最长时间
OSSchedLockTimeMaxCur
0
当前调度器被锁的最长时间
OSSafetyCriticalStartFlag
  
DEF_FALSE
  
系统安全关键开始标志
OSSchedRoundRobinEn
DEF_FALSE
使能Round-Robin调度
OSSchedRoundRobinDfltTimeQuanta
  
OSCfg_TickRate_Hz / 10u
  
默认Round-Robin调度时间片大小
OS_AppTaskCreateHookPtr
0
任务创建钩子函数指针
OS_AppTaskDelHookPtr
  
0
  
任务删除钩子函数指针
OS_AppTaskReturnHookPtr
0
任务返回钩子函数指针
OS_AppIdleTaskHookPtr
  
0
  
空闲钩子函数指针
OS_AppStatTaskHookPtr
0
启动任务钩子函数指针
OS_AppTaskSwHookPtr
  
0
  
任务切换钩子函数指针
OS_AppTimeTickHookPtr
0
滴答定时器钩子函数指针
OSTaskRegNextAvailID
0
任务寄存器下一个有效ID
    函数OSInit()中的其它初始化会在后面讲到的时候再做详细阐述。下面把初始化函数做一下分析。

baiyongbin2009 回答时间:2014-12-24 20:05:42
(续)11.3  μCOS-III初始化

11.3.2      初始化函数OSInit()
  1. /*
  2. ***********************************************************************************************************
  3. *                                                    初始化
  4. *
  5. * 功能说明: 此函数用于uC/OS-III的内部初始化,这个函数是使用uC/OS-III时需要第一个执行的函数,切记不要搞错顺*           序,然后才是任务创建和OS_Start().
  6. * 形    参: p_err    变量指针,用于返回错误代码
  7. *                    OS_ERR_NONE    初始化成功
  8. *                    Other          根据调用的子函数返回其它OS_ERR_xxx
  9. * 返 回 值: 无
  10. ***********************************************************************************************************
  11. */

  12. void  OSInit (OS_ERR  *p_err)
  13. {
  14.     CPU_STK      *p_stk;
  15.     CPU_STK_SIZE  size;



  16. #ifdef OS_SAFETY_CRITICAL                                  /* 安全关键代码 */                      (1)
  17.     if (p_err == (OS_ERR *)0) {
  18.         OS_SAFETY_CRITICAL_EXCEPTION();
  19.         return;
  20.     }
  21. #endif

  22.     OSInitHook();                                           /* 初始化钩子函数 */                                      

  23.     OSIntNestingCtr                 = (OS_NESTING_CTR)0;    /* 清零中断嵌套计数*/                  (2)

  24.     OSRunning                       =  OS_STATE_OS_STOPPED; /* 多任务运行标志,初始化为还没开始  */

  25.     OSSchedLockNestingCtr           = (OS_NESTING_CTR)0;    /* 调度锁计数清零  */

  26.     OSTCBCurPtr                     = (OS_TCB *)0;          /* 初始化 OS_TCB 指针为已知状态 */     (3)
  27.     OSTCBHighRdyPtr                 = (OS_TCB *)0;

  28.     OSPrioCur                       = (OS_PRIO)0;     /* 初始化优先级变量为已知状态  */
  29.     OSPrioHighRdy                   = (OS_PRIO)0;
  30.     OSPrioSaved                     = (OS_PRIO)0;

  31. #if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u               /* 调度锁时间测量 */
  32.     OSSchedLockTimeBegin            = (CPU_TS)0;
  33.     OSSchedLockTimeMax              = (CPU_TS)0;
  34.     OSSchedLockTimeMaxCur           = (CPU_TS)0;
  35. #endif

  36. #ifdef OS_SAFETY_CRITICAL_IEC61508                    /* 安全关键开启标志 */                       (4)
  37.     OSSafetyCriticalStartFlag       =  DEF_FALSE;
  38. #endif

  39. #if OS_CFG_SCHED_ROUND_ROBIN_EN > 0u                  /* 时间片调度默认配置 */                     (5)
  40.     OSSchedRoundRobinEn             = DEF_FALSE;
  41.     OSSchedRoundRobinDfltTimeQuanta = OSCfg_TickRate_Hz / 10u;
  42. #endif

  43.     if (OSCfg_ISRStkSize > (CPU_STK_SIZE)0) {                                                                                                  (6)
  44.         p_stk = OSCfg_ISRStkBasePtr;                  /* 清零异常堆栈,方便后面做堆栈利用率检测   */
  45.         if (p_stk != (CPU_STK *)0) {
  46.             size  = OSCfg_ISRStkSize;
  47.             while (size > (CPU_STK_SIZE)0) {
  48.                 size--;
  49.                *p_stk = (CPU_STK)0;
  50.                 p_stk++;
  51.             }
  52.         }
  53.     }

  54. #if OS_CFG_APP_HOOKS_EN > 0u                                                                      (7)
  55.     OS_AppTaskCreateHookPtr = (OS_APP_HOOK_TCB )0;     /* 初始化钩子函数指针  */
  56.     OS_AppTaskDelHookPtr    = (OS_APP_HOOK_TCB )0;
  57.     OS_AppTaskReturnHookPtr = (OS_APP_HOOK_TCB )0;

  58.     OS_AppIdleTaskHookPtr   = (OS_APP_HOOK_VOID)0;
  59.     OS_AppStatTaskHookPtr   = (OS_APP_HOOK_VOID)0;
  60.     OS_AppTaskSwHookPtr     = (OS_APP_HOOK_VOID)0;
  61.     OS_AppTimeTickHookPtr   = (OS_APP_HOOK_VOID)0;
  62. #endif

  63. #if OS_CFG_TASK_REG_TBL_SIZE > 0u
  64.     OSTaskRegNextAvailID    = (OS_REG_ID)0;     /* 清零任务寄存器下一个有效 ID */
  65. #endif

  66.     OS_PrioInit();                              /* 初始化优先级位图 */

  67.     OS_RdyListInit();                           /* 初始化就行列表 */

  68.    
  69. #if OS_CFG_FLAG_EN > 0u                         /* 初始化事件标志组 */
  70.     OS_FlagInit(p_err);
  71.     if (*p_err != OS_ERR_NONE) {
  72.         return;
  73.     }
  74. #endif


  75. #if OS_CFG_MEM_EN > 0u                         /* 初始化内存管理 */
  76.     OS_MemInit(p_err);
  77.     if (*p_err != OS_ERR_NONE) {
  78.         return;
  79.     }
  80. #endif


  81. #if (OS_MSG_EN) > 0u                          /* 初始化OS_MSGs空闲列表  */
  82.     OS_MsgPoolInit(p_err);
  83.     if (*p_err != OS_ERR_NONE) {
  84.         return;
  85.     }
  86. #endif


  87. #if OS_CFG_MUTEX_EN > 0u                      /* 初始化互斥信号量 */
  88.     OS_MutexInit(p_err);
  89.     if (*p_err != OS_ERR_NONE) {
  90.         return;
  91.     }
  92. #endif


  93. #if OS_CFG_Q_EN > 0u
  94.     OS_QInit(p_err);                         /* 初始化消息队列 */
  95.     if (*p_err != OS_ERR_NONE) {
  96.         return;
  97.     }
  98. #endif


  99. #if OS_CFG_SEM_EN > 0u                       /* 初始化信号量 */
  100.     OS_SemInit(p_err);
  101.     if (*p_err != OS_ERR_NONE) {
  102.         return;
  103.     }
  104. #endif


  105. #if defined(OS_CFG_TLS_TBL_SIZE) && (OS_CFG_TLS_TBL_SIZE > 0u)
  106.     OS_TLS_Init(p_err);                    /* 创建任务前,初始化 */
  107.     if (*p_err != OS_ERR_NONE) {
  108.         return;
  109.     }
  110. #endif


  111.     OS_TaskInit(p_err);                    /* 初始化任务管理 */
  112.     if (*p_err != OS_ERR_NONE) {
  113.         return;
  114.     }


  115. #if OS_CFG_ISR_POST_DEFERRED_EN > 0u
  116.     OS_IntQTaskInit(p_err);                /* 初始化中断队列管理任务 */
  117.     if (*p_err != OS_ERR_NONE) {
  118.         return;
  119.     }
  120. #endif

  121.    
  122.     OS_IdleTaskInit(p_err);                /* 初始化空闲任务  */
  123.     if (*p_err != OS_ERR_NONE) {
  124.         return;
  125.     }


  126.     OS_TickTaskInit(p_err);                /* 初始化嘀嗒定时器任务 */
  127.     if (*p_err != OS_ERR_NONE) {
  128.         return;
  129.     }


  130. #if OS_CFG_STAT_TASK_EN > 0u               /* 初始化统计任务  */
  131.     OS_StatTaskInit(p_err);
  132.     if (*p_err != OS_ERR_NONE) {
  133.         return;
  134.     }
  135. #endif


  136. #if OS_CFG_TMR_EN > 0u                     /* 初始化定时器管理任务  */
  137.     OS_TmrInit(p_err);
  138.     if (*p_err != OS_ERR_NONE) {
  139.         return;
  140.     }
  141. #endif


  142. #if OS_CFG_DBG_EN > 0u
  143.     OS_Dbg_Init();                          /* OS调试初始化  */
  144. #endif


  145.     OSCfg_Init();                           /* OS配置初始化  */
  146. }
复制代码

1.    如果用户在工程预定义中加入了OS_SAFETY_CRITICAL,那么函数就会执行参数检查功能,如果参数不满足条件的话就会进入安全关键异常OS_SAFETY_CRITICAL_EXCEPTION()。安全关键的代码是需要用户去实现的。

2.    OSIntNestingCtr  用于记录中断嵌套次数,在μCOS-III中使用中断的话,一般采用如下的方式:
void  OS_CPU_SysTickHandler (void)
{
CPU_SR_ALLOC();

CPU_CRITICAL_ENTER();
OSIntNestingCtr++;                                          
CPU_CRITICAL_EXIT();

//添加用户代码

OSIntExit();                                            
}
    也就是说进入中断后,先将OSIntNestingCtr加一,退出的时候再执行减一。为什么要这么做?为了说明这个问题,这里举一个例子,假如有低优先级中断A和高优先级中断B,A中断执行的时候,中断B抢占了A的执行,中断B执行完退出的时候会执行函数OSIntExit();(这个函数最主要的作用就是中断级任务切换)。可以想象,如果没有中断嵌套计数变量,退出高优先级中断B的时候运行函数OSIntExit();有可能会执行中断级任务切换,此时执行任务切换的话就会破换正常的寄存器入栈和出栈顺序,从而使得系统崩溃。其实进入Cortex-M3/M4时代已经不存在这个问题了,因为我们设置PendSV中断为最低的优先级(任务切换是在PendSV中断里面执行的),PendSV中断会在所有其它高优先级中断执行完后才会得到执行。
    为了使得μCOS-III可以适应各种处理器内核和复杂的系统设置,中断嵌套计数还是很有必要的。

3.    当前任务控制块指针OSTCBCurPtr和最高就绪任务的任务控制块指针OSTCBHighRdyPtr都指向了0地址空间。初始为指向0地址空间主要是为了使这两个指针变量都有个初始量。而且方便后面用到这两个指针变量的函数进行检测。

4.    默认安全关键的标志OSSafetyCriticalStartFlag是关闭的。

5.    这里个两个变量:OSSchedRoundRobinEn            = DEF_FALSE;
OSSchedRoundRobinDfltTimeQuanta= OSCfg_TickRate_Hz / 10u;
    是用于配置时间片的,默认时间片调度是关闭的,时间片大小是OSCfg_TickRate_Hz / 10u。这两个关于时间片的配置变量大家一定要记住。

6.    这里是几个钩子函数指针,初始化钩子函数,关于钩子函数,咱们在上期教程有详细讲解。
    函数中还有有很多其它的初始化,我们会在后面再跟大家详细的讲述。


baiyongbin2009 回答时间:2014-12-24 20:07:43
11.4  ucos-III启动

11.4.1      启动
    不像其它RTOS,μCOS-III有一个标准的初始化过程,所以特别建议初学的同学按照这个过程进行初始化,如果不按照这个过程进行初始化,往往会出现莫名其妙的后果,标准的初始化流程如下:
  1. /*
  2. ***********************************************************************************************************
  3. *    函 数 名: main
  4. *    功能说明: 标准c程序入口。
  5. *    形    参:无
  6. *    返 回 值: 无
  7. ***********************************************************************************************************
  8. */
  9. int main(void)
  10. {
  11.     OS_ERR  err;
  12.    
  13.     /* 第一步:初始化系统 */
  14.     OSInit(&err);                                            

  15.     /* 第二步:至少创建一个任务,这里是创建了一个启动任务 */
  16. OSTaskCreate((OS_TCB       *)&AppTaskStartTCB,            
  17.                  (CPU_CHAR     *)"App Task Start",
  18.                  (OS_TASK_PTR   )AppTaskStart,
  19.                  (void         *)0,
  20.                  (OS_PRIO       )APP_CFG_TASK_START_PRIO,
  21.                  (CPU_STK      *)&AppTaskStartStk[0],
  22.                  (CPU_STK_SIZE  )APP_CFG_TASK_START_STK_SIZE / 10,
  23.                  (CPU_STK_SIZE  )APP_CFG_TASK_START_STK_SIZE,
  24.                  (OS_MSG_QTY    )0,
  25.                  (OS_TICK       )0,
  26.                  (void         *)0,
  27.                  (OS_OPT        )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
  28.                  (OS_ERR       *)&err);

  29.     /* 第三步:启动系统 */
  30.     OSStart(&err);                                               
  31.     (void)&err;
  32.    
  33.     return (0);
  34. }

  35. /*
  36. ***********************************************************************************************************
  37. *    函 数 名: AppTaskStart
  38. *    功能说明: 这是一个启动任务,在多任务系统启动后,必须初始化滴答计数器(在BSP_Init中实现)
  39. *    形    参:p_arg 是在创建该任务时传递的形参
  40. *    返 回 值: 无
  41.      优 先 级:2
  42. ***********************************************************************************************************
  43. */
  44. static  void  AppTaskStart (void *p_arg)
  45. {
  46. OS_ERR      err;   
  47.    (void)p_arg;

  48.      /* 第四步:初始化外设驱动 */
  49.      bsp_Init();
  50.      CPU_Init();
  51.      /* 第五步:初始化嘀嗒定时器 */
  52.      BSP_Tick_Init();                     

  53. #if OS_CFG_STAT_TASK_EN > 0u
  54.      OSStatTaskCPUUsageInit(&err);  
  55. #endif

  56. #ifdef CPU_CFG_INT_DIS_MEAS_EN
  57.     CPU_IntDisMeasMaxCurReset();
  58. #endif
  59.                                        
  60.     AppTaskCreate();                                          
  61.     while (1)
  62.      {                                       
  63.          bsp_LedToggle(1);
  64.          OSTimeDly(1000, OS_OPT_TIME_DLY, &err);
  65.     }
  66. }
复制代码
    上面的五部就是标准的初始化流程,一定要按照这个顺序进行,这个流程是官方推荐的。为什么要按照这个流程进行初始化? 随着后面源码的讲解,大家会深刻的领悟到这一点。
11.4.2      启动函数OSStart ()
  1. /*
  2. ***********************************************************************************************************
  3. *                                                 开始多任务
  4. *
  5. * 函数说明: 此函数用开始多任务处理,调用这个函数前一定要先调用OSStart(),然后至少需要创建一个应用任务。
  6. * 形   参: p_err     错误代码指针变量
  7. *                    OS_ERR_FATAL_RETURN    OS已经运行,OSStart()返回。
  8. *                    OS_ERR_OS_RUNNING      OS已经开始运行, 再调用OSStart()无效
  9. * 返 回 值: 无
  10. * 说    明: 1) OSStartHighRdy():
  11. *              a) 然后调用OSTaskSwHook()
  12. *              b) 加载OSTCBHighRdyPtr指向的任务控制块
  13. *              c) 执行任务
  14. *           2) 正常启动OS的话,函数OSStart()是不返回参数的。如果返回的话,会返回致命错误。
  15. ***********************************************************************************************************
  16. */

  17. void  OSStart (OS_ERR  *p_err)
  18. {
  19. #ifdef OS_SAFETY_CRITICAL                                                                           (1)                                                                              
  20.     if (p_err == (OS_ERR *)0) {
  21.         OS_SAFETY_CRITICAL_EXCEPTION();
  22.         return;
  23.     }
  24. #endif

  25.     if (OSRunning == OS_STATE_OS_STOPPED) {                                                         (2)
  26.         OSPrioHighRdy   = OS_PrioGetHighest();            /* 获取需要执行的最高优先级任务 */        (3)
  27.         OSPrioCur       = OSPrioHighRdy;
  28.         OSTCBHighRdyPtr = OSRdyList[OSPrioHighRdy].HeadPtr;                                         (4)
  29.         OSTCBCurPtr     = OSTCBHighRdyPtr;
  30.         OSRunning       = OS_STATE_OS_RUNNING;                                                      (6)
  31.         OSStartHighRdy();                                 /* 开始执行任务切换,执行最高优先级任务 */(7)
  32.        *p_err           = OS_ERR_FATAL_RETURN;            /* 正常不会运行到这里 */                  (8)
  33.     } else {
  34.        *p_err           = OS_ERR_OS_RUNNING;              /* OS已经启动 */                          (9)
  35.     }
  36. }
复制代码

1.     后面大家会看到,只要是供用户调用的函数和部分内部函数里面都会有这个安全关键代码,主要是用来防止错误的输入形参。
2.     前面初始化的时候,设置OSRunning = OS_STATE_OS_STOPPED,所以按照正常的初始化顺序,程序会进入到if语句中。
3.     通过函数OS_PrioGetHighest()可以获得当前需要执行的最高优先级任务,这个会在下期教程跟大家详细讲述。
4.     从任务的就绪链表中获得当前需要执行的最高优先级任务。
5.     设置系统的运行状态为OSRunning = OS_STATE_OS_RUNNING,然后开始μCOS-III多任务的执行。
6.     关于这个函数,咱们在上期教程中有详细的讲解,这个函数执行完就会进入到PendSV中断。
7.     正常情况下程序是不会执行到这里的。
8.     如果系统已经启动了,用户程序要是再次调用这个函数会进入到这里。


baiyongbin2009 回答时间:2014-12-24 20:08:41
11.5  获取系统版本
    有时候我们需要获取系统的版本号,下面就是系统版本的获取函数。这个函数比较简单,特别注意函数注释。
  1. /*
  2. ***********************************************************************************************************
  3. *                                                    获取版本号
  4. *
  5. * 函数说明: 此函数用于获取uC/OS-III的版本号,获取的结果是原版本号乘以了10000,比如版本号是3.01.02,那么获
  6. *           取的结果就是30102.
  7. * 形    参: p_err  错误代码指针变量
  8. * 返 回 值: uC/OS-III的版本号乘以10000.
  9. ***********************************************************************************************************
  10. */

  11. CPU_INT16U  OSVersion (OS_ERR  *p_err)
  12. {
  13. #ifdef OS_SAFETY_CRITICAL
  14.     if (p_err == (OS_ERR *)0) {
  15.         OS_SAFETY_CRITICAL_EXCEPTION();
  16.         return ((CPU_INT16U)0u);
  17.     }
  18. #endif

  19.    *p_err = OS_ERR_NONE;
  20.     return (OS_VERSION);
  21. }
复制代码


baiyongbin2009 回答时间:2014-12-24 20:10:39
11.6  空闲任务
    几乎所有的小型RTOS中都会有一个空闲任务,空闲任务应该属于系统任务,是必须要执行的,用户程序不能将其关闭。不光小型系统中有空闲任务,大型的系统里面也有的,比如XP,下面的截图就是XP中的空闲进程。
11.3.png

    空闲任务主要有以下几个作用:
  l 我们不能让系统一直在执行各个应用任务,这样的话系统利用率就是100%,系统就会一直的超负荷运行,所以空闲任务很有必要。
  l 为了更好的实现低功耗,空闲任务也很有必要,我们可以在空闲任务中实现睡眠,待机等低功耗措施。
11.6.1      创建空闲任务OS_IdleTaskInit ()
  1. /*
  2. ***********************************************************************************************************
  3. *                                               初始化空闲任务
  4. *
  5. * 函数说明: 此函数用于创建
  6. * 形    参: p_err    错误代码指针变量
  7. * 返 回 值: 无
  8. * 说    明: 1) 这个函数属于uC/OS-III内部函数,用户程序不能调用这个函数。
  9. ***********************************************************************************************************
  10. */

  11. void  OS_IdleTaskInit (OS_ERR  *p_err)
  12. {
  13. #ifdef OS_SAFETY_CRITICAL
  14.     if (p_err == (OS_ERR *)0) {
  15.         OS_SAFETY_CRITICAL_EXCEPTION();
  16.         return;
  17.     }
  18. #endif

  19.     OSIdleTaskCtr = (OS_IDLE_CTR)0;
  20.                                            /* ---------------- 创建空闲任务 ---------------- */
  21.     OSTaskCreate((OS_TCB     *)&OSIdleTaskTCB,
  22.                  (CPU_CHAR   *)((void *)"uC/OS-III Idle Task"),
  23.                  (OS_TASK_PTR)OS_IdleTask,
  24.                  (void       *)0,
  25.                  (OS_PRIO     )(OS_CFG_PRIO_MAX - 1u),
  26.                  (CPU_STK    *)OSCfg_IdleTaskStkBasePtr,
  27.                  (CPU_STK_SIZE)OSCfg_IdleTaskStkLimit,
  28.                  (CPU_STK_SIZE)OSCfg_IdleTaskStkSize,
  29.                  (OS_MSG_QTY  )0u,
  30.                  (OS_TICK     )0u,
  31.                  (void       *)0,
  32.                  (OS_OPT      )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR | OS_OPT_TASK_NO_TLS),
  33.                  (OS_ERR     *)p_err);
  34. }
复制代码

    关于任务的创建,本期教程暂时还不做介绍。
11.6.2      空闲任务OS_IdleTask ()
  1. /*
  2. ***********************************************************************************************************
  3. *                                                      空闲任务
  4. *
  5. * 函数说明: uC/OS-III内部任务
  6. * 形    参: p_arg    用于任务创建时传递的参数
  7. * 返 回 值: 无
  8. * 注    意: 1) 空闲任务是uC/OS-III的内部任务,用户程序不能调用它
  9. *           2) 在临界区后面调用OSIdleTaskHook()是为了确保有些处理器在使能中断后需要过几个时钟周期才能真正
  10. *              使能。比如Philip XA
  11. *           3) 用户可以在钩子函数中加入待机,休眠等低功耗操作
  12. ***********************************************************************************************************
  13. */

  14. void  OS_IdleTask (void  *p_arg)
  15. {
  16.     CPU_SR_ALLOC();                                                                               (1)



  17.     p_arg = p_arg;                 /* 防止编译器警告 */                                           (2)

  18.     while (DEF_ON) {                                                                              (3)
  19.         CPU_CRITICAL_ENTER();
  20.         OSIdleTaskCtr++;                                                                          (4)
  21. #if OS_CFG_STAT_TASK_EN > 0u
  22.         OSStatTaskCtr++;                                                                          (5)
  23. #endif
  24.         CPU_CRITICAL_EXIT();

  25.         OSIdleTaskHook();          /* 调用钩子函数 */                                             (6)
  26.     }
  27. }
复制代码

1.    函数CPU_SR_ALLOC()是为CPU_CRITICAL_ENTER()和CPU_CRITICAL_EXIT()申请一个变量:
#define  CPU_SR_ALLOC()           CPU_SR cpu_sr = (CPU_SR)0
这个是临界代码段,在下面一个小节有详细讲解。
2.    这样做是为了防止编译器警告。
3.    μCOS-III中主要有以下布尔宏定义:
宏定义
数值
DEF_FALSE
0u
DEF_TRUE
1u
DEF_NO
0u
DEF_YES
1u
DEF_DISABLED
0u
DEF_ENABLED
1u
DEF_INACTIVE
0u
DEF_ACTIVE
1u
DEF_INVALID
0u
DEF_VALID
1u
DEF_OFF   
0u
DEF_ON
1u
DEF_CLR
0u
DEF_SET   
1u
DEF_FAIL
0u
DEF_OK
1u
4.    空闲任务计数。
5.    统计任务计数,这两个计数都是为了计算CPU利用率。
6.    用户可以在钩子函数中加入待机,休眠等低功耗操作。

baiyongbin2009 回答时间:2014-12-24 20:13:11
本帖最后由 baiyongbin2009 于 2014-12-24 20:14 编辑

11.7  临界段

11.7.1      临界段基本概念
    代码的临界段也称为临界区,指处理时不可分割的代码。一旦这部分代码开始执行,则不允许任何中断打入。为确保临界段代码的执行,在进入临界段之前要关中断,而临界段代码执行完以后要立即开中断。
    从代码上来看,处在关中断和开中断之间的代码段就是临界段。
    由于各厂商的CPU和C编译器的关中断和开中断的方法以及指令不尽相同,为增强μCOS-III的可移植性(即在μCOS-III的各个C语言函数中尽可能地不出现汇编语言代码),μCOS-III用CPU_INT_DIS()和CPU_INT_EN()这两个宏封装了与系统硬件相关的关中断和开中断指令。
    另外,不要在临界段中调用μCOS-III提供的功能函数,防止系统崩溃。
11.7.2      临界段相关的宏定义
    CPU_INT_DIS()和CPU_INT_EN()可以以下四种不同的实现方法。
  1. #define  CPU_CRITICAL_METHOD_NONE                  0u
  2. #define  CPU_CRITICAL_METHOD_INT_DIS_EN            1u
  3. #define  CPU_CRITICAL_METHOD_STATUS_STK            2u
  4. #define  CPU_CRITICAL_METHOD_STATUS_LOCAL          3u
复制代码
    至于在实际应用时使用哪种方法,取决于用户使用的处理器和C编译器。用户可以通过cpu.h文件中的宏定义进行选择:
  1. #define  CPU_CFG_CRITICAL_METHOD    CPU_CRITICAL_METHOD_STATUS_LOCAL

  2. typedef  CPU_INT32U                 CPU_SR;

  3. #if  (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
  4. #define  CPU_SR_ALLOC()             CPU_SR  cpu_sr = (CPU_SR)0
  5. #else
  6. #define  CPU_SR_ALLOC()
  7. #endif



  8. #define  CPU_INT_DIS()         do { cpu_sr = CPU_SR_Save(); } while (0)                                <b>(1)</b>
  9. #define  CPU_INT_EN()          do { CPU_SR_Restore(cpu_sr); } while (0)                               <b> (2)</b>

  10. #ifdef   CPU_CFG_INT_DIS_MEAS_EN

  11. #define  CPU_CRITICAL_ENTER()  do { CPU_INT_DIS();         \
  12. CPU_IntDisMeasStart(); }  while (0)

  13. #define  CPU_CRITICAL_EXIT()   do { CPU_IntDisMeasStop();  \
  14. CPU_INT_EN();          }  while (0)

  15. #else

  16. #define  CPU_CRITICAL_ENTER()  do { CPU_INT_DIS(); } while (0)
  17. #define  CPU_CRITICAL_EXIT()   do { CPU_INT_EN();  } while (0)
  18. #endif
复制代码
1.    当CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN时
    这种方式最简单,即直接使用处理器的开中断和关中断指令来实现宏。但是不推荐使用这种方式,因为不支持中断嵌套,但是考虑到有些处理器或者编译器仅支持这种方式,不得不选择这种方式。
2.    当CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_INT_DIS_EN时
    这种方法稍复杂些,但可使CPU中断使能标志的状态在临界段前和临界段后不发生变化。
    进入临界段前:
         (1) Push/save  中断状态保存到堆栈中
         (2) Disable    关闭中断
    退出临界段:
        (3) Pop/restore  恢复中断标志
3.    当CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL时
    这种方法的前提是,用户使用的C编译器具有扩展功能。用户可获得程序状态字的值,这样就可把该值保存在C函数的局部变量中,而不必压到堆栈里。上面的宏定义就是采用的这种方式,也就是(1),(2)注释的地方。
4.    关于临界段,在文件os.h中也有几个相关的宏定义,这几个宏定义的含义会在后面跟大家讲
#if      OS_CFG_SCHED_LOCK_TIME_MEAS_EN> 0u && defined(CPU_CFG_INT_DIS_MEAS_EN)
#define OS_SCHED_LOCK_TIME_MEAS_START()   OS_SchedLockTimeMeasStart()
#else
#define OS_SCHED_LOCK_TIME_MEAS_START()
#endif


#if     OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u && defined(CPU_CFG_INT_DIS_MEAS_EN)
#define OS_SCHED_LOCK_TIME_MEAS_STOP()    OS_SchedLockTimeMeasStop()
#else
#define OS_SCHED_LOCK_TIME_MEAS_STOP()
#endif

#if OS_CFG_ISR_POST_DEFERRED_EN > 0u                      /* Deferred ISR Posts */
                                                          /* Lock the scheduler */
#define  OS_CRITICAL_ENTER()                                       \
         do {                                                     \
            CPU_CRITICAL_ENTER();                                \
            OSSchedLockNestingCtr++;                              \
             if(OSSchedLockNestingCtr == 1u) {                    \
                OS_SCHED_LOCK_TIME_MEAS_START();                  \
             }                                                     \
            CPU_CRITICAL_EXIT();                                  \
         } while (0)
                                                          /* Lock the scheduler but re-enable interrupts*/
#define  OS_CRITICAL_ENTER_CPU_EXIT()                              \
         do {                                                     \
            OSSchedLockNestingCtr++;                              \
                                                                  \
             if(OSSchedLockNestingCtr == 1u) {                    \
                OS_SCHED_LOCK_TIME_MEAS_START();                  \
             }                                                    \
            CPU_CRITICAL_EXIT();                                 \
         } while (0)

                                                         /* Scheduling occurs only if an interruptoccurs */
#define  OS_CRITICAL_EXIT()                                        \
         do {                                                      \
            CPU_CRITICAL_ENTER();                                 \
            OSSchedLockNestingCtr--;                              \
             if(OSSchedLockNestingCtr == (OS_NESTING_CTR)0) {     \
                 OS_SCHED_LOCK_TIME_MEAS_STOP();                   \
                 if(OSIntQNbrEntries > (OS_OBJ_QTY)0) {           \
                    CPU_CRITICAL_EXIT();                          \
                    OS_Sched0();                                  \
                 } else {                                          \
                    CPU_CRITICAL_EXIT();                          \
                 }                                                \
             } else {                                              \
                CPU_CRITICAL_EXIT();                              \
             }                                                    \
         } while (0)

#define OS_CRITICAL_EXIT_NO_SCHED()                               \
         do {                                                     \
            CPU_CRITICAL_ENTER();                                 \
            OSSchedLockNestingCtr--;                              \
             if(OSSchedLockNestingCtr == (OS_NESTING_CTR)0) {     \
                OS_SCHED_LOCK_TIME_MEAS_STOP();                   \
             }                                                    \
            CPU_CRITICAL_EXIT();                                 \
         } while (0)


#else                                             /* Direct ISR Posts  */


#define  OS_CRITICAL_ENTER()                    CPU_CRITICAL_ENTER()

#define OS_CRITICAL_ENTER_CPU_EXIT()

#define  OS_CRITICAL_EXIT()                     CPU_CRITICAL_EXIT()

#define OS_CRITICAL_EXIT_NO_SCHED()           CPU_CRITICAL_EXIT()

#endif




123下一页

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版