示例#1
0
/*!
 * \brief Gets a pointer to the kernel ISR for the specified vector number. The 
 * kernel ISR depends on the PSP.
 *  
 * \param[in] vector Vector number whose kernel ISR is requested.
 * 
 * \return Pointer to the kernel ISR (Success.)
 * \return NULL   
 * 
 * \warning On failure, calls _task_set_error() to set the task error code:
 * \li MQX_INVALID_VECTORED_INTERRUPT 
 * 
 * \see _int_kernel_isr
 * \see _int_install_kernel_isr
 */
INT_KERNEL_ISR_FPTR _int_get_kernel_isr
(
      _mqx_uint int_vector
)
{ /* Body */

#if MQX_CHECK_ERRORS
   if ( int_vector >= PSP_MAXIMUM_INTERRUPT_VECTORS ) {
      _task_set_error(MQX_INVALID_VECTORED_INTERRUPT);
      return NULL;
   } /* Endif */
#endif

#if defined (PSP_BOOKE) || defined( PSP_BOOKE_VLE) 

   return _bsp_int_get_kernel_isr(int_vector);

#else   /* !PSP_BOOKE (Original exception model) */

   #ifdef PSP_MPC566
   return (INT_KERNEL_ISR_FPTR)(_int_get_vector_table() + (int_vector * 0x100));
   #else
   return (INT_KERNEL_ISR_FPTR)(int_vector * 0x100);
   #endif
   
#endif /* PSP_BOOKE */

} /* Endbody */
示例#2
0
/*!
 * \brief Installs the kernel ISR handler. The kernel ISR depends on the PSP.
 *
 * Some real-time applications need special event handling to occur outside the
 * scope of MQX. The need might arise that the latency in servicing an interrupt
 * be less than the MQX interrupt latency. If this is the case, an application can
 * use _int_install_kernel_isr() to bypass MQX and let the interrupt be serviced
 * immediately.
 * \n Because the function returns the previous kernel ISR, applications can
 * temporarily install an ISR or chain ISRs so that each new one calls the one
 * installed before it.
 * \n A kernel ISR must save the registers that it needs and must service the
 * hardware interrupt. When the kernel ISR is finished, it must restore the
 * registers and perform a return-from-interrupt instruction.
 * \n A kernel ISR cannot call MQX functions. However, it can put data in global
 * data, which a task can access.
 *
 * \note The function is not available for all PSPs.
 *
 * \param[in] vector  Vector where the ISR is to be installed.
 * \param[in] isr_ptr Pointer to the ISR to install into the vector table.
 *
 * \return Pointer to the previous kernel ISR for the vector (Success.).
 * \return NULL
 *
 * \see _int_kernel_isr
 * \see _int_get_kernel_isr
 */
INT_KERNEL_ISR_FPTR _int_install_kernel_isr
(
    uint_32             vector,
    INT_KERNEL_ISR_FPTR isr_ptr
)
{
#if !MQX_ROM_VECTORS

#if MQX_KERNEL_LOGGING
   KERNEL_DATA_STRUCT_PTR kernel_data;
#endif
   INT_KERNEL_ISR_FPTR    old_isr_ptr;
   uint_32                result_code;
   uint_32_ptr            loc_ptr;

#if MQX_KERNEL_LOGGING
   _GET_KERNEL_DATA(kernel_data);
#endif

   _KLOGE3(KLOG_int_install_kernel_isr, vector, isr_ptr);

#if MQX_CHECK_ERRORS
   result_code = MQX_OK;
   old_isr_ptr = NULL;

   if ( vector >= PSP_MAXIMUM_INTERRUPT_VECTORS ) {
      result_code = MQX_INVALID_VECTORED_INTERRUPT;
   } else {
#endif

   loc_ptr = (uint_32_ptr)_int_get_vector_table();
   old_isr_ptr = (INT_KERNEL_ISR_FPTR)loc_ptr[vector];
   loc_ptr[vector] = (uint_32)isr_ptr;

#if MQX_CHECK_ERRORS
   } /* Endif */

   /* Set result code and return result. */
   _task_set_error(result_code);
#endif

   _KLOGX3(KLOG_int_install_kernel_isr, old_isr_ptr, result_code);
   return (old_isr_ptr);
#else

#if MQX_CHECK_ERRORS
   /* Set result code and return result. */
   _task_set_error(MQX_INVALID_CONFIGURATION);
#endif

   return NULL;
#endif
}
示例#3
0
/*!
 * \brief This function initializes kernel interrupt tables.
 */
