_mem_size _partition_get_total_size ( /* [IN] the partition to obtain information about */ _partition_id partition ) { /* Body */ PARTPOOL_STRUCT_PTR partpool_ptr = (PARTPOOL_STRUCT_PTR)partition; PARTPOOL_BLOCK_STRUCT_PTR partpool_block_ptr; register _mem_size size; uchar_ptr tmp_ptr; #if MQX_CHECK_VALIDITY if (partpool_ptr->POOL.VALID != PARTITION_VALID) { _task_set_error(PARTITION_INVALID); return 0; } /* Endif */ #endif size = 0; partpool_block_ptr = partpool_ptr->POOL.NEXT_POOL_PTR; while (partpool_block_ptr != NULL) { tmp_ptr = (uchar_ptr)partpool_block_ptr + sizeof(PARTPOOL_BLOCK_STRUCT); tmp_ptr = (uchar_ptr)_ALIGN_ADDR_TO_HIGHER_MEM(tmp_ptr); size += (_mem_size)(tmp_ptr - (uchar_ptr)partpool_block_ptr); partpool_block_ptr = partpool_block_ptr->NEXT_POOL_PTR; } /* Endif */ tmp_ptr = (uchar_ptr)partition + sizeof(PARTPOOL_STRUCT); tmp_ptr = (uchar_ptr)_ALIGN_ADDR_TO_HIGHER_MEM(tmp_ptr); size += (_mem_size)(tmp_ptr - (uchar_ptr)partition); return(size + partpool_ptr->BLOCK_SIZE * partpool_ptr->TOTAL_BLOCKS); } /* Endbody */
void _msgpool_add_internal ( /* [IN] a pointer to the message pool */ MSGPOOL_STRUCT_PTR msgpool_ptr, /* [IN] the number of messages to attempt to add */ uint_16 num_messages ) { /* Body */ INTERNAL_MESSAGE_STRUCT_PTR first_imsg_ptr; INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr; MSGPOOL_BLOCK_STRUCT_PTR msgpool_block_ptr; _mqx_int raw_message_size; _mqx_uint count; raw_message_size = sizeof(INTERNAL_MESSAGE_STRUCT) - sizeof(MESSAGE_HEADER_STRUCT) + msgpool_ptr->MESSAGE_SIZE; _MEMORY_ALIGN_VAL_LARGER(raw_message_size); msgpool_block_ptr = (MSGPOOL_BLOCK_STRUCT_PTR)_mem_alloc_system((_mem_size) ((raw_message_size*num_messages) + sizeof(MSGPOOL_BLOCK_STRUCT) + PSP_MEMORY_ALIGNMENT)); #if MQX_CHECK_MEMORY_ALLOCATION_ERRORS if (msgpool_block_ptr == NULL) { return; } /* Endif */ #endif _mem_set_type(msgpool_block_ptr, MEM_TYPE_MESSAGE_POOL_BLOCKS); msgpool_block_ptr->NEXT_BLOCK_PTR = NULL; msgpool_block_ptr->RAW_MESSAGE_SIZE = raw_message_size; msgpool_block_ptr->NUM_MESSAGES = num_messages; first_imsg_ptr =(INTERNAL_MESSAGE_STRUCT_PTR) ((uchar _PTR_)msgpool_block_ptr + sizeof(MSGPOOL_BLOCK_STRUCT)); first_imsg_ptr = (INTERNAL_MESSAGE_STRUCT_PTR) _ALIGN_ADDR_TO_HIGHER_MEM(first_imsg_ptr); msgpool_block_ptr->FIRST_IMSG_PTR = first_imsg_ptr; imsg_ptr = first_imsg_ptr; count = num_messages + 1; while (--count){ imsg_ptr->NEXT = NULL; /* Free list pointer */ imsg_ptr->VALID = MSG_VALID; imsg_ptr->FREE = TRUE; imsg_ptr->QUEUED = FALSE; imsg_ptr->MSGPOOL_PTR = msgpool_ptr; imsg_ptr->TD_PTR = NULL; if (count > 1) { /* imsg is in the middle of the list */ imsg_ptr->NEXT = (INTERNAL_MESSAGE_STRUCT_PTR) ((uchar _PTR_)imsg_ptr + raw_message_size); imsg_ptr = imsg_ptr->NEXT; }/* Endif */ } /* Endwhile */ /* Now make the pool entries available */ _int_disable(); msgpool_block_ptr->NEXT_BLOCK_PTR = msgpool_ptr->MSGPOOL_BLOCK_PTR; msgpool_ptr->MSGPOOL_BLOCK_PTR = msgpool_block_ptr; /* imsg_ptr here is the last message on the list */ imsg_ptr->NEXT = msgpool_ptr->MSG_FREE_LIST_PTR; msgpool_ptr->MSG_FREE_LIST_PTR = first_imsg_ptr; msgpool_ptr->SIZE += num_messages; msgpool_ptr->MAX += num_messages; _int_enable(); } /* Endbody */
_mqx_uint _mem_extend_pool_internal ( /* [IN] the address of the start of the memory pool addition */ pointer start_of_pool, /* [IN] the size of the memory pool addition */ _mem_size size, /* [IN] the memory pool to extend */ MEMPOOL_STRUCT_PTR mem_pool_ptr ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; STOREBLOCK_STRUCT_PTR block_ptr; STOREBLOCK_STRUCT_PTR end_ptr; STOREBLOCK_STRUCT_PTR free_ptr; STOREBLOCK_STRUCT_PTR tmp_ptr; MEMPOOL_EXTENSION_STRUCT_PTR ext_ptr; uchar_ptr real_start_ptr; uchar_ptr end_of_pool; _mem_size block_size; _mem_size real_size; _mem_size free_block_size; _GET_KERNEL_DATA(kernel_data); #if MQX_CHECK_ERRORS if (size < (_mem_size)(3*MQX_MIN_MEMORY_STORAGE_SIZE)) { /* Pool must be big enough to hold at least 3 memory blocks */ return(MQX_INVALID_SIZE); }/* Endif */ #endif #if MQX_CHECK_VALIDITY if (mem_pool_ptr->VALID != MEMPOOL_VALID) { return(MQX_INVALID_COMPONENT_HANDLE); }/* Endif */ #endif ext_ptr = (MEMPOOL_EXTENSION_STRUCT_PTR) _ALIGN_ADDR_TO_HIGHER_MEM(start_of_pool); real_start_ptr = (uchar_ptr)ext_ptr + sizeof(MEMPOOL_EXTENSION_STRUCT); real_start_ptr = (uchar_ptr)_ALIGN_ADDR_TO_HIGHER_MEM(real_start_ptr); end_of_pool = (uchar_ptr)start_of_pool + size; end_of_pool = (uchar_ptr)_ALIGN_ADDR_TO_LOWER_MEM(end_of_pool); real_size = (_mem_size)(end_of_pool - real_start_ptr); ext_ptr->START = start_of_pool; ext_ptr->SIZE = size; ext_ptr->REAL_START = real_start_ptr; block_ptr = (STOREBLOCK_STRUCT_PTR)real_start_ptr; block_size = MQX_MIN_MEMORY_STORAGE_SIZE; free_ptr = (STOREBLOCK_STRUCT_PTR)((uchar_ptr)block_ptr + block_size); free_block_size = real_size - (_mem_size)(2 * MQX_MIN_MEMORY_STORAGE_SIZE); end_ptr = (STOREBLOCK_STRUCT_PTR)((uchar_ptr)free_ptr + free_block_size); /* ** Make a small minimal sized memory block to be as ** the first block in the pool. This will be an in-use block ** and will thus avoid problems with memory co-allescing during ** memory frees */ block_ptr->BLOCKSIZE = block_size; block_ptr->MEM_TYPE = 0; block_ptr->USER_AREA = 0; block_ptr->PREVBLOCK = (struct storeblock_struct _PTR_)NULL; block_ptr->NEXTBLOCK = free_ptr; MARK_BLOCK_AS_USED(block_ptr, SYSTEM_TASK_ID(kernel_data)); CALC_CHECKSUM(block_ptr); /* ** Let the next block be the actual free block that will be added ** to the free list */ free_ptr->BLOCKSIZE = free_block_size; free_ptr->MEM_TYPE = 0; free_ptr->USER_AREA = 0; free_ptr->PREVBLOCK = block_ptr; free_ptr->NEXTBLOCK = end_ptr; MARK_BLOCK_AS_FREE(free_ptr); CALC_CHECKSUM(free_ptr); /* ** Set up a minimal sized block at the end of the pool, and also ** mark it as being allocated. Again this is to comply with the ** _mem_free algorithm */ end_ptr->BLOCKSIZE = block_size; end_ptr->MEM_TYPE = 0; end_ptr->USER_AREA = 0; end_ptr->PREVBLOCK = free_ptr; end_ptr->NEXTBLOCK = NULL; MARK_BLOCK_AS_USED(end_ptr, SYSTEM_TASK_ID(kernel_data)); CALC_CHECKSUM(end_ptr); _int_disable(); /* Add the block to the free list */ tmp_ptr = mem_pool_ptr->POOL_FREE_LIST_PTR; mem_pool_ptr->POOL_FREE_LIST_PTR = free_ptr; if (tmp_ptr != NULL) { PREV_FREE(tmp_ptr) = free_ptr; } /* Endif */ PREV_FREE(free_ptr) = NULL; NEXT_FREE(free_ptr) = tmp_ptr; /* Reset the free list queue walker for some other task */ mem_pool_ptr->POOL_FREE_CURRENT_BLOCK = mem_pool_ptr->POOL_FREE_LIST_PTR; /* Link in the extension */ _QUEUE_ENQUEUE(&mem_pool_ptr->EXT_LIST, &ext_ptr->LINK); _int_enable(); return(MQX_OK); } /* Endbody */
/*! * \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 */
_mqx_uint _mem_create_pool_internal ( /* [IN] the start of the memory pool */ pointer start, /* [IN] the end of the memory pool */ pointer end, /* [IN] where to store the memory pool context info. */ MEMPOOL_STRUCT_PTR mem_pool_ptr ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; STOREBLOCK_STRUCT_PTR block_ptr; STOREBLOCK_STRUCT_PTR end_block_ptr; _GET_KERNEL_DATA(kernel_data); #if MQX_CHECK_VALIDITY _INT_DISABLE(); if (kernel_data->MEM_COMP.VALID != MEMPOOL_VALID) { /* The RTOS memory system has been corrupted */ _int_enable(); return(MQX_CORRUPT_MEMORY_SYSTEM); } /* Endif */ _INT_ENABLE(); #endif /* Align the start of the pool */ mem_pool_ptr->POOL_PTR = (STOREBLOCK_STRUCT_PTR) _ALIGN_ADDR_TO_HIGHER_MEM(start); /* Set the end of memory (aligned) */ mem_pool_ptr->POOL_LIMIT = (STOREBLOCK_STRUCT_PTR) _ALIGN_ADDR_TO_LOWER_MEM(end); #if MQX_CHECK_ERRORS if ( (uchar_ptr)mem_pool_ptr->POOL_LIMIT <= ((uchar_ptr)mem_pool_ptr->POOL_PTR + MQX_MIN_MEMORY_POOL_SIZE) ) { return MQX_MEM_POOL_TOO_SMALL; } /* Endif */ #endif block_ptr = (STOREBLOCK_STRUCT_PTR)mem_pool_ptr->POOL_PTR; mem_pool_ptr->POOL_HIGHEST_MEMORY_USED = (pointer)block_ptr; mem_pool_ptr->POOL_CHECK_POOL_PTR = (char _PTR_)mem_pool_ptr->POOL_PTR; mem_pool_ptr->POOL_BLOCK_IN_ERROR = NULL; /* Compute the pool size. */ mem_pool_ptr->POOL_SIZE = (_mem_size)((uchar_ptr)mem_pool_ptr->POOL_LIMIT - (uchar_ptr)mem_pool_ptr->POOL_PTR); /* Set up the first block as an idle block */ block_ptr->BLOCKSIZE = mem_pool_ptr->POOL_SIZE - MQX_MIN_MEMORY_STORAGE_SIZE; block_ptr->USER_AREA = NULL; block_ptr->PREVBLOCK = NULL; block_ptr->NEXTBLOCK = NULL; MARK_BLOCK_AS_FREE(block_ptr); CALC_CHECKSUM(block_ptr); mem_pool_ptr->POOL_FREE_LIST_PTR = block_ptr; /* ** Set up last block as an in_use block, so that the _mem_free algorithm ** will work (block coalescing) */ end_block_ptr = (STOREBLOCK_STRUCT_PTR) ((uchar_ptr)block_ptr + block_ptr->BLOCKSIZE); end_block_ptr->BLOCKSIZE = (_mem_size)(MQX_MIN_MEMORY_STORAGE_SIZE); end_block_ptr->USER_AREA = 0; end_block_ptr->PREVBLOCK = (struct storeblock_struct _PTR_)block_ptr; end_block_ptr->NEXTBLOCK = NULL; MARK_BLOCK_AS_USED(end_block_ptr, SYSTEM_TASK_ID(kernel_data)); CALC_CHECKSUM(end_block_ptr); mem_pool_ptr->POOL_END_PTR = end_block_ptr; /* Initialize the list of extensions to this pool */ _QUEUE_INIT(&mem_pool_ptr->EXT_LIST, 0); mem_pool_ptr->VALID = MEMPOOL_VALID; /* Protect the list of pools while adding new pool */ _lwsem_wait((LWSEM_STRUCT_PTR)&kernel_data->MEM_COMP.SEM); _QUEUE_ENQUEUE(&kernel_data->MEM_COMP.POOLS, &mem_pool_ptr->LINK); _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->MEM_COMP.SEM); return MQX_OK; } /* Endbody */
_mqx_uint _partition_create_internal ( /* [IN] the start of the partition */ PARTPOOL_STRUCT_PTR partpool_ptr, /* [IN] the total size of each block with overheads */ _mem_size actual_size, /* [IN] the initial number of blocks in the partition */ _mqx_uint initial_blocks ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; INTERNAL_PARTITION_BLOCK_STRUCT_PTR block_ptr; PARTITION_COMPONENT_STRUCT_PTR part_component_ptr; _mqx_uint result; _GET_KERNEL_DATA(kernel_data); part_component_ptr = (PARTITION_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_PARTITIONS]; if (part_component_ptr == NULL) { result = _partition_create_component(); part_component_ptr = (PARTITION_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_PARTITIONS]; #if MQX_CHECK_MEMORY_ALLOCATION_ERRORS if (part_component_ptr == NULL){ return(result); } /* Endif */ #endif } /* Endif */ _mem_zero(partpool_ptr, (_mem_size)sizeof(PARTPOOL_STRUCT)); partpool_ptr->BLOCK_SIZE = actual_size; /* START CR 308 */ partpool_ptr->POOL.VALID = PARTITION_VALID; /* END CR 308 */ partpool_ptr->POOL.NUMBER_OF_BLOCKS = initial_blocks; partpool_ptr->AVAILABLE = initial_blocks; partpool_ptr->TOTAL_BLOCKS = initial_blocks; block_ptr = (INTERNAL_PARTITION_BLOCK_STRUCT_PTR)((uchar_ptr)partpool_ptr + sizeof(PARTPOOL_STRUCT)); block_ptr = (INTERNAL_PARTITION_BLOCK_STRUCT_PTR) _ALIGN_ADDR_TO_HIGHER_MEM(block_ptr); partpool_ptr->POOL.FIRST_IBLOCK_PTR = block_ptr; while (initial_blocks--) { block_ptr->LINK.NEXT_BLOCK_PTR = partpool_ptr->FREE_LIST_PTR; CALC_PARTITION_CHECKSUM(block_ptr); partpool_ptr->FREE_LIST_PTR = block_ptr; block_ptr = (INTERNAL_PARTITION_BLOCK_STRUCT_PTR)((uchar_ptr)block_ptr + actual_size); } /* Endwhile */ _int_disable(); _QUEUE_ENQUEUE(&part_component_ptr->PARTITIONS, partpool_ptr); _int_enable(); return(MQX_OK); } /* Endbody */