PageRenderTime 57ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/src/compiler/ucos-vs2008/UCOS_SIM/src/ucosii/os_flag.c

http://ftk.googlecode.com/
C | 1146 lines | 684 code | 78 blank | 384 comment | 168 complexity | a63cb391c7b63d8ecbd98fd475c6e1e4 MD5 | raw file
Possible License(s): LGPL-3.0
  1. /*
  2. *********************************************************************************************************
  3. * uC/OS-II
  4. * The Real-Time Kernel
  5. * EVENT FLAG MANAGEMENT
  6. *
  7. * (c) Copyright 2001-2005, Jean J. Labrosse, Weston, FL
  8. * All Rights Reserved
  9. *
  10. * File : OS_FLAG.C
  11. * By : Jean J. Labrosse
  12. * Version : V2.80
  13. *********************************************************************************************************
  14. */
  15. #ifndef OS_MASTER_FILE
  16. #include <ucos_ii.h>
  17. #endif
  18. #if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
  19. /*
  20. *********************************************************************************************************
  21. * LOCAL PROTOTYPES
  22. *********************************************************************************************************
  23. */
  24. static void OS_FlagBlock(OS_FLAG_GRP *pgrp, OS_FLAG_NODE *pnode, OS_FLAGS flags, INT8U wait_type, INT16U timeout);
  25. static BOOLEAN OS_FlagTaskRdy(OS_FLAG_NODE *pnode, OS_FLAGS flags_rdy);
  26. /*$PAGE*/
  27. /*
  28. *********************************************************************************************************
  29. * CHECK THE STATUS OF FLAGS IN AN EVENT FLAG GROUP
  30. *
  31. * Description: This function is called to check the status of a combination of bits to be set or cleared
  32. * in an event flag group. Your application can check for ANY bit to be set/cleared or ALL
  33. * bits to be set/cleared.
  34. *
  35. * This call does not block if the desired flags are not present.
  36. *
  37. * Arguments : pgrp is a pointer to the desired event flag group.
  38. *
  39. * flags Is a bit pattern indicating which bit(s) (i.e. flags) you wish to check.
  40. * The bits you want are specified by setting the corresponding bits in
  41. * 'flags'. e.g. if your application wants to wait for bits 0 and 1 then
  42. * 'flags' would contain 0x03.
  43. *
  44. * wait_type specifies whether you want ALL bits to be set/cleared or ANY of the bits
  45. * to be set/cleared.
  46. * You can specify the following argument:
  47. *
  48. * OS_FLAG_WAIT_CLR_ALL You will check ALL bits in 'flags' to be clear (0)
  49. * OS_FLAG_WAIT_CLR_ANY You will check ANY bit in 'flags' to be clear (0)
  50. * OS_FLAG_WAIT_SET_ALL You will check ALL bits in 'flags' to be set (1)
  51. * OS_FLAG_WAIT_SET_ANY You will check ANY bit in 'flags' to be set (1)
  52. *
  53. * NOTE: Add OS_FLAG_CONSUME if you want the event flag to be 'consumed' by
  54. * the call. Example, to wait for any flag in a group AND then clear
  55. * the flags that are present, set 'wait_type' to:
  56. *
  57. * OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME
  58. *
  59. * err is a pointer to an error code and can be:
  60. * OS_NO_ERR No error
  61. * OS_ERR_EVENT_TYPE You are not pointing to an event flag group
  62. * OS_FLAG_ERR_WAIT_TYPE You didn't specify a proper 'wait_type' argument.
  63. * OS_FLAG_INVALID_PGRP You passed a NULL pointer instead of the event flag
  64. * group handle.
  65. * OS_FLAG_ERR_NOT_RDY The desired flags you are waiting for are not
  66. * available.
  67. *
  68. * Returns : The flags in the event flag group that made the task ready or, 0 if a timeout or an error
  69. * occurred.
  70. *
  71. * Called from: Task or ISR
  72. *
  73. * Note(s) : 1) IMPORTANT, the behavior of this function has changed from PREVIOUS versions. The
  74. * function NOW returns the flags that were ready INSTEAD of the current state of the
  75. * event flags.
  76. *********************************************************************************************************
  77. */
  78. #if OS_FLAG_ACCEPT_EN > 0
  79. OS_FLAGS OSFlagAccept (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U wait_type, INT8U *err)
  80. {
  81. OS_FLAGS flags_rdy;
  82. INT8U result;
  83. BOOLEAN consume;
  84. #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
  85. OS_CPU_SR cpu_sr = 0;
  86. #endif
  87. #if OS_ARG_CHK_EN > 0
  88. if (err == (INT8U *)0) { /* Validate 'err' */
  89. return ((OS_FLAGS)0);
  90. }
  91. if (pgrp == (OS_FLAG_GRP *)0) { /* Validate 'pgrp' */
  92. *err = OS_FLAG_INVALID_PGRP;
  93. return ((OS_FLAGS)0);
  94. }
  95. #endif
  96. if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Validate event block type */
  97. *err = OS_ERR_EVENT_TYPE;
  98. return ((OS_FLAGS)0);
  99. }
  100. result = wait_type & OS_FLAG_CONSUME;
  101. if (result != (INT8U)0) { /* See if we need to consume the flags */
  102. wait_type &= ~OS_FLAG_CONSUME;
  103. consume = TRUE;
  104. } else {
  105. consume = FALSE;
  106. }
  107. /*$PAGE*/
  108. *err = OS_NO_ERR; /* Assume NO error until proven otherwise. */
  109. OS_ENTER_CRITICAL();
  110. switch (wait_type) {
  111. case OS_FLAG_WAIT_SET_ALL: /* See if all required flags are set */
  112. flags_rdy = pgrp->OSFlagFlags & flags; /* Extract only the bits we want */
  113. if (flags_rdy == flags) { /* Must match ALL the bits that we want */
  114. if (consume == TRUE) { /* See if we need to consume the flags */
  115. pgrp->OSFlagFlags &= ~flags_rdy; /* Clear ONLY the flags that we wanted */
  116. }
  117. } else {
  118. *err = OS_FLAG_ERR_NOT_RDY;
  119. }
  120. OS_EXIT_CRITICAL();
  121. break;
  122. case OS_FLAG_WAIT_SET_ANY:
  123. flags_rdy = pgrp->OSFlagFlags & flags; /* Extract only the bits we want */
  124. if (flags_rdy != (OS_FLAGS)0) { /* See if any flag set */
  125. if (consume == TRUE) { /* See if we need to consume the flags */
  126. pgrp->OSFlagFlags &= ~flags_rdy; /* Clear ONLY the flags that we got */
  127. }
  128. } else {
  129. *err = OS_FLAG_ERR_NOT_RDY;
  130. }
  131. OS_EXIT_CRITICAL();
  132. break;
  133. #if OS_FLAG_WAIT_CLR_EN > 0
  134. case OS_FLAG_WAIT_CLR_ALL: /* See if all required flags are cleared */
  135. flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & flags; /* Extract only the bits we want */
  136. if (flags_rdy == flags) { /* Must match ALL the bits that we want */
  137. if (consume == TRUE) { /* See if we need to consume the flags */
  138. pgrp->OSFlagFlags |= flags_rdy; /* Set ONLY the flags that we wanted */
  139. }
  140. } else {
  141. *err = OS_FLAG_ERR_NOT_RDY;
  142. }
  143. OS_EXIT_CRITICAL();
  144. break;
  145. case OS_FLAG_WAIT_CLR_ANY:
  146. flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & flags; /* Extract only the bits we want */
  147. if (flags_rdy != (OS_FLAGS)0) { /* See if any flag cleared */
  148. if (consume == TRUE) { /* See if we need to consume the flags */
  149. pgrp->OSFlagFlags |= flags_rdy; /* Set ONLY the flags that we got */
  150. }
  151. } else {
  152. *err = OS_FLAG_ERR_NOT_RDY;
  153. }
  154. OS_EXIT_CRITICAL();
  155. break;
  156. #endif
  157. default:
  158. OS_EXIT_CRITICAL();
  159. flags_rdy = (OS_FLAGS)0;
  160. *err = OS_FLAG_ERR_WAIT_TYPE;
  161. break;
  162. }
  163. return (flags_rdy);
  164. }
  165. #endif
  166. /*$PAGE*/
  167. /*
  168. *********************************************************************************************************
  169. * CREATE AN EVENT FLAG
  170. *
  171. * Description: This function is called to create an event flag group.
  172. *
  173. * Arguments : flags Contains the initial value to store in the event flag group.
  174. *
  175. * err is a pointer to an error code which will be returned to your application:
  176. * OS_NO_ERR if the call was successful.
  177. * OS_ERR_CREATE_ISR if you attempted to create an Event Flag from an
  178. * ISR.
  179. * OS_FLAG_GRP_DEPLETED if there are no more event flag groups
  180. *
  181. * Returns : A pointer to an event flag group or a NULL pointer if no more groups are available.
  182. *
  183. * Called from: Task ONLY
  184. *********************************************************************************************************
  185. */
  186. OS_FLAG_GRP *OSFlagCreate (OS_FLAGS flags, INT8U *err)
  187. {
  188. OS_FLAG_GRP *pgrp;
  189. #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
  190. OS_CPU_SR cpu_sr = 0;
  191. #endif
  192. #if OS_ARG_CHK_EN > 0
  193. if (err == (INT8U *)0) { /* Validate 'err' */
  194. return ((OS_FLAG_GRP *)0);
  195. }
  196. #endif
  197. if (OSIntNesting > 0) { /* See if called from ISR ... */
  198. *err = OS_ERR_CREATE_ISR; /* ... can't CREATE from an ISR */
  199. return ((OS_FLAG_GRP *)0);
  200. }
  201. OS_ENTER_CRITICAL();
  202. pgrp = OSFlagFreeList; /* Get next free event flag */
  203. if (pgrp != (OS_FLAG_GRP *)0) { /* See if we have event flag groups available */
  204. /* Adjust free list */
  205. OSFlagFreeList = (OS_FLAG_GRP *)OSFlagFreeList->OSFlagWaitList;
  206. pgrp->OSFlagType = OS_EVENT_TYPE_FLAG; /* Set to event flag group type */
  207. pgrp->OSFlagFlags = flags; /* Set to desired initial value */
  208. pgrp->OSFlagWaitList = (void *)0; /* Clear list of tasks waiting on flags */
  209. #if OS_FLAG_NAME_SIZE > 1
  210. pgrp->OSFlagName[0] = '?';
  211. pgrp->OSFlagName[1] = OS_ASCII_NUL;
  212. #endif
  213. OS_EXIT_CRITICAL();
  214. *err = OS_NO_ERR;
  215. } else {
  216. OS_EXIT_CRITICAL();
  217. *err = OS_FLAG_GRP_DEPLETED;
  218. }
  219. return (pgrp); /* Return pointer to event flag group */
  220. }
  221. /*$PAGE*/
  222. /*
  223. *********************************************************************************************************
  224. * DELETE AN EVENT FLAG GROUP
  225. *
  226. * Description: This function deletes an event flag group and readies all tasks pending on the event flag
  227. * group.
  228. *
  229. * Arguments : pgrp is a pointer to the desired event flag group.
  230. *
  231. * opt determines delete options as follows:
  232. * opt == OS_DEL_NO_PEND Deletes the event flag group ONLY if no task pending
  233. * opt == OS_DEL_ALWAYS Deletes the event flag group even if tasks are
  234. * waiting. In this case, all the tasks pending will be
  235. * readied.
  236. *
  237. * err is a pointer to an error code that can contain one of the following values:
  238. * OS_NO_ERR The call was successful and the event flag group was
  239. * deleted
  240. * OS_ERR_DEL_ISR If you attempted to delete the event flag group from
  241. * an ISR
  242. * OS_FLAG_INVALID_PGRP If 'pgrp' is a NULL pointer.
  243. * OS_ERR_EVENT_TYPE If you didn't pass a pointer to an event flag group
  244. * OS_ERR_INVALID_OPT An invalid option was specified
  245. * OS_ERR_TASK_WAITING One or more tasks were waiting on the event flag
  246. * group.
  247. *
  248. * Returns : pgrp upon error
  249. * (OS_EVENT *)0 if the event flag group was successfully deleted.
  250. *
  251. * Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of
  252. * the event flag group MUST check the return code of OSFlagAccept() and OSFlagPend().
  253. * 2) This call can potentially disable interrupts for a long time. The interrupt disable
  254. * time is directly proportional to the number of tasks waiting on the event flag group.
  255. *********************************************************************************************************
  256. */
  257. #if OS_FLAG_DEL_EN > 0
  258. OS_FLAG_GRP *OSFlagDel (OS_FLAG_GRP *pgrp, INT8U opt, INT8U *err)
  259. {
  260. BOOLEAN tasks_waiting;
  261. OS_FLAG_NODE *pnode;
  262. OS_FLAG_GRP *pgrp_return;
  263. #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
  264. OS_CPU_SR cpu_sr = 0;
  265. #endif
  266. #if OS_ARG_CHK_EN > 0
  267. if (err == (INT8U *)0) { /* Validate 'err' */
  268. return (pgrp);
  269. }
  270. if (pgrp == (OS_FLAG_GRP *)0) { /* Validate 'pgrp' */
  271. *err = OS_FLAG_INVALID_PGRP;
  272. return (pgrp);
  273. }
  274. #endif
  275. if (OSIntNesting > 0) { /* See if called from ISR ... */
  276. *err = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */
  277. return (pgrp);
  278. }
  279. if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Validate event group type */
  280. *err = OS_ERR_EVENT_TYPE;
  281. return (pgrp);
  282. }
  283. OS_ENTER_CRITICAL();
  284. if (pgrp->OSFlagWaitList != (void *)0) { /* See if any tasks waiting on event flags */
  285. tasks_waiting = TRUE; /* Yes */
  286. } else {
  287. tasks_waiting = FALSE; /* No */
  288. }
  289. switch (opt) {
  290. case OS_DEL_NO_PEND: /* Delete group if no task waiting */
  291. if (tasks_waiting == FALSE) {
  292. #if OS_FLAG_NAME_SIZE > 1
  293. pgrp->OSFlagName[0] = '?'; /* Unknown name */
  294. pgrp->OSFlagName[1] = OS_ASCII_NUL;
  295. #endif
  296. pgrp->OSFlagType = OS_EVENT_TYPE_UNUSED;
  297. pgrp->OSFlagWaitList = (void *)OSFlagFreeList; /* Return group to free list */
  298. pgrp->OSFlagFlags = (OS_FLAGS)0;
  299. OSFlagFreeList = pgrp;
  300. OS_EXIT_CRITICAL();
  301. *err = OS_NO_ERR;
  302. pgrp_return = (OS_FLAG_GRP *)0; /* Event Flag Group has been deleted */
  303. } else {
  304. OS_EXIT_CRITICAL();
  305. *err = OS_ERR_TASK_WAITING;
  306. pgrp_return = pgrp;
  307. }
  308. break;
  309. case OS_DEL_ALWAYS: /* Always delete the event flag group */
  310. pnode = (OS_FLAG_NODE *)pgrp->OSFlagWaitList;
  311. while (pnode != (OS_FLAG_NODE *)0) { /* Ready ALL tasks waiting for flags */
  312. (void)OS_FlagTaskRdy(pnode, (OS_FLAGS)0);
  313. pnode = (OS_FLAG_NODE *)pnode->OSFlagNodeNext;
  314. }
  315. #if OS_FLAG_NAME_SIZE > 1
  316. pgrp->OSFlagName[0] = '?'; /* Unknown name */
  317. pgrp->OSFlagName[1] = OS_ASCII_NUL;
  318. #endif
  319. pgrp->OSFlagType = OS_EVENT_TYPE_UNUSED;
  320. pgrp->OSFlagWaitList = (void *)OSFlagFreeList;/* Return group to free list */
  321. pgrp->OSFlagFlags = (OS_FLAGS)0;
  322. OSFlagFreeList = pgrp;
  323. OS_EXIT_CRITICAL();
  324. if (tasks_waiting == TRUE) { /* Reschedule only if task(s) were waiting */
  325. OS_Sched(); /* Find highest priority task ready to run */
  326. }
  327. *err = OS_NO_ERR;
  328. pgrp_return = (OS_FLAG_GRP *)0; /* Event Flag Group has been deleted */
  329. break;
  330. default:
  331. OS_EXIT_CRITICAL();
  332. *err = OS_ERR_INVALID_OPT;
  333. pgrp_return = pgrp;
  334. break;
  335. }
  336. return (pgrp_return);
  337. }
  338. #endif
  339. /*$PAGE*/
  340. /*
  341. *********************************************************************************************************
  342. * GET THE NAME OF AN EVENT FLAG GROUP
  343. *
  344. * Description: This function is used to obtain the name assigned to an event flag group
  345. *
  346. * Arguments : pgrp is a pointer to the event flag group.
  347. *
  348. * pname is a pointer to an ASCII string that will receive the name of the event flag
  349. * group. The string must be able to hold at least OS_FLAG_NAME_SIZE characters.
  350. *
  351. * err is a pointer to an error code that can contain one of the following values:
  352. *
  353. * OS_NO_ERR if the requested task is resumed
  354. * OS_ERR_EVENT_TYPE if 'pevent' is not pointing to an event flag group
  355. * OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname'
  356. * OS_FLAG_INVALID_PGRP if you passed a NULL pointer for 'pgrp'
  357. *
  358. * Returns : The length of the string or 0 if the 'pgrp' is a NULL pointer.
  359. *********************************************************************************************************
  360. */
  361. #if OS_FLAG_NAME_SIZE > 1
  362. INT8U OSFlagNameGet (OS_FLAG_GRP *pgrp, INT8U *pname, INT8U *err)
  363. {
  364. INT8U len;
  365. #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
  366. OS_CPU_SR cpu_sr = 0;
  367. #endif
  368. OS_ENTER_CRITICAL();
  369. #if OS_ARG_CHK_EN > 0
  370. if (err == (INT8U *)0) { /* Validate 'err' */
  371. OS_EXIT_CRITICAL();
  372. return (0);
  373. }
  374. if (pgrp == (OS_FLAG_GRP *)0) { /* Is 'pgrp' a NULL pointer? */
  375. OS_EXIT_CRITICAL(); /* Yes */
  376. *err = OS_FLAG_INVALID_PGRP;
  377. return (0);
  378. }
  379. if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */
  380. OS_EXIT_CRITICAL(); /* Yes */
  381. *err = OS_ERR_PNAME_NULL;
  382. return (0);
  383. }
  384. #endif
  385. if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) {
  386. OS_EXIT_CRITICAL();
  387. *err = OS_ERR_EVENT_TYPE;
  388. return (0);
  389. }
  390. len = OS_StrCopy(pname, pgrp->OSFlagName); /* Copy name from OS_FLAG_GRP */
  391. OS_EXIT_CRITICAL();
  392. *err = OS_NO_ERR;
  393. return (len);
  394. }
  395. #endif
  396. /*$PAGE*/
  397. /*
  398. *********************************************************************************************************
  399. * ASSIGN A NAME TO AN EVENT FLAG GROUP
  400. *
  401. * Description: This function assigns a name to an event flag group.
  402. *
  403. * Arguments : pgrp is a pointer to the event flag group.
  404. *
  405. * pname is a pointer to an ASCII string that will be used as the name of the event flag
  406. * group. The string must be able to hold at least OS_FLAG_NAME_SIZE characters.
  407. *
  408. * err is a pointer to an error code that can contain one of the following values:
  409. *
  410. * OS_NO_ERR if the requested task is resumed
  411. * OS_ERR_EVENT_TYPE if 'pevent' is not pointing to an event flag group
  412. * OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname'
  413. * OS_FLAG_INVALID_PGRP if you passed a NULL pointer for 'pgrp'
  414. *
  415. * Returns : None
  416. *********************************************************************************************************
  417. */
  418. #if OS_FLAG_NAME_SIZE > 1
  419. void OSFlagNameSet (OS_FLAG_GRP *pgrp, INT8U *pname, INT8U *err)
  420. {
  421. INT8U len;
  422. #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
  423. OS_CPU_SR cpu_sr = 0;
  424. #endif
  425. OS_ENTER_CRITICAL();
  426. #if OS_ARG_CHK_EN > 0
  427. if (err == (INT8U *)0) { /* Validate 'err' */
  428. OS_EXIT_CRITICAL();
  429. return;
  430. }
  431. if (pgrp == (OS_FLAG_GRP *)0) { /* Is 'pgrp' a NULL pointer? */
  432. OS_EXIT_CRITICAL(); /* Yes */
  433. *err = OS_FLAG_INVALID_PGRP;
  434. return;
  435. }
  436. if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */
  437. OS_EXIT_CRITICAL(); /* Yes */
  438. *err = OS_ERR_PNAME_NULL;
  439. return;
  440. }
  441. #endif
  442. if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) {
  443. OS_EXIT_CRITICAL();
  444. *err = OS_ERR_EVENT_TYPE;
  445. return;
  446. }
  447. len = OS_StrLen(pname); /* Can we fit the string in the storage area? */
  448. if (len > (OS_FLAG_NAME_SIZE - 1)) { /* No */
  449. OS_EXIT_CRITICAL();
  450. *err = OS_ERR_FLAG_NAME_TOO_LONG;
  451. return;
  452. }
  453. (void)OS_StrCopy(pgrp->OSFlagName, pname); /* Yes, copy name from OS_FLAG_GRP */
  454. OS_EXIT_CRITICAL();
  455. *err = OS_NO_ERR;
  456. return;
  457. }
  458. #endif
  459. /*$PAGE*/
  460. /*
  461. *********************************************************************************************************
  462. * WAIT ON AN EVENT FLAG GROUP
  463. *
  464. * Description: This function is called to wait for a combination of bits to be set in an event flag
  465. * group. Your application can wait for ANY bit to be set or ALL bits to be set.
  466. *
  467. * Arguments : pgrp is a pointer to the desired event flag group.
  468. *
  469. * flags Is a bit pattern indicating which bit(s) (i.e. flags) you wish to wait for.
  470. * The bits you want are specified by setting the corresponding bits in
  471. * 'flags'. e.g. if your application wants to wait for bits 0 and 1 then
  472. * 'flags' would contain 0x03.
  473. *
  474. * wait_type specifies whether you want ALL bits to be set or ANY of the bits to be set.
  475. * You can specify the following argument:
  476. *
  477. * OS_FLAG_WAIT_CLR_ALL You will wait for ALL bits in 'mask' to be clear (0)
  478. * OS_FLAG_WAIT_SET_ALL You will wait for ALL bits in 'mask' to be set (1)
  479. * OS_FLAG_WAIT_CLR_ANY You will wait for ANY bit in 'mask' to be clear (0)
  480. * OS_FLAG_WAIT_SET_ANY You will wait for ANY bit in 'mask' to be set (1)
  481. *
  482. * NOTE: Add OS_FLAG_CONSUME if you want the event flag to be 'consumed' by
  483. * the call. Example, to wait for any flag in a group AND then clear
  484. * the flags that are present, set 'wait_type' to:
  485. *
  486. * OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME
  487. *
  488. * timeout is an optional timeout (in clock ticks) that your task will wait for the
  489. * desired bit combination. If you specify 0, however, your task will wait
  490. * forever at the specified event flag group or, until a message arrives.
  491. *
  492. * err is a pointer to an error code and can be:
  493. * OS_NO_ERR The desired bits have been set within the specified
  494. * 'timeout'.
  495. * OS_ERR_PEND_ISR If you tried to PEND from an ISR
  496. * OS_FLAG_INVALID_PGRP If 'pgrp' is a NULL pointer.
  497. * OS_ERR_EVENT_TYPE You are not pointing to an event flag group
  498. * OS_TIMEOUT The bit(s) have not been set in the specified
  499. * 'timeout'.
  500. * OS_FLAG_ERR_WAIT_TYPE You didn't specify a proper 'wait_type' argument.
  501. *
  502. * Returns : The flags in the event flag group that made the task ready or, 0 if a timeout or an error
  503. * occurred.
  504. *
  505. * Called from: Task ONLY
  506. *
  507. * Note(s) : 1) IMPORTANT, the behavior of this function has changed from PREVIOUS versions. The
  508. * function NOW returns the flags that were ready INSTEAD of the current state of the
  509. * event flags.
  510. *********************************************************************************************************
  511. */
  512. OS_FLAGS OSFlagPend (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U wait_type, INT16U timeout, INT8U *err)
  513. {
  514. OS_FLAG_NODE node;
  515. OS_FLAGS flags_rdy;
  516. INT8U result;
  517. BOOLEAN consume;
  518. #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
  519. OS_CPU_SR cpu_sr = 0;
  520. #endif
  521. #if OS_ARG_CHK_EN > 0
  522. if (err == (INT8U *)0) { /* Validate 'err' */
  523. return ((OS_FLAGS)0);
  524. }
  525. if (pgrp == (OS_FLAG_GRP *)0) { /* Validate 'pgrp' */
  526. *err = OS_FLAG_INVALID_PGRP;
  527. return ((OS_FLAGS)0);
  528. }
  529. #endif
  530. if (OSIntNesting > 0) { /* See if called from ISR ... */
  531. *err = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */
  532. return ((OS_FLAGS)0);
  533. }
  534. if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Validate event block type */
  535. *err = OS_ERR_EVENT_TYPE;
  536. return ((OS_FLAGS)0);
  537. }
  538. result = wait_type & OS_FLAG_CONSUME;
  539. if (result != (INT8U)0) { /* See if we need to consume the flags */
  540. wait_type &= ~OS_FLAG_CONSUME;
  541. consume = TRUE;
  542. } else {
  543. consume = FALSE;
  544. }
  545. /*$PAGE*/
  546. OS_ENTER_CRITICAL();
  547. switch (wait_type) {
  548. case OS_FLAG_WAIT_SET_ALL: /* See if all required flags are set */
  549. flags_rdy = pgrp->OSFlagFlags & flags; /* Extract only the bits we want */
  550. if (flags_rdy == flags) { /* Must match ALL the bits that we want */
  551. if (consume == TRUE) { /* See if we need to consume the flags */
  552. pgrp->OSFlagFlags &= ~flags_rdy; /* Clear ONLY the flags that we wanted */
  553. }
  554. OSTCBCur->OSTCBFlagsRdy = flags_rdy; /* Save flags that were ready */
  555. OS_EXIT_CRITICAL(); /* Yes, condition met, return to caller */
  556. *err = OS_NO_ERR;
  557. return (flags_rdy);
  558. } else { /* Block task until events occur or timeout */
  559. OS_FlagBlock(pgrp, &node, flags, wait_type, timeout);
  560. OS_EXIT_CRITICAL();
  561. }
  562. break;
  563. case OS_FLAG_WAIT_SET_ANY:
  564. flags_rdy = pgrp->OSFlagFlags & flags; /* Extract only the bits we want */
  565. if (flags_rdy != (OS_FLAGS)0) { /* See if any flag set */
  566. if (consume == TRUE) { /* See if we need to consume the flags */
  567. pgrp->OSFlagFlags &= ~flags_rdy; /* Clear ONLY the flags that we got */
  568. }
  569. OSTCBCur->OSTCBFlagsRdy = flags_rdy; /* Save flags that were ready */
  570. OS_EXIT_CRITICAL(); /* Yes, condition met, return to caller */
  571. *err = OS_NO_ERR;
  572. return (flags_rdy);
  573. } else { /* Block task until events occur or timeout */
  574. OS_FlagBlock(pgrp, &node, flags, wait_type, timeout);
  575. OS_EXIT_CRITICAL();
  576. }
  577. break;
  578. #if OS_FLAG_WAIT_CLR_EN > 0
  579. case OS_FLAG_WAIT_CLR_ALL: /* See if all required flags are cleared */
  580. flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & flags; /* Extract only the bits we want */
  581. if (flags_rdy == flags) { /* Must match ALL the bits that we want */
  582. if (consume == TRUE) { /* See if we need to consume the flags */
  583. pgrp->OSFlagFlags |= flags_rdy; /* Set ONLY the flags that we wanted */
  584. }
  585. OSTCBCur->OSTCBFlagsRdy = flags_rdy; /* Save flags that were ready */
  586. OS_EXIT_CRITICAL(); /* Yes, condition met, return to caller */
  587. *err = OS_NO_ERR;
  588. return (flags_rdy);
  589. } else { /* Block task until events occur or timeout */
  590. OS_FlagBlock(pgrp, &node, flags, wait_type, timeout);
  591. OS_EXIT_CRITICAL();
  592. }
  593. break;
  594. case OS_FLAG_WAIT_CLR_ANY:
  595. flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & flags; /* Extract only the bits we want */
  596. if (flags_rdy != (OS_FLAGS)0) { /* See if any flag cleared */
  597. if (consume == TRUE) { /* See if we need to consume the flags */
  598. pgrp->OSFlagFlags |= flags_rdy; /* Set ONLY the flags that we got */
  599. }
  600. OSTCBCur->OSTCBFlagsRdy = flags_rdy; /* Save flags that were ready */
  601. OS_EXIT_CRITICAL(); /* Yes, condition met, return to caller */
  602. *err = OS_NO_ERR;
  603. return (flags_rdy);
  604. } else { /* Block task until events occur or timeout */
  605. OS_FlagBlock(pgrp, &node, flags, wait_type, timeout);
  606. OS_EXIT_CRITICAL();
  607. }
  608. break;
  609. #endif
  610. default:
  611. OS_EXIT_CRITICAL();
  612. flags_rdy = (OS_FLAGS)0;
  613. *err = OS_FLAG_ERR_WAIT_TYPE;
  614. return (flags_rdy);
  615. }
  616. OS_Sched(); /* Find next HPT ready to run */
  617. OS_ENTER_CRITICAL();
  618. if (OSTCBCur->OSTCBPendTO == TRUE) { /* Have we timed-out? */
  619. OSTCBCur->OSTCBPendTO = FALSE;
  620. OS_FlagUnlink(&node);
  621. OSTCBCur->OSTCBStat = OS_STAT_RDY; /* Yes, make task ready-to-run */
  622. OS_EXIT_CRITICAL();
  623. flags_rdy = (OS_FLAGS)0;
  624. *err = OS_TIMEOUT; /* Indicate that we timed-out waiting */
  625. return (flags_rdy);
  626. }
  627. flags_rdy = OSTCBCur->OSTCBFlagsRdy;
  628. if (consume == TRUE) { /* See if we need to consume the flags */
  629. switch (wait_type) {
  630. case OS_FLAG_WAIT_SET_ALL:
  631. case OS_FLAG_WAIT_SET_ANY: /* Clear ONLY the flags we got */
  632. pgrp->OSFlagFlags &= ~flags_rdy;
  633. break;
  634. #if OS_FLAG_WAIT_CLR_EN > 0
  635. case OS_FLAG_WAIT_CLR_ALL:
  636. case OS_FLAG_WAIT_CLR_ANY: /* Set ONLY the flags we got */
  637. pgrp->OSFlagFlags |= flags_rdy;
  638. break;
  639. #endif
  640. default:
  641. OS_EXIT_CRITICAL();
  642. *err = OS_FLAG_ERR_WAIT_TYPE;
  643. return ((OS_FLAGS)0);
  644. }
  645. }
  646. OS_EXIT_CRITICAL();
  647. *err = OS_NO_ERR; /* Event(s) must have occurred */
  648. return (flags_rdy);
  649. }
  650. /*$PAGE*/
  651. /*
  652. *********************************************************************************************************
  653. * GET FLAGS WHO CAUSED TASK TO BECOME READY
  654. *
  655. * Description: This function is called to obtain the flags that caused the task to become ready to run.
  656. * In other words, this function allows you to tell "Who done it!".
  657. *
  658. * Arguments : None
  659. *
  660. * Returns : The flags that caused the task to be ready.
  661. *
  662. * Called from: Task ONLY
  663. *********************************************************************************************************
  664. */
  665. OS_FLAGS OSFlagPendGetFlagsRdy (void)
  666. {
  667. OS_FLAGS flags;
  668. #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
  669. OS_CPU_SR cpu_sr = 0;
  670. #endif
  671. OS_ENTER_CRITICAL();
  672. flags = OSTCBCur->OSTCBFlagsRdy;
  673. OS_EXIT_CRITICAL();
  674. return (flags);
  675. }
  676. /*$PAGE*/
  677. /*
  678. *********************************************************************************************************
  679. * POST EVENT FLAG BIT(S)
  680. *
  681. * Description: This function is called to set or clear some bits in an event flag group. The bits to
  682. * set or clear are specified by a 'bit mask'.
  683. *
  684. * Arguments : pgrp is a pointer to the desired event flag group.
  685. *
  686. * flags If 'opt' (see below) is OS_FLAG_SET, each bit that is set in 'flags' will
  687. * set the corresponding bit in the event flag group. e.g. to set bits 0, 4
  688. * and 5 you would set 'flags' to:
  689. *
  690. * 0x31 (note, bit 0 is least significant bit)
  691. *
  692. * If 'opt' (see below) is OS_FLAG_CLR, each bit that is set in 'flags' will
  693. * CLEAR the corresponding bit in the event flag group. e.g. to clear bits 0,
  694. * 4 and 5 you would specify 'flags' as:
  695. *
  696. * 0x31 (note, bit 0 is least significant bit)
  697. *
  698. * opt indicates whether the flags will be:
  699. * set (OS_FLAG_SET) or
  700. * cleared (OS_FLAG_CLR)
  701. *
  702. * err is a pointer to an error code and can be:
  703. * OS_NO_ERR The call was successfull
  704. * OS_FLAG_INVALID_PGRP You passed a NULL pointer
  705. * OS_ERR_EVENT_TYPE You are not pointing to an event flag group
  706. * OS_FLAG_INVALID_OPT You specified an invalid option
  707. *
  708. * Returns : the new value of the event flags bits that are still set.
  709. *
  710. * Called From: Task or ISR
  711. *
  712. * WARNING(s) : 1) The execution time of this function depends on the number of tasks waiting on the event
  713. * flag group.
  714. * 2) The amount of time interrupts are DISABLED depends on the number of tasks waiting on
  715. * the event flag group.
  716. *********************************************************************************************************
  717. */
  718. OS_FLAGS OSFlagPost (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U opt, INT8U *err)
  719. {
  720. OS_FLAG_NODE *pnode;
  721. BOOLEAN sched;
  722. OS_FLAGS flags_cur;
  723. OS_FLAGS flags_rdy;
  724. BOOLEAN rdy;
  725. #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
  726. OS_CPU_SR cpu_sr = 0;
  727. #endif
  728. #if OS_ARG_CHK_EN > 0
  729. if (err == (INT8U *)0) { /* Validate 'err' */
  730. return ((OS_FLAGS)0);
  731. }
  732. if (pgrp == (OS_FLAG_GRP *)0) { /* Validate 'pgrp' */
  733. *err = OS_FLAG_INVALID_PGRP;
  734. return ((OS_FLAGS)0);
  735. }
  736. #endif
  737. if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Make sure we are pointing to an event flag grp */
  738. *err = OS_ERR_EVENT_TYPE;
  739. return ((OS_FLAGS)0);
  740. }
  741. /*$PAGE*/
  742. OS_ENTER_CRITICAL();
  743. switch (opt) {
  744. case OS_FLAG_CLR:
  745. pgrp->OSFlagFlags &= ~flags; /* Clear the flags specified in the group */
  746. break;
  747. case OS_FLAG_SET:
  748. pgrp->OSFlagFlags |= flags; /* Set the flags specified in the group */
  749. break;
  750. default:
  751. OS_EXIT_CRITICAL(); /* INVALID option */
  752. *err = OS_FLAG_INVALID_OPT;
  753. return ((OS_FLAGS)0);
  754. }
  755. sched = FALSE; /* Indicate that we don't need rescheduling */
  756. pnode = (OS_FLAG_NODE *)pgrp->OSFlagWaitList;
  757. while (pnode != (OS_FLAG_NODE *)0) { /* Go through all tasks waiting on event flag(s) */
  758. switch (pnode->OSFlagNodeWaitType) {
  759. case OS_FLAG_WAIT_SET_ALL: /* See if all req. flags are set for current node */
  760. flags_rdy = pgrp->OSFlagFlags & pnode->OSFlagNodeFlags;
  761. if (flags_rdy == pnode->OSFlagNodeFlags) {
  762. rdy = OS_FlagTaskRdy(pnode, flags_rdy); /* Make task RTR, event(s) Rx'd */
  763. if (rdy == TRUE) {
  764. sched = TRUE; /* When done we will reschedule */
  765. }
  766. }
  767. break;
  768. case OS_FLAG_WAIT_SET_ANY: /* See if any flag set */
  769. flags_rdy = pgrp->OSFlagFlags & pnode->OSFlagNodeFlags;
  770. if (flags_rdy != (OS_FLAGS)0) {
  771. rdy = OS_FlagTaskRdy(pnode, flags_rdy); /* Make task RTR, event(s) Rx'd */
  772. if (rdy == TRUE) {
  773. sched = TRUE; /* When done we will reschedule */
  774. }
  775. }
  776. break;
  777. #if OS_FLAG_WAIT_CLR_EN > 0
  778. case OS_FLAG_WAIT_CLR_ALL: /* See if all req. flags are set for current node */
  779. flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & pnode->OSFlagNodeFlags;
  780. if (flags_rdy == pnode->OSFlagNodeFlags) {
  781. rdy = OS_FlagTaskRdy(pnode, flags_rdy); /* Make task RTR, event(s) Rx'd */
  782. if (rdy == TRUE) {
  783. sched = TRUE; /* When done we will reschedule */
  784. }
  785. }
  786. break;
  787. case OS_FLAG_WAIT_CLR_ANY: /* See if any flag set */
  788. flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & pnode->OSFlagNodeFlags;
  789. if (flags_rdy != (OS_FLAGS)0) {
  790. rdy = OS_FlagTaskRdy(pnode, flags_rdy); /* Make task RTR, event(s) Rx'd */
  791. if (rdy == TRUE) {
  792. sched = TRUE; /* When done we will reschedule */
  793. }
  794. }
  795. break;
  796. #endif
  797. default:
  798. OS_EXIT_CRITICAL();
  799. *err = OS_FLAG_ERR_WAIT_TYPE;
  800. return ((OS_FLAGS)0);
  801. }
  802. pnode = (OS_FLAG_NODE *)pnode->OSFlagNodeNext; /* Point to next task waiting for event flag(s) */
  803. }
  804. OS_EXIT_CRITICAL();
  805. if (sched == TRUE) {
  806. OS_Sched();
  807. }
  808. OS_ENTER_CRITICAL();
  809. flags_cur = pgrp->OSFlagFlags;
  810. OS_EXIT_CRITICAL();
  811. *err = OS_NO_ERR;
  812. return (flags_cur);
  813. }
  814. /*$PAGE*/
  815. /*
  816. *********************************************************************************************************
  817. * QUERY EVENT FLAG
  818. *
  819. * Description: This function is used to check the value of the event flag group.
  820. *
  821. * Arguments : pgrp is a pointer to the desired event flag group.
  822. *
  823. * err is a pointer to an error code returned to the called:
  824. * OS_NO_ERR The call was successfull
  825. * OS_FLAG_INVALID_PGRP You passed a NULL pointer
  826. * OS_ERR_EVENT_TYPE You are not pointing to an event flag group
  827. *
  828. * Returns : The current value of the event flag group.
  829. *
  830. * Called From: Task or ISR
  831. *********************************************************************************************************
  832. */
  833. #if OS_FLAG_QUERY_EN > 0
  834. OS_FLAGS OSFlagQuery (OS_FLAG_GRP *pgrp, INT8U *err)
  835. {
  836. OS_FLAGS flags;
  837. #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
  838. OS_CPU_SR cpu_sr = 0;
  839. #endif
  840. #if OS_ARG_CHK_EN > 0
  841. if (err == (INT8U *)0) { /* Validate 'err' */
  842. return ((OS_FLAGS)0);
  843. }
  844. if (pgrp == (OS_FLAG_GRP *)0) { /* Validate 'pgrp' */
  845. *err = OS_FLAG_INVALID_PGRP;
  846. return ((OS_FLAGS)0);
  847. }
  848. #endif
  849. if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Validate event block type */
  850. *err = OS_ERR_EVENT_TYPE;
  851. return ((OS_FLAGS)0);
  852. }
  853. OS_ENTER_CRITICAL();
  854. flags = pgrp->OSFlagFlags;
  855. OS_EXIT_CRITICAL();
  856. *err = OS_NO_ERR;
  857. return (flags); /* Return the current value of the event flags */
  858. }
  859. #endif
  860. /*$PAGE*/
  861. /*
  862. *********************************************************************************************************
  863. * SUSPEND TASK UNTIL EVENT FLAG(s) RECEIVED OR TIMEOUT OCCURS
  864. *
  865. * Description: This function is internal to uC/OS-II and is used to put a task to sleep until the desired
  866. * event flag bit(s) are set.
  867. *
  868. * Arguments : pgrp is a pointer to the desired event flag group.
  869. *
  870. * pnode is a pointer to a structure which contains data about the task waiting for
  871. * event flag bit(s) to be set.
  872. *
  873. * flags Is a bit pattern indicating which bit(s) (i.e. flags) you wish to check.
  874. * The bits you want are specified by setting the corresponding bits in
  875. * 'flags'. e.g. if your application wants to wait for bits 0 and 1 then
  876. * 'flags' would contain 0x03.
  877. *
  878. * wait_type specifies whether you want ALL bits to be set/cleared or ANY of the bits
  879. * to be set/cleared.
  880. * You can specify the following argument:
  881. *
  882. * OS_FLAG_WAIT_CLR_ALL You will check ALL bits in 'mask' to be clear (0)
  883. * OS_FLAG_WAIT_CLR_ANY You will check ANY bit in 'mask' to be clear (0)
  884. * OS_FLAG_WAIT_SET_ALL You will check ALL bits in 'mask' to be set (1)
  885. * OS_FLAG_WAIT_SET_ANY You will check ANY bit in 'mask' to be set (1)
  886. *
  887. * timeout is the desired amount of time that the task will wait for the event flag
  888. * bit(s) to be set.
  889. *
  890. * Returns : none
  891. *
  892. * Called by : OSFlagPend() OS_FLAG.C
  893. *
  894. * Note(s) : This function is INTERNAL to uC/OS-II and your application should not call it.
  895. *********************************************************************************************************
  896. */
  897. static void OS_FlagBlock (OS_FLAG_GRP *pgrp, OS_FLAG_NODE *pnode, OS_FLAGS flags, INT8U wait_type, INT16U timeout)
  898. {
  899. OS_FLAG_NODE *pnode_next;
  900. INT8U y;
  901. OSTCBCur->OSTCBStat |= OS_STAT_FLAG;
  902. OSTCBCur->OSTCBPendTO = FALSE;
  903. OSTCBCur->OSTCBDly = timeout; /* Store timeout in task's TCB */
  904. OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
  905. #if OS_TASK_DEL_EN > 0
  906. OSTCBCur->OSTCBFlagNode = pnode; /* TCB to link to node */
  907. #endif
  908. pnode->OSFlagNodeFlags = flags; /* Save the flags that we need to wait for */
  909. pnode->OSFlagNodeWaitType = wait_type; /* Save the type of wait we are doing */
  910. pnode->OSFlagNodeTCB = (void *)OSTCBCur; /* Link to task's TCB */
  911. pnode->OSFlagNodeNext = pgrp->OSFlagWaitList; /* Add node at beginning of event flag wait list */
  912. pnode->OSFlagNodePrev = (void *)0;
  913. pnode->OSFlagNodeFlagGrp = (void *)pgrp; /* Link to Event Flag Group */
  914. pnode_next = (OS_FLAG_NODE *)pgrp->OSFlagWaitList;
  915. if (pnode_next != (void *)0) { /* Is this the first NODE to insert? */
  916. pnode_next->OSFlagNodePrev = pnode; /* No, link in doubly linked list */
  917. }
  918. pgrp->OSFlagWaitList = (void *)pnode;
  919. y = OSTCBCur->OSTCBY; /* Suspend current task until flag(s) received */
  920. OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX;
  921. if (OSRdyTbl[y] == 0x00) {
  922. OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
  923. }
  924. }
  925. /*$PAGE*/
  926. /*
  927. *********************************************************************************************************
  928. * INITIALIZE THE EVENT FLAG MODULE
  929. *
  930. * Description: This function is called by uC/OS-II to initialize the event flag module. Your application
  931. * MUST NOT call this function. In other words, this function is internal to uC/OS-II.
  932. *
  933. * Arguments : none
  934. *
  935. * Returns : none
  936. *
  937. * WARNING : You MUST NOT call this function from your code. This is an INTERNAL function to uC/OS-II.
  938. *********************************************************************************************************
  939. */
  940. void OS_FlagInit (void)
  941. {
  942. #if OS_MAX_FLAGS == 1
  943. OSFlagFreeList = (OS_FLAG_GRP *)&OSFlagTbl[0]; /* Only ONE event flag group! */
  944. OSFlagFreeList->OSFlagType = OS_EVENT_TYPE_UNUSED;
  945. OSFlagFreeList->OSFlagWaitList = (void *)0;
  946. OSFlagFreeList->OSFlagFlags = (OS_FLAGS)0;
  947. #if OS_FLAG_NAME_SIZE > 1
  948. OSFlagFreeList->OSFlagName[0] = '?';
  949. OSFlagFreeList->OSFlagName[1] = OS_ASCII_NUL;
  950. #endif
  951. #endif
  952. #if OS_MAX_FLAGS >= 2
  953. INT16U i;
  954. OS_FLAG_GRP *pgrp1;
  955. OS_FLAG_GRP *pgrp2;
  956. OS_MemClr((INT8U *)&OSFlagTbl[0], sizeof(OSFlagTbl)); /* Clear the flag group table */
  957. pgrp1 = &OSFlagTbl[0];
  958. pgrp2 = &OSFlagTbl[1];
  959. for (i = 0; i < (OS_MAX_FLAGS - 1); i++) { /* Init. list of free EVENT FLAGS */
  960. pgrp1->OSFlagType = OS_EVENT_TYPE_UNUSED;
  961. pgrp1->OSFlagWaitList = (void *)pgrp2;
  962. #if OS_FLAG_NAME_SIZE > 1
  963. pgrp1->OSFlagName[0] = '?'; /* Unknown name */
  964. pgrp1->OSFlagName[1] = OS_ASCII_NUL;
  965. #endif
  966. pgrp1++;
  967. pgrp2++;
  968. }
  969. pgrp1->OSFlagType = OS_EVENT_TYPE_UNUSED;
  970. pgrp1->OSFlagWaitList = (void *)0;
  971. #if OS_FLAG_NAME_SIZE > 1
  972. pgrp1->OSFlagName[0] = '?'; /* Unknown name */
  973. pgrp1->OSFlagName[1] = OS_ASCII_NUL;
  974. #endif
  975. OSFlagFreeList = &OSFlagTbl[0];
  976. #endif
  977. }
  978. /*$PAGE*/
  979. /*
  980. *********************************************************************************************************
  981. * MAKE TASK READY-TO-RUN, EVENT(s) OCCURRED
  982. *
  983. * Description: This function is internal to uC/OS-II and is used to make a task ready-to-run because the
  984. * desired event flag bits have been set.
  985. *
  986. * Arguments : pnode is a pointer to a structure which contains data about the task waiting for
  987. * event flag bit(s) to be set.
  988. *
  989. * flags_rdy contains the bit pattern of the event flags that cause the task to become
  990. * ready-to-run.
  991. *
  992. * Returns : TRUE If the task has been placed in the ready list and thus needs scheduling
  993. * FALSE The task is still not ready to run and thus scheduling is not necessary
  994. *
  995. * Called by : OSFlagsPost() OS_FLAG.C
  996. *
  997. * Note(s) : 1) This function assumes that interrupts are disabled.
  998. * 2) This function is INTERNAL to uC/OS-II and your application should not call it.
  999. *********************************************************************************************************
  1000. */
  1001. static BOOLEAN OS_FlagTaskRdy (OS_FLAG_NODE *pnode, OS_FLAGS flags_rdy)
  1002. {
  1003. OS_TCB *ptcb;
  1004. BOOLEAN sched;
  1005. ptcb = (OS_TCB *)pnode->OSFlagNodeTCB; /* Point to TCB of waiting task */
  1006. ptcb->OSTCBDly = 0;
  1007. ptcb->OSTCBFlagsRdy = flags_rdy;
  1008. ptcb->OSTCBStat &= ~OS_STAT_FLAG;
  1009. ptcb->OSTCBPendTO = FALSE;
  1010. if (ptcb->OSTCBStat == OS_STAT_RDY) { /* Task now ready? */
  1011. OSRdyGrp |= ptcb->OSTCBBitY; /* Put task into ready list */
  1012. OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
  1013. sched = TRUE;
  1014. } else {
  1015. sched = FALSE;
  1016. }
  1017. OS_FlagUnlink(pnode);
  1018. return (sched);
  1019. }
  1020. /*$PAGE*/
  1021. /*
  1022. *********************************************************************************************************
  1023. * UNLINK EVENT FLAG NODE FROM WAITING LIST
  1024. *
  1025. * Description: This function is internal to uC/OS-II and is used to unlink an event flag node from a
  1026. * list of tasks waiting for the event flag.
  1027. *
  1028. * Arguments : pnode is a pointer to a structure which contains data about the task waiting for
  1029. * event flag bit(s) to be set.
  1030. *
  1031. * Returns : none
  1032. *
  1033. * Called by : OS_FlagTaskRdy() OS_FLAG.C
  1034. * OSFlagPend() OS_FLAG.C
  1035. * OSTaskDel() OS_TASK.C
  1036. *
  1037. * Note(s) : 1) This function assumes that interrupts are disabled.
  1038. * 2) This function is INTERNAL to uC/OS-II and your application should not call it.
  1039. *********************************************************************************************************
  1040. */
  1041. void OS_FlagUnlink (OS_FLAG_NODE *pnode)
  1042. {
  1043. #if OS_TASK_DEL_EN > 0
  1044. OS_TCB *ptcb;
  1045. #endif
  1046. OS_FLAG_GRP *pgrp;
  1047. OS_FLAG_NODE *pnode_prev;
  1048. OS_FLAG_NODE *pnode_next;
  1049. pnode_prev = (OS_FLAG_NODE *)pnode->OSFlagNodePrev;
  1050. pnode_next = (OS_FLAG_NODE *)pnode->OSFlagNodeNext;
  1051. if (pnode_prev == (OS_FLAG_NODE *)0) { /* Is it first node in wait list? */
  1052. pgrp = (OS_FLAG_GRP *)pnode->OSFlagNodeFlagGrp;
  1053. pgrp->OSFlagWaitList = (void *)pnode_next; /* Update list for new 1st node */
  1054. if (pnode_next != (OS_FLAG_NODE *)0) {
  1055. pnode_next->OSFlagNodePrev = (OS_FLAG_NODE *)0; /* Link new 1st node PREV to NULL */
  1056. }
  1057. } else { /* No, A node somewhere in the list */
  1058. pnode_prev->OSFlagNodeNext = pnode_next; /* Link around the node to unlink */
  1059. if (pnode_next != (OS_FLAG_NODE *)0) { /* Was this the LAST node? */
  1060. pnode_next->OSFlagNodePrev = pnode_prev; /* No, Link around current node */
  1061. }
  1062. }
  1063. #if OS_TASK_DEL_EN > 0
  1064. ptcb = (OS_TCB *)pnode->OSFlagNodeTCB;
  1065. ptcb->OSTCBFlagNode = (OS_FLAG_NODE *)0;
  1066. #endif
  1067. }
  1068. #endif