Пример #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
boolean _watchdog_stop
   (
      void
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR kernel_data;
   TD_STRUCT_PTR          td_ptr;

   _GET_KERNEL_DATA(kernel_data);

   _KLOGE1(KLOG_watchdog_stop);

   td_ptr = kernel_data->ACTIVE_PTR;
   if (td_ptr->FLAGS & TASK_WATCHDOG_STARTED) {
      _INT_DISABLE();
      /* Start CR 333 */
      /* td_ptr->FLAGS &= ~(TASK_WATCHDOG_STARTED | TASK_WATCHDOG_RUNNING); */
      td_ptr->FLAGS &= ~TASK_WATCHDOG_RUNNING;
      /* End CR 333 */
      _INT_ENABLE();
      _KLOGX2(KLOG_watchdog_stop, TRUE);
      return(TRUE);
   } /* Endif */

   _KLOGX2(KLOG_watchdog_stop, FALSE);
   return(FALSE);
   
} /* Endbody */
Пример #3
0
/*!
 * \brief Used by a task to clear the specified event bits in the ligtweight event.
 *
 * \param[in] event_ptr Pointer to the event.
 * \param[in] bit_mask  Bit mask. Each bit represents an event bit to clear.
 *
 * \return MQX_OK
 * \return MQX_LWEVENT_INVALID (Lightweight event is not valid.)
 *
 * \see _lwevent_create
 * \see _lwevent_destroy
 * \see _lwevent_set
 * \see _lwevent_set_auto_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_clear
(
    LWEVENT_STRUCT_PTR  event_ptr,
    _mqx_uint           bit_mask
)
{
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data);

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

    _KLOGM(_GET_KERNEL_DATA(kernel_data));
    _KLOGE3(KLOG_lwevent_clear, event_ptr, bit_mask);

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

    event_ptr->VALUE &= ~bit_mask;
    _INT_ENABLE();

    _KLOGX2(KLOG_lwevent_clear, MQX_OK);
    return (MQX_OK);
}
Пример #4
0
_mqx_uint _lwsem_wait_for
   (
      /* [IN] the semaphore address */
      LWSEM_STRUCT_PTR sem_ptr,

      /* [IN] the number of ticks to delay */
      MQX_TICK_STRUCT_PTR ticks
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR kernel_data;
   TD_STRUCT_PTR          td_ptr;
   _mqx_uint              result;

   _GET_KERNEL_DATA(kernel_data);

   _KLOGE3(KLOG_lwsem_wait_for, sem_ptr, ticks);

#if MQX_CHECK_ERRORS
   if (kernel_data->IN_ISR) {
      _KLOGX2(KLOG_lwsem_wait_for, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
      return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
   } /* Endif */
#endif
#if MQX_CHECK_VALIDITY
   if (sem_ptr->VALID != LWSEM_VALID) {
      _KLOGX2(KLOG_lwsem_wait_for, MQX_INVALID_LWSEM);
      return(MQX_INVALID_LWSEM);
   } /* Endif */
#endif

   _INT_DISABLE();
   if (sem_ptr->VALUE <= 0) {
      td_ptr = kernel_data->ACTIVE_PTR;
      /* Calculate time to wake up the task */
      PSP_ADD_TICKS(ticks, &kernel_data->TIME, &td_ptr->TIMEOUT);
      result = _lwsem_wait_timed_internal(sem_ptr, td_ptr);
   } else {
      --sem_ptr->VALUE;
      /* Start CR 788 */
      result = MQX_OK;
      /* End  CR 788 */
   } /* Endif */

//#if MQX_COMPONENT_DESTRUCTION
   /* We must check for component destruction */
   if (sem_ptr->VALID != LWSEM_VALID) {
      _int_enable();
      /* The semaphore has been deleted */
      _KLOGX2(KLOG_lwsem_wait_for, MQX_INVALID_LWSEM);
      return(MQX_INVALID_LWSEM);
   } /* Endif */
//#endif

   _INT_ENABLE();

   _KLOGX2(KLOG_lwsem_wait_for, result);

   return(result);
   
} /* Endbody */
Пример #5
0
void _time_delay_for
   (
      /* [IN] the number of ticks to delay */
      register MQX_TICK_STRUCT_PTR ticks
   )
{ /* Body */
   register KERNEL_DATA_STRUCT_PTR  kernel_data;
   register TD_STRUCT_PTR           td_ptr;
   
   _GET_KERNEL_DATA(kernel_data);

   _KLOGE2(KLOG_time_delay_for, ticks);

#if MQX_CHECK_ERRORS
   if (ticks == NULL) {
      _task_set_error(MQX_INVALID_PARAMETER);
      _KLOGX2(KLOG_time_delay_for, MQX_INVALID_PARAMETER);
      return;
   } /* Endif */
#endif

   td_ptr = kernel_data->ACTIVE_PTR;

   _INT_DISABLE();

   /* Calculate time to wake up the task */
   PSP_ADD_TICKS(ticks, &kernel_data->TIME, &td_ptr->TIMEOUT);

   _time_delay_internal(td_ptr);

   _INT_ENABLE();

   _KLOGX1(KLOG_time_delay_for);

} /* Endbody */
Пример #6
0
void _time_set
   (
      /* [IN] the address where the new time is to be taken from */
      register TIME_STRUCT_PTR time_ptr
   )
{ /* Body */
   register KERNEL_DATA_STRUCT_PTR kernel_data;
   MQX_TICK_STRUCT                 ticks;

   _GET_KERNEL_DATA(kernel_data);

   _KLOGE4(KLOG_time_set, time_ptr, time_ptr->SECONDS, time_ptr->MILLISECONDS);

   /* Normalize time */
   MQX_NORMALIZE_TIME_STRUCT(time_ptr);

   /* First convert old time struct into the tick struct */
   PSP_TIME_TO_TICKS(time_ptr, &ticks);

   _INT_DISABLE();

   /* Calculate offset */
   PSP_SUB_TICKS(&ticks, &kernel_data->TIME, &kernel_data->TIME_OFFSET);

   _INT_ENABLE();

   _KLOGX1(KLOG_time_set);

} /* Endbody */
Пример #7
0
/*FUNCTION*-----------------------------------------------------
* 
* Function Name    : _mem_alloc_align
* Returned Value   : pointer. NULL is returned upon error.
* Comments         : allocates an aligned block of memory
*
*END*---------------------------------------------------------*/
pointer _mem_alloc_align
   (
      /* [IN] the size of the memory block */
      _mem_size size,
      /* [IN] the alignment of the memory block */
     _mem_size align
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR  kernel_data;
   _mqx_uint               error;
   pointer                 result;

   _GET_KERNEL_DATA(kernel_data);
   _KLOGE2(KLOG_mem_alloc, size);

   _INT_DISABLE();
   result = _mem_alloc_internal_align(size, align, kernel_data->ACTIVE_PTR, (MEMPOOL_STRUCT_PTR)&kernel_data->KD_POOL, &error);

   /* update the memory allocation pointer in case a lower priority
   ** task was preempted inside _mem_alloc_internal
   */
   kernel_data->KD_POOL.POOL_ALLOC_CURRENT_BLOCK = kernel_data->KD_POOL.POOL_FREE_LIST_PTR;

   _INT_ENABLE();
   
#if MQX_CHECK_ERRORS
   if (error != MQX_OK) {
      _task_set_error(error);
   } /* Endif */
#endif

   _KLOGX3(KLOG_mem_alloc_align, result, kernel_data->KD_POOL.POOL_BLOCK_IN_ERROR);
   return(result);
}
Пример #8
0
void _klog_log
(
    /* [IN] what type of log is this */
    _mqx_uint     type,

    /* [IN] parameter 1 */
    _mqx_max_type p1,

    /* [IN] parameter 2 */
    _mqx_max_type p2,

    /* [IN] parameter 3 */
    _mqx_max_type p3,

    /* [IN] parameter 4 */
    _mqx_max_type p4,

    /* [IN] parameter 5 */
    _mqx_max_type p5
)
{   /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    _mqx_max_type          calling_pc;

    _GET_KERNEL_DATA(kernel_data);
    if ( !(kernel_data->LOG_CONTROL & KLOG_ENABLED) ) {
        return;
    } /* Endif */
    if ( kernel_data->LOG_CONTROL & KLOG_TASK_QUALIFIED ) {
        if (! (kernel_data->ACTIVE_PTR->FLAGS & TASK_LOGGING_ENABLED) ) {
            return;
        } /* Endif */
    } /* Endif */

    if ((type == KLOG_FUNCTION_ENTRY) || (type == KLOG_FUNCTION_EXIT))  {
        if ( !(kernel_data->LOG_CONTROL & KLOG_FUNCTIONS_ENABLED) ) {
            return;
        } /* Endif */
        /* Functions enabled, now lets check function group enabled */
        if (((p1 & KLOG_FUNCTION_MASK) & kernel_data->LOG_CONTROL) == 0) {
            return;
        } /* Endif */
    } /* Endif */

    if (type == KLOG_FUNCTION_ENTRY) {
        calling_pc = (_mqx_max_type)_PSP_GET_CALLING_PC();
    } else {
        calling_pc = 0;
    } /* Endif */

    _INT_DISABLE();
    _lwlog_write(LOG_KERNEL_LOG_NUMBER, (_mqx_max_type)type, p1, p2, p3, p4, p5,
                 calling_pc);
    _INT_ENABLE();

} /* Endbody */
Пример #9
0
_mqx_uint _taskq_suspend
   (
      /* [IN] the task queue handle */
      pointer users_task_queue_ptr
   )
{ /* 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);

   _KLOGE2(KLOG_taskq_suspend, users_task_queue_ptr);

#if MQX_CHECK_ERRORS
   if (task_queue_ptr == NULL){
      _KLOGX2(KLOG_taskq_suspend, MQX_INVALID_PARAMETER);
      return(MQX_INVALID_PARAMETER);
   } /* Endif */
   if (kernel_data->IN_ISR) {
      _KLOGX2(KLOG_taskq_suspend, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
      return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
   }/* Endif */
#endif

   td_ptr      = kernel_data->ACTIVE_PTR;

   _INT_DISABLE();

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

   td_ptr->STATE = TASK_QUEUE_BLOCKED;
   _QUEUE_UNLINK(td_ptr); /* Remove task from ready to run queue */
   td_ptr->INFO = (_mqx_uint)&task_queue_ptr->TD_QUEUE;
   if (task_queue_ptr->POLICY & MQX_TASK_QUEUE_BY_PRIORITY)  {
      _sched_insert_priorityq_internal(&task_queue_ptr->TD_QUEUE, td_ptr);
   } else {
      _QUEUE_ENQUEUE(&task_queue_ptr->TD_QUEUE, td_ptr);
   } /* Endif */

   _sched_execute_scheduler_internal(); /* Let the other tasks run */

   _INT_ENABLE();

   _KLOGX2(KLOG_taskq_suspend, MQX_OK);
   return( MQX_OK );
   
} /* Endbody */
Пример #10
0
/*!
 * \brief Marks the message as "free".
 * 
 * Only the task that has the message as its resource can free the message. A 
 * message becomes a task's resource when the task allocates the message, and it 
 * continues to be a resource until the task either frees it or puts it in a 
 * message queue. A message becomes a resource of the task that got it from a 
 * message queue.
 * \n The function returns the message to the message pool from which it was 
 * allocated.
 * 
 * \param[in] msg_ptr Pointer to a message struct which is to be freed.
 * 
 * \warning On failure, calls _task_set_error() to set one the following task 
 * error codes:
 * \li MQX_INVALID_POINTER (Msg_ptr does not point to a valid message.)
 * \li MQX_NOT_RESOURCE_OWNER (Message is already freed.)
 * \li MSGQ_MESSAGE_IS_QUEUED (Message is in a queue.)
 * 
 * \see _msgpool_create
 * \see _msgpool_create_system
 * \see _msgpool_destroy
 * \see _msg_alloc_system
 * \see _msg_alloc
 * \see _task_set_error
 * \see MESSAGE_HEADER_STRUCT    
 */ 
void _msg_free
(
    pointer msg_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR               kernel_data;
    register INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr;
    register MSGPOOL_STRUCT_PTR          msgpool_ptr;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_msg_free, msg_ptr);

    imsg_ptr = GET_INTERNAL_MESSAGE_PTR(msg_ptr);
#if MQX_CHECK_VALIDITY
    if ( imsg_ptr->VALID != MSG_VALID )
    {
        _KLOGX2(KLOG_msg_free, MQX_INVALID_POINTER);
        _task_set_error(MQX_INVALID_POINTER);
        return;
    } /* Endif */
#endif

#if MQX_CHECK_ERRORS
    if (imsg_ptr->FREE)
    {
        _KLOGX2(KLOG_msg_free, MQX_NOT_RESOURCE_OWNER);
        _task_set_error(MQX_NOT_RESOURCE_OWNER);
        return;
    } /* Endif */
    if (imsg_ptr->QUEUED)
    {
        _KLOGX2(KLOG_msg_free, MSGQ_MESSAGE_IS_QUEUED);
        _task_set_error(MSGQ_MESSAGE_IS_QUEUED);
        return;
    } /* Endif */
#endif

    msgpool_ptr = imsg_ptr->MSGPOOL_PTR;
    imsg_ptr->FREE = TRUE;
    imsg_ptr->QUEUED = FALSE;

    _INT_DISABLE();
    /* Link onto the free list */
    imsg_ptr->NEXT = msgpool_ptr->MSG_FREE_LIST_PTR;
    msgpool_ptr->MSG_FREE_LIST_PTR = imsg_ptr;
    ++msgpool_ptr->SIZE;
    _INT_ENABLE();

    _KLOGX2(KLOG_msg_free, MQX_OK);

} /* Endbody */
Пример #11
0
/*!
 * \brief An MQX-provided default ISR for unhandled interrupts. The function
 * depends on the PSP.
 *
 * The function changes the state of the active task to UNHANDLED_INT_BLOCKED and
 * blocks the task.
 * \n The function uses the default I/O channel to display at least:
 * \li Vector number that caused the unhandled exception.
 * \li Task ID and task descriptor of the active task.
 *
 * \n Depending on the PSP, more information might be displayed.
 *
 * \param[in] parameter Parameter passed to the default ISR.
 *
 * \note
 * Since the ISR uses printf() to display information to the default I/O channel,
 * default I/O must not be on a channel that uses interrupt-driven I/O or the
 * debugger.
 *
 * \warning Blocks the active task.
 *
 * \see _int_install_unexpected_isr
 */
