os_time.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. /*
  2. * Copyright (c) 2021, Meco Jianting Man <jiantingman@foxmail.com>
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-09-20 Meco Man first version
  9. */
  10. /*
  11. *********************************************************************************************************
  12. * uC/OS-II
  13. * The Real-Time Kernel
  14. *
  15. * Copyright 1992-2020 Silicon Laboratories Inc. www.silabs.com
  16. *
  17. * SPDX-License-Identifier: APACHE-2.0
  18. *
  19. * This software is subject to an open source license and is distributed by
  20. * Silicon Laboratories Inc. pursuant to the terms of the Apache License,
  21. * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
  22. *
  23. *********************************************************************************************************
  24. */
  25. /*
  26. *********************************************************************************************************
  27. *
  28. * TIME MANAGEMENT
  29. *
  30. * Filename : os_time.c
  31. * Version : V2.93.00
  32. *********************************************************************************************************
  33. */
  34. #include "ucos_ii.h"
  35. /*
  36. *********************************************************************************************************
  37. * DELAY TASK 'n' TICKS
  38. *
  39. * Description: This function is called to delay execution of the currently running task until the
  40. * specified number of system ticks expires. This, of course, directly equates to delaying
  41. * the current task for some time to expire. No delay will result If the specified delay is
  42. * 0. If the specified delay is greater than 0 then, a context switch will result.
  43. *
  44. * Arguments : ticks is the time delay that the task will be suspended in number of clock 'ticks'.
  45. * Note that by specifying 0, the task will not be delayed.
  46. *
  47. * Returns : none
  48. *********************************************************************************************************
  49. */
  50. void OSTimeDly (INT32U ticks)
  51. {
  52. if (OSIntNesting > 0u) { /* See if trying to call from an ISR */
  53. return;
  54. }
  55. if (OSLockNesting > 0u) { /* See if called with scheduler locked */
  56. return;
  57. }
  58. if (ticks > 0u) { /* 0 means no delay! */
  59. rt_thread_delay(ticks);
  60. }
  61. }
  62. /*
  63. *********************************************************************************************************
  64. * DELAY TASK FOR SPECIFIED TIME
  65. *
  66. * Description: This function is called to delay execution of the currently running task until some time
  67. * expires. This call allows you to specify the delay time in HOURS, MINUTES, SECONDS and
  68. * MILLISECONDS instead of ticks.
  69. *
  70. * Arguments : hours specifies the number of hours that the task will be delayed (max. is 255)
  71. * minutes specifies the number of minutes (max. 59)
  72. * seconds specifies the number of seconds (max. 59)
  73. * ms specifies the number of milliseconds (max. 999)
  74. *
  75. * Returns : OS_ERR_NONE
  76. * OS_ERR_TIME_INVALID_MINUTES
  77. * OS_ERR_TIME_INVALID_SECONDS
  78. * OS_ERR_TIME_INVALID_MS
  79. * OS_ERR_TIME_ZERO_DLY
  80. * OS_ERR_TIME_DLY_ISR
  81. *
  82. * Note(s) : The resolution on the milliseconds depends on the tick rate. For example, you can't do
  83. * a 10 mS delay if the ticker interrupts every 100 mS. In this case, the delay would be
  84. * set to 0. The actual delay is rounded to the nearest tick.
  85. *********************************************************************************************************
  86. */
  87. #if OS_TIME_DLY_HMSM_EN > 0u
  88. INT8U OSTimeDlyHMSM (INT8U hours,
  89. INT8U minutes,
  90. INT8U seconds,
  91. INT16U ms)
  92. {
  93. INT32U ticks;
  94. if (OSIntNesting > 0u) { /* See if trying to call from an ISR */
  95. return (OS_ERR_TIME_DLY_ISR);
  96. }
  97. if (OSLockNesting > 0u) { /* See if called with scheduler locked */
  98. return (OS_ERR_SCHED_LOCKED);
  99. }
  100. #if OS_ARG_CHK_EN > 0u
  101. if (hours == 0u) {
  102. if (minutes == 0u) {
  103. if (seconds == 0u) {
  104. if (ms == 0u) {
  105. return (OS_ERR_TIME_ZERO_DLY);
  106. }
  107. }
  108. }
  109. }
  110. if (minutes > 59u) {
  111. return (OS_ERR_TIME_INVALID_MINUTES); /* Validate arguments to be within range */
  112. }
  113. if (seconds > 59u) {
  114. return (OS_ERR_TIME_INVALID_SECONDS);
  115. }
  116. if (ms > 999u) {
  117. return (OS_ERR_TIME_INVALID_MS);
  118. }
  119. #endif
  120. /* Compute the total number of clock ticks required.. */
  121. /* .. (rounded to the nearest tick) */
  122. ticks = ((INT32U)hours * 3600uL + (INT32U)minutes * 60uL + (INT32U)seconds) * OS_TICKS_PER_SEC
  123. + OS_TICKS_PER_SEC * ((INT32U)ms + 500uL / OS_TICKS_PER_SEC) / 1000uL;
  124. OSTimeDly(ticks);
  125. return (OS_ERR_NONE);
  126. }
  127. #endif
  128. /*
  129. *********************************************************************************************************
  130. * RESUME A DELAYED TASK
  131. *
  132. * Description: This function is used resume a task that has been delayed through a call to either
  133. * OSTimeDly() or OSTimeDlyHMSM(). Note that you can call this function to resume a
  134. * task that is waiting for an event with timeout. This would make the task look
  135. * like a timeout occurred.
  136. *
  137. * Arguments : prio specifies the priority of the task to resume
  138. *
  139. * Returns : OS_ERR_NONE Task has been resumed
  140. * OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed
  141. * (i.e. >= OS_LOWEST_PRIO)
  142. * OS_ERR_TIME_NOT_DLY Task is not waiting for time to expire
  143. * OS_ERR_TASK_NOT_EXIST The desired task has not been created or has been assigned to a Mutex.
  144. *********************************************************************************************************
  145. */
  146. #if OS_TIME_DLY_RESUME_EN > 0u
  147. INT8U OSTimeDlyResume (INT8U prio)
  148. {
  149. OS_TCB *ptcb;
  150. #if OS_CRITICAL_METHOD == 3u /* Storage for CPU status register */
  151. OS_CPU_SR cpu_sr = 0u;
  152. #endif
  153. if (prio >= OS_LOWEST_PRIO) {
  154. return (OS_ERR_PRIO_INVALID);
  155. }
  156. OS_ENTER_CRITICAL();
  157. ptcb = OSTCBPrioTbl[prio]; /* Make sure that task exist */
  158. if (ptcb == (OS_TCB *)0) {
  159. OS_EXIT_CRITICAL();
  160. return (OS_ERR_TASK_NOT_EXIST); /* The task does not exist */
  161. }
  162. if (ptcb == OS_TCB_RESERVED) {
  163. OS_EXIT_CRITICAL();
  164. return (OS_ERR_TASK_NOT_EXIST); /* The task does not exist */
  165. }
  166. if (!(ptcb->OSTask.thread_timer.parent.flag
  167. & RT_TIMER_FLAG_ACTIVATED)) { /* See if task is delayed */
  168. OS_EXIT_CRITICAL();
  169. return (OS_ERR_TIME_NOT_DLY); /* Indicate that task was not delayed */
  170. }
  171. #ifndef PKG_USING_UCOSII_WRAPPER_TINY
  172. ptcb->OSTCBDly = 0u; /* Clear the time delay */
  173. #endif
  174. if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) {
  175. ptcb->OSTCBStat &= ~OS_STAT_PEND_ANY; /* Yes, Clear status flag */
  176. ptcb->OSTCBStatPend = OS_STAT_PEND_TO; /* Indicate PEND timeout */
  177. } else {
  178. ptcb->OSTCBStatPend = OS_STAT_PEND_OK;
  179. }
  180. ptcb->OSTask.error = -RT_ETIMEOUT;
  181. rt_thread_resume(&ptcb->OSTask);
  182. rt_schedule();
  183. return (OS_ERR_NONE);
  184. }
  185. #endif
  186. /*
  187. *********************************************************************************************************
  188. * GET CURRENT SYSTEM TIME
  189. *
  190. * Description: This function is used by your application to obtain the current value of the 32-bit
  191. * counter which keeps track of the number of clock ticks.
  192. *
  193. * Arguments : none
  194. *
  195. * Returns : The current value of OSTime
  196. *********************************************************************************************************
  197. */
  198. #if OS_TIME_GET_SET_EN > 0u
  199. INT32U OSTimeGet (void)
  200. {
  201. return rt_tick_get();
  202. }
  203. #endif
  204. /*
  205. *********************************************************************************************************
  206. * SET SYSTEM CLOCK
  207. *
  208. * Description: This function sets the 32-bit counter which keeps track of the number of clock ticks.
  209. *
  210. * Arguments : ticks specifies the new value that OSTime needs to take.
  211. *
  212. * Returns : none
  213. *********************************************************************************************************
  214. */
  215. #if OS_TIME_GET_SET_EN > 0u
  216. void OSTimeSet (INT32U ticks)
  217. {
  218. rt_tick_set(ticks);
  219. }
  220. #endif