示例#1
0
pointer _lwmem_alloc_system_from
   (
      /* [IN] the pool to allocate from */
      _lwmem_pool_id   pool_id,

      /* [IN] the size of the memory block */
      _mem_size        size

   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR  kernel_data;
   pointer                 result;

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

   result = _lwmem_alloc_internal(size, SYSTEM_TD_PTR(kernel_data), pool_id, FALSE);

   _KLOGX2(KLOG_lwmem_alloc_system_from, result);
   return(result);

} /* Endbody */
示例#2
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);

}
示例#3
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 */
示例#4
0
_mqx_uint _task_abort
   (
      /* [IN] the task id of the task to abort */
      _task_id task_id
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR    kernel_data;
   TD_STRUCT_PTR             td_ptr;
   pointer                   stack_ptr;
   _processor_number         processor;

   _GET_KERNEL_DATA(kernel_data);
   _KLOGE2(KLOG_task_abort, task_id);

   if (task_id != MQX_NULL_TASK_ID) {
      processor = PROC_NUMBER_FROM_TASKID(task_id);
      if (processor != (_processor_number)kernel_data->INIT.PROCESSOR_NUMBER ) {
#if MQX_IS_MULTI_PROCESSOR
         if ( kernel_data->IPC != NULL ) {
            _KLOGX2(KLOG_task_abort, MQX_OK);
            return( (*kernel_data->IPC)(FALSE, processor,
               KERNEL_MESSAGES, IPC_TASK_ABORT, 1, (_mqx_uint)task_id) );
         } else {
#endif
            _KLOGX2(KLOG_task_abort, MQX_INVALID_TASK_ID);
            return(MQX_INVALID_TASK_ID);
#if MQX_IS_MULTI_PROCESSOR
         } /* Endif */
#endif
      }/* Endif */
   }/* Endif */

   td_ptr = (TD_STRUCT_PTR)_task_get_td(task_id);

#if MQX_CHECK_ERRORS
   if ( (td_ptr == NULL) || (td_ptr == SYSTEM_TD_PTR(kernel_data)) ) {
      _KLOGX2(KLOG_task_abort, MQX_INVALID_TASK_ID);
      return( MQX_INVALID_TASK_ID );
   } /* Endif */
#endif

   if (td_ptr == kernel_data->ACTIVE_PTR) {
      if (kernel_data->IN_ISR) {
         stack_ptr = (pointer)td_ptr->STACK_PTR;
         _PSP_SET_PC_OF_INTERRUPTED_TASK(stack_ptr, 
            _task_exit_function_internal);
      } else {
         _task_exit_function_internal();
      }/* Endif */
   } else {

      _int_disable();
      /* Task is not running */
      stack_ptr = (pointer)td_ptr->STACK_PTR;
      _PSP_SET_PC_OF_BLOCKED_TASK(stack_ptr, 
         _task_exit_function_internal);
      /* Start CR 1222 */
      if (td_ptr->STATE & IS_ON_TIMEOUT_Q){
         /* Remove from time queue (uses NEXT, PREV field) */
         _TIME_DEQUEUE(td_ptr, kernel_data);
      /* End CR 1222 */
      } else if (td_ptr->STATE & TD_IS_ON_QUEUE) {
         _QUEUE_REMOVE(td_ptr->INFO, td_ptr);
      /* Begin CR 1223 */
      } else if((td_ptr->STATE & BLOCKED_ON_AUX_QUEUE) ==BLOCKED_ON_AUX_QUEUE){
         /* We need to remove it here because _task_ready() below will
            change its state to READY */
         _QUEUE_REMOVE(td_ptr->INFO, &td_ptr->AUX_QUEUE);
      } /* Endif */
      /* End CR 1223 */
      if (td_ptr->STATE & IS_BLOCKED) {
         _task_ready(td_ptr);
      } /* Endif */
      _int_enable();
   }/* Endif */

   _KLOGX2(KLOG_task_abort, MQX_OK);
   return(MQX_OK);
   
} /* Endbody */
示例#5
0
/*!
 * \brief Initializes MQXLite on the processor.
 *
 * The function does the following:
 * \n - Initializes kernel data.
 * \n - Creates the interrupt stack.
 * \n - Creates the ready queues.
 * \n - Creates a lightweight semaphore for task creation/destruction.
 * \n - Initializes interrupts.
 * \n - Initializes system timer.
 *
 * \param[in] mqx_init Pointer to the MQXLITE initialization structure for the
 * processor.
 *
 * \return MQX_OK
 * \return Initialization error code
 *
 * \warning Must be called exactly once per processor.
 *
 * \see _mqxlite
 * \see _mqx_exit
 * \see MQXLITE_INITIALIZATION_STRUCT
 */