void _int_unexpected_isr
(
    void   *parameter
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    TD_STRUCT_PTR              td_ptr;

    _GET_KERNEL_DATA(kernel_data);
    td_ptr = kernel_data->ACTIVE_PTR;

#if MQXCFG_PRINT_MEM_DUMP
#error  "MQXCFG_PRINT_MEM_DUMP functionality is currently not supported. This feature will be supported again in future release.\
         Please set MQXCFG_PRINT_MEM_DUMP to zero."
#endif

#if MQXCFG_PRINT_MEM_DUMP
    {
        unsigned int                psp, msp, i;
        printf("\n\r*** UNHANDLED INTERRUPT ***\n\r");
        printf("Vector #: 0x%02x Task Id: 0x%0x Td_ptr 0x%x\n\r",
        (unsigned int)parameter, (unsigned int)td_ptr->TASK_ID, (unsigned int)td_ptr);

        psp = __get_PSP();
        msp = __get_MSP();
        printf("PSP: 0x%08x MSP: 0x%08x PSR: 0x%08x\n\r", psp, msp, (unsigned int)__get_xPSR());

        printf("\n\r\n\rMemory dump:\n\r");
        for (i = 0; i < 32; i += 4) {
            printf("0x%08x : 0x%08x 0x%08x 0x%08x 0x%08x\n\r", psp + i * 4, ((unsigned int*)psp)[i], ((unsigned int*)psp)[i + 1], ((unsigned int*)psp)[i + 2], ((unsigned int*)psp)[i + 3]);
        }

        printf("\n\r\n\rMemory dump:\n\r");
        for (i = 0; i < 32; i += 4) {
            printf("0x%08x : 0x%08x 0x%08x 0x%08x 0x%08x\n\r", msp + i * 4, ((unsigned int*)msp)[i], ((unsigned int*)msp)[i + 1], ((unsigned int*)msp)[i + 2], ((unsigned int*)msp)[i + 3]);
        }
    }
#endif /* MQXCFG_PRINT_MEM_DUMP */
    _INT_DISABLE();
    if (td_ptr->STATE != UNHANDLED_INT_BLOCKED) {
        td_ptr->STATE = UNHANDLED_INT_BLOCKED;
        td_ptr->INFO  = (_mqx_uint)parameter;

        _QUEUE_UNLINK(td_ptr);
    } /* Endif */
   _INT_ENABLE();

} /* Endbody */
Пример #12
0
_mqx_uint _event_clear
   (
      /* [IN] - An event handle returned from a call to _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;
   register EVENT_CONNECTION_STRUCT_PTR event_connection_ptr;
   register EVENT_STRUCT_PTR            event_ptr;

   _GET_KERNEL_DATA(kernel_data);
   _KLOGE3(KLOG_event_clear, 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_clear, EVENT_INVALID_EVENT_HANDLE);
      return(EVENT_INVALID_EVENT_HANDLE); 
   } /* 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_clear, EVENT_INVALID_EVENT);
      return(EVENT_INVALID_EVENT); 
   } /* Endif */
#endif

   event_ptr->EVENT &= ~bit_mask;
   _INT_ENABLE();

   _KLOGX2(KLOG_event_clear, MQX_OK);
   return(MQX_OK);

} /* Endbody */
Пример #13
0
void _int_unexpected_isr
   (
      /* [IN] the parameter passed to the default ISR, the vector */
      pointer parameter
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR     kernel_data;
   TD_STRUCT_PTR              td_ptr;
   //PSP_INT_CONTEXT_STRUCT_PTR exception_frame_ptr;
   uint_32                    psp, msp, i;

   _GET_KERNEL_DATA(kernel_data);
   td_ptr = kernel_data->ACTIVE_PTR;
   //exception_frame_ptr = kernel_data->INTERRUPT_CONTEXT_PTR;

   printf("\n\r*** UNHANDLED INTERRUPT ***\n\r"); 
   printf("Vector #: 0x%02x Task Id: 0x%0x Td_ptr 0x%x\n\r",
      (uint_32)parameter, (uint_32)td_ptr->TASK_ID, (uint_32)td_ptr);

   psp = __get_PSP();
   msp = __get_MSP();
   printf("PC: 0x%08x LR: 0x%08x PSP: 0x%08x MSP: 0x%08x PSR: 0x%08x\n\r", __get_PC(), __get_LR(), psp, msp, __get_PSR());

   printf("\n\r\n\rMemory dump:\n\r");
   for (i = 0; i < 32; i += 4) {
       printf("0x%08x : 0x%08x 0x%08x 0x%08x 0x%08x\n\r", psp + i * 4, ((uint_32*)psp)[i], ((uint_32*)psp)[i + 1], ((uint_32*)psp)[i + 2], ((uint_32*)psp)[i + 3]);
   }

   printf("\n\r\n\rMemory dump:\n\r");
   for (i = 0; i < 32; i += 4) {
       printf("0x%08x : 0x%08x 0x%08x 0x%08x 0x%08x\n\r", msp + i * 4, ((uint_32*)msp)[i], ((uint_32*)msp)[i + 1], ((uint_32*)msp)[i + 2], ((uint_32*)msp)[i + 3]);
   }

   _INT_ENABLE();
   if (td_ptr->STATE != UNHANDLED_INT_BLOCKED) {
      td_ptr->STATE = UNHANDLED_INT_BLOCKED;
      td_ptr->INFO  = (_mqx_uint)parameter;

      _QUEUE_UNLINK(td_ptr);
   } /* Endif */
   _INT_DISABLE();

} /* Endbody */
Пример #14
0
void _time_get_elapsed_ticks
   (
      /* [IN/OUT] the address where the time is to be put */
      MQX_TICK_STRUCT_PTR tick_ptr
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR kernel_data;

#if MQX_CHECK_ERRORS
   if ( tick_ptr == NULL ) {
      return;
   } /* Endif */
#endif

   _GET_KERNEL_DATA(kernel_data);

   _INT_DISABLE();

   *tick_ptr = kernel_data->TIME;
   /* Start CR 1082*/
   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.
      tick_ptr->HW_TICKS = (*kernel_data->GET_HWTICKS)
         (kernel_data->GET_HWTICKS_PARAM);
   } /* Endif */

   _INT_ENABLE(); // The timer ISR may go off and increment kernel_data->TIME

   // 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(tick_ptr);
   /* End CR 1082*/

} /* Endbody */
Пример #15
0
/*!
 * \brief Writes to the lightweight log.
 *
 * This function writes the log entry only if it returns MQX_OK.
 *
 * \param[in] log_number Log number of a previously created lightweight log.
 * \param[in] p1         Data to be written to the log entry. If log_number is 0
 * and p1 is >= 10 (0 through 9 are reserved for MQX), data specified by p2 through
 * p7 is written to kernel log.
 * \param[in] p2         Data to be written into the log entry.
 * \param[in] p3         Data to be written into the log entry.
 * \param[in] p4         Data to be written into the log entry.
 * \param[in] p5         Data to be written into the log entry.
 * \param[in] p6         Data to be written into the log entry.
 * \param[in] p7         Data to be written into the log entry.
 *
 * \return MQX_OK
 * \return LOG_FULL (Log is full and LOG_OVERWRITE is not set.)
 * \return LOG_DISABLED (Log is disabled.)
 * \return LOG_INVALID (Log_number is out of range.)
 * \return LOG_DOES_NOT_EXIST (Log_number was not created.)
 * \return MQX_INVALID_COMPONENT_HANDLE (Log component data is not valid.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Log component is not created.)
 *
 * \see _lwlog_create
 * \see _lwlog_create_at
 * \see _lwlog_read
 * \see _lwlog_disable
 * \see _lwlog_enable
 */
