コード例 #1
0
ファイル: tq_func.c プロジェクト: gxliu/MQX_3.8.0
_mqx_uint _taskq_resume
   (
      /* [IN] the task queue handle */
      pointer users_task_queue_ptr,
      
      /* [IN] TRUE if all tasks on the queue to be resumed */
      boolean all_tasks
   )
{ /* Body */
   register KERNEL_DATA_STRUCT_PTR kernel_data;
   register TD_STRUCT_PTR          td_ptr;
   register TASK_QUEUE_STRUCT_PTR  task_queue_ptr = 
      (TASK_QUEUE_STRUCT_PTR)users_task_queue_ptr;

   _GET_KERNEL_DATA(kernel_data);

   _KLOGE3(KLOG_taskq_resume, users_task_queue_ptr, all_tasks);

#if MQX_CHECK_ERRORS
   if (task_queue_ptr == NULL){
      _KLOGX2(KLOG_taskq_resume, MQX_INVALID_TASK_QUEUE);
      return(MQX_INVALID_TASK_QUEUE);
   } /* Endif */
#endif

   _INT_DISABLE();

#if MQX_CHECK_VALIDITY
   if (task_queue_ptr->VALID != TASK_QUEUE_VALID) {
      _int_enable();
      _KLOGX2(KLOG_taskq_resume, MQX_INVALID_TASK_QUEUE);
      return(MQX_INVALID_TASK_QUEUE);
   } /* Endif */
#endif

   if (_QUEUE_GET_SIZE(&task_queue_ptr->TD_QUEUE) == 0) {
      /* Task queue is empty */
      _int_enable();
      _KLOGX2(KLOG_taskq_resume, MQX_TASK_QUEUE_EMPTY);
      return(MQX_TASK_QUEUE_EMPTY);
   } /* Endif */

   if (all_tasks) {
      while (_QUEUE_GET_SIZE(&task_queue_ptr->TD_QUEUE)) {
         _QUEUE_DEQUEUE(&task_queue_ptr->TD_QUEUE, td_ptr);
         _TASK_READY(td_ptr, kernel_data);
      } /* Endwhile */
   } else {
      _QUEUE_DEQUEUE(&task_queue_ptr->TD_QUEUE, td_ptr);
      _TASK_READY(td_ptr, kernel_data);
   } /* Endif */

   _INT_ENABLE();      

   _CHECK_RUN_SCHEDULER();/* Let higher priority task run */

   _KLOGX2(KLOG_taskq_resume, MQX_OK);
   return( MQX_OK );
   
} /* Endbody */
コード例 #2
0
ファイル: ti_krnl.c プロジェクト: gxliu/MQX_3.8.0
void _time_notify_kernel
   (
      void
   )
{ /* Body */
   register KERNEL_DATA_STRUCT_PTR kernel_data;
   register TD_STRUCT_PTR          td_ptr;
   register TD_STRUCT_PTR          next_td_ptr;
   register _mqx_uint              count;
   register _mqx_int               result;

   _GET_KERNEL_DATA(kernel_data);

   /*
   ** Update the current time.
   */
   PSP_INC_TICKS(&kernel_data->TIME);

   _INT_DISABLE();

   if (kernel_data->GET_HWTICKS) {
      // The hardware clock may have counted passed it's reference
      // and have an interrupt pending.  Thus, HW_TICKS may exceed
      // kernel_data->HW_TICKS_PER_TICK and this tick_ptr may need
      // normalizing.  This is done in a moment.
      kernel_data->TIME.HW_TICKS = (*kernel_data->GET_HWTICKS)
         (kernel_data->GET_HWTICKS_PARAM);
   } /* Endif */

   // The tick_ptr->HW_TICKS value might exceed the
   // kernel_data->HW_TICKS_PER_TICK and need to be
   // normalized for the PSP.
   PSP_NORMALIZE_TICKS(&kernel_data->TIME);

   /*
   ** Check for tasks on the timeout queue, and wake the appropriate
   ** ones up.  The timeout queue is a time-priority queue.
   */
   count = _QUEUE_GET_SIZE(&kernel_data->TIMEOUT_QUEUE);
   if (count) {
      td_ptr = (TD_STRUCT_PTR)((pointer)kernel_data->TIMEOUT_QUEUE.NEXT);
      ++count;
      while ( --count ) {
         next_td_ptr = td_ptr->TD_NEXT;
         result = PSP_CMP_TICKS(&kernel_data->TIME, &td_ptr->TIMEOUT);
         if (result >= 0) {
            --kernel_data->TIMEOUT_QUEUE.SIZE;
            _QUEUE_UNLINK(td_ptr);
            td_ptr->STATE &= ~IS_ON_TIMEOUT_Q;
            if (td_ptr->STATE & TD_IS_ON_AUX_QUEUE) {
               td_ptr->STATE &= ~TD_IS_ON_AUX_QUEUE;
               _QUEUE_REMOVE(td_ptr->INFO, &td_ptr->AUX_QUEUE);
            } /* Endif */
            _TASK_READY(td_ptr, kernel_data);
         } else {
            break;  /* No more to do */
         } /* Endif */
         td_ptr = next_td_ptr;
      } /* Endwhile */
   } /* Endif */

#if MQX_HAS_TIME_SLICE
   /*
   ** Check if the currently running task is a time slice task
   ** and if its time has expired, put it at the end of its queue
   */
   td_ptr = kernel_data->ACTIVE_PTR;
   if ( td_ptr->FLAGS & MQX_TIME_SLICE_TASK ) {
      PSP_INC_TICKS(&td_ptr->CURRENT_TIME_SLICE);
      if (! (td_ptr->FLAGS & TASK_PREEMPTION_DISABLED) ) {
         result = PSP_CMP_TICKS(&td_ptr->CURRENT_TIME_SLICE, &td_ptr->TIME_SLICE);
         if ( result >= 0 ) {
            _QUEUE_UNLINK(td_ptr);
            _TASK_READY(td_ptr,kernel_data);
         } /* Endif */
      } /* Endif */
   } /* Endif */
#endif

   _INT_ENABLE();
#if MQX_USE_TIMER
   /* If the timer component needs servicing, call its ISR function */
   if (kernel_data->TIMER_COMPONENT_ISR != NULL) {
      (*kernel_data->TIMER_COMPONENT_ISR)();
   }/* Endif */
#endif

#if MQX_USE_LWTIMER
   /* If the lwtimer needs servicing, call its ISR function */
   if (kernel_data->LWTIMER_ISR != NULL) {
      (*kernel_data->LWTIMER_ISR)();
   }/* Endif */
#endif

} /* Endbody */
コード例 #3
0
ファイル: lwevent.c プロジェクト: Vinhuit/Freescale
/*!
 * \brief Used by a task to set the specified event bits in an event.
 *
 * \param[in] event_ptr Pointer to the lightweight event to set bits in.
 * \param[in] bit_mask  Bit mask. Each bit represents an event bit to be set.
 *
 * \return MQX_OK
 * \return MQX_LWEVENT_INVALID (Lightweight event was invalid.)
 *
 * \see _lwevent_create
 * \see _lwevent_destroy
 * \see _lwevent_set_auto_clear
 * \see _lwevent_clear
 * \see _lwevent_test
 * \see _lwevent_wait_for
 * \see _lwevent_wait_ticks
 * \see _lwevent_wait_until
 * \see _lwevent_get_signalled
 * \see LWEVENT_STRUCT
 */
