選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 
 

281 行
11 KiB

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