os_time.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. /*
  2. *********************************************************************************************************
  3. * uC/OS-III
  4. * The Real-Time Kernel
  5. *
  6. * Copyright 2009-2022 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. * TIME MANAGEMENT
  19. *
  20. * File : os_time.c
  21. * Version : V3.08.02
  22. *********************************************************************************************************
  23. */
  24. #define MICRIUM_SOURCE
  25. #include "os.h"
  26. #ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
  27. const CPU_CHAR *os_time__c = "$Id: $";
  28. #endif
  29. /*
  30. ************************************************************************************************************************
  31. * DELAY TASK 'n' TICKS
  32. *
  33. * Description: This function is called to delay execution of the currently running task until the specified number of
  34. * system ticks expires. This, of course, directly equates to delaying the current task for some time to
  35. * expire. No delay will result if the specified delay is 0. If the specified delay is greater than 0
  36. * then, a context switch will result.
  37. *
  38. * Arguments : dly is a value in 'clock ticks' that the task will either delay for or, the target match value
  39. * of the tick counter (OSTickCtr). Note that specifying 0 means the task is not to delay.
  40. *
  41. * depending on the option argument, the task will wake up when OSTickCtr reaches:
  42. *
  43. * OS_OPT_TIME_DLY : OSTickCtr + dly
  44. * OS_OPT_TIME_TIMEOUT : OSTickCtr + dly
  45. * OS_OPT_TIME_MATCH : dly
  46. * OS_OPT_TIME_PERIODIC : OSTCBCurPtr->TickCtrPrev + dly
  47. *
  48. * opt specifies whether 'dly' represents absolute or relative time; default option marked with *** :
  49. *
  50. * *** OS_OPT_TIME_DLY specifies a relative time from the current value of OSTickCtr.
  51. * OS_OPT_TIME_TIMEOUT same as OS_OPT_TIME_DLY.
  52. * OS_OPT_TIME_MATCH indicates that 'dly' specifies the absolute value that OSTickCtr
  53. * must reach before the task will be resumed.
  54. * OS_OPT_TIME_PERIODIC indicates that 'dly' specifies the periodic value that OSTickCtr
  55. * must reach before the task will be resumed.
  56. *
  57. * p_err is a pointer to a variable that will contain an error code from this call.
  58. *
  59. * OS_ERR_NONE The call was successful and the delay occurred
  60. * OS_ERR_OPT_INVALID If you specified an invalid option for this function
  61. * OS_ERR_OS_NOT_RUNNING If uC/OS-III is not running yet
  62. * OS_ERR_SCHED_LOCKED Can't delay when the scheduler is locked
  63. * OS_ERR_TIME_DLY_ISR If you called this function from an ISR
  64. * OS_ERR_TIME_ZERO_DLY If the effective delay is zero
  65. * OS_ERR_TICK_DISABLED If kernel ticks are disabled
  66. *
  67. * Returns : none
  68. *
  69. * Note(s) : none
  70. ************************************************************************************************************************
  71. */
  72. void OSTimeDly (OS_TICK dly,
  73. OS_OPT opt,
  74. OS_ERR *p_err)
  75. {
  76. #if (OS_CFG_TICK_EN > 0u)
  77. CPU_SR_ALLOC();
  78. #endif
  79. #ifdef OS_SAFETY_CRITICAL
  80. if (p_err == (OS_ERR *)0) {
  81. OS_SAFETY_CRITICAL_EXCEPTION();
  82. return;
  83. }
  84. #endif
  85. #if (OS_CFG_TICK_EN == 0u)
  86. *p_err = OS_ERR_TICK_DISABLED;
  87. return;
  88. #else
  89. #if (OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u)
  90. if (OSIntNestingCtr > 0u) { /* Not allowed to call from an ISR */
  91. *p_err = OS_ERR_TIME_DLY_ISR;
  92. return;
  93. }
  94. #endif
  95. #if (OS_CFG_INVALID_OS_CALLS_CHK_EN > 0u)
  96. if (OSRunning != OS_STATE_OS_RUNNING) { /* Is the kernel running? */
  97. *p_err = OS_ERR_OS_NOT_RUNNING;
  98. return;
  99. }
  100. #endif
  101. if (OSSchedLockNestingCtr > 0u) { /* Can't delay when the scheduler is locked */
  102. *p_err = OS_ERR_SCHED_LOCKED;
  103. return;
  104. }
  105. switch (opt) {
  106. case OS_OPT_TIME_DLY:
  107. case OS_OPT_TIME_TIMEOUT:
  108. case OS_OPT_TIME_PERIODIC:
  109. case OS_OPT_TIME_MATCH:
  110. break;
  111. default:
  112. *p_err = OS_ERR_OPT_INVALID;
  113. return;
  114. }
  115. #if (OS_CFG_TICK_EN > 0u)
  116. CPU_CRITICAL_ENTER();
  117. OS_TickListInsertDly(OSTCBCurPtr,
  118. dly,
  119. opt,
  120. p_err);
  121. if (*p_err != OS_ERR_NONE) {
  122. CPU_CRITICAL_EXIT();
  123. return;
  124. }
  125. OS_RdyListRemove(OSTCBCurPtr); /* Remove current task from ready list */
  126. CPU_CRITICAL_EXIT();
  127. OSSched(); /* Find next task to run! */
  128. #endif
  129. #endif
  130. }
  131. /*
  132. ************************************************************************************************************************
  133. * DELAY TASK FOR SPECIFIED TIME
  134. *
  135. * Description: This function is called to delay execution of the currently running task until some time expires. This
  136. * call allows you to specify the delay time in HOURS, MINUTES, SECONDS and MILLISECONDS instead of ticks.
  137. *
  138. * Arguments : hours specifies the number of hours that the task will be delayed (max. is 999 if the tick rate is
  139. * 1000 Hz or less otherwise, a higher value would overflow a 32-bit unsigned counter).
  140. *
  141. * minutes specifies the number of minutes (max. 59 if 'opt' is OS_OPT_TIME_HMSM_STRICT)
  142. *
  143. * seconds specifies the number of seconds (max. 59 if 'opt' is OS_OPT_TIME_HMSM_STRICT)
  144. *
  145. * milli specifies the number of milliseconds (max. 999 if 'opt' is OS_OPT_TIME_HMSM_STRICT)
  146. *
  147. * opt specifies time delay bit-field options logically OR'd; default options marked with *** :
  148. *
  149. * *** OS_OPT_TIME_DLY specifies a relative time from the current value of OSTickCtr.
  150. * OS_OPT_TIME_TIMEOUT same as OS_OPT_TIME_DLY.
  151. * OS_OPT_TIME_MATCH indicates that the delay specifies the absolute value that OSTickCtr
  152. * must reach before the task will be resumed.
  153. * OS_OPT_TIME_PERIODIC indicates that the delay specifies the periodic value that OSTickCtr
  154. * must reach before the task will be resumed.
  155. *
  156. * *** OS_OPT_TIME_HMSM_STRICT strictly allow only hours (0...99)
  157. * minutes (0...59)
  158. * seconds (0...59)
  159. * milliseconds (0...999)
  160. * OS_OPT_TIME_HMSM_NON_STRICT allow any value of hours (0...999)
  161. * minutes (0...9999)
  162. * seconds (0...65535)
  163. * milliseconds (0...4294967295)
  164. *
  165. * p_err is a pointer to a variable that will receive an error code from this call.
  166. *
  167. * OS_ERR_NONE If the function returns from the desired delay
  168. * OS_ERR_OPT_INVALID If you specified an invalid option for 'opt'
  169. * OS_ERR_OS_NOT_RUNNING If uC/OS-III is not running yet
  170. * OS_ERR_SCHED_LOCKED Can't delay when the scheduler is locked
  171. * OS_ERR_TIME_DLY_ISR If called from an ISR
  172. * OS_ERR_TIME_INVALID_HOURS If you didn't specify a valid value for 'hours'
  173. * OS_ERR_TIME_INVALID_MINUTES If you didn't specify a valid value for 'minutes'
  174. * OS_ERR_TIME_INVALID_SECONDS If you didn't specify a valid value for 'seconds'
  175. * OS_ERR_TIME_INVALID_MILLISECONDS If you didn't specify a valid value for 'milli'
  176. * OS_ERR_TIME_ZERO_DLY If the effective delay is zero
  177. * OS_ERR_TICK_DISABLED If kernel ticks are disabled
  178. *
  179. * Returns : none
  180. *
  181. * Note(s) : 1) The resolution on the milliseconds depends on the tick rate. For example, you can't do a 10 mS delay
  182. * if the ticker interrupts every 100 mS. In this case, the delay would be set to 0. The actual delay
  183. * is rounded to the nearest tick.
  184. *
  185. * 2) Although this function allows you to delay a task for many, many hours, it's not recommended to put
  186. * a task to sleep for that long.
  187. ************************************************************************************************************************
  188. */
  189. #if (OS_CFG_TIME_DLY_HMSM_EN > 0u)
  190. void OSTimeDlyHMSM (CPU_INT16U hours,
  191. CPU_INT16U minutes,
  192. CPU_INT16U seconds,
  193. CPU_INT32U milli,
  194. OS_OPT opt,
  195. OS_ERR *p_err)
  196. {
  197. #if (OS_CFG_TICK_EN > 0u)
  198. #if (OS_CFG_ARG_CHK_EN > 0u)
  199. CPU_BOOLEAN opt_invalid;
  200. CPU_BOOLEAN opt_non_strict;
  201. #endif
  202. OS_OPT opt_time;
  203. OS_RATE_HZ tick_rate;
  204. OS_TICK ticks;
  205. CPU_SR_ALLOC();
  206. #endif
  207. #ifdef OS_SAFETY_CRITICAL
  208. if (p_err == (OS_ERR *)0) {
  209. OS_SAFETY_CRITICAL_EXCEPTION();
  210. return;
  211. }
  212. #endif
  213. #if (OS_CFG_TICK_EN == 0u)
  214. *p_err = OS_ERR_TICK_DISABLED;
  215. return;
  216. #else
  217. #if (OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u)
  218. if (OSIntNestingCtr > 0u) { /* Not allowed to call from an ISR */
  219. *p_err = OS_ERR_TIME_DLY_ISR;
  220. return;
  221. }
  222. #endif
  223. #if (OS_CFG_INVALID_OS_CALLS_CHK_EN > 0u)
  224. if (OSRunning != OS_STATE_OS_RUNNING) { /* Is the kernel running? */
  225. *p_err = OS_ERR_OS_NOT_RUNNING;
  226. return;
  227. }
  228. #endif
  229. if (OSSchedLockNestingCtr > 0u) { /* Can't delay when the scheduler is locked */
  230. *p_err = OS_ERR_SCHED_LOCKED;
  231. return;
  232. }
  233. opt_time = opt & OS_OPT_TIME_MASK; /* Retrieve time options only. */
  234. switch (opt_time) {
  235. case OS_OPT_TIME_DLY:
  236. case OS_OPT_TIME_TIMEOUT:
  237. case OS_OPT_TIME_PERIODIC:
  238. case OS_OPT_TIME_MATCH:
  239. break;
  240. default:
  241. *p_err = OS_ERR_OPT_INVALID;
  242. return;
  243. }
  244. #if (OS_CFG_ARG_CHK_EN > 0u) /* Validate arguments to be within range */
  245. opt_invalid = ((((opt) & (~OS_OPT_TIME_OPTS_MASK)) == 0u) ? (OS_FALSE) : (OS_TRUE));
  246. if (opt_invalid == OS_TRUE) {
  247. *p_err = OS_ERR_OPT_INVALID;
  248. return;
  249. }
  250. opt_non_strict = ((((opt) & (OS_OPT_TIME_HMSM_NON_STRICT)) == 0u) ? (OS_FALSE) : (OS_TRUE));
  251. if (opt_non_strict != OS_TRUE) {
  252. if (milli > 999u) {
  253. *p_err = OS_ERR_TIME_INVALID_MILLISECONDS;
  254. return;
  255. }
  256. if (seconds > 59u) {
  257. *p_err = OS_ERR_TIME_INVALID_SECONDS;
  258. return;
  259. }
  260. if (minutes > 59u) {
  261. *p_err = OS_ERR_TIME_INVALID_MINUTES;
  262. return;
  263. }
  264. if (hours > 99u) {
  265. *p_err = OS_ERR_TIME_INVALID_HOURS;
  266. return;
  267. }
  268. } else {
  269. if (minutes > 9999u) {
  270. *p_err = OS_ERR_TIME_INVALID_MINUTES;
  271. return;
  272. }
  273. if (hours > 999u) {
  274. *p_err = OS_ERR_TIME_INVALID_HOURS;
  275. return;
  276. }
  277. }
  278. #endif
  279. /* Compute the total number of clock ticks required.. */
  280. /* .. (rounded to the nearest tick) */
  281. tick_rate = OSCfg_TickRate_Hz;
  282. ticks = ((((OS_TICK)hours * (OS_TICK)3600u) + ((OS_TICK)minutes * (OS_TICK)60u) + (OS_TICK)seconds) * tick_rate)
  283. + ((tick_rate * ((OS_TICK)milli + ((OS_TICK)500u / tick_rate))) / (OS_TICK)1000u);
  284. CPU_CRITICAL_ENTER();
  285. OS_TickListInsertDly(OSTCBCurPtr,
  286. ticks,
  287. opt_time,
  288. p_err);
  289. if (*p_err != OS_ERR_NONE) {
  290. CPU_CRITICAL_EXIT();
  291. return;
  292. }
  293. OS_RdyListRemove(OSTCBCurPtr); /* Remove current task from ready list */
  294. CPU_CRITICAL_EXIT();
  295. OSSched(); /* Find next task to run! */
  296. #endif
  297. }
  298. #endif
  299. /*
  300. ************************************************************************************************************************
  301. * RESUME A DELAYED TASK
  302. *
  303. * Description: This function is used resume a task that has been delayed through a call to either OSTimeDly() or
  304. * OSTimeDlyHMSM(). Note that you cannot call this function to resume a task that is waiting for an event
  305. * with timeout.
  306. *
  307. * Arguments : p_tcb is a pointer to the TCB of the task to resume.
  308. *
  309. * p_err is a pointer to a variable that will receive an error code
  310. *
  311. * OS_ERR_NONE Task has been resumed
  312. * OS_ERR_OS_NOT_RUNNING If uC/OS-III is not running yet
  313. * OS_ERR_STATE_INVALID Task is in an invalid state
  314. * OS_ERR_TASK_NOT_DLY Task is not waiting for time to expire
  315. * OS_ERR_TASK_SUSPENDED Task cannot be resumed, it was suspended by OSTaskSuspend()
  316. * OS_ERR_TCB_INVALID If 'p_tcb' is a NULL pointer
  317. * OS_ERR_TIME_DLY_RESUME_ISR If called from an ISR
  318. *
  319. * Returns : none
  320. *
  321. * Note(s) : none
  322. ************************************************************************************************************************
  323. */
  324. #if (OS_CFG_TIME_DLY_RESUME_EN > 0u)
  325. void OSTimeDlyResume (OS_TCB *p_tcb,
  326. OS_ERR *p_err)
  327. {
  328. CPU_SR_ALLOC();
  329. #ifdef OS_SAFETY_CRITICAL
  330. if (p_err == (OS_ERR *)0) {
  331. OS_SAFETY_CRITICAL_EXCEPTION();
  332. return;
  333. }
  334. #endif
  335. #if (OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u)
  336. if (OSIntNestingCtr > 0u) { /* Not allowed to call from an ISR */
  337. *p_err = OS_ERR_TIME_DLY_RESUME_ISR;
  338. return;
  339. }
  340. #endif
  341. #if (OS_CFG_ARG_CHK_EN > 0u) /* ---------------- VALIDATE ARGUMENTS ---------------- */
  342. if (p_tcb == (OS_TCB *)0) { /* User must supply a valid OS_TCB */
  343. *p_err = OS_ERR_TCB_INVALID;
  344. return;
  345. }
  346. #endif
  347. #if (OS_CFG_INVALID_OS_CALLS_CHK_EN > 0u)
  348. if (OSRunning != OS_STATE_OS_RUNNING) { /* Is the kernel running? */
  349. *p_err = OS_ERR_OS_NOT_RUNNING;
  350. return;
  351. }
  352. #endif
  353. CPU_CRITICAL_ENTER();
  354. switch (p_tcb->TaskState) {
  355. case OS_TASK_STATE_RDY: /* Cannot Abort delay if task is ready */
  356. case OS_TASK_STATE_PEND:
  357. case OS_TASK_STATE_PEND_TIMEOUT:
  358. case OS_TASK_STATE_SUSPENDED:
  359. case OS_TASK_STATE_PEND_SUSPENDED:
  360. case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
  361. CPU_CRITICAL_EXIT();
  362. *p_err = OS_ERR_TASK_NOT_DLY;
  363. break;
  364. case OS_TASK_STATE_DLY:
  365. p_tcb->TaskState = OS_TASK_STATE_RDY;
  366. #if (OS_CFG_TICK_EN > 0u)
  367. OS_TickListRemove(p_tcb); /* Remove task from tick list */
  368. OS_RdyListInsert(p_tcb); /* Add to ready list */
  369. #endif
  370. CPU_CRITICAL_EXIT();
  371. *p_err = OS_ERR_NONE;
  372. break;
  373. case OS_TASK_STATE_DLY_SUSPENDED:
  374. p_tcb->TaskState = OS_TASK_STATE_SUSPENDED;
  375. #if (OS_CFG_TICK_EN > 0u)
  376. OS_TickListRemove(p_tcb); /* Remove task from tick list */
  377. #endif
  378. CPU_CRITICAL_EXIT();
  379. *p_err = OS_ERR_TASK_SUSPENDED;
  380. break;
  381. default:
  382. CPU_CRITICAL_EXIT();
  383. *p_err = OS_ERR_STATE_INVALID;
  384. break;
  385. }
  386. OSSched();
  387. }
  388. #endif
  389. /*
  390. ************************************************************************************************************************
  391. * GET CURRENT SYSTEM TIME
  392. *
  393. * Description: This function is used by your application to obtain the current value of the counter which keeps track of
  394. * the number of clock ticks.
  395. *
  396. * Arguments : p_err is a pointer to a variable that will receive an error code
  397. *
  398. * OS_ERR_NONE If the call was successful
  399. * OS_ERR_TICK_DISABLED If kernel ticks are disabled
  400. *
  401. * Returns : The current value of OSTickCtr
  402. *
  403. * Note(s) : none
  404. ************************************************************************************************************************
  405. */
  406. OS_TICK OSTimeGet (OS_ERR *p_err)
  407. {
  408. OS_TICK ticks;
  409. #if (OS_CFG_TICK_EN > 0u)
  410. CPU_SR_ALLOC();
  411. #endif
  412. #ifdef OS_SAFETY_CRITICAL
  413. if (p_err == (OS_ERR *)0) {
  414. OS_SAFETY_CRITICAL_EXCEPTION();
  415. return (0u);
  416. }
  417. #endif
  418. #if (OS_CFG_TICK_EN > 0u)
  419. CPU_CRITICAL_ENTER();
  420. #if (OS_CFG_DYN_TICK_EN > 0u)
  421. if (OSRunning == OS_STATE_OS_RUNNING) {
  422. ticks = OSTickCtr + OS_DynTickGet();
  423. } else {
  424. ticks = OSTickCtr;
  425. }
  426. #else
  427. ticks = OSTickCtr;
  428. #endif
  429. CPU_CRITICAL_EXIT();
  430. *p_err = OS_ERR_NONE;
  431. #else
  432. ticks = 0u;
  433. *p_err = OS_ERR_TICK_DISABLED;
  434. #endif
  435. return (ticks);
  436. }
  437. /*
  438. ************************************************************************************************************************
  439. * SET SYSTEM CLOCK
  440. *
  441. * Description: This function sets the counter which keeps track of the number of clock ticks.
  442. *
  443. * Arguments : ticks is the desired tick value
  444. *
  445. * p_err is a pointer to a variable that will receive an error code
  446. *
  447. * OS_ERR_NONE If the call was successful
  448. * OS_ERR_TICK_DISABLED If kernel ticks are disabled
  449. *
  450. * Returns : none
  451. *
  452. * Note(s) : none
  453. ************************************************************************************************************************
  454. */
  455. void OSTimeSet (OS_TICK ticks,
  456. OS_ERR *p_err)
  457. {
  458. #if (OS_CFG_TICK_EN > 0u)
  459. CPU_SR_ALLOC();
  460. #else
  461. (void)ticks;
  462. #endif
  463. #ifdef OS_SAFETY_CRITICAL
  464. if (p_err == (OS_ERR *)0) {
  465. OS_SAFETY_CRITICAL_EXCEPTION();
  466. return;
  467. }
  468. #endif
  469. #if (OS_CFG_TICK_EN > 0u)
  470. CPU_CRITICAL_ENTER();
  471. OSTickCtr = ticks;
  472. OS_TRACE_TICK_INCREMENT(OSTickCtr);
  473. CPU_CRITICAL_EXIT();
  474. *p_err = OS_ERR_NONE;
  475. #else
  476. *p_err = OS_ERR_TICK_DISABLED;
  477. #endif
  478. }
  479. /*
  480. ************************************************************************************************************************
  481. * PROCESS SYSTEM TICK
  482. *
  483. * Description: This function is used to signal to uC/OS-III the occurrence of a 'system tick' (also known as a
  484. * 'clock tick'). This function should be called by the tick ISR.
  485. *
  486. * Arguments : none
  487. *
  488. * Returns : none
  489. *
  490. * Note(s) : none
  491. ************************************************************************************************************************
  492. */
  493. void OSTimeTick (void)
  494. {
  495. if (OSRunning != OS_STATE_OS_RUNNING) {
  496. return;
  497. }
  498. OSTimeTickHook(); /* Call user definable hook */
  499. #if (OS_CFG_SCHED_ROUND_ROBIN_EN > 0u)
  500. OS_SchedRoundRobin(&OSRdyList[OSPrioCur]); /* Update quanta ctr for the task which just ran */
  501. #endif
  502. #if (OS_CFG_TICK_EN > 0u)
  503. OS_TickUpdate(1u); /* Update from the ISR */
  504. #endif
  505. }
  506. /*
  507. ************************************************************************************************************************
  508. * PROCESS SYSTEM TICK (DYNAMIC)
  509. *
  510. * Description: This function is used to signal to uC/OS-III the occurrence of a 'system tick' (also known as a
  511. * 'clock tick'). This function should be called by the tick ISR.
  512. *
  513. * Arguments : none
  514. *
  515. * Returns : none
  516. *
  517. * Note(s) : none
  518. ************************************************************************************************************************
  519. */
  520. #if (OS_CFG_DYN_TICK_EN > 0u)
  521. void OSTimeDynTick (OS_TICK ticks)
  522. {
  523. if (OSRunning != OS_STATE_OS_RUNNING) {
  524. return;
  525. }
  526. OSTimeTickHook();
  527. OS_TickUpdate(ticks); /* Update from the ISR */
  528. }
  529. #endif