_mqx_uint _lwevent_set
(
    LWEVENT_STRUCT_PTR  event_ptr,
    _mqx_uint           bit_mask
)
{
    KERNEL_DATA_STRUCT_PTR kernel_data;
    QUEUE_ELEMENT_STRUCT_PTR q_ptr;
    QUEUE_ELEMENT_STRUCT_PTR next_q_ptr;
    TD_STRUCT_PTR td_ptr;
    _mqx_uint set_bits;

#if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI
    if (MQX_RUN_IN_USER_MODE)
    {
        return _usr_lwevent_set(event_ptr, bit_mask);
    }
#endif

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_lwevent_set, event_ptr, bit_mask);

    _INT_DISABLE();
#if MQX_CHECK_VALIDITY
    if (event_ptr->VALID != LWEVENT_VALID)
    {
        _int_enable();
        _KLOGX2(KLOG_lwevent_set, MQX_LWEVENT_INVALID);
        return (MQX_LWEVENT_INVALID);
    } /* Endif */
#endif

    set_bits = event_ptr->VALUE | bit_mask;

    if (_QUEUE_GET_SIZE(&event_ptr->WAITING_TASKS))
    {
        /* Schedule waiting task(s) to run if bits ok */

        q_ptr = event_ptr->WAITING_TASKS.NEXT;
        while (q_ptr != (QUEUE_ELEMENT_STRUCT_PTR) ((void *) &event_ptr->WAITING_TASKS))
        {
            td_ptr = (void *) q_ptr;
            _BACKUP_POINTER(td_ptr, TD_STRUCT, AUX_QUEUE);
            next_q_ptr = q_ptr->NEXT;
            if (((td_ptr->FLAGS & TASK_LWEVENT_ALL_BITS_WANTED) && ((td_ptr->LWEVENT_BITS & set_bits)
                            == td_ptr->LWEVENT_BITS)) || ((!(td_ptr->FLAGS & TASK_LWEVENT_ALL_BITS_WANTED))
                            && (td_ptr->LWEVENT_BITS & set_bits)))
            {
                _QUEUE_REMOVE(&event_ptr->WAITING_TASKS, q_ptr);
                _TIME_DEQUEUE(td_ptr, kernel_data);
                td_ptr->INFO = 0;
                _TASK_READY(td_ptr, kernel_data);

                /* store information about which bits caused task to be unblocked */
                td_ptr->LWEVENT_BITS &= set_bits;
                set_bits &= ~(event_ptr->AUTO & td_ptr->LWEVENT_BITS);

            } /* Endif */
            q_ptr = next_q_ptr;
        } /* Endwhile */
    } /* Endif */

    event_ptr->VALUE = set_bits;
    _INT_ENABLE();

    /* May need to let higher priority task run */
    _CHECK_RUN_SCHEDULER();

    _KLOGX2(KLOG_lwevent_set, MQX_OK);
    return (MQX_OK);

}
コード例 #4
0
ファイル: lwevent.c プロジェクト: Vinhuit/Freescale
/*!
 * \private
 *
 * \brief Used by a task to destroy an instance of a lightweight event.
 *
 * \param[in] event_ptr Pointer to the lightweight event to be deinitialized.
 * \param[in] user      User mode
 *
 * \return MQX_OK
 * \return MQX_LWEVENT_INVALID (Lightweight event was not valid.)
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 *
 * \see _lwevent_destroy
 * \see LWEVENT_STRUCT
 */
