os_time.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /*
  2. *********************************************************************************************************
  3. * uC/OS-II
  4. * The Real-Time Kernel
  5. * TIME MANAGEMENT
  6. *
  7. * (c) Copyright 1992-2009, Micrium, Weston, FL
  8. * All Rights Reserved
  9. *
  10. * File : OS_TIME.C
  11. * By : Jean J. Labrosse
  12. * Version : V2.91
  13. *
  14. * LICENSING TERMS:
  15. * ---------------
  16. * uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research.
  17. * If you plan on using uC/OS-II in a commercial product you need to contact Micriµm to properly license
  18. * its use in your product. We provide ALL the source code for your convenience and to help you experience
  19. * uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a
  20. * licensing fee.
  21. *********************************************************************************************************
  22. */
  23. #ifndef OS_MASTER_FILE
  24. #include <ucos_ii.h>
  25. #endif
  26. /*
  27. *********************************************************************************************************
  28. * DELAY TASK 'n' TICKS
  29. *
  30. * Description: This function is called to delay execution of the currently running task until the
  31. * specified number of system ticks expires. This, of course, directly equates to delaying
  32. * the current task for some time to expire. No delay will result If the specified delay is
  33. * 0. If the specified delay is greater than 0 then, a context switch will result.
  34. *
  35. * Arguments : ticks is the time delay that the task will be suspended in number of clock 'ticks'.
  36. * Note that by specifying 0, the task will not be delayed.
  37. *
  38. * Returns : none
  39. *********************************************************************************************************
  40. */
  41. void OSTimeDly (INT32U ticks)
  42. {
  43. INT8U y;
  44. #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
  45. OS_CPU_SR cpu_sr = 0u;
  46. #endif
  47. if (OSIntNesting > 0u) { /* See if trying to call from an ISR */
  48. return;
  49. }
  50. if (OSLockNesting > 0u) { /* See if called with scheduler locked */
  51. return;
  52. }
  53. if (ticks > 0u) { /* 0 means no delay! */
  54. OS_ENTER_CRITICAL();
  55. y = OSTCBCur->OSTCBY; /* Delay current task */
  56. OSRdyTbl[y] &= (OS_PRIO)~OSTCBCur->OSTCBBitX;
  57. if (OSRdyTbl[y] == 0u) {
  58. OSRdyGrp &= (OS_PRIO)~OSTCBCur->OSTCBBitY;
  59. }
  60. OSTCBCur->OSTCBDly = ticks; /* Load ticks in TCB */
  61. OS_EXIT_CRITICAL();
  62. OS_Sched(); /* Find next task to run! */
  63. }
  64. }
  65. /*$PAGE*/
  66. /*
  67. *********************************************************************************************************
  68. * DELAY TASK FOR SPECIFIED TIME
  69. *
  70. * Description: This function is called to delay execution of the currently running task until some time
  71. * expires. This call allows you to specify the delay time in HOURS, MINUTES, SECONDS and
  72. * MILLISECONDS instead of ticks.
  73. *
  74. * Arguments : hours specifies the number of hours that the task will be delayed (max. is 255)
  75. * minutes specifies the number of minutes (max. 59)
  76. * seconds specifies the number of seconds (max. 59)
  77. * ms specifies the number of milliseconds (max. 999)
  78. *
  79. * Returns : OS_ERR_NONE
  80. * OS_ERR_TIME_INVALID_MINUTES
  81. * OS_ERR_TIME_INVALID_SECONDS
  82. * OS_ERR_TIME_INVALID_MS
  83. * OS_ERR_TIME_ZERO_DLY
  84. * OS_ERR_TIME_DLY_ISR
  85. *
  86. * Note(s) : The resolution on the milliseconds depends on the tick rate. For example, you can't do
  87. * a 10 mS delay if the ticker interrupts every 100 mS. In this case, the delay would be
  88. * set to 0. The actual delay is rounded to the nearest tick.
  89. *********************************************************************************************************
  90. */
  91. #if OS_TIME_DLY_HMSM_EN > 0u
  92. INT8U OSTimeDlyHMSM (INT8U hours,
  93. INT8U minutes,
  94. INT8U seconds,
  95. INT16U ms)
  96. {
  97. INT32U ticks;
  98. if (OSIntNesting > 0u) { /* See if trying to call from an ISR */
  99. return (OS_ERR_TIME_DLY_ISR);
  100. }
  101. if (OSLockNesting > 0u) { /* See if called with scheduler locked */
  102. return (OS_ERR_SCHED_LOCKED);
  103. }
  104. #if OS_ARG_CHK_EN > 0u
  105. if (hours == 0u) {
  106. if (minutes == 0u) {
  107. if (seconds == 0u) {
  108. if (ms == 0u) {
  109. return (OS_ERR_TIME_ZERO_DLY);
  110. }
  111. }
  112. }
  113. }
  114. if (minutes > 59u) {
  115. return (OS_ERR_TIME_INVALID_MINUTES); /* Validate arguments to be within range */
  116. }
  117. if (seconds > 59u) {
  118. return (OS_ERR_TIME_INVALID_SECONDS);
  119. }
  120. if (ms > 999u) {
  121. return (OS_ERR_TIME_INVALID_MS);
  122. }
  123. #endif
  124. /* Compute the total number of clock ticks required.. */
  125. /* .. (rounded to the nearest tick) */
  126. ticks = ((INT32U)hours * 3600uL + (INT32U)minutes * 60uL + (INT32U)seconds) * OS_TICKS_PER_SEC
  127. + OS_TICKS_PER_SEC * ((INT32U)ms + 500uL / OS_TICKS_PER_SEC) / 1000uL;
  128. OSTimeDly(ticks);
  129. return (OS_ERR_NONE);
  130. }
  131. #endif
  132. /*$PAGE*/
  133. /*
  134. *********************************************************************************************************
  135. * RESUME A DELAYED TASK
  136. *
  137. * Description: This function is used resume a task that has been delayed through a call to either
  138. * OSTimeDly() or OSTimeDlyHMSM(). Note that you can call this function to resume a
  139. * task that is waiting for an event with timeout. This would make the task look
  140. * like a timeout occurred.
  141. *
  142. * Arguments : prio specifies the priority of the task to resume
  143. *
  144. * Returns : OS_ERR_NONE Task has been resumed
  145. * OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed
  146. * (i.e. >= OS_LOWEST_PRIO)
  147. * OS_ERR_TIME_NOT_DLY Task is not waiting for time to expire
  148. * OS_ERR_TASK_NOT_EXIST The desired task has not been created or has been assigned to a Mutex.
  149. *********************************************************************************************************
  150. */
  151. #if OS_TIME_DLY_RESUME_EN > 0u
  152. INT8U OSTimeDlyResume (INT8U prio)
  153. {
  154. OS_TCB *ptcb;
  155. #if OS_CRITICAL_METHOD == 3u /* Storage for CPU status register */
  156. OS_CPU_SR cpu_sr = 0u;
  157. #endif
  158. if (prio >= OS_LOWEST_PRIO) {
  159. return (OS_ERR_PRIO_INVALID);
  160. }
  161. OS_ENTER_CRITICAL();
  162. ptcb = OSTCBPrioTbl[prio]; /* Make sure that task exist */
  163. if (ptcb == (OS_TCB *)0) {
  164. OS_EXIT_CRITICAL();
  165. return (OS_ERR_TASK_NOT_EXIST); /* The task does not exist */
  166. }
  167. if (ptcb == OS_TCB_RESERVED) {
  168. OS_EXIT_CRITICAL();
  169. return (OS_ERR_TASK_NOT_EXIST); /* The task does not exist */
  170. }
  171. if (ptcb->OSTCBDly == 0u) { /* See if task is delayed */
  172. OS_EXIT_CRITICAL();
  173. return (OS_ERR_TIME_NOT_DLY); /* Indicate that task was not delayed */
  174. }
  175. ptcb->OSTCBDly = 0u; /* Clear the time delay */
  176. if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) {
  177. ptcb->OSTCBStat &= ~OS_STAT_PEND_ANY; /* Yes, Clear status flag */
  178. ptcb->OSTCBStatPend = OS_STAT_PEND_TO; /* Indicate PEND timeout */
  179. } else {
  180. ptcb->OSTCBStatPend = OS_STAT_PEND_OK;
  181. }
  182. if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) { /* Is task suspended? */
  183. OSRdyGrp |= ptcb->OSTCBBitY; /* No, Make ready */
  184. OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
  185. OS_EXIT_CRITICAL();
  186. OS_Sched(); /* See if this is new highest priority */
  187. } else {
  188. OS_EXIT_CRITICAL(); /* Task may be suspended */
  189. }
  190. return (OS_ERR_NONE);
  191. }
  192. #endif
  193. /*$PAGE*/
  194. /*
  195. *********************************************************************************************************
  196. * GET CURRENT SYSTEM TIME
  197. *
  198. * Description: This function is used by your application to obtain the current value of the 32-bit
  199. * counter which keeps track of the number of clock ticks.
  200. *
  201. * Arguments : none
  202. *
  203. * Returns : The current value of OSTime
  204. *********************************************************************************************************
  205. */
  206. #if OS_TIME_GET_SET_EN > 0u
  207. INT32U OSTimeGet (void)
  208. {
  209. INT32U ticks;
  210. #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
  211. OS_CPU_SR cpu_sr = 0u;
  212. #endif
  213. OS_ENTER_CRITICAL();
  214. ticks = OSTime;
  215. OS_EXIT_CRITICAL();
  216. return (ticks);
  217. }
  218. #endif
  219. /*
  220. *********************************************************************************************************
  221. * SET SYSTEM CLOCK
  222. *
  223. * Description: This function sets the 32-bit counter which keeps track of the number of clock ticks.
  224. *
  225. * Arguments : ticks specifies the new value that OSTime needs to take.
  226. *
  227. * Returns : none
  228. *********************************************************************************************************
  229. */
  230. #if OS_TIME_GET_SET_EN > 0u
  231. void OSTimeSet (INT32U ticks)
  232. {
  233. #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
  234. OS_CPU_SR cpu_sr = 0u;
  235. #endif
  236. OS_ENTER_CRITICAL();
  237. OSTime = ticks;
  238. OS_EXIT_CRITICAL();
  239. }
  240. #endif