_mqx_uint _lwlog_write
(
    _mqx_uint     log_number,
    _mqx_max_type p1,
    _mqx_max_type p2,
    _mqx_max_type p3,
    _mqx_max_type p4,
    _mqx_max_type p5,
    _mqx_max_type p6,
    _mqx_max_type p7
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    _mqx_uint              result;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (log_number >= LOG_MAXIMUM_NUMBER)
    {
        return (LOG_INVALID);
    } /* Endif */

    if (kernel_data->KERNEL_COMPONENTS[KERNEL_LWLOG] == NULL)
    {
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif

    _INT_DISABLE();

    result = _lwlog_write_internal(log_number, p1, p2, p3, p4, p5, p6, p7);

    _INT_ENABLE();

    return (result);

} /* Endbody */
Пример #16
0
pointer _mem_alloc_system_zero_uncached
   (
      /* [IN] the size of the memory block */
      _mem_size size
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR  kernel_data;
   pointer                 result;
   _mqx_uint               error;

   _GET_KERNEL_DATA(kernel_data);
   //_KLOGE2(KLOG_mem_alloc_system_zero_uncached, size);

   _INT_DISABLE();
   result = _mem_alloc_internal(size, SYSTEM_TD_PTR(kernel_data), (MEMPOOL_STRUCT_PTR)&kernel_data->UNCACHED_POOL, &error);

   /* update the memory allocation pointer in case a lower priority
   ** task was preempted inside _mem_alloc_internal
   */
   kernel_data->UNCACHED_POOL.POOL_ALLOC_CURRENT_BLOCK = kernel_data->UNCACHED_POOL.POOL_FREE_LIST_PTR;

   _INT_ENABLE();
   
#if MQX_CHECK_ERRORS
   if (error != MQX_OK) {
      _task_set_error(error);
   } /* Endif */
#endif

   if (result != NULL) {
      _mem_zero(result, size);
   } /* Endif */

   //_KLOGX3(KLOG_mem_alloc_system_zero_uncached, result, kernel_data->UNCACHED_POOL.POOL_BLOCK_IN_ERROR);
   return(result);

}
Пример #17
0
MESSAGE_HEADER_STRUCT_PTR _msgq_receive_internal
   (
      /* [IN]  id of the queue from which a message is to be received */
     _queue_id             queue_id,

      /* [IN]  indication of the number of ticks which can expire before
      **       this request times out
      */
      MQX_TICK_STRUCT_PTR  timeout_tick_ptr,

      /* [IN]  relative or absolute time specified in tick_ptr */
      _mqx_uint            mode,

      /* [OUT] where the error code is to be stored */
      _mqx_uint_ptr        error_ptr
   )
{ /* Body */
            KERNEL_DATA_STRUCT_PTR      kernel_data;
            MSG_COMPONENT_STRUCT_PTR    msg_component_ptr;
   register TD_STRUCT_PTR               td_ptr;
            MESSAGE_HEADER_STRUCT_PTR   message_ptr;
   register INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr;
   register MSGQ_STRUCT_PTR             msgq_ptr;
            _queue_number               queue;

   *error_ptr = MQX_OK;

   _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
   if (kernel_data->IN_ISR) {
      _task_set_error(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
      *error_ptr = MQX_CANNOT_CALL_FUNCTION_FROM_ISR;
      return(NULL);
   }/* Endif */
#endif
 
   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);
      *error_ptr = MQX_COMPONENT_DOES_NOT_EXIST;
      return(NULL);
   } /* Endif */
#endif

   message_ptr    = NULL;
   td_ptr         = kernel_data->ACTIVE_PTR;

   if (queue_id == MSGQ_ANY_QUEUE){
      /* if queue_id is 0 than a receive from any queue is performed */

      /* Does the task own a queue */
      if (td_ptr->MSG_QUEUE_HEAD == NULL){
         /* Does NOT */
         _task_set_error(MSGQ_QUEUE_IS_NOT_OPEN);
         *error_ptr = MSGQ_QUEUE_IS_NOT_OPEN;
         return NULL;
      } /* Endif */

      _INT_DISABLE();
      if (td_ptr->MESSAGES_AVAILABLE == 0){
         td_ptr->STATE = RCV_ANY_BLOCKED;
         td_ptr->INFO = queue_id;
         td_ptr->MESSAGE = NULL;

         if (mode == MSG_TIMEOUT_NONE) {
            _task_block();
         } else if (mode == MSG_TIMEOUT_RELATIVE) {
            _time_delay_for(timeout_tick_ptr);
         } else {
            _time_delay_until(timeout_tick_ptr);
         } /* Endif */

         /* 
         ** SHORT CUT...
         ** The message send routine does not queue up a message in this case.
         ** the message is deposited directly into the task descriptor
         */
         message_ptr = (MESSAGE_HEADER_STRUCT_PTR)td_ptr->MESSAGE;
         if (message_ptr == NULL){
            /* A timeout has occurred */
            #if MQXCFG_ENABLE_MSG_TIMEOUT_ERROR
            _task_set_error(MSGQ_MESSAGE_NOT_AVAILABLE);
            #endif
         } /* Endif */
         td_ptr->MESSAGE = NULL;

      } else {

         /*  Check all queues for an available entry .. There must be at least
         **  one entry available
         */
         msgq_ptr = (MSGQ_STRUCT_PTR)td_ptr->MSG_QUEUE_HEAD;
         while (msgq_ptr != NULL){

            if (msgq_ptr->NO_OF_ENTRIES){
               /* dequeue the top entry */
               DEQUEUE_TOP_MSG_ENTRY(msgq_ptr, imsg_ptr, message_ptr, td_ptr);
               break;
            } /* Endif */
            msgq_ptr = msgq_ptr->NEXT_MSGQ_PTR;

         } /* Endwhile */
      } /* Endif */

   } else {

      /* RECEIVE from a specific qid */
      queue = QUEUE_FROM_QID(queue_id);
#if MQX_CHECK_ERRORS
      if ( (PROC_NUMBER_FROM_QID(queue_id) != kernel_data->INIT.PROCESSOR_NUMBER) ||
         (! VALID_QUEUE(queue)) )
      {
         _task_set_error(MSGQ_INVALID_QUEUE_ID);
         *error_ptr = MSGQ_INVALID_QUEUE_ID;
         return (pointer)message_ptr;
      } /* Endif */
#endif

      msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue];
#if MQX_CHECK_ERRORS
      if ( msgq_ptr->QUEUE != queue ) {
         _task_set_error(MSGQ_QUEUE_IS_NOT_OPEN);
         *error_ptr =  MSGQ_QUEUE_IS_NOT_OPEN;
         return message_ptr;
      } /* Endif */
      if ( (msgq_ptr->TD_PTR != NULL) && (msgq_ptr->TD_PTR != td_ptr) ) {
         _task_set_error(MSGQ_NOT_QUEUE_OWNER);
         *error_ptr = MSGQ_NOT_QUEUE_OWNER;
         return message_ptr;
      } /* Endif */
#endif

      /*
      ** check the specified queue for an entry
      ** if not entry, then block until an entry is received or
      ** timeout occurs
      */
      _INT_DISABLE();
      if (msgq_ptr->NO_OF_ENTRIES == 0) {
         if (msgq_ptr->TD_PTR == NULL) {
            /* A system message queue, indicate none available */
            message_ptr = NULL;
         } else {
            td_ptr->STATE   = RCV_SPECIFIC_BLOCKED;
            td_ptr->INFO    = queue;
            td_ptr->MESSAGE = NULL;

            if (mode == MSG_TIMEOUT_NONE) {
               _task_block();
            } else if (mode == MSG_TIMEOUT_RELATIVE) {
               _time_delay_for(timeout_tick_ptr);
            } else {
               _time_delay_until(timeout_tick_ptr);
            } /* Endif */

            message_ptr = (MESSAGE_HEADER_STRUCT_PTR)td_ptr->MESSAGE;
            if ( message_ptr == NULL ) {
               #if MQXCFG_ENABLE_MSG_TIMEOUT_ERROR
               _task_set_error(MSGQ_MESSAGE_NOT_AVAILABLE);
               #endif
            } else if ((message_ptr->TARGET_QID != queue_id) &&
                       (msgq_ptr->NO_OF_ENTRIES > 0)) {
               /* The original msg was swapped out in msgq_sendi() for 
                  a higher priority msg with a different target_qid.
                  Enqueue this msg, and then dequeue the msg we need.
                */
               register MSGQ_STRUCT_PTR tmp_msgq_ptr;
               register _queue_number   tmp_queue;
              
               /* Get the msg's queue */
               tmp_queue = QUEUE_FROM_QID(message_ptr->TARGET_QID);
               tmp_msgq_ptr = &msg_component_ptr->MSGQS_PTR[tmp_queue];

               if ((tmp_msgq_ptr->MAX_ENTRIES == 0) ||
                   (tmp_msgq_ptr->NO_OF_ENTRIES < tmp_msgq_ptr->MAX_ENTRIES))
               {
                   /* the msg's queue has room */
                   imsg_ptr = GET_INTERNAL_MESSAGE_PTR(message_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);
                      message_ptr = NULL;
                   } else
#endif
                   {
                      /* enqueue the msg */
                      _msgq_insert_message_internal(tmp_msgq_ptr, imsg_ptr, TRUE);
                      
                      if (tmp_msgq_ptr->TD_PTR) {
                         ++(tmp_msgq_ptr->TD_PTR->MESSAGES_AVAILABLE);
                      } /* Endif */

                      /* now dequeue our queue's top entry */
                      DEQUEUE_TOP_MSG_ENTRY(msgq_ptr, imsg_ptr, message_ptr, td_ptr);
                   }
               } else {
                  /* Queue full, error - this should not happen 
                     since msgq_sendi() checks for room on the queue 
                     for all msgs, including short-cut msgs. */
                  _task_set_error(MSGQ_QUEUE_FULL);
                  message_ptr = NULL;
               }
            } /* Endif */
            td_ptr->MESSAGE = NULL;
         } /* Endif */
      } else {   
         /* dequeue the top entry */
         DEQUEUE_TOP_MSG_ENTRY(msgq_ptr, imsg_ptr, message_ptr, td_ptr);
      } /* Endif */
   } /* Endif */
      
   _INT_ENABLE();

   return message_ptr;

} /* Endbody */
Пример #18
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 */
Пример #19
0
_mqx_uint _lwsem_wait_ticks
   (
      /* [IN] the semaphore address */
      LWSEM_STRUCT_PTR sem_ptr,

      /* [IN] the number of ticks to delay, if 0, delay forever */
      _mqx_uint time_in_ticks
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR kernel_data;
   TD_STRUCT_PTR          td_ptr;
   _mqx_uint              result;
   
#if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI
    if (MQX_RUN_IN_USER_MODE) {
        return _usr_lwsem_wait_ticks(sem_ptr, time_in_ticks);
    }
#endif

   _GET_KERNEL_DATA(kernel_data);

   _KLOGE3(KLOG_lwsem_wait_ticks, sem_ptr, time_in_ticks);

#if MQX_CHECK_ERRORS
   if (kernel_data->IN_ISR) {
      _KLOGX2(KLOG_lwsem_wait_ticks, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
      return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
   } /* Endif */
#endif
#if MQX_CHECK_VALIDITY
   if (sem_ptr->VALID != LWSEM_VALID) {
      _KLOGX2(KLOG_lwsem_wait_ticks, MQX_INVALID_LWSEM);
      return(MQX_INVALID_LWSEM);
   } /* Endif */
#endif

   _INT_DISABLE();
   if (sem_ptr->VALUE <= 0) {
      td_ptr = kernel_data->ACTIVE_PTR;
      if (time_in_ticks == 0) {
         td_ptr->STATE = LWSEM_BLOCKED;
         td_ptr->INFO  = (_mqx_uint)&sem_ptr->TD_QUEUE;
         _QUEUE_UNLINK(td_ptr);
         _QUEUE_ENQUEUE(&sem_ptr->TD_QUEUE, &td_ptr->AUX_QUEUE);
         _sched_execute_scheduler_internal();  /* Let the other tasks run */
         /* Another task has posted a semaphore, and it has been tranfered to this 
         ** task.
         */
         result = MQX_OK;
      } else {
         PSP_ADD_TICKS_TO_TICK_STRUCT(&kernel_data->TIME, time_in_ticks, 
            &td_ptr->TIMEOUT);
         result = _lwsem_wait_timed_internal(sem_ptr, td_ptr);
      } /* Endif */
   } else {
      --sem_ptr->VALUE;
      /* Start CR 788 */
      result = MQX_OK;
      /* End  CR 788 */
   } /* Endif */

//#if MQX_COMPONENT_DESTRUCTION
   /* We must check for component destruction */
   if (sem_ptr->VALID != LWSEM_VALID) {
      _int_enable();
      /* The semaphore has been deleted */
      _KLOGX2(KLOG_lwsem_wait_ticks, MQX_INVALID_LWSEM);
      return(MQX_INVALID_LWSEM);
   } /* Endif */
//#endif

   _INT_ENABLE();

   _KLOGX2(KLOG_lwsem_wait_ticks, result);

   return(result);
   
}
Пример #20
0
/*!
 * \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);

}
Пример #21
0
/*!
 * \brief Reads the data from the log.
 * 
 * <table>
 *   <tr>
 *     <td><b>read_type</b></td>
 *     <td><b>Returns this entry in the log:</b></td> 
 *   </tr>
 *   <tr>
 *     <td>LOG_READ_NEWEST</td>
 *     <td>Newest.</td> 
 *   </tr>
 *   <tr>
 *     <td>LOG_READ_NEXT</td>
 *     <td>Next one after the previous one read (must be used with LOG_READ_OLDEST).</td> 
 *   </tr>
 *   <tr>
 *     <td>LOG_READ_OLDEST</td>
 *     <td>Oldest.</td> 
 *   </tr>
 *   <tr>
 *     <td>LOG_READ_OLDEST_AND_DELETE</td>
 *     <td>Oldest and deletes it.</td> 
 *   </tr>     
 * </table>
 * 
 * \param[in] log_number   Log number of a previously created log.
 * \param[in] read_type    Type of read operation (see Description).
 * \param[in] size_to_read Maximum number of _mqx_uints (not including the entry 
 * header) to be read from an entry.
 * \param[in] entry_ptr    Where to write the log entry (any structure that 
 * starts with LOG_STRUCT or LOG_ENTRY_STRUCT).
 * 
 * \return MQX_OK
 * \return LOG_INVALID (Log_number is out of range.)
 * \return LOG_DOES_NOT_EXIST (Log_number was not created.)
 * \return LOG_ENTRY_NOT_AVAILABLE (Log entry is not available.)
 * \return LOG_INVALID_READ_TYPE (Read_type is not valid.) 
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Log component is not created.)
 * \return MQX_INVALID_POINTER (Entry_ptr is NULL.)
 * \return MQX_INVALID_COMPONENT_HANDLE (Log component data is not valid.)
 * 
 * \see _log_create
 * \see _log_write
 * \see LOG_STRUCT
 * \see LOG_ENTRY_STRUCT        
 */ 
_mqx_uint _log_read
(
    _mqx_uint            log_number,
    _mqx_uint            read_type,
    _mqx_uint            size_to_read,
    LOG_ENTRY_STRUCT_PTR entry_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    LOG_COMPONENT_STRUCT_PTR log_component_ptr;
    LOG_HEADER_STRUCT_PTR    log_header_ptr;
    LOG_ENTRY_STRUCT_PTR     log_ptr;
    _mqx_uint_ptr            data_ptr;
    _mqx_uint_ptr            next_ptr;
    _mqx_uint_ptr            user_ptr;
    _mqx_uint                size;
    uint_16                  milliseconds;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (log_number >= LOG_MAXIMUM_NUMBER)
    {
        return(LOG_INVALID);
    } /* Endif */
    if (kernel_data->KERNEL_COMPONENTS[KERNEL_LOG] == NULL)
    {
        return(MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
    if (entry_ptr == NULL)
    {
        return(MQX_INVALID_POINTER);
    } /* Endif */
#endif

    log_component_ptr = (LOG_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_LOG];

#if MQX_CHECK_VALIDITY
    if (log_component_ptr->VALID != LOG_VALID)
    {
        return(MQX_INVALID_COMPONENT_HANDLE);
    } /* Endif */
#endif

    _INT_DISABLE();
    log_header_ptr = log_component_ptr->LOGS[log_number];
#if MQX_CHECK_ERRORS
    if (log_header_ptr == NULL)
    {
        _int_enable();
        return(LOG_DOES_NOT_EXIST);
    } /* Endif */
#endif

    if (log_header_ptr->SIZE == 0)
    {
        /* No data available */
        _INT_ENABLE();
        return(LOG_ENTRY_NOT_AVAILABLE);
    } /* Endif */

    if (read_type == LOG_READ_OLDEST_AND_DELETE)
    {
        data_ptr = log_header_ptr->LOG_READ;
    }
    else if (read_type == LOG_READ_NEXT)
    {
        data_ptr = log_header_ptr->LOG_NEXT;
        if (data_ptr == NULL)
        {
            _INT_ENABLE();
            return(LOG_ENTRY_NOT_AVAILABLE);
        } /* Endif */
    }
    else if (read_type == LOG_READ_OLDEST)
    {
        data_ptr = log_header_ptr->LOG_READ;
    }
    else if (read_type == LOG_READ_NEWEST)
    {
        data_ptr = log_header_ptr->LAST_LOG;
#if MQX_CHECK_ERRORS
    }
    else
    {
        _int_enable();
        return(LOG_INVALID_READ_TYPE);
#endif
    } /* Endif */

    size = *data_ptr;
    next_ptr = data_ptr + size;

#if 0
    if (next_ptr >= log_header_ptr->LOG_END)
    {
        next_ptr = log_header_ptr->LOG_START +
        (next_ptr - log_header_ptr->LOG_END);
    } /* Endif */
#else
    if (log_header_ptr->LOG_READ < log_header_ptr->LOG_WRITE)
    {
        /* R < W */
        if (next_ptr >= log_header_ptr->LOG_WRITE)
        {
            next_ptr = log_header_ptr->LOG_READ;
        } /* Endif */
    }
    else
    {
        /* R > W */
        if (next_ptr >= log_header_ptr->LOG_END)
        {
            next_ptr = log_header_ptr->LOG_START +
            (next_ptr - log_header_ptr->LOG_END);
        } /* Endif */
        if (next_ptr == log_header_ptr->LOG_WRITE)
        {
            next_ptr = log_header_ptr->LOG_READ;
        } /* Endif */
    } /* Endif */
#endif

    if (read_type == LOG_READ_OLDEST_AND_DELETE)
    {
        log_header_ptr->LOG_READ += size;
        log_header_ptr->SIZE -= size;
        if (log_header_ptr->LOG_READ >= log_header_ptr->LOG_END)
        {
            log_header_ptr->LOG_READ = log_header_ptr->LOG_START +
            (log_header_ptr->LOG_READ - log_header_ptr->LOG_END);
        } /* Endif */
    } /* Endif */

    if (size > (size_to_read + (_mqx_uint)sizeof(LOG_ENTRY_STRUCT)/sizeof(_mqx_uint)))
    {
        size = (size_to_read + (_mqx_uint)sizeof(LOG_ENTRY_STRUCT)/sizeof(_mqx_uint));
    } /* Endif */

    ++size;
    user_ptr = (_mqx_uint_ptr)((pointer)entry_ptr);
    while (--size)
    {
        *user_ptr++ = *data_ptr++;
        if (data_ptr == log_header_ptr->LOG_END)
        {
            data_ptr = log_header_ptr->LOG_START;
        } /* Endif */
    } /* Endwhile */
    log_ptr = entry_ptr;
    if (log_ptr->MICROSECONDS > MICROSECS_IN_MILLISECOND)
    {
        milliseconds = log_ptr->MICROSECONDS / (uint_16)MICROSECS_IN_MILLISECOND;
        log_ptr->MILLISECONDS += milliseconds;
        log_ptr->MICROSECONDS -= (milliseconds * (uint_16)MICROSECS_IN_MILLISECOND);
    } /* Endif */

    if (read_type == LOG_READ_NEXT)
    {
        log_header_ptr->LOG_NEXT = next_ptr;
    }
    else if (read_type == LOG_READ_OLDEST)
    {
        log_header_ptr->LOG_NEXT = next_ptr;
    }
    else
    {
        log_header_ptr->LOG_NEXT = NULL;
    } /* Endif */
    _INT_ENABLE();

    return(MQX_OK);

} /* Endbody */
Пример #22
0
/*!
 * \brief Allocates a message from the private message pool.
 * 
 * The size of the message is determined by the message size that a task 
 * specified when it called _msgpool_create(). The message is a resource of the 
 * task until the task either frees it (_msg_free()) or puts it on a message 
 * queue (_msgq_send() family of functions.)
 * 
 * \param[in] pool A pool ID from _msgpool_create().
 * 
 * \return Pointer to a message (Success.)
 * \return NULL (Failure.)
 *  
 * \warning On failure, calls _task_set_error() to set one the following task 
 * error codes:
 * \li MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * \li MSGPOOL_INVALID_POOL_ID (Pool_id is not valid.)
 * \li MSGPOOL_OUT_OF_MESSAGES (All the messages in the pool are allocated.)
 * \li Task error codes from _mem_alloc_system() (If MQX needs to grow the pool.)
 * 
 * \see _msg_alloc_system
 * \see _msg_free
 * \see _msgpool_create
 * \see _msgpool_destroy
 * \see _task_set_error
 * \see _mem_alloc
 * \see _mem_alloc_from
 * \see _mem_alloc_system
 * \see _mem_alloc_system_from
 * \see _mem_alloc_system_zero
 * \see _mem_alloc_system_zero_from
 * \see _mem_alloc_zero
 * \see _mem_alloc_zero_from
 * \see _mem_alloc_align
 * \see _mem_alloc_align_from
 * \see _mem_alloc_at
 * \see MESSAGE_HEADER_STRUCT     
 */ 
pointer _msg_alloc
(
    _pool_id pool
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR               kernel_data;
#if MQX_CHECK_ERRORS
    MSG_COMPONENT_STRUCT_PTR             msg_component_ptr;
#endif
    register INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr;
    register MESSAGE_HEADER_STRUCT_PTR   message_ptr;
    register MSGPOOL_STRUCT_PTR          msgpool_ptr;
    uint_16                              grow_number;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_msg_alloc, pool);

#if MQX_CHECK_ERRORS
    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
    if (msg_component_ptr == NULL)
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        _KLOGX3(KLOG_msg_alloc, NULL, MQX_COMPONENT_DOES_NOT_EXIST);
        return(NULL);
    } /* Endif */
#endif

    message_ptr = NULL;
    msgpool_ptr = (MSGPOOL_STRUCT_PTR)pool;

#if MQX_CHECK_VALIDITY || MQX_CHECK_ERRORS
    if (
#if MQX_CHECK_VALIDITY
                    (msgpool_ptr->VALID != MSG_VALID)
#if MQX_CHECK_ERRORS
                    ||
#endif
#endif
#if MQX_CHECK_ERRORS
                    (msgpool_ptr->MSGPOOL_TYPE != MSG_POOL)
#endif
    )
    {
        _task_set_error(MSGPOOL_INVALID_POOL_ID);
        _KLOGX3(KLOG_msg_alloc, message_ptr, MSGPOOL_INVALID_POOL_ID);
        return (message_ptr);
    } /* Endif */
#endif

    if ( (msgpool_ptr->SIZE == 0) && (msgpool_ptr->GROW_NUMBER) &&
                    ( (msgpool_ptr->MAX < msgpool_ptr->GROW_LIMIT) ||
                                    (msgpool_ptr->GROW_LIMIT == 0) ) )
    {
        /* Attempt to add elements to the pool */
        grow_number = msgpool_ptr->GROW_NUMBER;
        if (grow_number > (uint_16)(msgpool_ptr->GROW_LIMIT - msgpool_ptr->MAX))
        {
            grow_number = msgpool_ptr->GROW_LIMIT - msgpool_ptr->MAX;
        } /* Endif */
        _msgpool_add_internal(msgpool_ptr, grow_number);
    } /* Endif */

    _INT_DISABLE();
    imsg_ptr = msgpool_ptr->MSG_FREE_LIST_PTR;
    if (imsg_ptr == NULL)
    {
        _int_enable();
        _task_set_error(MSGPOOL_OUT_OF_MESSAGES);
        _KLOGX3(KLOG_msg_alloc, message_ptr, MSGPOOL_OUT_OF_MESSAGES);
        return((pointer)message_ptr);
    } /* Endif */

    msgpool_ptr->MSG_FREE_LIST_PTR = imsg_ptr->NEXT;
    --msgpool_ptr->SIZE;
    _INT_ENABLE();
    imsg_ptr->FREE = FALSE;
    imsg_ptr->QUEUED = FALSE;
    if (kernel_data->IN_ISR)
    {
        imsg_ptr->TD_PTR = NULL;
    }
    else
    {
        imsg_ptr->TD_PTR = kernel_data->ACTIVE_PTR;
    } /* Endif */
    message_ptr = (MESSAGE_HEADER_STRUCT_PTR)&imsg_ptr->MESSAGE;
    message_ptr->TARGET_QID = MSGQ_NULL_QUEUE_ID;
    message_ptr->SOURCE_QID = MSGQ_NULL_QUEUE_ID;
    message_ptr->SIZE = msgpool_ptr->MESSAGE_SIZE;
    message_ptr->CONTROL = MSG_HDR_ENDIAN | MSG_DATA_ENDIAN;
    _KLOGX3(KLOG_msg_alloc, message_ptr, MQX_OK);
    return (pointer)message_ptr;

} /* Endbody */
Пример #23
0
/*!
 * \brief Gets the number of free messages in the message pool.
 * 
 * The function fails if either:
 * \li Message component is not created.
 * \li Pool_id is for a private message pool, but does not represent a valid one.
 * 
 * \param[in] pool One of the following:
 * \li Private message pool for which to get the number of free messages.
 * \li MSGPOOL_NULL_POOL_ID (for system message pools).
 * 
 * \return The number of free messages in the private message pool (success).
 * \return The number of free messages in all system message pools (success).
 * \return 0 (Success: No free messages.)
 * \return 0 (Failure: see Description.)
 * 
 * \warning If pool_id does not represent a valid private message pool, calls 
 * _task_set_error() to set the task error code to MSGPOOL_INVALID_POOL_ID
 * 
 * \see _msgpool_create
 * \see _msgpool_destroy
 * \see _msg_free
 * \see _msg_alloc_system
 * \see _task_set_error
 * \see _msg_create_component      
 */ 
_mqx_uint _msg_available
(
    _pool_id pool
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR      kernel_data;
    MSG_COMPONENT_STRUCT_PTR    msg_component_ptr;
    register MSGPOOL_STRUCT_PTR msgpool_ptr;
    _mqx_uint                   i;
    _mqx_uint                   count;

    _GET_KERNEL_DATA(kernel_data);

    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
#if MQX_CHECK_ERRORS
    if (msg_component_ptr == NULL)
    {
        return(0);
    } /* Endif */
#endif

    msgpool_ptr = msg_component_ptr->MSGPOOLS_PTR;
#if MQX_CHECK_ERRORS
    if (msgpool_ptr == NULL)
    {
        return(0);
    }/* Endif */
#endif

    if (pool == MSGPOOL_NULL_POOL_ID)
    {

        count = 0;
        _INT_DISABLE();
        i = msg_component_ptr->MAX_MSGPOOLS_EVER + 1;
        while ( --i )
        {
            if (
#if MQX_CHECK_VALIDITY
                (msgpool_ptr->VALID == MSG_VALID) &&
#endif
                (msgpool_ptr->MSGPOOL_TYPE == SYSTEM_MSG_POOL))
            {
                count += msgpool_ptr->SIZE;
            } /* Endif */
            ++msgpool_ptr;
        } /* Endwhile */
        _INT_ENABLE();
        return count;

    }
    else
    {

        msgpool_ptr = (MSGPOOL_STRUCT_PTR)pool;
        if (
#if MQX_CHECK_VALIDITY
            (msgpool_ptr->VALID != MSG_VALID) ||
#endif
            (msgpool_ptr->MSGPOOL_TYPE != MSG_POOL) )
        {
            _task_set_error(MSGPOOL_INVALID_POOL_ID);
            return (0);
        } /* Endif */
        return (_mqx_uint)msgpool_ptr->SIZE;

    } /* Endif */

} /* Endbody */
Пример #24
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 */
Пример #25
0
_mqx_uint _mem_create_pool_internal
(
    /* [IN] the start of the memory pool */
    pointer             start,

    /* [IN] the end of the memory pool */
    pointer             end,

    /* [IN] where to store the memory pool context info. */
    MEMPOOL_STRUCT_PTR  mem_pool_ptr

)
{   /* Body */
    KERNEL_DATA_STRUCT_PTR  kernel_data;
    STOREBLOCK_STRUCT_PTR   block_ptr;
    STOREBLOCK_STRUCT_PTR   end_block_ptr;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_VALIDITY
    _INT_DISABLE();
    if (kernel_data->MEM_COMP.VALID != MEMPOOL_VALID) {
        /* The RTOS memory system has been corrupted */
        _int_enable();
        return(MQX_CORRUPT_MEMORY_SYSTEM);
    } /* Endif */

    _INT_ENABLE();
#endif

    /* Align the start of the pool */
    mem_pool_ptr->POOL_PTR = (STOREBLOCK_STRUCT_PTR)
                             _ALIGN_ADDR_TO_HIGHER_MEM(start);

    /* Set the end of memory (aligned) */
    mem_pool_ptr->POOL_LIMIT = (STOREBLOCK_STRUCT_PTR)
                               _ALIGN_ADDR_TO_LOWER_MEM(end);

#if MQX_CHECK_ERRORS
    if ( (uchar_ptr)mem_pool_ptr->POOL_LIMIT <=
            ((uchar_ptr)mem_pool_ptr->POOL_PTR + MQX_MIN_MEMORY_POOL_SIZE) )
    {
        return MQX_MEM_POOL_TOO_SMALL;
    } /* Endif */
#endif

    block_ptr = (STOREBLOCK_STRUCT_PTR)mem_pool_ptr->POOL_PTR;
    mem_pool_ptr->POOL_HIGHEST_MEMORY_USED = (pointer)block_ptr;
    mem_pool_ptr->POOL_CHECK_POOL_PTR      = (char _PTR_)mem_pool_ptr->POOL_PTR;
    mem_pool_ptr->POOL_BLOCK_IN_ERROR      = NULL;

    /* Compute the pool size. */
    mem_pool_ptr->POOL_SIZE = (_mem_size)((uchar_ptr)mem_pool_ptr->POOL_LIMIT -
                                          (uchar_ptr)mem_pool_ptr->POOL_PTR);

    /* Set up the first block as an idle block */
    block_ptr->BLOCKSIZE = mem_pool_ptr->POOL_SIZE - MQX_MIN_MEMORY_STORAGE_SIZE;
    block_ptr->USER_AREA = NULL;
    block_ptr->PREVBLOCK = NULL;
    block_ptr->NEXTBLOCK = NULL;
    MARK_BLOCK_AS_FREE(block_ptr);

    CALC_CHECKSUM(block_ptr);

    mem_pool_ptr->POOL_FREE_LIST_PTR = block_ptr;

    /*
    ** Set up last block as an in_use block, so that the _mem_free algorithm
    ** will work (block coalescing)
    */
    end_block_ptr = (STOREBLOCK_STRUCT_PTR)
                    ((uchar_ptr)block_ptr + block_ptr->BLOCKSIZE);
    end_block_ptr->BLOCKSIZE = (_mem_size)(MQX_MIN_MEMORY_STORAGE_SIZE);
    end_block_ptr->USER_AREA = 0;
    end_block_ptr->PREVBLOCK = (struct storeblock_struct _PTR_)block_ptr;
    end_block_ptr->NEXTBLOCK = NULL;
    MARK_BLOCK_AS_USED(end_block_ptr, SYSTEM_TASK_ID(kernel_data));
    CALC_CHECKSUM(end_block_ptr);

    mem_pool_ptr->POOL_END_PTR = end_block_ptr;

    /* Initialize the list of extensions to this pool */
    _QUEUE_INIT(&mem_pool_ptr->EXT_LIST, 0);

    mem_pool_ptr->VALID = MEMPOOL_VALID;

    /* Protect the list of pools while adding new pool */
    _lwsem_wait((LWSEM_STRUCT_PTR)&kernel_data->MEM_COMP.SEM);
    _QUEUE_ENQUEUE(&kernel_data->MEM_COMP.POOLS, &mem_pool_ptr->LINK);
    _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->MEM_COMP.SEM);

    return MQX_OK;

} /* Endbody */
Пример #26
0
/*!
 * \brief Writes data to the log.
 * 
 * The function writes the log entry only if it returns MQX_OK.
 * 
 * \param[in] log_number           Log number of a previously created log.
 * \param[in] number_of_parameters Number of parameters to write.
 * 
 * \return MQX_OK
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Log component is not created.)
 * \return MQX_INVALID_COMPONENT_HANDLE (Log component data is not valid.)
 * \return LOG_INVALID (Log_number is out of range.)
 * \return LOG_DOES_NOT_EXIST (Log_number was not created.)
 * \return LOG_DISABLED (Log is disabled.)
 * \return LOG_FULL (Log is full and LOG_OVERWRITE is not set.)      
 */ 