_mqx_uint _mqxlite_init
(
    MQXLITE_INITIALIZATION_STRUCT const * mqx_init
)
{   /* Body */
    KERNEL_DATA_STRUCT_PTR  kernel_data;
    pointer                 stack_ptr;
    _mqx_uint               result = MQX_OK;

    /*
     * 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) (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. */
    {
        MQX_INITIALIZATION_STRUCT  * MQX_init_struct_ptr;

        *(volatile pointer*) kernel_data = (pointer) & _mqx_version_number;
        *(volatile pointer*) kernel_data = (pointer) & _mqx_vendor;
        *(volatile pointer*) kernel_data = (pointer) & _mqx_path;
        *(volatile pointer*) kernel_data = (pointer) & _mqxlite_version_number;
        *(volatile pointer*) kernel_data = (pointer) & MQX_init_struct_ptr;
    }
    /* 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 correctly without
     * errors.  This is necessary during BSP development to validate the
     * DRAM controller is initialized properly.
     */
    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 ) {
            return (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;

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

#if MQX_USE_LWMEM == 1
    /**
     * Initialize lightweight memory pool for dynamic memory allocation
     */
    {
        /* Extern symbols defined in linker command file */
        extern char      __heap_addr[];
        extern char      __heap_size[];

        KERNEL_DATA_STRUCT   * kernel_data;
        LWMEM_POOL_STRUCT    * pool_ptr;

        void *                 start_addr;

        _GET_KERNEL_DATA(kernel_data);

        pool_ptr = (LWMEM_POOL_STRUCT *) __heap_addr;

        kernel_data->KERNEL_LWMEM_POOL = pool_ptr;

        start_addr = (void *)((char *) __heap_addr + sizeof(LWMEM_POOL_STRUCT));

        _lwmem_create_pool(pool_ptr, start_addr, (_mem_size)__heap_size);
    }
#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
    {
        return (MQX_INVALID_PARAMETER);
    } /* 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 /* MQX_USE_INTERRUPTS */

#if MQX_USE_IDLE_TASK == 0
    {
        /*
         * Set the stack for the system TD, in case the idle task gets blocked
         * by an exception or if idle task is not used.
         */
        TD_STRUCT_PTR   td_ptr;
        uchar_ptr       stack_base_ptr;

        stack_base_ptr = (uchar_ptr) _GET_STACK_BASE(mqx_system_stack, PSP_MINSTACKSIZE);
        td_ptr = SYSTEM_TD_PTR(kernel_data);
        td_ptr->STACK_PTR   = (pointer)(stack_base_ptr - sizeof(PSP_STACK_START_STRUCT));
        td_ptr->STACK_BASE  = stack_base_ptr;
#if MQX_TD_HAS_STACK_LIMIT
        td_ptr->STACK_LIMIT = _GET_STACK_LIMIT(mqx_system_stack, PSP_MINSTACKSIZE);
#endif
        _mqx_system_stack   = td_ptr->STACK_PTR;
    }
#endif /* MQX_USE_IDLE_TASK */

    /* Build the MQX ready to run queues */
    result = _psp_init_readyqs();
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if ( result != MQX_OK ) {
        return (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);

    /* Set the CPU type */
    _mqx_set_cpu_type(MQX_CPU);

    result = _psp_int_init(FIRST_INTERRUPT_VECTOR_USED, LAST_INTERRUPT_VECTOR_USED);
    if (result != MQX_OK) {
        return(result); /* RETURN TO USER */
    }

    /* set possible new interrupt vector table
     * if MQX_ROM_VECTORS = 0 switch to ram interrupt table which
     * was initialized in _psp_int_init)
     */
    _int_set_vector_table((uint32_t)(&__vect_table));

    /*
     * Initialize System Timer and Ticks parameters in kernel_data structure
     */
    system_timer_init(NULL);

    return MQX_OK; /* To satisfy lint */

} /* Endbody */