Exemplo n.º 1
0
/*!
 * \brief Set the time slice in milliseconds.
 *
 * \param[in] task_id     One of the following:
 * \n - Task ID for a task on this processor for which to set info.
 * \n - MQX_DEFAULT_TASK_ID (Set the time slice for the processor.)
 * \n - MQX_NULL_TASK_ID (Set the time slice for the calling task.)
 * \param[in] rr_interval New time slice (in milliseconds).
 *
 * \return old_rr_interval Previous time slice (Success.)
 * \return MAX_UINT_32
 *
 * \warning On failure, calls _task_set_error() to set the task error code to
 * MQX_SCHED_INVALID_TASK_ID.
 *
 * \see _sched_set_rr_interval_ticks
 * \see _sched_get_rr_interval
 * \see _sched_get_rr_interval_ticks
 * \see _task_set_error
 */
uint32_t _sched_set_rr_interval
(
    _task_id task_id,
    uint32_t  rr_interval
)
{ /* Body */
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data);
    uint32_t         old_rr_interval;
    MQX_TICK_STRUCT ticks;
    MQX_TICK_STRUCT old_ticks;
    _mqx_uint       result;

    _KLOGM(_GET_KERNEL_DATA(kernel_data));

    _KLOGE3(KLOG_sched_set_rr_interval, (_mqx_uint)task_id, rr_interval);

#if MQX_CHECK_ERRORS
    /* Validate parameters */
    if (0 == rr_interval)
    {
        _KLOGX2(KLOG_sched_set_rr_interval, MAX_UINT_32);
        _task_set_error( MQX_SCHED_INVALID_PARAMETER_PTR );
        return (MAX_UINT_32);
    } /* Endif */
#endif

    /* Compute the number of tick events required to accomplish the least amount of time[ms]. */
    /* tick_events = (required_time[ms] + (time_per_tick[ms] - 1)) / time_per_tick[ms])  -->
     * tick_events = ((required_time[ms] - 1) / time_per_tick[ms]) + 1
     */
    rr_interval--;
    /* Convert milliseconds to ticks, truncated */
    PSP_MILLISECONDS_TO_TICKS_QUICK(rr_interval, &ticks);
    /* Resolve truncation by adding one tick. */
    PSP_ADD_TICKS_TO_TICK_STRUCT(&ticks, 1, &ticks);

    result = _sched_set_rr_interval_internal(task_id, &ticks, &old_ticks);

    if (result != MQX_OK)
    {
        _task_set_error(result);
        _KLOGX2(KLOG_sched_set_rr_interval, MAX_UINT_32);
        return(MAX_UINT_32);
    } /* Endif */

    old_rr_interval = PSP_TICKS_TO_MILLISECONDS(&old_ticks, &result);

    _KLOGX2(KLOG_sched_set_rr_interval, old_rr_interval);

    return(old_rr_interval);

} /* Endbody */
Exemplo n.º 2
0
/*!
 * \brief Used by a task to wait for the event for the number of ticks.
 *
 * \param[in] event_ptr        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] timeout_in_ticks The maximum number of ticks to wait for the events
 * to be set. If the value is 0, then the timeout will be infinite.
 *
 * \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_create
 * \see _lwevent_destroy
 * \see _lwevent_set
 * \see _lwevent_set_auto_clear
 * \see _lwevent_clear
 * \see _lwevent_wait_for
 * \see _lwevent_wait_until
 * \see _lwevent_get_signalled
 * \see LWEVENT_STRUCT
 */