_mqx_uint _log_write
(
    _mqx_uint log_number,
    _mqx_uint number_of_parameters,

    ...
)
{ /* Body */
    MQX_TICK_STRUCT          ticks;
    TIME_STRUCT              time;
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    LOG_COMPONENT_STRUCT_PTR log_component_ptr;
    LOG_HEADER_STRUCT_PTR    log_header_ptr;
    _mqx_uint_ptr            data_ptr;
    va_list                  param_ptr;
    _mqx_uint                us;
    _mqx_uint                i;
    _mqx_uint                size;
    _mqx_uint                old_size;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (kernel_data->KERNEL_COMPONENTS[KERNEL_LOG] == NULL)
    {
        return(MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif

    log_component_ptr = (LOG_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_LOG];

#if MQX_CHECK_VALIDITY
    if (log_component_ptr->VALID != LOG_VALID)
    {
        return(MQX_INVALID_COMPONENT_HANDLE);
    } /* Endif */
#endif

#if MQX_CHECK_ERRORS
    if (log_number >= LOG_MAXIMUM_NUMBER)
    {
        return(LOG_INVALID);
    } /* Endif */
#endif

    log_header_ptr = log_component_ptr->LOGS[log_number];

#if MQX_CHECK_ERRORS
    if (log_header_ptr == NULL)
    {
        return(LOG_DOES_NOT_EXIST);
    } /* Endif */
#endif

    if (! (log_header_ptr->FLAGS & LOG_ENABLED))
    {
        return(LOG_DISABLED);
    } /* Endif */

    size = sizeof(LOG_ENTRY_STRUCT)/sizeof(_mqx_uint) + number_of_parameters;
#if MQX_CHECK_ERRORS
    if (size > log_header_ptr->MAX)
    {
        /* 
         * The request is to log an entry larger than the
         * entire log. Reject this.
         */
        return(LOG_FULL);
    } /* Endif */
#endif

    va_start(param_ptr, number_of_parameters);

    i = number_of_parameters + 1;

    _INT_DISABLE();
    if ((log_header_ptr->SIZE + size) > log_header_ptr->MAX)
    {
        if (log_header_ptr->FLAGS & LOG_OVERWRITE)
        {
            /* Remove leading elements until it can fit */
            while ((log_header_ptr->SIZE + size) > log_header_ptr->MAX)
            {
                data_ptr = log_header_ptr->LOG_READ;
                old_size = *data_ptr;
                log_header_ptr->SIZE -= old_size;
                data_ptr += old_size;
                if (data_ptr >= log_header_ptr->LOG_END)
                {
                    data_ptr = log_header_ptr->LOG_START +
                    (data_ptr - log_header_ptr->LOG_END);
                } /* Endif */
                if (log_header_ptr->LOG_NEXT == log_header_ptr->LOG_READ)
                {
                    /* Move up the next read pointer */
                    log_header_ptr->LOG_NEXT = data_ptr;
                } /* Endif */
                log_header_ptr->LOG_READ = data_ptr;
            } /* Endwhile */
        }
        else
        {
            _INT_ENABLE();
            va_end(param_ptr);
            return(LOG_FULL);
        } /* Endif */
    } /* Endif */

    log_header_ptr->SIZE += size;

    data_ptr = log_header_ptr->LOG_WRITE;
    log_header_ptr->LAST_LOG = data_ptr;

    *data_ptr++ = size;
    if (data_ptr == log_header_ptr->LOG_END)
    {
        data_ptr = log_header_ptr->LOG_START;
    } /* Endif */

    *data_ptr++ = log_header_ptr->NUMBER++;
    if (data_ptr == log_header_ptr->LOG_END)
    {
        data_ptr = log_header_ptr->LOG_START;
    } /* Endif */

    us = (_mqx_uint)_time_get_microseconds();
    PSP_ADD_TICKS(&kernel_data->TIME, &kernel_data->TIME_OFFSET, &ticks);
    PSP_TICKS_TO_TIME(&ticks, &time);

#if MQX_INT_SIZE_IN_BITS >= 32
    *data_ptr++ = (_mqx_uint)time.SECONDS;
#else
#if PSP_ENDIAN == MQX_BIG_ENDIAN
    *data_ptr++ = (_mqx_uint)((time.SECONDS >> MQX_INT_SIZE_IN_BITS) &
                    MAX_MQX_UINT);
    if (data_ptr == log_header_ptr->LOG_END)
    {
        data_ptr = log_header_ptr->LOG_START;
    } /* Endif */
    *data_ptr++ = (_mqx_uint)(time.SECONDS & MAX_MQX_UINT);
#else
    *data_ptr++ = (_mqx_uint)(time.SECONDS & MAX_MQX_UINT);
    if (data_ptr == log_header_ptr->LOG_END)
    {
        data_ptr = log_header_ptr->LOG_START;
    } /* Endif */
    *data_ptr++ = (_mqx_uint)((time.SECONDS >> MQX_INT_SIZE_IN_BITS) &
                    MAX_MQX_UINT);
#endif
#endif

    if (data_ptr >= log_header_ptr->LOG_END)
    {
        data_ptr = log_header_ptr->LOG_START;
    } /* Endif */

#if PSP_MEMORY_ADDRESSING_CAPABILITY >= 32
    *data_ptr++ = time.MILLISECONDS;
    if (data_ptr == log_header_ptr->LOG_END)
    {
        data_ptr = log_header_ptr->LOG_START;
    } /* Endif */
    *data_ptr++ = us;
#elif MQX_INT_SIZE_IN_BITS == 32
#if PSP_ENDIAN == MQX_LITTLE_ENDIAN
    *data_ptr++ = time.MILLISECONDS | (us << 16);
#else
    *data_ptr++ = us | (time.MILLISECONDS << 16);
#endif
#else
    *data_ptr++ = (_mqx_uint)time.MILLISECONDS;
    if (data_ptr == log_header_ptr->LOG_END)
    {
        data_ptr = log_header_ptr->LOG_START;
    } /* Endif */
    *data_ptr++ = us;
#endif

    if (data_ptr >= log_header_ptr->LOG_END)
    {
        data_ptr = log_header_ptr->LOG_START;
    } /* Endif */

    while (--i)
    {
        *data_ptr++ = (_mqx_uint)va_arg(param_ptr, _mqx_uint);
        if (data_ptr == log_header_ptr->LOG_END)
        {
            data_ptr = log_header_ptr->LOG_START;
        } /* Endif */
    } /* Endwhile */

    log_header_ptr->LOG_WRITE = data_ptr;
    _INT_ENABLE();

    va_end(param_ptr);

    return(MQX_OK);

} /* Endbody */
Пример #27
0
/*!
 * \brief Allocates a message from a system message pool.
 * 
 * The size of the message is determined by the message size that a task 
 * specified when it called _msgpool_create_system().
 * \n The message is a resource of the task until the task either frees it 
 * (_msg_free()) or puts it on a message queue (_msgq_send family of functions.)
 * 
 * \param[in] message_size Maximum size (in single-addressable units) of the 
 * message.
 * 
 * \return Pointer to a message of at least message_size single-addressable 
 * units (success).
 * \return NULL (Failure: message component is not created.)
 * 
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * \li Task error codes from _mem_alloc_system() (If MQX needs to grow the pool.)
 * 
 * \see _mem_alloc
 * \see _mem_alloc_from
 * \see _mem_alloc_system
 * \see _mem_alloc_system_from
 * \see _mem_alloc_system_zero
 * \see _mem_alloc_system_zero_from
 * \see _mem_alloc_zero
 * \see _mem_alloc_zero_from
 * \see _mem_alloc_align
 * \see _mem_alloc_align_from
 * \see _mem_alloc_at        
 * \see _msg_alloc
 * \see _msg_free
 * \see _msgpool_create_system
 * \see _msgq_send
 * \see _task_set_error
 * \see MESSAGE_HEADER_STRUCT 
 */ 
pointer _msg_alloc_system
(
    _msg_size message_size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR               kernel_data;
    MSG_COMPONENT_STRUCT_PTR             msg_component_ptr;
    register INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr;
    register MESSAGE_HEADER_STRUCT_PTR   message_ptr;
    register MSGPOOL_STRUCT_PTR          msgpool_ptr;
    uint_16                              grow_number;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_msg_alloc_system, message_size );

    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);
        _KLOGX2( KLOG_msg_alloc_system, NULL );
        return(NULL);
    }/* Endif */