_mqx_uint _lwevent_destroy_internal
(
    LWEVENT_STRUCT_PTR  event_ptr,
    bool             user
)
{
    KERNEL_DATA_STRUCT_PTR kernel_data;
#if MQX_COMPONENT_DESTRUCTION
    TD_STRUCT_PTR td_ptr;
#endif

#if MQX_ENABLE_USER_MODE
    if (user && !_psp_mem_check_access_mask((uint32_t)event_ptr,
                                            sizeof(LWEVENT_STRUCT),
                                            MPU_UM_R, MPU_UM_RW))
    {
        return MQX_LWEVENT_INVALID;
    }
#endif

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_lwevent_destroy, event_ptr);

#if MQX_COMPONENT_DESTRUCTION

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        _KLOGX2(KLOG_lwevent_destroy, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return (MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    } /* Endif */
#endif

    _int_disable();
#if MQX_CHECK_VALIDITY
    if (event_ptr->VALID != LWEVENT_VALID)
    {
        _int_enable();
        _KLOGX2(KLOG_lwevent_destroy, MQX_LWEVENT_INVALID);
        return (MQX_LWEVENT_INVALID);
    } /* Endif */
#endif

    /* Effectively stop all access to the event */
    event_ptr->VALID = 0;
    while (_QUEUE_GET_SIZE(&event_ptr->WAITING_TASKS))
    {
        _QUEUE_DEQUEUE(&event_ptr->WAITING_TASKS, td_ptr);
        _BACKUP_POINTER(td_ptr, TD_STRUCT, AUX_QUEUE);
        _TIME_DEQUEUE(td_ptr, kernel_data);
        _TASK_READY(td_ptr, kernel_data);
    } /* Endwhile */

    /* remove event from kernel LWEVENTS queue */
#if MQX_ENABLE_USER_MODE
    if (user)
    {
        _QUEUE_REMOVE(&kernel_data->USR_LWEVENTS, event_ptr);
    }
    else
#endif
    {
        _QUEUE_REMOVE(&kernel_data->LWEVENTS, event_ptr);
    }

    _int_enable();

    /* May need to let higher priority task run */
    _CHECK_RUN_SCHEDULER();
#endif

    _KLOGX2(KLOG_lwevent_destroy, MQX_OK);
    return (MQX_OK);

}
コード例 #5
0
ファイル: ev_set.c プロジェクト: gxliu/MQX_3.8.0
_mqx_uint _event_set
   (
      /* [IN] - An event handle returned from _event_open or _event_open_fast */
      pointer users_event_ptr, 

      /* [IN] - bit mask, each bit of which represents an event. */
      _mqx_uint bit_mask
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR      kernel_data;
   EVENT_STRUCT_PTR            event_ptr;
   EVENT_COMPONENT_STRUCT_PTR  event_component_ptr;
   EVENT_CONNECTION_STRUCT_PTR conn_ptr;
   EVENT_CONNECTION_STRUCT_PTR next_conn_ptr;
   EVENT_CONNECTION_STRUCT_PTR event_connection_ptr;
   TD_STRUCT_PTR               new_td_ptr;
   _mqx_uint                    set_bits;
            
   _GET_KERNEL_DATA(kernel_data);

   _KLOGE3(KLOG_event_set, users_event_ptr, bit_mask);

   event_connection_ptr = (EVENT_CONNECTION_STRUCT_PTR)users_event_ptr;

#if MQX_CHECK_VALIDITY
   if (event_connection_ptr->VALID != EVENT_VALID){
      _KLOGX2(KLOG_event_set, EVENT_INVALID_EVENT_HANDLE);
      return(EVENT_INVALID_EVENT_HANDLE); 
   } /* Endif */
#endif

   event_component_ptr = (EVENT_COMPONENT_STRUCT_PTR)
      kernel_data->KERNEL_COMPONENTS[KERNEL_EVENTS];

#if MQX_CHECK_ERRORS
   if (event_component_ptr == NULL){
      _KLOGX2(KLOG_event_set, MQX_COMPONENT_DOES_NOT_EXIST);
      return(MQX_COMPONENT_DOES_NOT_EXIST);
   } /* Endif */
#endif
#if MQX_CHECK_VALIDITY
   if (event_component_ptr->VALID != EVENT_VALID){
      _KLOGX2(KLOG_event_set, MQX_INVALID_COMPONENT_BASE);
      return(MQX_INVALID_COMPONENT_BASE);
   } /* Endif */
#endif

#if MQX_IS_MULTI_PROCESSOR
   if (event_connection_ptr->REMOTE_CPU) {
      if (kernel_data->IPC) {
         /* This open is for a remote processor */
         (*kernel_data->IPC)(TRUE, event_connection_ptr->REMOTE_CPU, 
             KERNEL_EVENTS, IPC_EVENT_SET, 2, event_connection_ptr->EVENT_PTR,
             bit_mask);
         _KLOGX2(KLOG_event_set, kernel_data->ACTIVE_PTR->TASK_ERROR_CODE);
         return(kernel_data->ACTIVE_PTR->TASK_ERROR_CODE);
      } else {
         _KLOGX2(KLOG_event_set, EVENT_NOT_FOUND);
         return(EVENT_NOT_FOUND);
      }/* Endif */
   }/* Endif */
#endif

   _INT_DISABLE();
   event_ptr = event_connection_ptr->EVENT_PTR;

#if MQX_CHECK_VALIDITY
   if (event_ptr->VALID != EVENT_VALID) {
      _INT_ENABLE();
      _KLOGX2(KLOG_event_set, EVENT_INVALID_EVENT);
      return(EVENT_INVALID_EVENT);
   } /* Endif */
#endif

   set_bits = event_ptr->EVENT | bit_mask;

   if (_QUEUE_GET_SIZE(&event_ptr->WAITING_TASKS)) {
      /* Schedule waiting task(s) to run if bits ok */

      conn_ptr = (EVENT_CONNECTION_STRUCT_PTR)
         ((pointer)event_ptr->WAITING_TASKS.NEXT);
      while (conn_ptr != (EVENT_CONNECTION_STRUCT_PTR)
         ((pointer)&event_ptr->WAITING_TASKS))
      {
         next_conn_ptr = (EVENT_CONNECTION_STRUCT_PTR)conn_ptr->NEXT;
         if (((conn_ptr->FLAGS & EVENT_WANTS_ALL) && 
            ((conn_ptr->MASK & set_bits) == conn_ptr->MASK)) ||
            ((!(conn_ptr->FLAGS & EVENT_WANTS_ALL)) && 
            (conn_ptr->MASK & set_bits)))
         {  
            new_td_ptr = conn_ptr->TD_PTR;
            if ((new_td_ptr->STATE & STATE_MASK) == EVENT_BLOCKED) {
               /* He may have timed out */
               conn_ptr->FLAGS |= EVENT_OCCURRED;
               _TIME_DEQUEUE(new_td_ptr, kernel_data);
               _TASK_READY(new_td_ptr, kernel_data);
               /* Only ready one task if event is an auto clear event */
               if (event_ptr->AUTO_CLEAR) {
                  set_bits &= ~conn_ptr->MASK;
                  break;
               } /* Endif */
            } /* Endif */
         } /* Endif */
         conn_ptr = next_conn_ptr;
      } /* Endwhile */
   } /* Endif */

   event_ptr->EVENT = set_bits;

   _INT_ENABLE();

   /* May need to let higher priority task run */
   _CHECK_RUN_SCHEDULER();

   _KLOGX2(KLOG_event_set, MQX_OK);
   return(MQX_OK);
         
} /* Endbody */
コード例 #6
0
ファイル: ms_sendi.c プロジェクト: gxliu/MQX_3.8.0
boolean  _msgq_send_internal
   (
      /* [IN]  pointer to the  message being sent by application */
      MESSAGE_HEADER_STRUCT_PTR msg_ptr,

      /* [IN]  is the calling task to be blocked after the call */
      boolean                   blocking,

      /* [IN]  the queue to put the message onto */
      _queue_id                 target_qid
   )
{ /* Body */
            KERNEL_DATA_STRUCT_PTR       kernel_data;
            MSG_COMPONENT_STRUCT_PTR     msg_component_ptr;
   register INTERNAL_MESSAGE_STRUCT_PTR  imsg_ptr;
   register MSGQ_STRUCT_PTR              msgq_ptr;
   register TD_STRUCT_PTR                td_ptr;
            MESSAGE_HEADER_STRUCT_PTR    tmp_msg_ptr;
   register _mqx_uint                     state;
   register _queue_number                queue;
   register _processor_number            pnum;
/* Start CR 2191 */   
            boolean                      swapped_msg;
/* End CR 2191 */            
   
   _GET_KERNEL_DATA(kernel_data);

   msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
#if MQX_CHECK_ERRORS
   if (msg_component_ptr == NULL){
      _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
      return(FALSE);
   } /* Endif */
   if (msg_ptr == NULL) {
      _task_set_error(MSGQ_INVALID_MESSAGE);
      return(FALSE);
   } /* Endif */
#endif

   imsg_ptr = GET_INTERNAL_MESSAGE_PTR(msg_ptr);

#if MQX_CHECK_ERRORS
   if (imsg_ptr->VALID != MSG_VALID){
      /* An invalid message was input by the application. */
      _task_set_error(MSGQ_INVALID_MESSAGE);
      return FALSE;
   } /* Endif */
#endif

#if MQX_CHECK_ERRORS
   if (imsg_ptr->FREE || imsg_ptr->QUEUED){
      /* Trying to send a free message, or one on a message queue. */
      _task_set_error(MSGQ_INVALID_MESSAGE);
      return FALSE;
   } /* Endif */
#endif

   pnum  = PROC_NUMBER_FROM_QID(target_qid);

   /* If processor number is zero then the message is for this processor */
   if (pnum == 0) {
      /* Fix up the target QID in the message header */
      msg_ptr->TARGET_QID = BUILD_QID(kernel_data->INIT.PROCESSOR_NUMBER, 
         msg_ptr->TARGET_QID);
   } else if (pnum != kernel_data->INIT.PROCESSOR_NUMBER) {
#if MQX_IS_MULTI_PROCESSOR
      IPC_MSG_ROUTING_COMPONENT_STRUCT_PTR ipc_msg_comp_ptr;
      ipc_msg_comp_ptr = (IPC_MSG_ROUTING_COMPONENT_STRUCT_PTR)
         kernel_data->KERNEL_COMPONENTS[KERNEL_IPC_MSG_ROUTING];
      if (ipc_msg_comp_ptr && ipc_msg_comp_ptr->MSG_ROUTER) {
         return( (*ipc_msg_comp_ptr->MSG_ROUTER)(pnum, msg_ptr, blocking));
      } else {
#endif
         _msg_free(msg_ptr);
         _task_set_error(MSGQ_INVALID_QUEUE_ID);
         return FALSE;
#if MQX_IS_MULTI_PROCESSOR
      }/* Endif */
#endif
   } /* Endif */
      
   queue = QUEUE_FROM_QID(target_qid);

#if MQX_CHECK_ERRORS
   if ( ! VALID_QUEUE(queue)) {
      _msg_free(msg_ptr);
      _task_set_error(MSGQ_INVALID_QUEUE_ID);
      return FALSE;
   } /* Endif */
#endif

   msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue];
   if (msgq_ptr->QUEUE != queue) {
      msgq_ptr = NULL;
   } /* Endif */