_mqx_uint _lwevent_wait_ticks
(
    LWEVENT_STRUCT_PTR  event_ptr,
    _mqx_uint           bit_mask,
    bool             all,
    _mqx_uint           timeout_in_ticks
)
{
    MQX_TICK_STRUCT ticks;
    _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data);
    _mqx_uint result;

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

    _KLOGM(_GET_KERNEL_DATA(kernel_data));

    _KLOGE5(KLOG_lwevent_wait_ticks, event_ptr, bit_mask, all,
                    timeout_in_ticks);

    if (timeout_in_ticks)
    {
        ticks = _mqx_zero_tick_struct;

        PSP_ADD_TICKS_TO_TICK_STRUCT(&ticks, timeout_in_ticks, &ticks);
        result = _lwevent_wait_internal(event_ptr, bit_mask, all, &ticks, FALSE);
    }
    else
    {
        result = _lwevent_wait_internal(event_ptr, bit_mask, all, NULL, FALSE);
    } /* Endif */

    _KLOGX2(KLOG_lwevent_wait_ticks, result);
    return (result);

}
Exemplo n.º 3
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);
   
}
Exemplo n.º 4
0
/*!
 * \brief Initializes and starts MQX on the processor.
 * 
 * The function does the following:
 * \li Initializes the default memory pool and memory components.
 * \li Initializes kernel data.
 * \li Performs BSP-specific initialization, which includes installing the 
 * periodic timer.
 * \li Performs PSP-specific initialization.
 * \li Creates the interrupt stack.
 * \li Creates the ready queues.
 * \li Starts MQX tasks.
 * \li Starts autostart application tasks.
 * 
 * \param[in] mqx_init Pointer to the MQX initialization structure for the 
 * processor.
 * 
 * \return Does not return (Success.)
 * \return If application called _mqx_exit(), error code that it passed to 
 * _mqx_exit() (Success.)
 * \return Errors from _int_install_isr() (MQX cannot install the interrupt 
 *  subsystem.)
 * \return Errors from _io_init() (MQX cannot install the I/O subsystem.)
 * \return Errors from _mem_alloc_system() (There is not enough memory to 
 * allocate either the interrupt stack or the interrupt table.)
 * \return Errors from _mem_alloc_zero() (There is not enough memory to allocate 
 * the ready queues.)
 * \return MQX_KERNEL_MEMORY_TOO_SMALL (Init_struct_ptr does not specify enough 
 * kernel memory.)
 * \return MQX_OUT_OF_MEMORY (There is not enough memory to allocate either the 
 * ready queues, the interrupt stack, or the interrupt table.)
 * \return MQX_TIMER_ISR_INSTALL_FAIL (MQX cannot install the periodic timer ISR.)
 * 
 * \warning Must be called exactly once per processor.
 * 
 * \see _mqx_exit
 * \see _int_install_isr
 * \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 MQX_INITIALIZATION_STRUCT
 * \see TASK_TEMPLATE_STRUCT        
 */ 