#endif

    message_ptr = NULL;
    _INT_DISABLE();
    msgpool_ptr = msg_component_ptr->SMALLEST_MSGPOOL_PTR;
    while (msgpool_ptr != NULL)
    {
        if (msgpool_ptr->MESSAGE_SIZE >= message_size)
        {
            imsg_ptr = msgpool_ptr->MSG_FREE_LIST_PTR;
            if ( (imsg_ptr == NULL) &&
                            (msgpool_ptr->GROW_NUMBER) &&
                            (msgpool_ptr->MAX < msgpool_ptr->GROW_LIMIT) )
            {
                /* Attempt to add elements to the pool */
                grow_number = msgpool_ptr->GROW_NUMBER;
                if ( ((uint_16)(msgpool_ptr->MAX + grow_number) > msgpool_ptr->GROW_LIMIT))
                {
                    grow_number = msgpool_ptr->GROW_LIMIT - msgpool_ptr->MAX;
                } /* Endif */
                _msgpool_add_internal(msgpool_ptr, grow_number);
                imsg_ptr = msgpool_ptr->MSG_FREE_LIST_PTR;
            } /* Endif */
            if ( imsg_ptr != NULL )
            {
                msgpool_ptr->MSG_FREE_LIST_PTR = imsg_ptr->NEXT;
                --msgpool_ptr->SIZE;
                _INT_ENABLE();
                imsg_ptr->FREE = FALSE;
                imsg_ptr->QUEUED = FALSE;
                if (kernel_data->IN_ISR)
                {
                    imsg_ptr->TD_PTR = NULL;
                }
                else
                {
                    imsg_ptr->TD_PTR = kernel_data->ACTIVE_PTR;
                } /* Endif */
                message_ptr = (MESSAGE_HEADER_STRUCT_PTR)&imsg_ptr->MESSAGE;
                message_ptr->TARGET_QID = MSGQ_NULL_QUEUE_ID;
                message_ptr->SOURCE_QID = MSGQ_NULL_QUEUE_ID;
                message_ptr->SIZE = message_size;
                message_ptr->CONTROL = MSG_HDR_ENDIAN | MSG_DATA_ENDIAN;

                _KLOGX2(KLOG_msg_alloc_system, message_ptr);
                return (pointer)message_ptr;
            } /* Endif */
        } /* Endif */
        msgpool_ptr = msgpool_ptr->NEXT_MSGPOOL_PTR;
    } /* Endwhile */

    _int_enable();
    _KLOGX2(KLOG_msg_alloc_system, message_ptr);
    return (pointer)message_ptr;

} /* Endbody */
Пример #28
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 */
Пример #29
0
/*!
 * \private
 *
 * \brief This is internal function used by a task to wait for a specified event.
 *
 * \param[in] event_ptr          Read only. Pointer to the lightweight event.
 * \param[in] bit_mask           Bit mask. Each set bit represents an event bit
 * to wait for.
 * \param[in] all                TRUE (wait for all bits in bit_mask to be set),
 * FALSE (wait for any bit in bit_mask to be set).
 * \param[in] tick_ptr           Pointer to the maximum number of ticks to wait
 * for the events to be set. If the value is NULL, then the timeout will be infinite.
 * \param[in] ticks_are_absolute TRUE (ticks represents absolute time), FALSE
 * (ticks represents relative time).
 *
 * \return MQX_OK
 * \return LWEVENT_WAIT_TIMEOUT (The time elapsed before an event signalled.)
 * \return MQX_LWEVENT_INVALID (Lightweight event is no longer valid or was never valid.)
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 *
 * \see _lwevent_wait_for
 * \see _usr_lwevent_wait_for
 * \see _lwevent_wait_until
 * \see _usr_lwevent_wait_until
 * \see _lwevent_wait_ticks
 * \see _usr_lwevent_wait_ticks
 * \see LWEVENT_STRUCT
 * \see MQX_TICK_STRUCT
 */
