Пример #1
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
QUEUE_ELEMENT_STRUCT_PTR  _queue_dequeue
   ( 
      /* [IN] the queue to use */
      QUEUE_STRUCT_PTR q_ptr 
   )
{ /* Body */
   QUEUE_ELEMENT_STRUCT_PTR e_ptr;
   
   _int_disable();
   if (q_ptr->SIZE == 0) {
      _int_enable();
      return(NULL);
   } /* Endif */
   
   _QUEUE_DEQUEUE(q_ptr, e_ptr);
   _int_enable();
   return(e_ptr);

} /* Endbody */
Пример #3
0
_mqx_uint _mmu_destroy_vcontext
   (
      /* [IN] the task for which a virtual context is to be removed */
      _task_id task_id
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR         kernel_data;
   TD_STRUCT_PTR                  td_ptr;
   PSP_VIRTUAL_CONTEXT_STRUCT_PTR context_ptr;
   PSP_PAGE_INFO_STRUCT_PTR       mem_ptr;
   PSP_SUPPORT_STRUCT_PTR         psp_support_ptr;

   _GET_KERNEL_DATA(kernel_data);
   psp_support_ptr = kernel_data->PSP_SUPPORT_PTR;
   td_ptr = _task_get_td(task_id);
   if (td_ptr == NULL) {
      return(MQX_INVALID_TASK_ID);
   }/* Endif */
   _int_disable();
   if ((td_ptr->FLAGS & TASK_MMU_CONTEXT_EXISTS) == 0) {
      _int_enable();
      return(MQX_MMU_CONTEXT_DOES_NOT_EXIST);
   } /* Endif */
   if (td_ptr == kernel_data->ACTIVE_PTR) {
      /* Remove task MMU pages from the MMU table */
      _mmu_reset_vcontext_internal();
   }/* Endif */
   td_ptr->FLAGS &= ~TASK_MMU_CONTEXT_EXISTS;
   context_ptr = td_ptr->MMU_VIRTUAL_CONTEXT_PTR;
   td_ptr->MMU_VIRTUAL_CONTEXT_PTR = NULL;
   _lwsem_wait(&psp_support_ptr->VPAGE_FREELIST_LWSEM);
   _int_enable();

   while (_QUEUE_GET_SIZE(&context_ptr->PAGE_INFO)) {
      _QUEUE_DEQUEUE(&context_ptr->PAGE_INFO, mem_ptr);
      _QUEUE_ENQUEUE(&psp_support_ptr->VPAGE_FREELIST, &mem_ptr->ELEMENT);
   } /* Endwhile */
   _lwsem_post(&psp_support_ptr->VPAGE_FREELIST_LWSEM);
   _mem_free(context_ptr);
   return(MQX_OK);

} /* Endbody */
Пример #4
0
/*!
 * \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
_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 */
Пример #6
0
_mqx_uint _mmu_add_vcontext
   (
      /* [IN] the task to which a virtual context is to be added */
      _task_id  task_id,

      /* [IN] the virtual address to use */
      pointer   vaddr,

      /* [IN] the size */
      _mem_size input_size,

      /* [IN] the MMU flags to use */
      _mqx_uint flags
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR         kernel_data;
   TD_STRUCT_PTR                  td_ptr;
   PSP_VIRTUAL_CONTEXT_STRUCT_PTR context_ptr;
   PSP_PAGE_INFO_STRUCT_PTR       mem_ptr;
   PSP_SUPPORT_STRUCT_PTR         psp_support_ptr;
   uint_32                        page_size;
   int_32                         test_size;
   int_32                         size = (int_32)input_size;
   uint_32                        result;
   uchar_ptr                      taddr;
   pointer                        tmp;

   _GET_KERNEL_DATA(kernel_data);
   td_ptr = _task_get_td(task_id);
   if (td_ptr == NULL) {
      return(MQX_INVALID_TASK_ID);
   }/* Endif */
   context_ptr = td_ptr->MMU_VIRTUAL_CONTEXT_PTR;
   psp_support_ptr = kernel_data->PSP_SUPPORT_PTR;
   page_size = psp_support_ptr->PAGE_SIZE;

   _lwsem_wait(&psp_support_ptr->VPAGE_FREELIST_LWSEM);
   if ((td_ptr->FLAGS & TASK_MMU_CONTEXT_EXISTS) == 0) {
      _lwsem_post(&psp_support_ptr->VPAGE_FREELIST_LWSEM);
      return(MQX_MMU_CONTEXT_DOES_NOT_EXIST);
   } /* Endif */

   if (size > (_QUEUE_GET_SIZE(&psp_support_ptr->VPAGE_FREELIST) * page_size)) {
      _lwsem_post(&psp_support_ptr->VPAGE_FREELIST_LWSEM);
      return(MQX_OUT_OF_MEMORY);
   }/* Endif */

   /* Verify virtual memory not in use */
   test_size = size;
   taddr = vaddr;
   while (test_size > 0) {
      /* Use Vtop !! */
      if (_mmu_vtop(taddr,&tmp) == MQX_OK) {
         _lwsem_post(&psp_support_ptr->VPAGE_FREELIST_LWSEM);
         return(MQX_INVALID_PARAMETER);
      }/* Endif */
      taddr += page_size;
      test_size -= page_size;
   } /* Endwhile */

   while (size > 0) {
      _QUEUE_DEQUEUE(&psp_support_ptr->VPAGE_FREELIST,mem_ptr);
      mem_ptr->VADDR = vaddr;
      result = _mmu_set_vmem_loc_internal(mem_ptr, flags);
      if (result != MQX_OK) {
         _QUEUE_ENQUEUE(&psp_support_ptr->VPAGE_FREELIST,mem_ptr);
         _lwsem_post(&psp_support_ptr->VPAGE_FREELIST_LWSEM);
         return(MQX_OUT_OF_MEMORY);
      } /* Endif */
      if (td_ptr == kernel_data->ACTIVE_PTR) {
         result = _mmu_add_vregion(mem_ptr->ADDR, mem_ptr->VADDR, page_size,
            flags);
         if (result != MQX_OK) {
            _QUEUE_ENQUEUE(&psp_support_ptr->VPAGE_FREELIST,mem_ptr);
            _lwsem_post(&psp_support_ptr->VPAGE_FREELIST_LWSEM);
            return(MQX_OUT_OF_MEMORY);
         } /* Endif */
      } /* Endif */
      _QUEUE_ENQUEUE(&context_ptr->PAGE_INFO,mem_ptr);
      size  -= page_size;
      vaddr = (pointer)((uint_32)vaddr + page_size);
   } /* Endwhile */

   _lwsem_post(&psp_support_ptr->VPAGE_FREELIST_LWSEM);
   return(MQX_OK);

} /* Endbody */
Пример #7
0
_mqx_uint _lwevent_set
   (
      /* [IN] - The address of the light weight event */
      LWEVENT_STRUCT_PTR   event_ptr, 

      /* [IN] - bit mask, each bit of which represents an event. */
      _mqx_uint bit_mask
   )
{ /* Body */
   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)
         ((pointer)&event_ptr->WAITING_TASKS))
      {
         td_ptr = (pointer)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)))
         {  
/* Start CR 406 */
#if 0
            _QUEUE_DEQUEUE(&event_ptr->WAITING_TASKS, q_ptr);
#endif
            _QUEUE_REMOVE(&event_ptr->WAITING_TASKS, q_ptr);
/* End CR 406 */
            _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);
         
}
Пример #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 */