_mqx_uint _mqx
(
    register MQX_INITIALIZATION_STRUCT_PTR mqx_init
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    TASK_TEMPLATE_STRUCT_PTR template_ptr;
    TD_STRUCT_PTR td_ptr;
    _mqx_uint result;
    pointer stack_ptr;
    pointer sys_td_stack_ptr;
    uchar_ptr sys_stack_base_ptr;

#if MQX_EXIT_ENABLED || MQX_CRIPPLED_EVALUATION
    /* Setup a longjmp buffer using setjmp, so that if an error occurs
     * in mqx initialization, we can perform a longjmp to this location.
     *
     * Also _mqx_exit will use this jumpbuffer to longjmp to here in order
     * to cleanly exit MQX.
     */
    if ( MQX_SETJMP( _mqx_exit_jump_buffer_internal ) ) {
        _GET_KERNEL_DATA(kernel_data);
        _int_set_vector_table(kernel_data->USERS_VBR);
        return kernel_data->USERS_ERROR;
    } /* Endif */
#endif

    /*
     * The kernel data structure starts at the start of kernel memory,
     * as specified in the initialization structure. Make sure address
     * specified is aligned
     */
    kernel_data = (KERNEL_DATA_STRUCT_PTR) _ALIGN_ADDR_TO_HIGHER_MEM(mqx_init->START_OF_KERNEL_MEMORY);

    /* Set the global pointer to the kernel data structure */
    _SET_KERNEL_DATA(kernel_data);

    /* The following assignments are done to force the linker to include
     * the symbols, which are required by TAD.
     * Note that we should use address of the variable so it is not optimized
     * as direct constant assignment when optimization level is high.
     * Note that counter will be immediately reset to zero on the subsequent
     * _mem_zero call. */
    *(volatile pointer*) kernel_data = (pointer) & _mqx_version_number;
    *(volatile pointer*) kernel_data = (pointer) & _mqx_vendor;

    /* Initialize the kernel data to zero. */
    _mem_zero((pointer) kernel_data, (_mem_size) sizeof(KERNEL_DATA_STRUCT));

#if MQX_CHECK_ERRORS && MQX_VERIFY_KERNEL_DATA
    /* Verify that kernel data can be read and written correcly without
     * errors.  This is necessary during BSP development to validate the
     * DRAM controller is initialized properly.
     */

#ifndef PSP_KERNEL_DATA_VERIFY_ENABLE
#define PSP_KERNEL_DATA_VERIFY_ENABLE   0
#endif /* PSP_KERNEL_DATA_VERIFY_ENABLE */
    if (PSP_KERNEL_DATA_VERIFY_ENABLE) {
        /* This memory check is dangerous, because can destroy boot stack
         * stack which is used !!! -> MQX will failed !
         * Set PSP_KERNEL_DATA_VERIFY_ENABLE to 1
         * only if your boot stack is out of MQX memory heap
         */

        result = _mem_verify((uchar_ptr)kernel_data + sizeof(KERNEL_DATA_STRUCT),
                        mqx_init->END_OF_KERNEL_MEMORY);
        if ( result != MQX_OK ) {
            _mqx_exit(result); /* RETURN TO USER */
        }
    }
#endif /* MQX_CHECK_ERRORS && MQX_VERIFY_KERNEL_DATA */
    /* Copy the MQX initialization structure into kernel data. */
    kernel_data->INIT = *mqx_init;
    kernel_data->INIT.START_OF_KERNEL_MEMORY = (pointer) kernel_data;
    kernel_data->INIT.END_OF_KERNEL_MEMORY = (pointer) _ALIGN_ADDR_TO_LOWER_MEM(kernel_data->INIT.END_OF_KERNEL_MEMORY);

    /* init kernel data structures */
    _mqx_init_kernel_data_internal();

    /* Initialize the memory resource manager for the kernel */
    result = _mem_init_internal();
#if MQX_CHECK_ERRORS
    if ( result != MQX_OK ) {
        _mqx_exit(result); /* RETURN TO USER */
    } /* Endif */
#endif

#if MQX_USE_INTERRUPTS

    /* Now obtain the interrupt stack */
    if (kernel_data->INIT.INTERRUPT_STACK_LOCATION) {
        stack_ptr = kernel_data->INIT.INTERRUPT_STACK_LOCATION;
        result = kernel_data->INIT.INTERRUPT_STACK_SIZE;
    }
    else {
        if ( kernel_data->INIT.INTERRUPT_STACK_SIZE < PSP_MINSTACKSIZE ) {
            kernel_data->INIT.INTERRUPT_STACK_SIZE = PSP_MINSTACKSIZE;
        } /* Endif */
#if PSP_STACK_ALIGNMENT
        result = kernel_data->INIT.INTERRUPT_STACK_SIZE + PSP_STACK_ALIGNMENT + 1;
#else
        result = kernel_data->INIT.INTERRUPT_STACK_SIZE;
#endif
        stack_ptr = _mem_alloc_system((_mem_size)result);
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
        if (stack_ptr == NULL) {
            _mqx_exit(MQX_OUT_OF_MEMORY); /* RETURN TO USER */
        } /* Endif */
#endif
        _mem_set_type(stack_ptr, MEM_TYPE_INTERRUPT_STACK);
    } /* Endif */

#if MQX_MONITOR_STACK
    _task_fill_stack_internal((_mqx_uint_ptr)stack_ptr, result);
#endif

    kernel_data->INTERRUPT_STACK_PTR = _GET_STACK_BASE(stack_ptr, result);

#endif

    /*
     * Set the stack for the system TD, in case the idle task gets blocked
     * by an exception or if idle task is not used.
     */
    result = PSP_MINSTACKSIZE;
    sys_td_stack_ptr = _mem_alloc_system((_mem_size) result);
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (sys_td_stack_ptr == NULL) {
        _mqx_exit(MQX_OUT_OF_MEMORY); /* RETURN TO USER */
    } /* Endif */
#endif
    _mem_set_type(sys_td_stack_ptr, MEM_TYPE_SYSTEM_STACK);

    sys_stack_base_ptr = (uchar_ptr) _GET_STACK_BASE(sys_td_stack_ptr, result);
    td_ptr = SYSTEM_TD_PTR(kernel_data);
    td_ptr->STACK_PTR = (pointer)(sys_stack_base_ptr - sizeof(PSP_STACK_START_STRUCT));
    td_ptr->STACK_BASE = sys_stack_base_ptr;
#if MQX_TD_HAS_STACK_LIMIT
    td_ptr->STACK_LIMIT = _GET_STACK_LIMIT(sys_td_stack_ptr, result);
#endif
    _mqx_system_stack = td_ptr->STACK_PTR;

    /* Build the MQX ready to run queues */
    result = _psp_init_readyqs();
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if ( result != MQX_OK ) {
        _mqx_exit(result); /* RETURN TO USER */
    } /* Endif */
#endif

#if MQX_USE_COMPONENTS

    /* Create a light wait semaphore for component creation */
    _lwsem_create((LWSEM_STRUCT_PTR)&kernel_data->COMPONENT_CREATE_LWSEM, 1);
#endif

    /* Create a light wait semaphore for task creation/destruction creation */
    _lwsem_create((LWSEM_STRUCT_PTR) & kernel_data->TASK_CREATE_LWSEM, 1);

    /* Call bsp to enable timers and other devices */
    result = _bsp_enable_card();
#if MQX_CHECK_ERRORS
    if ( result != MQX_OK ) {
        _mqx_exit(result); /* RETURN TO USER */
    } /* Endif */
#endif

#if MQX_HAS_TIME_SLICE
    /* Set the kernel default time slice value */
    PSP_ADD_TICKS_TO_TICK_STRUCT(&kernel_data->SCHED_TIME_SLICE,
                    MQX_DEFAULT_TIME_SLICE, &kernel_data->SCHED_TIME_SLICE);
#endif

    /* Create the idle task */
#if MQX_USE_IDLE_TASK
    td_ptr = _task_init_internal(
                    (TASK_TEMPLATE_STRUCT_PTR)&kernel_data->IDLE_TASK_TEMPLATE,
                    kernel_data->ACTIVE_PTR->TASK_ID, MQX_IDLE_TASK_PARAMETER, TRUE, NULL, 0);
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (td_ptr == NULL) {
        _mqx_exit(MQX_OUT_OF_MEMORY);
    } /* Endif */
#endif
    _task_ready_internal(td_ptr);
#endif

    /* Check here for auto-create tasks, and create them here */
    template_ptr = kernel_data->INIT.TASK_TEMPLATE_LIST;
    while (template_ptr->TASK_TEMPLATE_INDEX) {
        if (template_ptr->TASK_ATTRIBUTES & MQX_AUTO_START_TASK) {
            td_ptr = _task_init_internal(template_ptr, kernel_data->ACTIVE_PTR->TASK_ID,
                            template_ptr->CREATION_PARAMETER, FALSE, NULL, 0);
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
            if (td_ptr == NULL) {
                _mqx_exit(MQX_OUT_OF_MEMORY);
            } /* Endif */
#endif
            _task_ready_internal(td_ptr);
        } /* Endif */
        ++template_ptr;
    } /* Endwhile */

    _sched_start_internal(); /* WILL NEVER RETURN FROM HERE */

    return MQX_OK; /* To satisfy lint */

} /* Endbody */
Exemplo n.º 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 */
Exemplo n.º 6
0
boolean _time_xdate_to_ticks
   (

     /* [IN]  pointer to date and time structure */
     MQX_XDATE_STRUCT_PTR  xdate_ptr,

     /* [OUT]  pointer to structure where num of ticks is to be written */   
     MQX_TICK_STRUCT_PTR   tick_ptr

   )
{ /* Body */
   uint_32                time;
   _mqx_uint              tmp;
   MQX_TICK_STRUCT        t2;
   KERNEL_DATA_STRUCT_PTR kernel_data;

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

   if (!_time_normalize_xdate(xdate_ptr)) {
      return FALSE;
   } /* Endif */

   /*
   ** Determine the number of days since Jan 1, 1970 at 00:00:00
   */
   time = _time_days_before_year_internal[(xdate_ptr->YEAR - 
      (uint_16)XCLK_FIRST_YEAR)];

   tmp = (_mqx_uint)_time_check_if_leap(xdate_ptr->YEAR);

   /*
   ** Add the number of days since 0000 hours, Jan 1, to the first
   ** day of month.
   */
   time += _time_days_before_month_internal[tmp][xdate_ptr->MONTH-1];

   /*
   ** Add the number of days since the beginning of the
   ** month
   */
   time += (uint_32)(xdate_ptr->MDAY - 1);

   /* Convert everything so far into hours */
   time = time * HOURS_IN_DAY + xdate_ptr->HOUR;

   /* Convert to seconds */
   tick_ptr->HW_TICKS = 0;
   t2 = _mqx_zero_tick_struct;
   PSP_ADD_TICKS_TO_TICK_STRUCT(&t2, SECS_IN_HOUR, &t2);
   PSP_MULTIPLY_TICKS_BY_UINT_32(&t2, time, tick_ptr);

   /* Add in seconds and minutes from XDATE struct */
   tmp = xdate_ptr->SEC + xdate_ptr->MIN * SECS_IN_MINUTE;
   PSP_ADD_TICKS_TO_TICK_STRUCT(tick_ptr, tmp, tick_ptr);

   /* Convert everything into ticks */
   _GET_KERNEL_DATA(kernel_data);
   time = (uint_32)kernel_data->TICKS_PER_SECOND;
   PSP_MULTIPLY_TICKS_BY_UINT_32(tick_ptr, time, tick_ptr);

   if (xdate_ptr->MSEC) {
      PSP_MILLISECONDS_TO_TICKS(xdate_ptr->MSEC, &t2);
      PSP_ADD_TICKS(tick_ptr, &t2, tick_ptr);
   } /* Endif */

   if (xdate_ptr->USEC) {
      PSP_MICROSECONDS_TO_TICKS(xdate_ptr->USEC, &t2);
      PSP_ADD_TICKS(tick_ptr, &t2, tick_ptr);
   } /* Endif */

   if (xdate_ptr->NSEC) {
      PSP_NANOSECONDS_TO_TICKS(xdate_ptr->NSEC, &t2);
      PSP_ADD_TICKS(tick_ptr, &t2, tick_ptr);
   } /* Endif */

   if (xdate_ptr->PSEC) {
      PSP_PICOSECONDS_TO_TICKS(xdate_ptr->PSEC, &t2);
      PSP_ADD_TICKS(tick_ptr, &t2, tick_ptr);
   } /* Endif */

   return TRUE;

} /* Endbody */
Exemplo n.º 7
0
TD_STRUCT_PTR _task_init_internal
   (
      /* [IN] the task template for the new task */
      TASK_TEMPLATE_STRUCT_PTR template_ptr,
      
      /* [IN] the task id of the creating task */
      _task_id                 creator_task_id,

      /* [IN] the creation parameter for the task */
      uint_32                  create_parameter,

/* START CR 897 */
      /* [IN] is the template ptr a dynamic template (ie not from list) */
      boolean                  dynamic,
      
      /* [IN] if not NULL, the location of the stack is provided */
      pointer                  input_stack_ptr,

      /* [IN] the input stack size if provided by the application */
      _mem_size                input_stack_size
/* END CR 897 */
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR   kernel_data;
   TD_STRUCT_PTR            td_ptr;
   READY_Q_STRUCT_PTR       ready_q_ptr;
   TASK_TEMPLATE_STRUCT_PTR new_template_ptr;
#if MQX_USE_LWMEM_ALLOCATOR==0
   STOREBLOCK_STRUCT_PTR    block_ptr;
#endif
   char_ptr                 stack_ptr;
   _mqx_uint                stack_size;
   _mqx_uint                td_size; // CR 1124

   _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (template_ptr->TASK_PRIORITY > kernel_data->LOWEST_TASK_PRIORITY)  {
#if MQX_USE_IDLE_TASK
        if (template_ptr != &kernel_data->IDLE_TASK_TEMPLATE) {
#endif

        _task_set_error(MQX_INVALID_TASK_PRIORITY);      
        return (NULL);
    
#if MQX_USE_IDLE_TASK
        }
#endif
    }
#endif

   
   /*
   ** Calculate space for the stack. Note that the stack size
   ** must be no smaller than a specified minimum, and it
   ** is made to be a multiple of longwords. The space allocated
   ** for the stack includes the specified stacksize and the
   ** overhead required by the kernel.
   */
/* START CR 897 */
   if (input_stack_ptr) {
      stack_size = input_stack_size;
#if MQX_CHECK_ERRORS
      if (stack_size <= (PSP_MINSTACKSIZE+sizeof(TD_STRUCT))){
         _task_set_error(MQX_INVALID_SIZE);
         return(NULL);
      } /* Endif */
#endif
      td_ptr = _task_alloc_td_internal(stack_size, &td_size, input_stack_ptr, template_ptr->TASK_ATTRIBUTES & MQX_USER_TASK);
      stack_size -= td_size;

      if (dynamic) stack_size -= sizeof(TASK_TEMPLATE_STRUCT);

   } else {
      stack_size = template_ptr->TASK_STACKSIZE;
#if MQX_CHECK_ERRORS
      if ( stack_size <= PSP_MINSTACKSIZE  ) {
         stack_size = PSP_MINSTACKSIZE; 
      } /* Endif */
#endif
      /* Make the size a multiple of the memory alignment */   
      _STACK_ALIGN_VAL_LARGER(stack_size);

#if 0 // we dont need this, because we using _mem_alloc_align function in _task_alloc_td_internal
#if PSP_MEMORY_ALIGNMENT
      /* But we need to add size to allow for alignment of stack base */
      stack_size += PSP_STACK_ALIGNMENT + 1;
#endif
#endif

      /* 
      ** Allocate space for a task descriptor and stack.
      ** If there is none available, 
      ** then indicate that the create failed.
      */
      td_ptr = _task_alloc_td_internal(dynamic ? (stack_size + sizeof(TASK_TEMPLATE_STRUCT)) : stack_size,
         &td_size, NULL, template_ptr->TASK_ATTRIBUTES & MQX_USER_TASK);
   }/* Endif */

/* END CR 897 */

#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (td_ptr == NULL) {
      _task_set_error(MQX_OUT_OF_TASK_DESCRIPTORS);
      return (NULL);
   } /* Endif */