_mqx_uint _lwevent_wait_internal
(
    LWEVENT_STRUCT_PTR  event_ptr,
    _mqx_uint           bit_mask,
    bool             all,
    MQX_TICK_STRUCT_PTR tick_ptr,
    bool             ticks_are_absolute
)
{
    KERNEL_DATA_STRUCT_PTR  kernel_data;
    TD_STRUCT_PTR           td_ptr;
    _mqx_uint               result;

    _GET_KERNEL_DATA(kernel_data);

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

    result = MQX_OK;
    td_ptr = kernel_data->ACTIVE_PTR;
    _INT_DISABLE();

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

    if (    (all &&  (event_ptr->VALUE & bit_mask) == bit_mask)
         || (!all && (event_ptr->VALUE & bit_mask)))
    {
        /* store information about which bits caused task to be unblocked */
        td_ptr->LWEVENT_BITS = event_ptr->VALUE & bit_mask;
        /* clear used automatic events */
        event_ptr->VALUE &= ~(event_ptr->AUTO & bit_mask);

        _INT_ENABLE();
        return (result);
    } /* Endif */

    /* Must wait for a event to become available */

    td_ptr->LWEVENT_BITS = bit_mask;
    if (all)
    {
        td_ptr->FLAGS |= TASK_LWEVENT_ALL_BITS_WANTED;
    }
    else
    {
        td_ptr->FLAGS &= ~TASK_LWEVENT_ALL_BITS_WANTED;
    } /* Endif */

    /* Enqueue at end */
    _QUEUE_ENQUEUE(&event_ptr->WAITING_TASKS, &td_ptr->AUX_QUEUE);

    /* Now put the task to sleep */
    td_ptr->STATE = LWEVENT_BLOCKED;
    td_ptr->INFO = (_mqx_uint) &event_ptr->WAITING_TASKS;
    if (tick_ptr)
    {
        if (ticks_are_absolute)
        {
            _time_delay_until(tick_ptr);
        }
        else
        {
            _time_delay_for(tick_ptr);
        } /* Endif */
        if (td_ptr->INFO)
        {
            /* Must have timed out */
            /*_QUEUE_REMOVE(&event_ptr->WAITING_TASKS, &td_ptr->AUX_QUEUE);*/
            result = LWEVENT_WAIT_TIMEOUT;
        } /* Endif */
    }
    else
    {
        _task_block();
    } /* Endif */

#if MQX_COMPONENT_DESTRUCTION
    if (event_ptr->VALID == 0)
    { /* We've been deleted */
        result = MQX_LWEVENT_INVALID;
    } /* Endif */
#endif

    _INT_ENABLE();
    return (result);

}
Пример #30
0
_mqx_uint _watchdog_create_component
   (
      /* [IN] the vector upon which timer interrupts on */
      _mqx_uint        timer_interrupt_vector,
      
      /* [IN] the function to call when a watchdog timer expires */
      void (_CODE_PTR_ error_function)(pointer td_ptr)
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR        kernel_data;
   WATCHDOG_COMPONENT_STRUCT_PTR watchdog_component_ptr;
   pointer                       interrupt_data;

   _GET_KERNEL_DATA(kernel_data);
   
   _KLOGE3(KLOG_watchdog_create_component, timer_interrupt_vector, error_function);

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

   _lwsem_wait((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
   if (kernel_data->KERNEL_COMPONENTS[KERNEL_WATCHDOG] != NULL) {
      _lwsem_post((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
      _KLOGX2(KLOG_watchdog_create_component, MQX_OK);
      return(MQX_OK);
   } /* Endif */

#if MQX_CHECK_ERRORS
   if (!error_function) {
      _lwsem_post((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
      _KLOGX2(KLOG_watchdog_create_component, WATCHDOG_INVALID_ERROR_FUNCTION);
      return(WATCHDOG_INVALID_ERROR_FUNCTION);
   } /* Endif */
   if ((timer_interrupt_vector < kernel_data->FIRST_USER_ISR_VECTOR) ||
       (timer_interrupt_vector > kernel_data->LAST_USER_ISR_VECTOR))
   {
      _lwsem_post((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
      _KLOGX2(KLOG_watchdog_create_component, WATCHDOG_INVALID_INTERRUPT_VECTOR);
      return(WATCHDOG_INVALID_INTERRUPT_VECTOR);
   } /* Endif */
#endif
   
   /* Get the watchdog component data structure */
   watchdog_component_ptr = (WATCHDOG_COMPONENT_STRUCT_PTR)
      _mem_alloc_system_zero((_mem_size)sizeof(WATCHDOG_COMPONENT_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (watchdog_component_ptr == NULL){
      _lwsem_post((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
      _KLOGX2(KLOG_watchdog_create_component, MQX_OUT_OF_MEMORY);
      return(MQX_OUT_OF_MEMORY);
   } /* Endif */
#endif   
   _mem_set_type(watchdog_component_ptr, MEM_TYPE_WATCHDOG_COMPONENT);

   watchdog_component_ptr->ERROR_FUNCTION   =
      (void (_CODE_PTR_)(TD_STRUCT_PTR))error_function;
   watchdog_component_ptr->VALID            = WATCHDOG_VALID;
   watchdog_component_ptr->INTERRUPT_VECTOR = timer_interrupt_vector;

   interrupt_data = _int_get_isr_data(timer_interrupt_vector);
   _INT_DISABLE();
   watchdog_component_ptr->TIMER_INTERRUPT_HANDLER = _int_install_isr(
      timer_interrupt_vector, _watchdog_isr, interrupt_data);
#if MQX_CHECK_ERRORS
   if (!watchdog_component_ptr->TIMER_INTERRUPT_HANDLER) {
      _int_enable();
      _lwsem_post((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
      _mem_free(watchdog_component_ptr);
      _KLOGX2(KLOG_watchdog_create_component, WATCHDOG_INVALID_INTERRUPT_VECTOR);
      return(WATCHDOG_INVALID_INTERRUPT_VECTOR);
   } /* Endif */
#endif

   kernel_data->KERNEL_COMPONENTS[KERNEL_WATCHDOG] = watchdog_component_ptr;
#if MQX_TASK_DESTRUCTION
   kernel_data->COMPONENT_CLEANUP[KERNEL_WATCHDOG] = _watchdog_cleanup;
#endif
   _INT_ENABLE();
   _lwsem_post((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));

   _KLOGX2(KLOG_watchdog_create_component, MQX_OK);

   return(MQX_OK);

} /* Endbody */