os_time.c 11 KB

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