示例#1
0
OS_RESULT os_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout) {
  /* Send message to a mailbox */
  P_MCB p_MCB = mailbox;
  P_TCB p_TCB;

  tsk_lock();
m:if (p_MCB->p_lnk != NULL && p_MCB->count == 0) {
    /* A task is waiting for message */
    p_TCB = os_get_first ((P_XCB)p_MCB);
    p_TCB->p_msg = p_msg;
    p_TCB->ret_val = OS_R_MBX;
    os_rmv_dly (p_TCB);
    os_dispatch (p_TCB);
  }
  else {
    /* Store message in mailbox queue */
    if (p_MCB->count == p_MCB->size) {
      /* No free message entry, wait for one. If message queue is full, */
      /* then no task is waiting for message. The 'p_MCB->p_lnk' list   */
      /* pointer can now be reused for send message waits task list.    */
      if (timeout == 0) {
        goto wto;
      }
      if (p_MCB->p_lnk != NULL) {
        os_put_prio ((P_XCB)p_MCB, os_runtask);
      }
      else {
        p_MCB->p_lnk = os_runtask;
        os_runtask->p_lnk  = NULL;
        os_runtask->p_rlnk = (P_TCB)p_MCB;
        /* Signal the 'isr_mbx_receive ()' that the task is waiting */
        /* to send a message */
        p_MCB->isr_st = 1;
      }
      if (os_block(timeout, WAIT_MBX) == OS_R_TMO) {
wto:    tsk_unlock();
        return (OS_R_TMO);
      }
      /* A message has been fetched, check the mailbox again. */
      goto m;
    }
    /* Yes, there is a free entry in a mailbox. */
    p_MCB->msg[p_MCB->first] = p_msg;
    _incw (&p_MCB->count);
    if (++p_MCB->first == p_MCB->size) {
      p_MCB->first = 0;
    }
  }
  tsk_unlock();
  return (OS_R_OK);
}
示例#2
0
OS_RESULT os_mbx_wait (OS_ID mailbox, void **message, U16 timeout) {
  /* Receive a message; possibly wait for it */
  P_MCB p_MCB = mailbox;
  P_TCB p_TCB;

  tsk_lock();
  /* If a message is available in the fifo buffer */
  /* remove it from the fifo buffer and return. */
  if (p_MCB->count) {
    *message = p_MCB->msg[p_MCB->last];
    _decw (&p_MCB->count);
    if (++p_MCB->last == p_MCB->size) {
      p_MCB->last = 0;
    }
    if (p_MCB->p_lnk != NULL) {
      /* A task is waiting to send message */
      p_TCB = os_get_first ((P_XCB)p_MCB);
      os_rmv_dly (p_TCB);
      os_dispatch (p_TCB);
    }
    tsk_unlock();
    return (OS_R_OK);
  }
  /* No message available: wait for one */
  if (timeout == 0) {
    goto rto;
  }
  if (p_MCB->p_lnk != NULL) {
    os_put_prio ((P_XCB)p_MCB, os_runtask);
  }
  else {
    p_MCB->p_lnk = os_runtask;
    os_runtask->p_lnk = NULL;
    os_runtask->p_rlnk = (P_TCB)p_MCB;
  }
  if (os_block(timeout, WAIT_MBX) == OS_R_TMO) {
rto:tsk_unlock();
    *message = NULL;
    return (OS_R_TMO);
  }
  tsk_unlock();
  *message = os_runtask->p_msg;
  return (OS_R_MBX);
}
示例#3
0
文件: rt_Mutex.c 项目: Qinyonghui/RTX
OS_RESULT os_mut_wait (OS_ID mutex, U16 timeout) {
  /* Wait for a mutex, continue when mutex is free. */
  P_MUCB p_MCB = mutex;

  tsk_lock();
  if (p_MCB->level == 0) {
    p_MCB->owner = os_runtask;
    p_MCB->prio  = os_runtask->prio;
    goto inc;
  }
  if (p_MCB->owner == os_runtask) {
    /* OK, running task is the owner of this mutex. */
inc:p_MCB->level++;
    tsk_unlock();
    return (OS_R_OK);
  }
  /* Mutex owned by another task, wait until released. */
  if (timeout == 0) {
    goto rto;
  }
  /* Raise the owner task priority if lower than current priority. */
  /* This priority inversion is called priority inheritance.       */
  if (p_MCB->prio < os_runtask->prio) {
    p_MCB->owner->prio = os_runtask->prio;
    os_resort_prio (p_MCB->owner);
  }
  if (p_MCB->p_lnk != NULL) {
    os_put_prio ((P_XCB)p_MCB, os_runtask);
  }
  else {
    p_MCB->p_lnk = os_runtask;
    os_runtask->p_lnk  = NULL;
    os_runtask->p_rlnk = (P_TCB)p_MCB;
  }
  if (os_block(timeout, WAIT_MUT) == OS_R_TMO) {
rto:tsk_unlock();
    return (OS_R_TMO);
  }
  /* A mutex has been released. */
  tsk_unlock();
  return (OS_R_MUT);
}
示例#4
0
OS_RESULT os_evt_wait (U16 wait_flags, U16 timeout, BOOL and_wait) {
  /* Wait for one or more event flags with optional time-out.                */
  /* "wait_flags" identifies the flags to wait for.                          */
  /* "timeout" is the time-out limit in system ticks (0xffff if no time-out) */
  /* "and_wait" specifies the AND-ing of "wait_flags" as condition to be met */
  /* to complete the wait. (OR-ing if set to 0).                             */
  U32 block_state;

  tsk_lock();
  if (and_wait) {
    /* Check for AND-connected events */
    if ((os_runtask->events & wait_flags) == wait_flags) {
      os_runtask->events &= ~wait_flags;
      tsk_unlock();
      return (OS_R_EVT);
    }
    block_state = WAIT_AND;
  }
  else {
    /* Check for OR-connected events */
    if (os_runtask->events & wait_flags) {
      os_runtask->waits = os_runtask->events & wait_flags;
      os_runtask->events &= ~wait_flags;
      tsk_unlock();
      return (OS_R_EVT);
    }
    block_state = WAIT_OR;
  }
  /* Task has to wait */
  os_runtask->waits = wait_flags;
  if (os_block(timeout, (U8)block_state) == OS_R_TMO) {
    tsk_unlock();
    return (OS_R_TMO);
  }
  tsk_unlock();
  return (OS_R_EVT);
}