os_flag.c
上传用户:yyyd609
上传日期:2022-07-18
资源大小:183k
文件大小:53k
源码类别:

微处理器开发

开发平台:

C/C++

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