/*! * \brief This function sets up the FLOATING POINT context of a new task descriptor. * * \param[in] td_ptr the address of the task descriptor */ bool _psp_build_float_context ( /* [IN] the address of the task descriptor */ TD_STRUCT_PTR td_ptr ) { PSP_BLOCKED_FP_STRUCT_PTR fp_ptr; /* Allocate space for saving/restoring the DSP registers */ fp_ptr = (PSP_BLOCKED_FP_STRUCT_PTR)_mem_alloc_zero((_mem_size)sizeof(PSP_BLOCKED_FP_STRUCT)); #if MQX_CHECK_MEMORY_ALLOCATION_ERRORS if (!fp_ptr) { /* Couldn't allocate memory for the DSP register context */ _task_set_error_td_internal(td_ptr, MQX_OUT_OF_MEMORY); return FALSE; } #endif _mem_set_type(fp_ptr, MEM_TYPE_FP_CONTEXT); /* ** Transfer the block to the task being created. This will ensure the ** float context will be freed if the task is destroyed. */ _mem_transfer_internal((void *)fp_ptr, td_ptr); /* This field should never be overwitten */ fp_ptr->TID = td_ptr->TASK_ID; td_ptr->FLOAT_CONTEXT_PTR = (void *)fp_ptr; return TRUE; }
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 */