/*! * \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; }
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 */