#if MQX_CHECK_ERRORS
   if (msgq_ptr == NULL) {
      _msg_free(msg_ptr);
      _task_set_error(MSGQ_QUEUE_IS_NOT_OPEN);
      return FALSE;
   } /* Endif */
#endif

   _INT_DISABLE();
   
   if ((msgq_ptr->MAX_ENTRIES == 0) ||
       (msgq_ptr->NO_OF_ENTRIES < msgq_ptr->MAX_ENTRIES))
   {
   /* End CR 2265 */
   
      /* There is room on the queue, so add the msg.  We 
         need to check for room here even if the msg ends up
         being short-cutted to the receiver (via td_ptr->MESSAGE)
         in case msg_receive needs to enqueue the msg.
      */

      if (msgq_ptr->TYPE == MSG_QUEUE) {
         /* THIS MESSAGE QUEUE IS ATTACHED TO A TASK */

         /* check for pending receive
         ** if a receive is pending then satisfy the request
         ** and add the receiving task onto the ready-to-run queue
         */
      
         td_ptr = msgq_ptr->TD_PTR;
         state  = td_ptr->STATE & STATE_MASK;
         if ( (state == RCV_ANY_BLOCKED) ||
             ((state == RCV_SPECIFIC_BLOCKED) && (td_ptr->INFO == queue)))
         {
            /* The task is blocked, waiting for a message */
            td_ptr->MESSAGE = &imsg_ptr->MESSAGE;
            imsg_ptr->TD_PTR = td_ptr;
            _TIME_DEQUEUE(td_ptr,kernel_data);
            _TASK_READY(td_ptr,kernel_data);

            /* Now run the notification function */
            if (msgq_ptr->NOTIFICATION_FUNCTION != NULL) {
               (*msgq_ptr->NOTIFICATION_FUNCTION)(msgq_ptr->NOTIFICATION_FUNCTION_PARAMETER);
            } /* Endif */

            if (blocking) {
               if ( ! kernel_data->IN_ISR) {
                  td_ptr = kernel_data->ACTIVE_PTR;
                  td_ptr->STATE = SEND_BLOCKED;
                  _task_block();
               } /* Endif */
            } else {
               /*
               **  if the highest priority ready task is not the
               **  same priority as the sending task, then a higher
               **  priority task was made ready and it has to be allowed
               **  to run.
               */
               _CHECK_RUN_SCHEDULER(); /* Let a higher priority task run */
            } /* Endif */

         } else {
            /* The task is ready to run and pre-empted OR blocked and
            ** on a different queue.
            */

/* Start CR 2191 */
            swapped_msg = FALSE;
/* End CR 2191 */            
            if ((msg_ptr->CONTROL & MSG_PRIORITY_MASK) &&
                (td_ptr->MESSAGE != NULL))
            {
               /* Check the message in the TD */
               tmp_msg_ptr = (MESSAGE_HEADER_STRUCT_PTR)td_ptr->MESSAGE;
               if ( (msg_ptr->CONTROL & MSG_HDR_URGENT) ||
                  /* Urgent messages first */
                    ( (! (tmp_msg_ptr->CONTROL & MSG_HDR_URGENT)) &&
                      /* Start CR 621 */
                      ( (_mqx_uint)(tmp_msg_ptr->CONTROL & MSG_HDR_PRIORITY_MASK) < 
                        (_mqx_uint)(msg_ptr->CONTROL & MSG_HDR_PRIORITY_MASK)) 
                      /* End CR 621 */
                    )
                  )
                  /* Higher priority messages first */
               {
                  /* Put new message into TD */
                  td_ptr->MESSAGE = msg_ptr;
 
/* Start CR 2193 */                  
                  /* Set the new message's ownership to the receiving queue's TD */
                  imsg_ptr = GET_INTERNAL_MESSAGE_PTR(msg_ptr);
                  imsg_ptr->TD_PTR = td_ptr; 

                  /* Old message which we pulled from TD, need to add to queue, below */  
/* End CR 2193 */                                   
                  msg_ptr  = tmp_msg_ptr;  
                  imsg_ptr = GET_INTERNAL_MESSAGE_PTR(msg_ptr);

                  /* Don't know the sender's TD for the swapped out msg,
                     so set it to NULL; */ 
                  imsg_ptr->TD_PTR = NULL;
/* Start CR 2191 */                  
                  /* Indicate that a swap occurred */
                  swapped_msg = TRUE;
                  /* Set the queue to the swapped msg's queue. */
                  if (target_qid != msg_ptr->TARGET_QID)
                  {
                     queue = QUEUE_FROM_QID(msg_ptr->TARGET_QID);
                     msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue];
                     
                     /* This msg's queue was not full when it was short-cut,
                        so we should not get here.  Check anyway. */
                     if ((msgq_ptr->MAX_ENTRIES != 0) &&
                         (msgq_ptr->NO_OF_ENTRIES >= msgq_ptr->MAX_ENTRIES))
                     {
                        /* Queue full, error */
                        _INT_ENABLE();
                        _msg_free(msg_ptr);
                        _task_set_error(MSGQ_QUEUE_FULL);
                        return FALSE;
                     } /* Endif */
                  } /* Endif */
               } /* Endif */
            } /* Endif */

            /* add the message */
            _msgq_insert_message_internal(msgq_ptr, imsg_ptr, swapped_msg);

            if (msgq_ptr->TD_PTR){
               ++(msgq_ptr->TD_PTR->MESSAGES_AVAILABLE);
            } /* Endif */

            /* Now run the notification function */
            if (msgq_ptr->NOTIFICATION_FUNCTION != NULL) {
               (*msgq_ptr->NOTIFICATION_FUNCTION)(msgq_ptr->NOTIFICATION_FUNCTION_PARAMETER);
            } /* Endif */

            if (blocking && ! kernel_data->IN_ISR ) {
               td_ptr = kernel_data->ACTIVE_PTR;
               td_ptr->STATE = SEND_BLOCKED;
               _task_block();
            } /* Endif */

      } /* Endif */
            
   } else {
      /* THIS IS A SYSTEM QUEUE NOT ATTACHED TO A TASK */


         /* add the message to the queue */
         _msgq_insert_message_internal(msgq_ptr, imsg_ptr, FALSE);


         /* Run the notification function. */
         if ( msgq_ptr->NOTIFICATION_FUNCTION != NULL ) {
            (*msgq_ptr->NOTIFICATION_FUNCTION)(msgq_ptr->NOTIFICATION_FUNCTION_PARAMETER);
         } /* Endif */

      } /* Endif */

   } else {
      /* Queue full, error */
      _INT_ENABLE();
      _task_set_error(MSGQ_QUEUE_FULL);
      _msg_free(&imsg_ptr->MESSAGE);
      return FALSE;
   } /* Endif */

   _INT_ENABLE();
   return TRUE;  /* Message sent MQX_OK */

} /* Endbody */
コード例 #7
0
ファイル: lwmsgq_recv.c プロジェクト: gxliu/MQX_3.8.0
_mqx_uint _lwmsgq_receive
   (
      /* Handle to the queue */
      pointer             handle,

      /* location of message to copy to */
      _mqx_max_type_ptr   message,

      /* flags for blocking on empty */
      _mqx_uint           flags,

      /* Timeout for receive if using ticks if 0, ignored */
      _mqx_uint           ticks,

      /* Timeout if receive timout using tick struct must have flags set */
      MQX_TICK_STRUCT_PTR tick_ptr
   )
{/* Body */
   KERNEL_DATA_STRUCT_PTR kernel_data;
   TD_STRUCT_PTR          td_ptr;
   LWMSGQ_STRUCT_PTR      q_ptr = (LWMSGQ_STRUCT_PTR)handle;
   _mqx_uint              i;
   _mqx_max_type_ptr      from_ptr;
   _mqx_max_type_ptr      to_ptr;

#if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI
    if (MQX_RUN_IN_USER_MODE) {
        return _usr_lwmsgq_receive(handle, message, flags, ticks, tick_ptr);
    }
#endif
    
   /* Start CR 1944 */
   _GET_KERNEL_DATA(kernel_data);
   _KLOGE6(KLOG_lwmsgq_receive, handle, message, flags, ticks, tick_ptr);
   /* End CR 1944 */
   
   _int_disable();
#if MQX_CHECK_VALIDITY
   if (q_ptr->VALID != LWMSGQ_VALID){
      _int_enable();
      /* Start CR 1944 */
      _KLOGX2(KLOG_lwmsgq_send, LWMSGQ_INVALID);
      /* End CR 1944 */
      return LWMSGQ_INVALID;
   } /* Endif */
#endif
   if (LWMSGQ_IS_EMPTY(q_ptr)) {
      if (flags & LWMSGQ_RECEIVE_BLOCK_ON_EMPTY) {
         td_ptr = kernel_data->ACTIVE_PTR;
         while (LWMSGQ_IS_EMPTY(q_ptr)) {
            td_ptr->STATE = LWMSGQ_READ_BLOCKED;
            td_ptr->INFO  = (_mqx_uint)&q_ptr->WAITING_READERS;
            _QUEUE_UNLINK(td_ptr);
            _QUEUE_ENQUEUE(&q_ptr->WAITING_READERS, &td_ptr->AUX_QUEUE);
            if (ticks || (flags & (LWMSGQ_TIMEOUT_UNTIL | LWMSGQ_TIMEOUT_FOR))){
               if (ticks) {
                  PSP_ADD_TICKS_TO_TICK_STRUCT(&kernel_data->TIME, ticks,
                     &td_ptr->TIMEOUT);
               } else if (flags & LWMSGQ_TIMEOUT_UNTIL){
                  td_ptr->TIMEOUT = *tick_ptr;
               } else {
                  PSP_ADD_TICKS(tick_ptr, &kernel_data->TIME, &td_ptr->TIMEOUT);
               } /* Endif */
               _time_delay_internal(td_ptr);
               if (td_ptr->INFO != 0) {
                  _int_enable();
                  /* Start CR 1944 */
                  _KLOGX2(KLOG_lwmsgq_receive, LWMSGQ_TIMEOUT);
                  /* End CR 1944 */
                  return LWMSGQ_TIMEOUT;
               } /* Endif */
            } else {
               _sched_execute_scheduler_internal(); /* Let other tasks run */
            } /* Endif */
         } /* Endwhile */
      } else {
         _int_enable();
         /* Start CR 1944 */
         _KLOGX2(KLOG_lwmsgq_receive, LWMSGQ_EMPTY);
         /* End CR 1944 */
         return LWMSGQ_EMPTY;
      } /* Endif */
   }/* Endif */
   from_ptr = q_ptr->MSG_READ_LOC;
   to_ptr = message;
   i = q_ptr->MSG_SIZE+1;
   while (--i) {
      *to_ptr++ = *from_ptr++;
   } /* Endwhile */
   q_ptr->MSG_READ_LOC += q_ptr->MSG_SIZE;
   if (q_ptr->MSG_READ_LOC >= q_ptr->MSG_END_LOC) {
      q_ptr->MSG_READ_LOC = q_ptr->MSG_START_LOC;
   } /* Endif */
   q_ptr->CURRENT_SIZE--;
   if (! _QUEUE_IS_EMPTY(&q_ptr->WAITING_WRITERS)) {
      _QUEUE_DEQUEUE(&q_ptr->WAITING_WRITERS, td_ptr);
      _BACKUP_POINTER(td_ptr, TD_STRUCT, AUX_QUEUE);
      td_ptr->INFO = 0;  /* Signal that post is activating the task */
      _TASK_READY(td_ptr, kernel_data);
      _CHECK_RUN_SCHEDULER(); /* Let higher priority task run */
   } /* Endif */
   _int_enable();
   /* Start CR 1944 */
   _KLOGX2(KLOG_lwmsgq_receive, MQX_OK);
   /* End CR 1944 */
   return MQX_OK;

}/* Endbody */
コード例 #8
0
ファイル: lwmsgq_send.c プロジェクト: gxliu/MQX_3.8.0
_mqx_uint _lwmsgq_send
   (
      /* Handle to the queue */
      pointer           handle,

      /* location of message to copy in */
      _mqx_max_type_ptr message,

      /* flags for blocking on full, blocking on send */
      _mqx_uint         flags
   )
{/* Body */
   KERNEL_DATA_STRUCT_PTR kernel_data;
   TD_STRUCT_PTR          td_ptr;
   LWMSGQ_STRUCT_PTR      q_ptr = (LWMSGQ_STRUCT_PTR)handle;
   _mqx_uint              i;
   _mqx_max_type_ptr      from_ptr;
   _mqx_max_type_ptr      to_ptr;

#if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI
    if (MQX_RUN_IN_USER_MODE) {
        return _usr_lwmsgq_send(handle, message, flags);
    }
#endif
    
   /* Start CR 1944 */
   _GET_KERNEL_DATA(kernel_data);
   _KLOGE4(KLOG_lwmsgq_send, handle, message, flags);
   /* End CR 1944 */
   
   _int_disable();
#if MQX_CHECK_VALIDITY
   if (q_ptr->VALID != LWMSGQ_VALID){
      _int_enable();
      /* Start CR 1944 */
      _KLOGX2(KLOG_lwmsgq_send, LWMSGQ_INVALID);
      /* End CR 1944 */
      return LWMSGQ_INVALID;
   } /* Endif */
#endif
   if (LWMSGQ_IS_FULL(q_ptr)) {
      if (flags & LWMSGQ_SEND_BLOCK_ON_FULL) {
         td_ptr = kernel_data->ACTIVE_PTR;
         while (LWMSGQ_IS_FULL(q_ptr)) {
            td_ptr->STATE = LWMSGQ_WRITE_BLOCKED;
            td_ptr->INFO  = (_mqx_uint)&q_ptr->WAITING_WRITERS;
            _QUEUE_UNLINK(td_ptr);
            _QUEUE_ENQUEUE(&q_ptr->WAITING_WRITERS, &td_ptr->AUX_QUEUE);
            _sched_execute_scheduler_internal(); /* Let other tasks run */
         } /* Endwhile */
      } else {
         _int_enable();
         /* Start CR 1944 */
         _KLOGX2(KLOG_lwmsgq_send, LWMSGQ_FULL);
         /* End CR 1944 */
         return LWMSGQ_FULL;
      } /* Endif */
   }/* Endif */
   to_ptr = q_ptr->MSG_WRITE_LOC;
   from_ptr = message;
   i = q_ptr->MSG_SIZE+1;
   while (--i) {
      *to_ptr++ = *from_ptr++;
   } /* Endwhile */
   q_ptr->MSG_WRITE_LOC += q_ptr->MSG_SIZE;
   if (q_ptr->MSG_WRITE_LOC >= q_ptr->MSG_END_LOC) {
      q_ptr->MSG_WRITE_LOC = q_ptr->MSG_START_LOC;
   } /* Endif */
   q_ptr->CURRENT_SIZE++;
   if (! _QUEUE_IS_EMPTY(&q_ptr->WAITING_READERS)) {
      _QUEUE_DEQUEUE(&q_ptr->WAITING_READERS, td_ptr);
      _BACKUP_POINTER(td_ptr, TD_STRUCT, AUX_QUEUE);
      _TIME_DEQUEUE(td_ptr, kernel_data);
      td_ptr->INFO = 0;  /* Signal that post is activating the task */
      _TASK_READY(td_ptr, kernel_data);
      if (flags & LWMSGQ_SEND_BLOCK_ON_SEND) {
         _task_block();
      } else {
         _CHECK_RUN_SCHEDULER(); /* Let higher priority task run */
      }/* Endif */
   } else {
      if (flags & LWMSGQ_SEND_BLOCK_ON_SEND) {
         _task_block();
      }/* Endif */
   } /* Endif */
   _int_enable();
   /* Start CR 1944 */
   _KLOGX2(KLOG_lwmsgq_send, MQX_OK);
   /* End CR 1944 */
   return MQX_OK;

}/* Endbody */
コード例 #9
0
ファイル: se_post.c プロジェクト: gxliu/MQX_3.8.0
_mqx_uint _sem_post
   (
      /* [IN] -  The semaphore handle returned by _sem_open. */
      pointer users_sem_ptr
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR    kernel_data;
   SEM_STRUCT_PTR            sem_ptr;
#if MQX_COMPONENT_DESTRUCTION
   SEM_COMPONENT_STRUCT_PTR  sem_component_ptr;
#endif
   SEM_CONNECTION_STRUCT_PTR new_sem_connection_ptr;
   SEM_CONNECTION_STRUCT_PTR sem_connection_ptr;
   TD_STRUCT_PTR             new_td_ptr;
   boolean                   task_added = FALSE;
   boolean                   destroying_semaphore = FALSE;
            
   _GET_KERNEL_DATA(kernel_data);

   _KLOGE2(KLOG_sem_post, users_sem_ptr);

   sem_connection_ptr = (SEM_CONNECTION_STRUCT_PTR)users_sem_ptr;

#if MQX_CHECK_VALIDITY
   if (sem_connection_ptr->VALID != SEM_VALID) {
      _KLOGX2(KLOG_sem_post, SEM_INVALID_SEMAPHORE_HANDLE);
      return(SEM_INVALID_SEMAPHORE_HANDLE); 
   } /* Endif */
#endif

   sem_ptr = sem_connection_ptr->SEM_PTR;

#if MQX_CHECK_ERRORS
   if (sem_ptr->POLICY & SEM_STRICT) {
      if (kernel_data->IN_ISR) {
         _KLOGX2(KLOG_sem_post, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
         return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
      } /* Endif */

      if (sem_connection_ptr->TD_PTR != kernel_data->ACTIVE_PTR) {
         /* ONLY OPENING task can use the semaphore */
         _KLOGX2(KLOG_sem_post, SEM_INVALID_SEMAPHORE_HANDLE);
         return(SEM_INVALID_SEMAPHORE_HANDLE); 
      } /* Endif */

      if (sem_connection_ptr->POST_STATE == 0) {
         _KLOGX2(KLOG_sem_post, SEM_CANNOT_POST);
         return(SEM_CANNOT_POST);
      } /* Endif */
   } /* Endif */
#endif

   _INT_DISABLE();
   
#if MQX_CHECK_VALIDITY
   if (sem_ptr->VALID != SEM_VALID) {
      _int_enable();
      _KLOGX2(KLOG_sem_post, SEM_INVALID_SEMAPHORE);
      return(SEM_INVALID_SEMAPHORE);
   } /* Endif */
#endif

   if (sem_ptr->POLICY & SEM_STRICT) {
#if MQX_CHECK_ERRORS
      if (sem_ptr->COUNT > sem_ptr->MAX_COUNT) {
         /* Corruption somewhere */
         _int_enable();
         _KLOGX2(KLOG_sem_post, SEM_INVALID_SEMAPHORE_COUNT);
         return(SEM_INVALID_SEMAPHORE_COUNT);
      } /* Endif */
#endif

      --sem_connection_ptr->POST_STATE;
      if (sem_connection_ptr->POST_STATE == 0) {
         _QUEUE_REMOVE(&sem_ptr->OWNING_TASKS, sem_connection_ptr);
      } /* Endif */
   } /* Endif */


   if (_QUEUE_GET_SIZE(&sem_ptr->WAITING_TASKS)) {
      /* Schedule a waiting task to run */

      new_sem_connection_ptr = (SEM_CONNECTION_STRUCT_PTR)
         ((pointer)sem_ptr->WAITING_TASKS.NEXT);
      while (new_sem_connection_ptr != (pointer)&sem_ptr->WAITING_TASKS) {
         new_td_ptr = new_sem_connection_ptr->TD_PTR;
         if ((new_td_ptr->STATE & STATE_MASK) == SEM_BLOCKED) {
            _TIME_DEQUEUE(new_td_ptr, kernel_data);
            _TASK_READY(new_td_ptr, kernel_data);
            new_td_ptr->INFO = SEM_AVAILABLE;
            task_added = TRUE;
            break;
         } /* Endif */
         new_sem_connection_ptr = (SEM_CONNECTION_STRUCT_PTR)
            new_sem_connection_ptr->NEXT;
      } /* Endwhile */

   } /* Endif */
   
   if (!task_added) {

      ++sem_ptr->COUNT;

#if MQX_COMPONENT_DESTRUCTION
     if ( sem_ptr->DELAYED_DESTROY ) {
        if ( ( (sem_ptr->POLICY & SEM_STRICT) &&
               (sem_ptr->COUNT == sem_ptr->MAX_COUNT) ) ||
             ( !(sem_ptr->POLICY & SEM_STRICT) ) ) 
        {
           /* Destroy the semaphore name */
           sem_ptr->VALID = 0;
           destroying_semaphore = TRUE;
        } /* Endif */
      } /* Endif */
#endif
   } /* Endif */

   if (sem_connection_ptr->BOOSTED && (sem_connection_ptr->POST_STATE == 0)) {
      /* This task was boosted by a waiting task */
      _sched_unboost_priority_internal(kernel_data->ACTIVE_PTR, 
         sem_connection_ptr->BOOSTED);
      sem_connection_ptr->BOOSTED = 0;
   } /* Endif */

   _INT_ENABLE();

   /* Let higher priority task run */
   _CHECK_RUN_SCHEDULER();

#if MQX_COMPONENT_DESTRUCTION
   if (destroying_semaphore) {
      sem_component_ptr = (SEM_COMPONENT_STRUCT_PTR)
         kernel_data->KERNEL_COMPONENTS[KERNEL_SEMAPHORES];
      if (sem_component_ptr != NULL) {
         _name_delete_internal(sem_component_ptr->NAME_TABLE_HANDLE,
            sem_ptr->NAME);
      } /* Endif */
      _mem_free(sem_ptr);
   } /* Endif */
#endif

   _KLOGX2(KLOG_sem_post, MQX_OK);
   return(MQX_OK);

} /* Endbody */