void _psp_int_install
(
    void
)
{   /* Body */

#if !MQX_ROM_VECTORS
    uint32_t                    i;
    uint32_t                *vbr_ptr;

    vbr_ptr = (uint32_t *)_int_get_vector_table();

    /* Initialize the hardware interrupt vector table */
    // 0: Initial stack pointer
    // 1: Initial program counter
    for (i = 2; i < PSP_MAXIMUM_INTERRUPT_VECTORS; i++ ) {
        vbr_ptr[i] = (uint32_t)_int_kernel_isr;
    } /* Endfor */
#endif
} /* Endbody */
示例#4
0
void _mqx_init_kernel_data_internal
   (
      void
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR        kernel_data;
   TASK_TEMPLATE_STRUCT_PTR      task_template_ptr;
   TD_STRUCT_PTR                 td_ptr;
   _mqx_uint                      priority_levels;
   _mqx_uint                      i;

   _GET_KERNEL_DATA(kernel_data);

   /* Store the configuration used when the kernel was compiled */
   kernel_data->CONFIG1 = MQX_CNFG1;
   kernel_data->CONFIG2 = MQX_CNFG2;

   /* Store the addressability of the processor. How many bits in a byte. */
   kernel_data->ADDRESSING_CAPABILITY = PSP_MEMORY_ADDRESSING_CAPABILITY;

   /* Indicate the endianess of the target */
   kernel_data->ENDIANESS = PSP_ENDIAN;

   /* Store PSP memory alignment information */

#if PSP_MEM_STOREBLOCK_ALIGNMENT != 0
   kernel_data->PSP_CFG_MEM_STOREBLOCK_ALIGNMENT = PSP_MEM_STOREBLOCK_ALIGNMENT;
#endif

   kernel_data->PSP_CFG_MEMORY_ALIGNMENT = PSP_MEMORY_ALIGNMENT;
   kernel_data->PSP_CFG_STACK_ALIGNMENT  = PSP_STACK_ALIGNMENT;

   /*
   ** Fill in fields of the kernel data structure from the initialization
   ** structure.
   */
   //kernel_data->PROCESSOR_NUMBER =  kernel_data->INIT.PROCESSOR_NUMBER;

   /* Set IPC id for compatibility */
#if MQX_USE_IPC
   kernel_data->MY_IPC_ID = BUILD_TASKID(kernel_data->INIT.PROCESSOR_NUMBER, 1);
#endif

    /* Store location of current interrupt vector table */
#if MQX_EXIT_ENABLED
   kernel_data->USERS_VBR = (_mqx_max_type)_int_get_vector_table();
#endif

#if MQX_CHECK_ERRORS
   if (kernel_data->INIT.TASK_TEMPLATE_LIST == NULL) {
      _mqx_exit(MQX_INVALID_POINTER);
   } /* Endif */
#endif

#if MQX_HAS_TIME_SLICE
   /* Set the default scheduling policy for created tasks */
   kernel_data->SCHED_POLICY = MQX_SCHED_FIFO;
#endif

#if MQX_KD_HAS_COUNTER
   /* Initialize the kernel counter. */
   kernel_data->COUNTER    = 1U;
#endif

   /* Set up the disable and enable priority levels */
   _psp_set_kernel_disable_level();

   /*
   ** Initialize the system task so that functions which update the
   ** task error code can be called. 
   ** The system task never runs, but it's TD is used for error codes
   ** during initialization, and for storage of memory blocks assigned
   ** to the system.
   */
   td_ptr = (TD_STRUCT_PTR)&kernel_data->SYSTEM_TD;
   kernel_data->ACTIVE_PTR  = td_ptr;
   kernel_data->ACTIVE_SR   = kernel_data->DISABLE_SR;
   td_ptr->TASK_SR          = kernel_data->DISABLE_SR;
   td_ptr->TASK_ID = BUILD_TASKID(kernel_data->INIT.PROCESSOR_NUMBER, SYSTEM_TASK_NUMBER);
   td_ptr->STATE   = BLOCKED;

   /* Initialize the light weight semaphores queue */
   _QUEUE_INIT(&kernel_data->LWSEM, 0);
   
#if MQX_ENABLE_USER_MODE
   _QUEUE_INIT(&kernel_data->USR_LWSEM, 0);
#endif
     
#if MQX_HAS_TICK
   /* Set up the timeout queue */
   _QUEUE_INIT(&kernel_data->TIMEOUT_QUEUE, 0);
#endif

   /* 
   ** Compute the number of MQX priority levels needed. This is done
   ** by determining the task that has the lowest priority (highest number)
   */
   priority_levels = 0;
   task_template_ptr = kernel_data->INIT.TASK_TEMPLATE_LIST;
   for (i = 0; 
      task_template_ptr->TASK_TEMPLATE_INDEX && 
         (i < MQX_MAXIMUM_NUMBER_OF_TASK_TEMPLATES); 
      ++i, ++task_template_ptr) 
   {
      if (priority_levels < task_template_ptr->TASK_PRIORITY)  {
         priority_levels = task_template_ptr->TASK_PRIORITY;
      } /* Endif */
   } /* Endfor */
   kernel_data->LOWEST_TASK_PRIORITY = priority_levels;
   

#if MQX_USE_IDLE_TASK
   /* 
   ** Initialize the task template for the IDLE Task.   
   ** NOTE that the idle task runs at 1 level lower than any user task.
   */
   task_template_ptr = (TASK_TEMPLATE_STRUCT_PTR)
      &kernel_data->IDLE_TASK_TEMPLATE;
   task_template_ptr->TASK_TEMPLATE_INDEX = IDLE_TASK;
   task_template_ptr->TASK_STACKSIZE      = PSP_IDLE_STACK_SIZE;
   task_template_ptr->TASK_NAME           = MQX_IDLE_TASK_NAME;
   task_template_ptr->TASK_ADDRESS        = _mqx_idle_task;
   task_template_ptr->TASK_PRIORITY       = priority_levels + 1;
#endif

   /* 
   ** Initialize the linked list of all TDs in the system.
   ** Initially zero. Not including system TD
   */
   _QUEUE_INIT(&kernel_data->TD_LIST, 0);

   /* Set the TD counter */
   /* Start SPR P171-0014-02       */
   /* kernel_data->TD_COUNTER = 1; */
   kernel_data->TASK_NUMBER = 1;
   /* End SPR P171-0014-02         */

} /* Endbody */