Example #1
0
/*!
 * \brief  This function sets up the stack frame of a new task descriptor.
 * 
 * \param[in] td_ptr the address of the task descriptor
 * \param[in] stack_ptr the address of the stack memory block
 * \param[in] stack_size the size of the stack
 * \param[in] template_ptr the task's template
 * \param[in] status_register the status register to use in creating the task
 * \param[in] create_parameter the task creation parameter
 */
bool _psp_build_stack_frame
   (
      /* [IN] the address of the task descriptor */
      TD_STRUCT_PTR    td_ptr,

      /* [IN] the address of the stack memory block */
      void            *stack_ptr,

      /* [IN] the size of the stack */
      _mem_size        stack_size,

      /* [IN] the task's template */
      TASK_TEMPLATE_STRUCT_PTR template_ptr,

      /* [IN] the status register to use in creating the task */
      _mqx_uint        status_register,

      /* [IN] the task creation parameter */
      uint32_t          create_parameter
   )
{
   unsigned char *stack_base_ptr;
   PSP_STACK_START_STRUCT_PTR stack_start_ptr;
   bool res = TRUE;

   stack_base_ptr  = (unsigned char *)_GET_STACK_BASE(stack_ptr, stack_size);
   stack_start_ptr = (PSP_STACK_START_STRUCT_PTR)(stack_base_ptr - sizeof(PSP_STACK_START_STRUCT));

   td_ptr->STACK_BASE  = (void *)stack_base_ptr;
   td_ptr->STACK_LIMIT = _GET_STACK_LIMIT(stack_ptr, stack_size);
   td_ptr->STACK_PTR   = stack_start_ptr;

   /*
   ** Build the task's initial stack frame. This contains the initialized
   ** registers, and an exception frame which will cause the task to
   ** "return" to the start of the task when it is dispatched.
   */
   _mem_zero(stack_start_ptr, (_mem_size)sizeof(PSP_STACK_START_STRUCT));
   stack_start_ptr->INITIAL_CONTEXT.LR = (uint32_t)_task_exit_function_internal;
   stack_start_ptr->INITIAL_CONTEXT.R0 = (uint32_t)create_parameter;
   stack_start_ptr->INITIAL_CONTEXT.PC = (uint32_t)(template_ptr->TASK_ADDRESS) | 1;
   stack_start_ptr->INITIAL_CONTEXT.PSR = 0x01000000;
   stack_start_ptr->PARAMETER = create_parameter;
#if PSP_MQX_CPU_IS_ARM_CORTEX_M4
   stack_start_ptr->INITIAL_CONTEXT.PENDSVPRIOR = 0;
   stack_start_ptr->INITIAL_CONTEXT.BASEPRI     = status_register;
   stack_start_ptr->INITIAL_CONTEXT.LR2         = 0xfffffffd;
#endif


#if MQXCFG_ENABLE_FP && PSP_HAS_FPU
   if (td_ptr->FLAGS & MQX_FLOATING_POINT_TASK) {
      res = _psp_build_float_context(td_ptr);
   }
#endif /* MQXCFG_ENABLE_FP && PSP_HAS_FPU */

   return res;
}
Example #2
0
boolean _psp_build_stack_frame
   (
      /* [IN] the address of the task descriptor */
      TD_STRUCT_PTR    td_ptr,

      /* [IN] the address of the stack memory block */
      pointer          stack_ptr,

      /* [IN] the size of the stack */
      uint_32          stack_size,

      /* [IN] the task template address */
      TASK_TEMPLATE_STRUCT_PTR template_ptr,

      /* [IN] the status register to use in creating the task */
      uint_32          status_register,

      /* [IN] the task creation parameter */
      uint_32          create_parameter
   )
{ /* Body */
   uchar_ptr stack_base_ptr;
   PSP_STACK_START_STRUCT_PTR stack_start_ptr;
   uint_32 reg_val;
   boolean res = TRUE;

   stack_base_ptr  = (uchar_ptr)_GET_STACK_BASE(stack_ptr, stack_size);
   stack_start_ptr = (pointer)(stack_base_ptr - sizeof(PSP_STACK_START_STRUCT));

   td_ptr->STACK_BASE  = (pointer)stack_base_ptr;
#if MQX_TD_HAS_STACK_LIMIT
   td_ptr->STACK_LIMIT = _GET_STACK_LIMIT(stack_ptr, stack_size);
#endif
   td_ptr->STACK_PTR   = stack_start_ptr;

   /*
   ** Build the task's initial stack frame. This contains the initialized
   ** registers, and an exception frame which will cause the task to
   ** "return" to the start of the task when it is dispatched.
   */
   _mem_zero(stack_start_ptr, (uint_32)sizeof(PSP_STACK_START_STRUCT));

   stack_start_ptr->INITIAL_CONTEXT.FRAME.STATUS_REGISTER =
      (uint_16)status_register;

   stack_start_ptr->INITIAL_CONTEXT.FRAME.FORMAT_AND_VECTOR =
      (uint_16)PSP_NORMAL_STACK_FRAME;

   stack_start_ptr->INITIAL_CONTEXT.FRAME.RETURN_ADDRESS =
      (void (_CODE_PTR_)(void))  template_ptr->TASK_ADDRESS;

   stack_start_ptr->EXIT_ADDRESS    = _task_exit_function_internal;

#if PSP_ABI == PSP_ABI_REG
   stack_start_ptr->INITIAL_CONTEXT.REGISTERS.D0 = create_parameter;
#endif

   stack_start_ptr->PARAMETER       = create_parameter;

   _PSP_GET_A5(reg_val);
   stack_start_ptr->INITIAL_CONTEXT.REGISTERS.A5    = (pointer)reg_val;

   /* Mark the bottom of the stack for debuggers*/
   stack_start_ptr->INITIAL_CONTEXT.REGISTERS.A6    =
      &stack_start_ptr->ZERO_LINK_ADDRESS;

#if PSP_HAS_FPU
   if ((td_ptr->FLAGS & MQX_FLOATING_POINT_TASK) != 0) {
      res = _psp_build_float_context(td_ptr);
   } /* Endif */
#endif

   return res;	
} /* Endbody */