Exemplo n.º 1
0
_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 */
Exemplo n.º 2
0
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 */
Exemplo n.º 3
0
_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 */
Exemplo n.º 4
0
/*!
 * \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 */
Exemplo n.º 5
0
_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 */
Exemplo n.º 6
0
_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 */