#endif
   td_ptr->STATE = BLOCKED;

   if (td_ptr->STACK_BASE) {
       stack_ptr = td_ptr->STACK_BASE;
   }
   else {
       stack_ptr = (char_ptr)td_ptr + td_size;
   }

   if (dynamic) {
      new_template_ptr = (pointer)stack_ptr;
      stack_ptr += sizeof(TASK_TEMPLATE_STRUCT);
      *new_template_ptr = *template_ptr;
      template_ptr = new_template_ptr;
      template_ptr->TASK_TEMPLATE_INDEX |= SYSTEM_TASK_FLAG;
   } /* Endif */

#if MQX_MONITOR_STACK 
   _task_fill_stack_internal((_mqx_uint_ptr)stack_ptr, stack_size);
#endif

   /*  Find the ready_q that the new task belongs to.  */
   /* The ready queues are stored as a array as follows:
   **     lowest priority - eg 9
   **                          8
   **                        ...
   **     highest priority     0
   ** With the READY_Q_LIST pointer pointing to the highest priority queue 
   */
   ready_q_ptr = kernel_data->READY_Q_LIST - template_ptr->TASK_PRIORITY;
   td_ptr->MY_QUEUE = ready_q_ptr;
#if MQX_HAS_DYNAMIC_PRIORITIES
  td_ptr->HOME_QUEUE  = ready_q_ptr;
#endif   
   td_ptr->TASK_SR     = ready_q_ptr->ENABLE_SR;
   td_ptr->FLAGS       = template_ptr->TASK_ATTRIBUTES;
   
#if MQX_ENABLE_USER_MODE
   if (template_ptr->TASK_ATTRIBUTES & MQX_USER_TASK) {
       td_ptr->FLAGS |= TASK_USER_MODE;
   }
#endif /* MQX_ENABLE_USER_MODE */

/* START CR 897 */
   if (input_stack_ptr) {
      td_ptr->FLAGS |= TASK_STACK_PREALLOCATED;
   } /* Endif */
/* END CR 897 */

   if (FALSE == _psp_build_stack_frame(td_ptr, stack_ptr, stack_size, template_ptr, (_mqx_uint)ready_q_ptr->ENABLE_SR, create_parameter)) {
   	  // build stack failed
   	  
   	  // TODO dealloc td_ptr ??? - litle bit complicate
   	  return NULL;
   }
   

   /* Initialize the task's task descriptor. */
#if MQX_TD_HAS_TASK_TEMPLATE_PTR
   td_ptr->TASK_TEMPLATE_PTR = template_ptr;
#endif
#if MQX_TD_HAS_TEMPLATE_INDEX
   td_ptr->TEMPLATE_INDEX    = template_ptr->TASK_TEMPLATE_INDEX;
#endif

#if MQX_HAS_TIME_SLICE
   /* Use the provided default time slice */
   if (template_ptr->DEFAULT_TIME_SLICE) {
#if (MQX_DEFAULT_TIME_SLICE_IN_TICKS == 0)
      uint_32 ticks;

      ticks = ((template_ptr->DEFAULT_TIME_SLICE * 2 *
         kernel_data->TICKS_PER_SECOND) / 1000) / 2  /* Rounding.. */;
      PSP_ADD_TICKS_TO_TICK_STRUCT(&td_ptr->TIME_SLICE, 
         ticks, &td_ptr->TIME_SLICE);
#else
      PSP_ADD_TICKS_TO_TICK_STRUCT(&td_ptr->TIME_SLICE, 
         template_ptr->DEFAULT_TIME_SLICE, &td_ptr->TIME_SLICE);
#endif
   } else {
      td_ptr->TIME_SLICE = kernel_data->SCHED_TIME_SLICE;
   } /* Endif */
   if (kernel_data->SCHED_POLICY == MQX_SCHED_RR) {
      td_ptr->FLAGS |= MQX_TIME_SLICE_TASK;
   } /* Endif */
#endif
   
#if MQX_USE_IO
   td_ptr->STDIN_STREAM  = kernel_data->PROCESSOR_STDIN;
   td_ptr->STDOUT_STREAM = kernel_data->PROCESSOR_STDOUT;
   td_ptr->STDERR_STREAM = kernel_data->PROCESSOR_STDERR;
#endif

#if MQX_TD_HAS_PARENT   
   td_ptr->PARENT = creator_task_id;
#endif

   /* 
   ** Move ownership of the td from the creating task, to the
   ** newly created task.
   */
#if MQX_USE_LWMEM_ALLOCATOR==0
   block_ptr = GET_MEMBLOCK_PTR(td_ptr);
   kernel_data->ACTIVE_PTR->MEMORY_RESOURCE_LIST = block_ptr->NEXTBLOCK;
#endif
/* START CR 897 */
   if (input_stack_ptr == 0) {
      _mem_transfer_internal(td_ptr, td_ptr);
      _mem_transfer_internal((dynamic) ? stack_ptr - sizeof(TASK_TEMPLATE_STRUCT): stack_ptr, td_ptr);
   } /* Endif */
/* END CR 897 */

   return (td_ptr);

} /* Endbody */