Example #1
0
/*!
 * \brief Reads the data from the log.
 * 
 * <table>
 *   <tr>
 *     <td><b>read_type</b></td>
 *     <td><b>Returns this entry in the log:</b></td> 
 *   </tr>
 *   <tr>
 *     <td>LOG_READ_NEWEST</td>
 *     <td>Newest.</td> 
 *   </tr>
 *   <tr>
 *     <td>LOG_READ_NEXT</td>
 *     <td>Next one after the previous one read (must be used with LOG_READ_OLDEST).</td> 
 *   </tr>
 *   <tr>
 *     <td>LOG_READ_OLDEST</td>
 *     <td>Oldest.</td> 
 *   </tr>
 *   <tr>
 *     <td>LOG_READ_OLDEST_AND_DELETE</td>
 *     <td>Oldest and deletes it.</td> 
 *   </tr>     
 * </table>
 * 
 * \param[in] log_number   Log number of a previously created log.
 * \param[in] read_type    Type of read operation (see Description).
 * \param[in] size_to_read Maximum number of _mqx_uints (not including the entry 
 * header) to be read from an entry.
 * \param[in] entry_ptr    Where to write the log entry (any structure that 
 * starts with LOG_STRUCT or LOG_ENTRY_STRUCT).
 * 
 * \return MQX_OK
 * \return LOG_INVALID (Log_number is out of range.)
 * \return LOG_DOES_NOT_EXIST (Log_number was not created.)
 * \return LOG_ENTRY_NOT_AVAILABLE (Log entry is not available.)
 * \return LOG_INVALID_READ_TYPE (Read_type is not valid.) 
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Log component is not created.)
 * \return MQX_INVALID_POINTER (Entry_ptr is NULL.)
 * \return MQX_INVALID_COMPONENT_HANDLE (Log component data is not valid.)
 * 
 * \see _log_create
 * \see _log_write
 * \see LOG_STRUCT
 * \see LOG_ENTRY_STRUCT        
 */ 
_mqx_uint _log_read
(
    _mqx_uint            log_number,
    _mqx_uint            read_type,
    _mqx_uint            size_to_read,
    LOG_ENTRY_STRUCT_PTR entry_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    LOG_COMPONENT_STRUCT_PTR log_component_ptr;
    LOG_HEADER_STRUCT_PTR    log_header_ptr;
    LOG_ENTRY_STRUCT_PTR     log_ptr;
    _mqx_uint_ptr            data_ptr;
    _mqx_uint_ptr            next_ptr;
    _mqx_uint_ptr            user_ptr;
    _mqx_uint                size;
    uint_16                  milliseconds;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (log_number >= LOG_MAXIMUM_NUMBER)
    {
        return(LOG_INVALID);
    } /* Endif */
    if (kernel_data->KERNEL_COMPONENTS[KERNEL_LOG] == NULL)
    {
        return(MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
    if (entry_ptr == NULL)
    {
        return(MQX_INVALID_POINTER);
    } /* Endif */
#endif

    log_component_ptr = (LOG_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_LOG];

#if MQX_CHECK_VALIDITY
    if (log_component_ptr->VALID != LOG_VALID)
    {
        return(MQX_INVALID_COMPONENT_HANDLE);
    } /* Endif */
#endif

    _INT_DISABLE();
    log_header_ptr = log_component_ptr->LOGS[log_number];
#if MQX_CHECK_ERRORS
    if (log_header_ptr == NULL)
    {
        _int_enable();
        return(LOG_DOES_NOT_EXIST);
    } /* Endif */
#endif

    if (log_header_ptr->SIZE == 0)
    {
        /* No data available */
        _INT_ENABLE();
        return(LOG_ENTRY_NOT_AVAILABLE);
    } /* Endif */

    if (read_type == LOG_READ_OLDEST_AND_DELETE)
    {
        data_ptr = log_header_ptr->LOG_READ;
    }
    else if (read_type == LOG_READ_NEXT)
    {
        data_ptr = log_header_ptr->LOG_NEXT;
        if (data_ptr == NULL)
        {
            _INT_ENABLE();
            return(LOG_ENTRY_NOT_AVAILABLE);
        } /* Endif */
    }
    else if (read_type == LOG_READ_OLDEST)
    {
        data_ptr = log_header_ptr->LOG_READ;
    }
    else if (read_type == LOG_READ_NEWEST)
    {
        data_ptr = log_header_ptr->LAST_LOG;
#if MQX_CHECK_ERRORS
    }
    else
    {
        _int_enable();
        return(LOG_INVALID_READ_TYPE);
#endif
    } /* Endif */

    size = *data_ptr;
    next_ptr = data_ptr + size;

#if 0
    if (next_ptr >= log_header_ptr->LOG_END)
    {
        next_ptr = log_header_ptr->LOG_START +
        (next_ptr - log_header_ptr->LOG_END);
    } /* Endif */
#else
    if (log_header_ptr->LOG_READ < log_header_ptr->LOG_WRITE)
    {
        /* R < W */
        if (next_ptr >= log_header_ptr->LOG_WRITE)
        {
            next_ptr = log_header_ptr->LOG_READ;
        } /* Endif */
    }
    else
    {
        /* R > W */
        if (next_ptr >= log_header_ptr->LOG_END)
        {
            next_ptr = log_header_ptr->LOG_START +
            (next_ptr - log_header_ptr->LOG_END);
        } /* Endif */
        if (next_ptr == log_header_ptr->LOG_WRITE)
        {
            next_ptr = log_header_ptr->LOG_READ;
        } /* Endif */
    } /* Endif */
#endif

    if (read_type == LOG_READ_OLDEST_AND_DELETE)
    {
        log_header_ptr->LOG_READ += size;
        log_header_ptr->SIZE -= size;
        if (log_header_ptr->LOG_READ >= log_header_ptr->LOG_END)
        {
            log_header_ptr->LOG_READ = log_header_ptr->LOG_START +
            (log_header_ptr->LOG_READ - log_header_ptr->LOG_END);
        } /* Endif */
    } /* Endif */

    if (size > (size_to_read + (_mqx_uint)sizeof(LOG_ENTRY_STRUCT)/sizeof(_mqx_uint)))
    {
        size = (size_to_read + (_mqx_uint)sizeof(LOG_ENTRY_STRUCT)/sizeof(_mqx_uint));
    } /* Endif */

    ++size;
    user_ptr = (_mqx_uint_ptr)((pointer)entry_ptr);
    while (--size)
    {
        *user_ptr++ = *data_ptr++;
        if (data_ptr == log_header_ptr->LOG_END)
        {
            data_ptr = log_header_ptr->LOG_START;
        } /* Endif */
    } /* Endwhile */
    log_ptr = entry_ptr;
    if (log_ptr->MICROSECONDS > MICROSECS_IN_MILLISECOND)
    {
        milliseconds = log_ptr->MICROSECONDS / (uint_16)MICROSECS_IN_MILLISECOND;
        log_ptr->MILLISECONDS += milliseconds;
        log_ptr->MICROSECONDS -= (milliseconds * (uint_16)MICROSECS_IN_MILLISECOND);
    } /* Endif */

    if (read_type == LOG_READ_NEXT)
    {
        log_header_ptr->LOG_NEXT = next_ptr;
    }
    else if (read_type == LOG_READ_OLDEST)
    {
        log_header_ptr->LOG_NEXT = next_ptr;
    }
    else
    {
        log_header_ptr->LOG_NEXT = NULL;
    } /* Endif */
    _INT_ENABLE();

    return(MQX_OK);

} /* Endbody */
Example #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 */
Example #3
0
_mqx_int _io_sai_int_open
(
    /* [IN] the file handle for the device being opened */
    MQX_FILE_PTR    fd_ptr,

    /* [IN] the remaining portion of the name of the device */
    char_ptr        open_name_ptr,

    /* [IN] the flags to be used during operation */
    char_ptr        flags
)
{ /* Body */
    IO_DEVICE_STRUCT_PTR        io_dev_ptr;
    IO_SAI_DEVICE_STRUCT_PTR    io_sai_dev_ptr;
    _mqx_int result = MQX_OK;
    uint_32 i = 0;
    boolean read_open = FALSE;
    boolean write_open = FALSE;
    
    io_dev_ptr = (IO_DEVICE_STRUCT_PTR)fd_ptr->DEV_PTR;
    io_sai_dev_ptr = (pointer)(io_dev_ptr->DRIVER_INIT_PTR);

 
    io_sai_dev_ptr->FLAGS = 0;
    
    if (flags == NULL)
    {
        flags = "rw";
    }
    while (flags[i] != '\0')
    {
        if (flags[i] == 'r') // open device for reading
        {
            read_open = TRUE;
        }
        if (flags[i++] == 'w') // open device for writing
        {
            write_open = TRUE;
        }
    }
    /* If we want to open device for reading */
    if (read_open)
    {
        _int_disable ();
        if (io_sai_dev_ptr->READ_COUNT)
        {
            /* Device is already opened for reading */
            _int_enable ();
            return MQX_IO_OPERATION_NOT_AVAILABLE;
        }
        _int_enable ();
        io_sai_dev_ptr->FLAGS |= I2S_IO_READ;
    }
    /* If we want to open device for writing */
    if (write_open)
    {
        _int_disable ();
        if (io_sai_dev_ptr->WRITE_COUNT)
        {
            /* Device is already opened for reading */
            _int_enable ();
            return MQX_IO_OPERATION_NOT_AVAILABLE;
        }
        _int_enable ();
        io_sai_dev_ptr->FLAGS |= I2S_IO_WRITE;
    }

    fd_ptr->FLAGS         = (_mqx_uint)flags;

    result = (*io_sai_dev_ptr->DEV_INIT)(io_sai_dev_ptr);
    if (result == MQX_OK)
    {
        if (read_open)
        {
            io_sai_dev_ptr->READ_COUNT = 1;
        }
        if (write_open)
        {
            io_sai_dev_ptr->WRITE_COUNT = 1;
        }
    }
    return result;
} /* Endbody */
Example #4
0
/*!
 * \private
 *
 * \brief Used by a task to destroy an instance of a lightweight event.
 *
 * \param[in] event_ptr Pointer to the lightweight event to be deinitialized.
 * \param[in] user      User mode
 *
 * \return MQX_OK
 * \return MQX_LWEVENT_INVALID (Lightweight event was not valid.)
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 *
 * \see _lwevent_destroy
 * \see LWEVENT_STRUCT
 */
_mqx_uint _lwevent_destroy_internal
(
    LWEVENT_STRUCT_PTR  event_ptr,
    bool             user
)
{
    KERNEL_DATA_STRUCT_PTR kernel_data;
#if MQX_COMPONENT_DESTRUCTION
    TD_STRUCT_PTR td_ptr;
#endif

#if MQX_ENABLE_USER_MODE
    if (user && !_psp_mem_check_access_mask((uint32_t)event_ptr,
                                            sizeof(LWEVENT_STRUCT),
                                            MPU_UM_R, MPU_UM_RW))
    {
        return MQX_LWEVENT_INVALID;
    }
#endif

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_lwevent_destroy, event_ptr);

#if MQX_COMPONENT_DESTRUCTION

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        _KLOGX2(KLOG_lwevent_destroy, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return (MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    } /* Endif */
#endif

    _int_disable();
#if MQX_CHECK_VALIDITY
    if (event_ptr->VALID != LWEVENT_VALID)
    {
        _int_enable();
        _KLOGX2(KLOG_lwevent_destroy, MQX_LWEVENT_INVALID);
        return (MQX_LWEVENT_INVALID);
    } /* Endif */
#endif

    /* Effectively stop all access to the event */
    event_ptr->VALID = 0;
    while (_QUEUE_GET_SIZE(&event_ptr->WAITING_TASKS))
    {
        _QUEUE_DEQUEUE(&event_ptr->WAITING_TASKS, td_ptr);
        _BACKUP_POINTER(td_ptr, TD_STRUCT, AUX_QUEUE);
        _TIME_DEQUEUE(td_ptr, kernel_data);
        _TASK_READY(td_ptr, kernel_data);
    } /* Endwhile */

    /* remove event from kernel LWEVENTS queue */
#if MQX_ENABLE_USER_MODE
    if (user)
    {
        _QUEUE_REMOVE(&kernel_data->USR_LWEVENTS, event_ptr);
    }
    else
#endif
    {
        _QUEUE_REMOVE(&kernel_data->LWEVENTS, event_ptr);
    }

    _int_enable();

    /* May need to let higher priority task run */
    _CHECK_RUN_SCHEDULER();
#endif

    _KLOGX2(KLOG_lwevent_destroy, MQX_OK);
    return (MQX_OK);

}
Example #5
0
/*!
 * \brief Used by a task to set the specified event bits in an event.
 *
 * \param[in] event_ptr Pointer to the lightweight event to set bits in.
 * \param[in] bit_mask  Bit mask. Each bit represents an event bit to be set.
 *
 * \return MQX_OK
 * \return MQX_LWEVENT_INVALID (Lightweight event was invalid.)
 *
 * \see _lwevent_create
 * \see _lwevent_destroy
 * \see _lwevent_set_auto_clear
 * \see _lwevent_clear
 * \see _lwevent_test
 * \see _lwevent_wait_for
 * \see _lwevent_wait_ticks
 * \see _lwevent_wait_until
 * \see _lwevent_get_signalled
 * \see LWEVENT_STRUCT
 */
_mqx_uint _lwevent_set
(
    LWEVENT_STRUCT_PTR  event_ptr,
    _mqx_uint           bit_mask
)
{
    KERNEL_DATA_STRUCT_PTR kernel_data;
    QUEUE_ELEMENT_STRUCT_PTR q_ptr;
    QUEUE_ELEMENT_STRUCT_PTR next_q_ptr;
    TD_STRUCT_PTR td_ptr;
    _mqx_uint set_bits;

#if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI
    if (MQX_RUN_IN_USER_MODE)
    {
        return _usr_lwevent_set(event_ptr, bit_mask);
    }
#endif

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_lwevent_set, event_ptr, bit_mask);

    _INT_DISABLE();
#if MQX_CHECK_VALIDITY
    if (event_ptr->VALID != LWEVENT_VALID)
    {
        _int_enable();
        _KLOGX2(KLOG_lwevent_set, MQX_LWEVENT_INVALID);
        return (MQX_LWEVENT_INVALID);
    } /* Endif */
#endif

    set_bits = event_ptr->VALUE | bit_mask;

    if (_QUEUE_GET_SIZE(&event_ptr->WAITING_TASKS))
    {
        /* Schedule waiting task(s) to run if bits ok */

        q_ptr = event_ptr->WAITING_TASKS.NEXT;
        while (q_ptr != (QUEUE_ELEMENT_STRUCT_PTR) ((void *) &event_ptr->WAITING_TASKS))
        {
            td_ptr = (void *) q_ptr;
            _BACKUP_POINTER(td_ptr, TD_STRUCT, AUX_QUEUE);
            next_q_ptr = q_ptr->NEXT;
            if (((td_ptr->FLAGS & TASK_LWEVENT_ALL_BITS_WANTED) && ((td_ptr->LWEVENT_BITS & set_bits)
                            == td_ptr->LWEVENT_BITS)) || ((!(td_ptr->FLAGS & TASK_LWEVENT_ALL_BITS_WANTED))
                            && (td_ptr->LWEVENT_BITS & set_bits)))
            {
                _QUEUE_REMOVE(&event_ptr->WAITING_TASKS, q_ptr);
                _TIME_DEQUEUE(td_ptr, kernel_data);
                td_ptr->INFO = 0;
                _TASK_READY(td_ptr, kernel_data);

                /* store information about which bits caused task to be unblocked */
                td_ptr->LWEVENT_BITS &= set_bits;
                set_bits &= ~(event_ptr->AUTO & td_ptr->LWEVENT_BITS);

            } /* Endif */
            q_ptr = next_q_ptr;
        } /* Endwhile */
    } /* Endif */

    event_ptr->VALUE = set_bits;
    _INT_ENABLE();

    /* May need to let higher priority task run */
    _CHECK_RUN_SCHEDULER();

    _KLOGX2(KLOG_lwevent_set, MQX_OK);
    return (MQX_OK);

}
Example #6
0
/*!
 * \brief Allocates a message from a system message pool.
 * 
 * The size of the message is determined by the message size that a task 
 * specified when it called _msgpool_create_system().
 * \n The message is a resource of the task until the task either frees it 
 * (_msg_free()) or puts it on a message queue (_msgq_send family of functions.)
 * 
 * \param[in] message_size Maximum size (in single-addressable units) of the 
 * message.
 * 
 * \return Pointer to a message of at least message_size single-addressable 
 * units (success).
 * \return NULL (Failure: message component is not created.)
 * 
 * \warning On failure, calls _task_set_error() to set one of the following task 
 * error codes:
 * \li MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * \li Task error codes from _mem_alloc_system() (If MQX needs to grow the pool.)
 * 
 * \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 _msg_alloc
 * \see _msg_free
 * \see _msgpool_create_system
 * \see _msgq_send
 * \see _task_set_error
 * \see MESSAGE_HEADER_STRUCT 
 */ 
void *_msg_alloc_system
(
    _msg_size message_size
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR               kernel_data;
    MSG_COMPONENT_STRUCT_PTR             msg_component_ptr;
    register INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr;
    register MESSAGE_HEADER_STRUCT_PTR   message_ptr;
    register MSGPOOL_STRUCT_PTR          msgpool_ptr;
    uint16_t                              grow_number;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE2(KLOG_msg_alloc_system, message_size );

    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
#if MQX_CHECK_ERRORS
    if (msg_component_ptr == NULL)
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        _KLOGX2( KLOG_msg_alloc_system, NULL );
        return(NULL);
    }/* Endif */
#endif

    message_ptr = NULL;
    _INT_DISABLE();
    msgpool_ptr = msg_component_ptr->SMALLEST_MSGPOOL_PTR;
    while (msgpool_ptr != NULL)
    {
        if (msgpool_ptr->MESSAGE_SIZE >= message_size)
        {
            imsg_ptr = msgpool_ptr->MSG_FREE_LIST_PTR;
            if ( (imsg_ptr == NULL) &&
                            (msgpool_ptr->GROW_NUMBER) &&
                            (msgpool_ptr->MAX < msgpool_ptr->GROW_LIMIT) )
            {
                /* Attempt to add elements to the pool */
                grow_number = msgpool_ptr->GROW_NUMBER;
                if ( ((uint16_t)(msgpool_ptr->MAX + grow_number) > msgpool_ptr->GROW_LIMIT))
                {
                    grow_number = msgpool_ptr->GROW_LIMIT - msgpool_ptr->MAX;
                } /* Endif */
                _msgpool_add_internal(msgpool_ptr, grow_number);
                imsg_ptr = msgpool_ptr->MSG_FREE_LIST_PTR;
            } /* Endif */
            if ( imsg_ptr != NULL )
            {
                msgpool_ptr->MSG_FREE_LIST_PTR = imsg_ptr->NEXT;
                --msgpool_ptr->SIZE;
                _INT_ENABLE();
                imsg_ptr->FREE = FALSE;
                imsg_ptr->QUEUED = FALSE;
                if (kernel_data->IN_ISR)
                {
                    imsg_ptr->TD_PTR = NULL;
                }
                else
                {
                    imsg_ptr->TD_PTR = kernel_data->ACTIVE_PTR;
                } /* Endif */
                message_ptr = (MESSAGE_HEADER_STRUCT_PTR)&imsg_ptr->MESSAGE;
                message_ptr->TARGET_QID = MSGQ_NULL_QUEUE_ID;
                message_ptr->SOURCE_QID = MSGQ_NULL_QUEUE_ID;
                message_ptr->SIZE = message_size;
                message_ptr->CONTROL = MSG_HDR_ENDIAN | MSG_DATA_ENDIAN;

                _KLOGX2(KLOG_msg_alloc_system, message_ptr);
                return (void *)message_ptr;
            } /* Endif */
        } /* Endif */
        msgpool_ptr = msgpool_ptr->NEXT_MSGPOOL_PTR;
    } /* Endwhile */

    _int_enable();
    _KLOGX2(KLOG_msg_alloc_system, message_ptr);
    return (void *)message_ptr;

} /* Endbody */
Example #7
0
boolean _29wsxxxN_program
(
    /* [IN] the flash information structure */
    IO_FLASHX_STRUCT_PTR dev_ptr,

    /* [IN] where to copy data from */
    char_ptr             from_ptr,

    /* [OUT] where to copy data to */
    char_ptr             to_ptr,

    /* [IN] the size to copy in bytes */
    _mem_size            size
)
{   /* Body */
    volatile uint_16 _PTR_  base16_ptr;
    uint_32                 result = FLASH_READY;

    uint_16                 temp_data = 0xFFFF;
    uchar_ptr               temp_data_ptr;
    uchar                   byte_data_counter = 0;
    /* get the offset in write word */
    uint_16 offset = (uint_16)to_ptr & 0x0001;

    /* test for flash write protect */
    if (_29wsxxxN_test_lock_bits(dev_ptr) == LOCKED) {
        return  FLASH_WRITE_PROTECT;
    }/* Endif */

    if (dev_ptr->WIDTH == 16) {

        (uint_16_ptr)temp_data_ptr =  &temp_data;

        /* if the start address !=  doesn't correspond with hardware, prepare
             variables for 1st word write */
        if(offset) {
            /* Align pointer to writable address */
            to_ptr -= offset;
            /* jump over old data */
            byte_data_counter = offset;
        }

        /* set the flash base address */
        base16_ptr = (uint_16_ptr)dev_ptr->BASE_ADDR;

        /* we have data to write */
        while (size) {
            /* read old data to write word */
            temp_data = *(uint_16_ptr)to_ptr;
            /* move data to write word byte by byte */
            while( byte_data_counter < WS_BYTES_IN_WORD && size ) {
                *(uchar_ptr)(temp_data_ptr+byte_data_counter) = *from_ptr++;
                byte_data_counter++;
                size--;
            }
            /* flash program */
            _int_disable();
            /* unlock flash */
            *( base16_ptr + 0x555 ) = 0x00AA;
            *( base16_ptr + 0x2AA ) = 0x0055;
            /* Write command */
            *( base16_ptr + 0x555 ) = 0x00A0;
            /* write value */
            *(uint_16 _PTR_)to_ptr = temp_data;
            _int_enable();

            /* test if the write operation complete */
            result = _29wsxxxN_test_program_cmd(to_ptr, temp_data);
            /* if write command failed, exit write command */
            if(result != FLASH_READY) {
                break;
            }
            byte_data_counter = 0;
            temp_data = 0xFFFF;
            to_ptr += WS_BYTES_IN_WORD;
        }/* Endwhile */

    }
    else
        result = FLASH_UNSUPPORTED_BUS_SIZE;

    return result;

} /* Endbody */
Example #8
0
void usb_filesystem_uninstall( USB_FILESYSTEM_STRUCT_PTR  usb_fs_ptr)
{
   int_32                     error_code;
   uint_32                    mfs_status;

   if (usb_fs_ptr == NULL) {
      return;
   }
    _int_disable();
   printf("\nDevice removed, starting device cleanup");
   printf("\n--->Closing MFS");
   if (usb_fs_ptr->FS_FD_PTR) {
      error_code = fclose(usb_fs_ptr->FS_FD_PTR);
      if ( error_code != IO_OK ) {
         printf("\nError closing MFS device: 0x%X.", error_code);
      } 
   }

   printf("\n--->Uninstalling %s",usb_fs_ptr->FS_NAME);
   if (usb_fs_ptr->FS_NAME) {
      mfs_status = _io_mfs_uninstall(usb_fs_ptr->FS_NAME);
      if ((mfs_status != MFS_NO_ERROR)  && (mfs_status !=IO_DEVICE_DOES_NOT_EXIST)) {
         printf("\nError while uninstalling MFS on device");
      } 
   }

   if (usb_fs_ptr->PM_FD_PTR != NULL) {
      /* Close partition device */
      printf("\n--->Closing partition");
      error_code = fclose(usb_fs_ptr->PM_FD_PTR);
      if ( error_code != IO_OK ) {
         printf("\nError closing Partition device %s: 0x%X.", usb_fs_ptr->PM_NAME, error_code);
      } 
   }

    if (usb_fs_ptr->PM_NAME) {
     /* Uninstall the partition manager */
      printf("\n--->Uninstalling PM");
      error_code = _io_part_mgr_uninstall(usb_fs_ptr->PM_NAME);
      if (( error_code != IO_OK ) && (mfs_status !=IO_DEVICE_DOES_NOT_EXIST)) {
         printf("\nError uninstalling Partition device %s: 0x%X.", usb_fs_ptr->PM_NAME, error_code);
      } 
   } 

   /* USB mass storage link device */
   if (usb_fs_ptr->DEV_FD_PTR) {
      printf("\n--->Closing disk");
      error_code = fclose(usb_fs_ptr->DEV_FD_PTR);
      if ( error_code != IO_OK ) {
         printf("\nError closing disk (0x%X)", error_code);
      } 
   }
   _int_enable();
   
   if (usb_fs_ptr->DEV_NAME) {
      printf("\n--->Closing USB MFS");
      _io_dev_uninstall(usb_fs_ptr->DEV_NAME);
   }

   _mem_free(usb_fs_ptr);
}
Example #9
0
/*!
 * \private
 *
 * \brief Creates the lightweight log.
 *
 * \param[in] log_number     Log number to create ( 1 through 15; 0 is reserved
 * for kernel log).
 * \param[in] max_size       Maximum number of entries in the log.
 * \param[in] flags          LOG_OVERWRITE (when the log is full, write new entries
 * over oldest ones), NULL (when the log is full, do not write entries; the default
 * behavior).
 * \param[in] log_header_ptr Pointer to lightweight log header.
 *
 * \return MQX_OK
 * \return LOG_INVALID (log_number is out of range.)
 * \return LOG_EXISTS (Lightweight log with log number log_number exists.)
 * \return MQX_OUT_OF_MEMORY (MQX is out of memory.)
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_INVALID_COMPONENT_BASE (Data for the lightweight log component is
 * not valid.)
 *
 * \see _lwlog_create
 * \see _lwlog_create_at
 * \see LWLOG_HEADER_STRUCT
 */
_mqx_uint _lwlog_create_internal
(
    _mqx_uint log_number,
    _mqx_uint max_size,
    _mqx_uint flags,
    LWLOG_HEADER_STRUCT_PTR log_header_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    LWLOG_COMPONENT_STRUCT_PTR log_component_ptr;
    LWLOG_ENTRY_STRUCT_PTR     entry_ptr;
    _mqx_uint                  i;
    _mqx_uint                  result = MQX_OK;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (log_number >= LOG_MAXIMUM_NUMBER)
    {
        return (LOG_INVALID);
    } /* Endif */
#endif

    log_component_ptr = (LWLOG_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_LWLOG];
    if (log_component_ptr == NULL)
    {
        result = _lwlog_create_component();
        log_component_ptr = (LWLOG_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_LWLOG];
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
        if (log_component_ptr == NULL)
        {
            return (result);
        } /* Endif */
#endif
#if MQX_CHECK_ERRORS
    }
    else if (log_component_ptr->LOGS[log_number] != NULL)
    {
        return (LOG_EXISTS);
#endif
    } /* Endif */

#if MQX_CHECK_VALIDITY
    if (log_component_ptr->VALID != LWLOG_VALID)
    {
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif
    _mem_zero((void *) log_header_ptr, (_mem_size) sizeof(LWLOG_HEADER_STRUCT));

    log_header_ptr->FLAGS = flags;
    log_header_ptr->FLAGS |= LWLOG_ENABLED;
    log_header_ptr->NUMBER = 1;
    log_header_ptr->MAX_ENTRIES = max_size;

    entry_ptr = &log_header_ptr->FIRST_ENTRY;

    log_header_ptr->READ_PTR = entry_ptr;
    log_header_ptr->OLDEST_PTR = entry_ptr;

    max_size--;
    for (i = 0; i < max_size; i++)
    {
        entry_ptr->NEXT_PTR = entry_ptr + 1;
        entry_ptr++;
    } /* Endfor */

    log_header_ptr->WRITE_PTR = entry_ptr;
    entry_ptr->NEXT_PTR = log_header_ptr->READ_PTR;

    _int_disable();
#if MQX_CHECK_ERRORS
    if (log_component_ptr->LOGS[log_number] != NULL)
    {
        _int_enable();
        return (LOG_EXISTS);
    } /* Endif */
#endif
    log_component_ptr->LOGS[log_number] = log_header_ptr;
    _int_enable();

    return (result);

} /* Endbody */
Example #10
0
_mqx_uint _mutex_init
   (
      /* [IN] - the address where the mutex is to be initialized */
      register MUTEX_STRUCT_PTR      mutex_ptr,

      /* [IN]  - Initialization parameters for the mutex  */
      register MUTEX_ATTR_STRUCT_PTR attr_ptr
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR     kernel_data;
   MUTEX_COMPONENT_STRUCT_PTR mutex_component_ptr;
   MUTEX_ATTR_STRUCT          default_attr;
#if MQX_CHECK_ERRORS
   MUTEX_STRUCT_PTR           mutex_chk_ptr;
#endif
   _mqx_uint                   result;

   _GET_KERNEL_DATA(kernel_data);
   if (attr_ptr == NULL) {
      attr_ptr = &default_attr;
      _mutatr_init(attr_ptr);
      _KLOGE3(KLOG_mutex_init, mutex_ptr, NULL);
   } else {
      _KLOGE3(KLOG_mutex_init, mutex_ptr, attr_ptr);
   } /* Endif */
   
#if MQX_CHECK_ERRORS
   if (mutex_ptr == NULL) {
      _KLOGX2(KLOG_mutex_init, MQX_EINVAL);
      return(MQX_EINVAL);
   } /* Endif */
#endif
#if MQX_CHECK_VALIDITY
   if (attr_ptr->VALID != MUTEX_VALID) {
      _KLOGX2(KLOG_mutex_init, MQX_EINVAL);
      return(MQX_EINVAL);
   } /* Endif */
#endif

   mutex_component_ptr = (MUTEX_COMPONENT_STRUCT_PTR)
      kernel_data->KERNEL_COMPONENTS[KERNEL_MUTEXES];
   if (mutex_component_ptr == NULL) {
      result = _mutex_create_component();
      mutex_component_ptr = (MUTEX_COMPONENT_STRUCT_PTR)
         kernel_data->KERNEL_COMPONENTS[KERNEL_MUTEXES];
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
      if (mutex_component_ptr == NULL){
         _KLOGX2(KLOG_mutex_init, result);
         return(result);
      } /* Endif */
#endif
   } /* Endif */

#if MQX_CHECK_VALIDITY
   if (mutex_component_ptr->VALID != MUTEX_VALID) {
      _KLOGX2(KLOG_mutex_init, MQX_INVALID_COMPONENT_BASE);
      return(MQX_INVALID_COMPONENT_BASE);
   } /* Endif */
#endif

   _int_disable();
#if MQX_CHECK_ERRORS
   /* Check if mutex is already initialized */
   mutex_chk_ptr = (MUTEX_STRUCT_PTR)
      ((pointer)mutex_component_ptr->MUTEXES.NEXT);
   while (mutex_chk_ptr != (MUTEX_STRUCT_PTR)
      ((pointer)&mutex_component_ptr->MUTEXES))
   {
      if (mutex_chk_ptr == mutex_ptr) {
         _int_enable();
         _KLOGX2(KLOG_mutex_init, MQX_EINVAL);
         return(MQX_EINVAL);
      } /* Endif */
      mutex_chk_ptr = (MUTEX_STRUCT_PTR)((pointer)mutex_chk_ptr->LINK.NEXT);
   } /* Endif */
#endif
   
   mutex_ptr->PROTOCOLS        = 
      attr_ptr->SCHED_PROTOCOL | attr_ptr->WAIT_PROTOCOL;
   mutex_ptr->VALID            = MUTEX_VALID;
   mutex_ptr->COUNT            = attr_ptr->COUNT;
   mutex_ptr->PRIORITY_CEILING = attr_ptr->PRIORITY_CEILING;
   mutex_ptr->LOCK             = 0;
   mutex_ptr->BOOSTED          = 0;
   mutex_ptr->OWNER_TD         = NULL;
   _QUEUE_INIT(&mutex_ptr->WAITING_TASKS, 0);

   _QUEUE_ENQUEUE(&mutex_component_ptr->MUTEXES, mutex_ptr);
   _int_enable();

   _KLOGX2(KLOG_mutex_init, MQX_EOK);
   return(MQX_EOK);
   
} /* Endbody */
Example #11
0
/*!
 * \brief Sets the scheduling policy for a task or the system.
 *
 * \param[in] task_id One of the following:
 * \n - Task on this processor for which to get info.
 * \n - MQX_DEFAULT_TASK_ID (Set the policy for the processor.)
 * \n - MQX_NULL_TASK_ID (Set the policy for the calling task.)
 * \param[in] policy  New scheduling policy; one of the following:
 * \n - MQX_SCHED_FIFO
 * \n - MQX_SCHED_RR
 *
 * \return Previous scheduling policy MQX_SCHED_FIFO or MQX_SCHED_RR (Success.)
 * \return MAX_MQX_UINT (Failure.)
 *
 * \warning On failure, _task_set_error() is called to set the following task
 * error codes:
 * \n - MQX_SCHED_INVALID_POLICY (Policy is not one of the allowed policies.)
 * \n - MQX_SCHED_INVALID_TASK_ID (Task_id is not a valid task on this processor.)
 *
 * \see _sched_get_policy
 * \see _task_set_error
 */
_mqx_uint _sched_set_policy
(
    _task_id  task_id,
    _mqx_uint policy
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR  kernel_data = NULL;
    (void)                  kernel_data; /* suppress 'unused variable' warning */
    TD_STRUCT_PTR           td_ptr = NULL;
    (void)                  td_ptr; /* suppress 'unused variable' warning */
    _mqx_uint               old_policy = MQX_SCHED_FIFO;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_sched_set_policy, (_mqx_uint)task_id, policy);
#if MQX_HAS_TIME_SLICE

#if MQX_CHECK_ERRORS
    if (! ((policy == MQX_SCHED_FIFO) || (policy == MQX_SCHED_RR)))
    {
        _task_set_error(MQX_SCHED_INVALID_POLICY);
        _KLOGX3(KLOG_sched_set_policy, MAX_MQX_UINT, MQX_SCHED_INVALID_POLICY);
        return(MAX_MQX_UINT);
    } /* Endif */
#endif

    /* Handle default case */
    if (task_id == MQX_DEFAULT_TASK_ID)
    {
        old_policy = kernel_data->SCHED_POLICY;
        kernel_data->SCHED_POLICY = policy;
    }
    else
    {
        td_ptr = (TD_STRUCT_PTR)_task_get_td(task_id);
        if (td_ptr == NULL)
        {
            _task_set_error(MQX_SCHED_INVALID_TASK_ID);
            _KLOGX3(KLOG_sched_set_policy, MAX_MQX_UINT, MQX_SCHED_INVALID_TASK_ID);
            return(MAX_MQX_UINT);
        } /* Endif */
        if (td_ptr->FLAGS & MQX_TIME_SLICE_TASK)
        {
            old_policy = MQX_SCHED_RR;
        }
        else
        {
            old_policy = MQX_SCHED_FIFO;
        } /* Endif */
        _int_disable();
        if (policy == MQX_SCHED_RR)
        {
            td_ptr->FLAGS |= MQX_TIME_SLICE_TASK;
        }
        else
        {
            td_ptr->FLAGS &= ~MQX_TIME_SLICE_TASK;
        } /* Endif */
        _int_enable();
    } /* Endif */
#else

#if MQX_CHECK_ERRORS
    if (policy != MQX_SCHED_FIFO)
    {
        _task_set_error(MQX_SCHED_INVALID_POLICY);
        _KLOGX3(KLOG_sched_set_policy, MAX_MQX_UINT, MQX_SCHED_INVALID_POLICY);
        return (MAX_MQX_UINT);
    } /* Endif */
    old_policy = MQX_SCHED_FIFO;
#endif

#endif

    _KLOGX3(KLOG_sched_set_policy, old_policy, 0L);
    return (old_policy);

} /* Endbody */
Example #12
0
_mqx_uint _lwmsgq_receive
   (
      /* Handle to the queue */
      pointer             handle,

      /* location of message to copy to */
      _mqx_max_type_ptr   message,

      /* flags for blocking on empty */
      _mqx_uint           flags,

      /* Timeout for receive if using ticks if 0, ignored */
      _mqx_uint           ticks,

      /* Timeout if receive timout using tick struct must have flags set */
      MQX_TICK_STRUCT_PTR tick_ptr
   )
{/* Body */
   KERNEL_DATA_STRUCT_PTR kernel_data;
   TD_STRUCT_PTR          td_ptr;
   LWMSGQ_STRUCT_PTR      q_ptr = (LWMSGQ_STRUCT_PTR)handle;
   _mqx_uint              i;
   _mqx_max_type_ptr      from_ptr;
   _mqx_max_type_ptr      to_ptr;

#if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI
    if (MQX_RUN_IN_USER_MODE) {
        return _usr_lwmsgq_receive(handle, message, flags, ticks, tick_ptr);
    }
#endif
    
   /* Start CR 1944 */
   _GET_KERNEL_DATA(kernel_data);
   _KLOGE6(KLOG_lwmsgq_receive, handle, message, flags, ticks, tick_ptr);
   /* End CR 1944 */
   
   _int_disable();
#if MQX_CHECK_VALIDITY
   if (q_ptr->VALID != LWMSGQ_VALID){
      _int_enable();
      /* Start CR 1944 */
      _KLOGX2(KLOG_lwmsgq_send, LWMSGQ_INVALID);
      /* End CR 1944 */
      return LWMSGQ_INVALID;
   } /* Endif */
#endif
   if (LWMSGQ_IS_EMPTY(q_ptr)) {
      if (flags & LWMSGQ_RECEIVE_BLOCK_ON_EMPTY) {
         td_ptr = kernel_data->ACTIVE_PTR;
         while (LWMSGQ_IS_EMPTY(q_ptr)) {
            td_ptr->STATE = LWMSGQ_READ_BLOCKED;
            td_ptr->INFO  = (_mqx_uint)&q_ptr->WAITING_READERS;
            _QUEUE_UNLINK(td_ptr);
            _QUEUE_ENQUEUE(&q_ptr->WAITING_READERS, &td_ptr->AUX_QUEUE);
            if (ticks || (flags & (LWMSGQ_TIMEOUT_UNTIL | LWMSGQ_TIMEOUT_FOR))){
               if (ticks) {
                  PSP_ADD_TICKS_TO_TICK_STRUCT(&kernel_data->TIME, ticks,
                     &td_ptr->TIMEOUT);
               } else if (flags & LWMSGQ_TIMEOUT_UNTIL){
                  td_ptr->TIMEOUT = *tick_ptr;
               } else {
                  PSP_ADD_TICKS(tick_ptr, &kernel_data->TIME, &td_ptr->TIMEOUT);
               } /* Endif */
               _time_delay_internal(td_ptr);
               if (td_ptr->INFO != 0) {
                  _int_enable();
                  /* Start CR 1944 */
                  _KLOGX2(KLOG_lwmsgq_receive, LWMSGQ_TIMEOUT);
                  /* End CR 1944 */
                  return LWMSGQ_TIMEOUT;
               } /* Endif */
            } else {
               _sched_execute_scheduler_internal(); /* Let other tasks run */
            } /* Endif */
         } /* Endwhile */
      } else {
         _int_enable();
         /* Start CR 1944 */
         _KLOGX2(KLOG_lwmsgq_receive, LWMSGQ_EMPTY);
         /* End CR 1944 */
         return LWMSGQ_EMPTY;
      } /* Endif */
   }/* Endif */
   from_ptr = q_ptr->MSG_READ_LOC;
   to_ptr = message;
   i = q_ptr->MSG_SIZE+1;
   while (--i) {
      *to_ptr++ = *from_ptr++;
   } /* Endwhile */
   q_ptr->MSG_READ_LOC += q_ptr->MSG_SIZE;
   if (q_ptr->MSG_READ_LOC >= q_ptr->MSG_END_LOC) {
      q_ptr->MSG_READ_LOC = q_ptr->MSG_START_LOC;
   } /* Endif */
   q_ptr->CURRENT_SIZE--;
   if (! _QUEUE_IS_EMPTY(&q_ptr->WAITING_WRITERS)) {
      _QUEUE_DEQUEUE(&q_ptr->WAITING_WRITERS, td_ptr);
      _BACKUP_POINTER(td_ptr, TD_STRUCT, AUX_QUEUE);
      td_ptr->INFO = 0;  /* Signal that post is activating the task */
      _TASK_READY(td_ptr, kernel_data);
      _CHECK_RUN_SCHEDULER(); /* Let higher priority task run */
   } /* Endif */
   _int_enable();
   /* Start CR 1944 */
   _KLOGX2(KLOG_lwmsgq_receive, MQX_OK);
   /* End CR 1944 */
   return MQX_OK;

}/* Endbody */
Example #13
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 */
Example #14
0
/*!
 * \brief Tests the log component for consistency.
 * 
 * \param[out] log_error_ptr Pointer to the log in error (NULL if no error is 
 * found).
 * 
 * \return MQX_OK Log component data is valid (*Log_error_ptr is 0.).
 * \return LOG_INVALID Information for a specific log is not valid 
 * (*log_error_ptr contains a log number of the first invalid log.). 
 * \return MQX_INVALID_COMPONENT_BASE Log component data is not valid 
 * (*log_error_ptr is NULL.). 
 * 
 * \warning Disables and enables interrupts
 * 
 * \see _log_create_component
 * \see _log_create
 */ 
_mqx_uint _log_test
(
    _mqx_uint _PTR_ log_error_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    LOG_COMPONENT_STRUCT_PTR log_component_ptr;
    LOG_HEADER_STRUCT_PTR    log_ptr;
    _mqx_uint                i;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_log_test, log_error_ptr);

    *log_error_ptr = 0;
    log_component_ptr = (LOG_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_LOG];
    if (log_component_ptr == NULL)
    {
        _KLOGX2(KLOG_log_test, MQX_OK);
        return(MQX_OK);
    } /* Endif */

    if (log_component_ptr->VALID != LOG_VALID)
    {
        _KLOGX2(KLOG_log_test, MQX_INVALID_COMPONENT_BASE);
        return(MQX_INVALID_COMPONENT_BASE);
    } /* Endif */

    _int_disable();
    for (i = 0; i < LOG_MAXIMUM_NUMBER; i++)
    {
        log_ptr = log_component_ptr->LOGS[i];
        if (log_ptr != NULL)
        {
            /* Verify the log pointers */
            if ((log_ptr->LOG_END != &log_ptr->DATA[log_ptr->MAX]) ||
                            (log_ptr->LOG_START != &log_ptr->DATA[0]))
            {
                break;
            } /* Endif */

            if ((log_ptr->LOG_WRITE > log_ptr->LOG_END) ||
                            (log_ptr->LOG_NEXT > log_ptr->LOG_END) ||
                            (log_ptr->LOG_READ > log_ptr->LOG_END) ||
                            (log_ptr->LAST_LOG > log_ptr->LOG_END))
            {
                break;
            } /* Endif */
            if ((log_ptr->LOG_WRITE < log_ptr->LOG_START) ||
                            (log_ptr->LOG_READ < log_ptr->LOG_START) ||
                            (log_ptr->LAST_LOG < log_ptr->LOG_START))
            {
                break;
            } /* Endif */
            if ((log_ptr->LOG_NEXT != NULL) &&
                            (log_ptr->LOG_NEXT < log_ptr->LOG_START))
            {
                break;
            } /* Endif */
        } /* Endif */
    } /* Endfor */
    _int_enable();

    if (i == LOG_MAXIMUM_NUMBER)
    {
        _KLOGX2(KLOG_log_test, MQX_OK);
        return(MQX_OK);
    } /* Endif */

    *log_error_ptr = i;
    _KLOGX3(KLOG_log_test, LOG_INVALID, i);
    return(LOG_INVALID);

} /* Endbody */
Example #15
0
void OS_Unlock(void)
{
    _int_enable();
}
Example #16
0
/*!
 * \brief Reads the information in the lightweight log.
 *
 * <table>
 *   <tr>
 *     <td><b>read_type</b></td>
 *     <td><b>Returns this entry in the log:</b></td>
 *   </tr>
 *   <tr>
 *     <td>LOG_READ_NEWEST</td>
 *     <td>Newest.</td>
 *   </tr>
 *   <tr>
 *     <td>LOG_READ_NEXT</td>
 *     <td>Next one after the previous one read (must be used with LOG_READ_OLDEST).</td>
 *   </tr>
 *   <tr>
 *     <td>LOG_READ_OLDEST</td>
 *     <td>Oldest.</td>
 *   </tr>
 *   <tr>
 *     <td>LOG_READ_OLDEST_AND_DELETE</td>
 *     <td>Oldest and deletes it.</td>
 *   </tr>
 * </table>
 *
 * \param[in] log_number Log number of a previously created lightweight log (if
 * log_number is 0, kernel log is read).
 * \param[in] read_type  Type of read operation.
 * \param[in] entry_ptr  Pointer to where to write the lightweight log entry.
 *
 * \return MQX_OK
 * \return LOG_DOES_NOT_EXIST (Log_number was not created.)
 * \return LOG_ENTRY_NOT_AVAILABLE (Log entry is not available.)
 * \return LOG_INVALID (Log_number is out of range.)
 * \return LOG_INVALID_READ_TYPE (Read_type is not valid.)
 * \return MQX_INVALID_POINTER (Entry_ptr is NULL.)
 * \return MQX_INVALID_COMPONENT_HANDLE (Lightweight log component data is not valid.)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Lightweight log component is not created.)
 *
 * \see _lwlog_create
 * \see _lwlog_create_at
 * \see _lwlog_write
 * \see _klog_display
 * \see LWLOG_ENTRY_STRUCT
 */
_mqx_uint _lwlog_read
(
    _mqx_uint               log_number,
    _mqx_uint               read_type,
    LWLOG_ENTRY_STRUCT_PTR  entry_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    LWLOG_COMPONENT_STRUCT_PTR log_component_ptr;
    LWLOG_HEADER_STRUCT_PTR    log_header_ptr;
    LWLOG_ENTRY_STRUCT_PTR     log_ptr;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (log_number >= LOG_MAXIMUM_NUMBER)
    {
        return (LOG_INVALID);
    } /* Endif */
    if (entry_ptr == NULL)
    {
        return (MQX_INVALID_POINTER);
    } /* Endif */
#endif

    log_component_ptr = (LWLOG_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_LWLOG];

#if MQX_CHECK_ERRORS
    if (log_component_ptr == NULL)
    {
        return (MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif

    _int_disable();
#if MQX_CHECK_VALIDITY
    if (log_component_ptr->VALID != LWLOG_VALID)
    {
        _int_enable();
        return (MQX_INVALID_COMPONENT_HANDLE);
    } /* Endif */
#endif

    log_header_ptr = log_component_ptr->LOGS[log_number];

#if MQX_CHECK_ERRORS
    if (log_header_ptr == NULL)
    {
        _int_enable();
        return (LOG_DOES_NOT_EXIST);
    } /* Endif */
#endif

    if (!log_header_ptr->CURRENT_ENTRIES)
    {
        /* No data available */
        _int_enable();
        return (LOG_ENTRY_NOT_AVAILABLE);
    } /* Endif */

    if (read_type == LOG_READ_OLDEST_AND_DELETE)
    {
        log_header_ptr->CURRENT_ENTRIES--;
        log_ptr = log_header_ptr->OLDEST_PTR;
        log_header_ptr->OLDEST_PTR = log_ptr->NEXT_PTR;
        log_header_ptr->READ_PTR = log_ptr->NEXT_PTR;
        log_header_ptr->READS = 0;
    }
    else if (read_type == LOG_READ_OLDEST)
    {
        log_ptr = log_header_ptr->OLDEST_PTR;
        log_header_ptr->READ_PTR = log_ptr->NEXT_PTR;
        log_header_ptr->READS = 1;
    }
    else if (read_type == LOG_READ_NEXT)
    {
        log_ptr = log_header_ptr->READ_PTR;
        if ((log_ptr == log_header_ptr->WRITE_PTR->NEXT_PTR) && (log_header_ptr->READS
                        >= log_header_ptr->CURRENT_ENTRIES))
        {
            _int_enable();
            return (LOG_ENTRY_NOT_AVAILABLE);
        } /* Endif */
        log_header_ptr->READ_PTR = log_ptr->NEXT_PTR;
        log_header_ptr->READS++;
    }
    else if (read_type == LOG_READ_NEWEST)
    {
        log_header_ptr->READS = log_header_ptr->CURRENT_ENTRIES;
        log_ptr = log_header_ptr->WRITE_PTR;
#if MQX_CHECK_ERRORS
    }
    else
    {
        _int_enable();
        return (LOG_INVALID_READ_TYPE);
#endif
    } /* Endif */

    *entry_ptr = *log_ptr;

    _int_enable();

    return (MQX_OK);

} /* Endbody */
Example #17
0
/*!
 * \brief Core mutex destroy function.
 * 
 * This function destroys a core mutex.
 * 
 * \param[in] mutex_ptr   Pointer to core_mutex structure.
 *
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Core mutex component not installed.)
 * \return MQX_INVALID_PARAMETER (Wrong input parameter.)
 * \return MQX_TASKQ_CREATE_FAILED (Failed to create a task queue.)
 * \return COREMUTEX_OK (Success.)
 * 
 * \see _core_mutex_create 
 * \see _core_mutex_create_at 
 */ 
uint32_t _core_mutex_destroy( CORE_MUTEX_PTR mutex_ptr )
{
    CORE_MUTEX_COMPONENT_PTR   component_ptr = _core_mutext_get_component_ptr();
    SEMA4_MemMapPtr            sema4_ptr;
    void                      *tq;
    uint32_t                   dev_num, mutex_num, i;

#if MQX_CHECK_ERRORS
    if (component_ptr == NULL) {
       return MQX_COMPONENT_DOES_NOT_EXIST;
    }

    if (mutex_ptr==NULL) {
        return MQX_INVALID_POINTER;
    }

    if (mutex_ptr->VALID != CORE_MUTEX_VALID) {
        return MQX_INVALID_POINTER;
    }
#endif

    mutex_num = mutex_ptr->GATE_NUM;

    /* figure out which device this mutex is associated with */
    for (i=0;i<SEMA4_NUM_DEVICES;i++) {
        sema4_ptr = _bsp_get_sema4_base_address(i);
        if (&sema4_ptr->Gate[mutex_num] == mutex_ptr->GATE_PTR) {
            dev_num = i;
            break;
        }
    }

    _int_disable();
#if MQX_CHECK_ERRORS
    if (component_ptr->DEVICE[dev_num].MUTEX_PTR[mutex_num] == NULL) {
       _int_enable();
       return MQX_COMPONENT_DOES_NOT_EXIST;
    }
#endif

    component_ptr->DEVICE[dev_num].MUTEX_PTR[mutex_num] = NULL;

    if (_psp_core_num()==0) {
        component_ptr->DEVICE[dev_num].SEMA4_PTR->CP0INE &= ~(1 << (SEMA4_NUM_GATES - 1 - idx[mutex_num]));	/* ~(1 << (SEMA4_NUM_GATES-1-mutex_num)); */
    } else {
        component_ptr->DEVICE[dev_num].SEMA4_PTR->CP1INE &= ~(1 << (SEMA4_NUM_GATES - 1 - idx[mutex_num]));	/* ~(1 << (SEMA4_NUM_GATES-1-mutex_num)); */
    }
    tq = mutex_ptr->WAIT_Q;
    mutex_ptr->VALID=0;
    _int_enable();

    if (component_ptr->DEVICE[dev_num].ALLOCED & (1<<mutex_num)) {
        component_ptr->DEVICE[dev_num].ALLOCED &=  ~(1<<mutex_num);
    } else {
        mutex_ptr=NULL;
    }
    _taskq_destroy(tq);
    if (mutex_ptr) {
        _mem_free(mutex_ptr);
    }

    return COREMUTEX_OK;
}
Example #18
0
/*!
 * \brief Tests the lightweight log component for consistency.
 *
 * \param[out] log_error_ptr Pointer to the lightweight log if error is found (NULL
 * if no error is found).
 *
 * \return MQX_OK Lightweight log component data is valid (Log_error_ptr is NULL.).
 * \return LOG_INVALID Information for a specific lightweight log is not valid
 * (Log_error_ptr contains log number of the first invalid lightweight log.).
 * \return MQX_INVALID_POINTER Log_error_ptr is NULL.
 * \return MQX_INVALID_COMPONENT_BASE Lightweight log component data is not valid
 * (Log_error_ptr is NULL.).
 *
 * \see _lwlog_create_component
 * \see _lwlog_create
 * \see _lwlog_create_at
 */
_mqx_uint _lwlog_test
(
    _mqx_uint  *log_error_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR     kernel_data;
    LWLOG_COMPONENT_STRUCT_PTR log_component_ptr;
    LWLOG_HEADER_STRUCT_PTR    log_header_ptr;
    LWLOG_ENTRY_STRUCT_PTR     entry_ptr;
    unsigned char                  *min_ptr;
    unsigned char                  *max_ptr;
    _mqx_uint                  i, j;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if ((void *) log_error_ptr == NULL)
    {
        return MQX_INVALID_POINTER;
    } /* Endif */
#endif

    *log_error_ptr = 0;
    log_component_ptr = (LWLOG_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_LWLOG];
    if (log_component_ptr == NULL)
    {
        return (MQX_OK);
    } /* Endif */

    _int_disable();

#if MQX_CHECK_VALIDITY
    if (log_component_ptr->VALID != LWLOG_VALID)
    {
        _int_enable();
        return (MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif

    for (i = 0; i < LOG_MAXIMUM_NUMBER; i++)
    {
        log_header_ptr = log_component_ptr->LOGS[i];
        if (log_header_ptr != NULL)
        {
            /* Verify the log pointers */
            min_ptr = (unsigned char *) log_header_ptr + sizeof(LWLOG_HEADER_STRUCT_PTR);
            max_ptr = min_ptr + sizeof(LWLOG_ENTRY_STRUCT) * log_header_ptr->MAX_ENTRIES;

            if (((unsigned char *) log_header_ptr->READ_PTR < min_ptr) || ((unsigned char *) log_header_ptr->READ_PTR >= max_ptr)
                            || ((unsigned char *) log_header_ptr->WRITE_PTR < min_ptr)
                            || ((unsigned char *) log_header_ptr->WRITE_PTR >= max_ptr)
                            || ((unsigned char *) log_header_ptr->OLDEST_PTR < min_ptr)
                            || ((unsigned char *) log_header_ptr->OLDEST_PTR >= max_ptr))

            {
                _int_enable();
                *log_error_ptr = i;
                return (LOG_INVALID);
            } /* Endif */

            /* Check each entry in the log */
            entry_ptr = &log_header_ptr->FIRST_ENTRY;
            j = log_header_ptr->MAX_ENTRIES;
            while (entry_ptr->NEXT_PTR && j)
            {
                entry_ptr = entry_ptr->NEXT_PTR;
                --j;
                if (((unsigned char *) entry_ptr < min_ptr) || ((unsigned char *) entry_ptr >= max_ptr))
                {
                    _int_enable();
                    *log_error_ptr = i;
                    return (LOG_INVALID);
                } /* Endif */
            } /* Endwhile */
        } /* Endif */
    } /* Endfor */

    _int_enable();

    return (MQX_OK);

} /* Endbody */
Example #19
0
/*!
 * \brief Allocates a message from the private message pool.
 * 
 * The size of the message is determined by the message size that a task 
 * specified when it called _msgpool_create(). The message is a resource of the 
 * task until the task either frees it (_msg_free()) or puts it on a message 
 * queue (_msgq_send() family of functions.)
 * 
 * \param[in] pool A pool ID from _msgpool_create().
 * 
 * \return Pointer to a message (Success.)
 * \return NULL (Failure.)
 *  
 * \warning On failure, calls _task_set_error() to set one the following task 
 * error codes:
 * \li MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * \li MSGPOOL_INVALID_POOL_ID (Pool_id is not valid.)
 * \li MSGPOOL_OUT_OF_MESSAGES (All the messages in the pool are allocated.)
 * \li Task error codes from _mem_alloc_system() (If MQX needs to grow the pool.)
 * 
 * \see _msg_alloc_system
 * \see _msg_free
 * \see _msgpool_create
 * \see _msgpool_destroy
 * \see _task_set_error
 * \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 MESSAGE_HEADER_STRUCT     
 */ 
void *_msg_alloc
(
    _pool_id pool
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR               kernel_data;
#if MQX_CHECK_ERRORS
    MSG_COMPONENT_STRUCT_PTR             msg_component_ptr;
#endif
    register INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr;
    register MESSAGE_HEADER_STRUCT_PTR   message_ptr;
    register MSGPOOL_STRUCT_PTR          msgpool_ptr;
    uint16_t                              grow_number;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_msg_alloc, pool);

#if MQX_CHECK_ERRORS
    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
    if (msg_component_ptr == NULL)
    {
        _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST);
        _KLOGX3(KLOG_msg_alloc, NULL, MQX_COMPONENT_DOES_NOT_EXIST);
        return(NULL);
    } /* Endif */
#endif

    message_ptr = NULL;
    msgpool_ptr = (MSGPOOL_STRUCT_PTR)pool;

#if MQX_CHECK_VALIDITY || MQX_CHECK_ERRORS
    if (
#if MQX_CHECK_VALIDITY
                    (msgpool_ptr->VALID != MSG_VALID)
#if MQX_CHECK_ERRORS
                    ||
#endif
#endif
#if MQX_CHECK_ERRORS
                    (msgpool_ptr->MSGPOOL_TYPE != MSG_POOL)
#endif
    )
    {
        _task_set_error(MSGPOOL_INVALID_POOL_ID);
        _KLOGX3(KLOG_msg_alloc, message_ptr, MSGPOOL_INVALID_POOL_ID);
        return (message_ptr);
    } /* Endif */
#endif

    if ( (msgpool_ptr->SIZE == 0) && (msgpool_ptr->GROW_NUMBER) &&
                    ( (msgpool_ptr->MAX < msgpool_ptr->GROW_LIMIT) ||
                                    (msgpool_ptr->GROW_LIMIT == 0) ) )
    {
        /* Attempt to add elements to the pool */
        grow_number = msgpool_ptr->GROW_NUMBER;
        if (grow_number > (uint16_t)(msgpool_ptr->GROW_LIMIT - msgpool_ptr->MAX))
        {
            grow_number = msgpool_ptr->GROW_LIMIT - msgpool_ptr->MAX;
        } /* Endif */
        _msgpool_add_internal(msgpool_ptr, grow_number);
    } /* Endif */

    _INT_DISABLE();
    imsg_ptr = msgpool_ptr->MSG_FREE_LIST_PTR;
    if (imsg_ptr == NULL)
    {
        _int_enable();
        _task_set_error(MSGPOOL_OUT_OF_MESSAGES);
        _KLOGX3(KLOG_msg_alloc, message_ptr, MSGPOOL_OUT_OF_MESSAGES);
        return((void *)message_ptr);
    } /* Endif */

    msgpool_ptr->MSG_FREE_LIST_PTR = imsg_ptr->NEXT;
    --msgpool_ptr->SIZE;
    _INT_ENABLE();
    imsg_ptr->FREE = FALSE;
    imsg_ptr->QUEUED = FALSE;
    if (kernel_data->IN_ISR)
    {
        imsg_ptr->TD_PTR = NULL;
    }
    else
    {
        imsg_ptr->TD_PTR = kernel_data->ACTIVE_PTR;
    } /* Endif */
    message_ptr = (MESSAGE_HEADER_STRUCT_PTR)&imsg_ptr->MESSAGE;
    message_ptr->TARGET_QID = MSGQ_NULL_QUEUE_ID;
    message_ptr->SOURCE_QID = MSGQ_NULL_QUEUE_ID;
    message_ptr->SIZE = msgpool_ptr->MESSAGE_SIZE;
    message_ptr->CONTROL = MSG_HDR_ENDIAN | MSG_DATA_ENDIAN;
    _KLOGX3(KLOG_msg_alloc, message_ptr, MQX_OK);
    return (void *)message_ptr;

} /* Endbody */
Example #20
0
_mqx_uint _mem_free_part
   (
      /* [IN] the address of the memory block whose size is to change */
      pointer    mem_ptr,

      /* [IN] the new size for the block */
      _mem_size  requested_size
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR kernel_data;
   STOREBLOCK_STRUCT_PTR  block_ptr;
   STOREBLOCK_STRUCT_PTR  prev_block_ptr;
   STOREBLOCK_STRUCT_PTR  next_block_ptr;
   STOREBLOCK_STRUCT_PTR  new_block_ptr;
   _mem_size              size;
   _mem_size              block_size;
   _mem_size              new_block_size;
   _mqx_uint              result_code;

   
   _GET_KERNEL_DATA(kernel_data);
   _KLOGE3(KLOG_mem_free_part, mem_ptr, requested_size);

#if MQX_CHECK_ERRORS
   /* Make sure a correct pointer was passed in.    */
   if (mem_ptr == NULL) {
      _task_set_error(MQX_INVALID_POINTER);
      _KLOGX2(KLOG_mem_free_part, MQX_INVALID_POINTER);
      return(MQX_INVALID_POINTER);
   } /* Endif */
#endif 

   /* Verify the block size */
   block_ptr = GET_MEMBLOCK_PTR(mem_ptr);

#if MQX_CHECK_ERRORS
   if (! _MEMORY_ALIGNED(block_ptr)) {
      _task_set_error(MQX_INVALID_POINTER);
      _KLOGX2(KLOG_mem_free_part, MQX_INVALID_POINTER);
      return(MQX_INVALID_POINTER);
   } /* Endif */

   if ( (block_ptr->BLOCKSIZE < MQX_MIN_MEMORY_STORAGE_SIZE) ||
      BLOCK_IS_FREE(block_ptr) )
   {
      _task_set_error(MQX_INVALID_POINTER);
      kernel_data->KD_POOL.POOL_BLOCK_IN_ERROR = block_ptr;
      _KLOGX3(KLOG_mem_free_part, MQX_INVALID_POINTER, block_ptr);
      return(MQX_INVALID_POINTER);
   } /* Endif */
#endif

#if MQX_CHECK_VALIDITY   
   _int_disable();
   if ( ! VALID_CHECKSUM(block_ptr) ) {
      _int_enable();
      _task_set_error(MQX_INVALID_CHECKSUM);
      kernel_data->KD_POOL.POOL_BLOCK_IN_ERROR = block_ptr;
      _KLOGX3(KLOG_mem_free_part, MQX_INVALID_CHECKSUM, block_ptr);
      return(MQX_INVALID_CHECKSUM);
   } /* Endif */
   _int_enable();
#endif

   /*  Walk through the memory resources of the task descriptor.
    *  Two pointers are maintained, one to the current block
    *  and one to the previous block.
    */
   next_block_ptr   = (STOREBLOCK_STRUCT_PTR)
      kernel_data->ACTIVE_PTR->MEMORY_RESOURCE_LIST;
   prev_block_ptr = GET_MEMBLOCK_PTR(&kernel_data->ACTIVE_PTR->MEMORY_RESOURCE_LIST);
      
   /* Scan the task's memory resource list searching for the block to
    * free, Stop when the current pointer is equal to the block to free
    * or the end of the list is reached.
    */
   while (  next_block_ptr  &&
   ((pointer)next_block_ptr != mem_ptr) ) {
      /* The block is not found, and the end of the list has not been
       * reached, so move down the list.
       */
      prev_block_ptr = GET_MEMBLOCK_PTR(next_block_ptr);
      next_block_ptr = (STOREBLOCK_STRUCT_PTR)prev_block_ptr->NEXTBLOCK;
   } /* Endwhile */

#if MQX_CHECK_ERRORS
   if ( next_block_ptr == NULL ) {
      /* The specified block does not belong to the calling task. */
      _task_set_error(MQX_NOT_RESOURCE_OWNER);
      _KLOGX2(KLOG_mem_free_part, MQX_NOT_RESOURCE_OWNER);
      return(MQX_NOT_RESOURCE_OWNER);
   } /* Endif */
#endif

    /* determine the size of the block.  */
   block_size = block_ptr->BLOCKSIZE;

   size = requested_size + (_mem_size)FIELD_OFFSET(STOREBLOCK_STRUCT,USER_AREA);
   if (size < MQX_MIN_MEMORY_STORAGE_SIZE) {
      size = MQX_MIN_MEMORY_STORAGE_SIZE;
   } /* Endif */
   _MEMORY_ALIGN_VAL_LARGER(size);

#if MQX_CHECK_ERRORS
   /* Verify that the size parameter is within range of the block size. */
   if (size <= block_size) {
#endif
      /* Adjust the size to allow for the overhead and force alignment */

      /* Compute the size of the new_ block that would be created. */
      new_block_size = block_size - size;

      /* Decide if it worthwile to split the block. If the amount of space
       * returned is not at least twice the size of the block overhead, 
       * then dont bother.
       */
      if (new_block_size >= (2*MQX_MIN_MEMORY_STORAGE_SIZE) ) {

         /* Create an 'inuse' block */
         new_block_ptr            = 
            (STOREBLOCK_STRUCT_PTR)((char _PTR_)block_ptr + size);
         new_block_ptr->BLOCKSIZE    = new_block_size;
         PREV_PHYS(new_block_ptr)    = block_ptr;
         new_block_ptr->TASK_NUMBER  = block_ptr->TASK_NUMBER;
         new_block_ptr->MEM_POOL_PTR = block_ptr->MEM_POOL_PTR;
         CALC_CHECKSUM(new_block_ptr);
         _int_disable();
         /* Split the block */
         block_ptr->BLOCKSIZE        = size;
         CALC_CHECKSUM(block_ptr);

         /* make sure right physical neighbour knows about it */
         block_ptr = NEXT_PHYS(new_block_ptr);
         PREV_PHYS(block_ptr) = new_block_ptr;
         CALC_CHECKSUM(block_ptr);

         /* Link the new block onto the requestor's task descriptor. */
         new_block_ptr->NEXTBLOCK = kernel_data->ACTIVE_PTR->MEMORY_RESOURCE_LIST;
         kernel_data->ACTIVE_PTR->MEMORY_RESOURCE_LIST =
            (char _PTR_)(&new_block_ptr->USER_AREA);
         _int_enable();

         result_code = _mem_free((pointer)&new_block_ptr->USER_AREA);
      } else {
         result_code = MQX_OK;
      } /* Endif */
#if MQX_CHECK_ERRORS
   } else {
      result_code = MQX_INVALID_SIZE;
   } /* Endif */
#endif

#if MQX_CHECK_ERRORS
   if ( result_code != MQX_OK ) {
      _task_set_error(result_code);
   } /* Endif */
#endif

   _KLOGX2(KLOG_mem_free_part, result_code);
   return (result_code);

} /* Endbody */
Example #21
0
/*!
 * \private
 *
 * \brief This is internal function used by a task to wait for a specified event.
 *
 * \param[in] event_ptr          Read only. Pointer to the lightweight event.
 * \param[in] bit_mask           Bit mask. Each set bit represents an event bit
 * to wait for.
 * \param[in] all                TRUE (wait for all bits in bit_mask to be set),
 * FALSE (wait for any bit in bit_mask to be set).
 * \param[in] tick_ptr           Pointer to the maximum number of ticks to wait
 * for the events to be set. If the value is NULL, then the timeout will be infinite.
 * \param[in] ticks_are_absolute TRUE (ticks represents absolute time), FALSE
 * (ticks represents relative time).
 *
 * \return MQX_OK
 * \return LWEVENT_WAIT_TIMEOUT (The time elapsed before an event signalled.)
 * \return MQX_LWEVENT_INVALID (Lightweight event is no longer valid or was never valid.)
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 *
 * \see _lwevent_wait_for
 * \see _usr_lwevent_wait_for
 * \see _lwevent_wait_until
 * \see _usr_lwevent_wait_until
 * \see _lwevent_wait_ticks
 * \see _usr_lwevent_wait_ticks
 * \see LWEVENT_STRUCT
 * \see MQX_TICK_STRUCT
 */
_mqx_uint _lwevent_wait_internal
(
    LWEVENT_STRUCT_PTR  event_ptr,
    _mqx_uint           bit_mask,
    bool             all,
    MQX_TICK_STRUCT_PTR tick_ptr,
    bool             ticks_are_absolute
)
{
    KERNEL_DATA_STRUCT_PTR  kernel_data;
    TD_STRUCT_PTR           td_ptr;
    _mqx_uint               result;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        _KLOGX2(KLOG_lwevent_wait_internal, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return (MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    } /* Endif */
#endif

    result = MQX_OK;
    td_ptr = kernel_data->ACTIVE_PTR;
    _INT_DISABLE();

#if MQX_CHECK_VALIDITY
    if (event_ptr->VALID != LWEVENT_VALID)
    {
        _int_enable();
        return (MQX_LWEVENT_INVALID);
    } /* Endif */
#endif

    if (    (all &&  (event_ptr->VALUE & bit_mask) == bit_mask)
         || (!all && (event_ptr->VALUE & bit_mask)))
    {
        /* store information about which bits caused task to be unblocked */
        td_ptr->LWEVENT_BITS = event_ptr->VALUE & bit_mask;
        /* clear used automatic events */
        event_ptr->VALUE &= ~(event_ptr->AUTO & bit_mask);

        _INT_ENABLE();
        return (result);
    } /* Endif */

    /* Must wait for a event to become available */

    td_ptr->LWEVENT_BITS = bit_mask;
    if (all)
    {
        td_ptr->FLAGS |= TASK_LWEVENT_ALL_BITS_WANTED;
    }
    else
    {
        td_ptr->FLAGS &= ~TASK_LWEVENT_ALL_BITS_WANTED;
    } /* Endif */

    /* Enqueue at end */
    _QUEUE_ENQUEUE(&event_ptr->WAITING_TASKS, &td_ptr->AUX_QUEUE);

    /* Now put the task to sleep */
    td_ptr->STATE = LWEVENT_BLOCKED;
    td_ptr->INFO = (_mqx_uint) &event_ptr->WAITING_TASKS;
    if (tick_ptr)
    {
        if (ticks_are_absolute)
        {
            _time_delay_until(tick_ptr);
        }
        else
        {
            _time_delay_for(tick_ptr);
        } /* Endif */
        if (td_ptr->INFO)
        {
            /* Must have timed out */
            /*_QUEUE_REMOVE(&event_ptr->WAITING_TASKS, &td_ptr->AUX_QUEUE);*/
            result = LWEVENT_WAIT_TIMEOUT;
        } /* Endif */
    }
    else
    {
        _task_block();
    } /* Endif */

#if MQX_COMPONENT_DESTRUCTION
    if (event_ptr->VALID == 0)
    { /* We've been deleted */
        result = MQX_LWEVENT_INVALID;
    } /* Endif */
#endif

    _INT_ENABLE();
    return (result);

}
Example #22
0
/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : mcf51xx_write_sector
* Returned Value   : true if success, or false
* Comments         :
*   Performs a write into flash memory  
*
*END*----------------------------------------------------------------------*/
boolean mcf51xx_write_sector(IO_FLASHX_STRUCT_PTR flash_ptr, 
      uchar_ptr from_ptr, uchar_ptr to_ptr, _mem_size size ) 
{

    #define BYTES_IN_WORD   4
    
    VMCF51XX_FTSR_STRUCT_PTR    ftsr_ptr;
    VMCF51XX_PMC_STRUCT_PTR     pmc_ptr; 
    INTERNAL_51XX_STRUCT_PTR    dev_spec_struct_ptr; 
        
    int (*RunInRAM)( uchar_ptr );
    uint_32 temp, temp_data = 0xFFFFFFFF;
    uchar_ptr temp_data_ptr;
    uchar byte_data_counter = 0;
    /* get the offset in write word */
    uint_32 offset = (uint_32)to_ptr & 0x00000003;;

    (uint_32_ptr)temp_data_ptr =  &temp_data;

    dev_spec_struct_ptr = flash_ptr->DEVICE_SPECIFIC_DATA;    
    /* select the proper ramcode function */
    *RunInRAM = (int(*)( uchar_ptr ))dev_spec_struct_ptr->flash_execute_code_ptr;

    /* get the pointer to cfm registers structure */
    ftsr_ptr = (VMCF51XX_FTSR_STRUCT_PTR)dev_spec_struct_ptr->ftsr_ptr;
    
    /* get the pointer to pmc registers structure */
    pmc_ptr = _bsp_get_pmc_address();    
    /* Clear any errors */
    _int_disable();
    ftsr_ptr->FSTAT = (MCF51XX_FTSR_FSTAT_FPVIOL | MCF51XX_FTSR_FSTAT_FACCERR); 
    
    /* if the start address !=  doesn't correspond with hardware, prepare
       variables for 1st word write */
    if(offset){
        /* Align pointer to writable address */
        to_ptr -= offset;
        /* jump over old data */
        byte_data_counter = offset; 
    }
    /* while are some data to write */
    while(size){
        /* move data to write word */       
        while( byte_data_counter < BYTES_IN_WORD && size ){
            *(temp_data_ptr+byte_data_counter) = *from_ptr++;
            byte_data_counter++;
            size--;
        }
        /* test the LVDF flag - if 1, we need to write data in 2 steps */
        if( pmc_ptr->SPMSC1 & MCF51XX_PMC_SPMSC1_LVDF) {
            /* write odd bytes */
            (*(vuint_32 *)(to_ptr)) = temp_data | 0x00FF00FF;
            /* write command to CFMCMD */
            ftsr_ptr->FCMD = MCF51XX_FTSR_FCMD_BURST_PROGRAM;
            /* run command and wait for it to finish (must execute from RAM) */     
            temp = _psp_get_sr();
            _psp_set_sr(temp | 0x0700);
            RunInRAM( (volatile uchar_ptr)&ftsr_ptr->FSTAT );
            _psp_set_sr(temp);
            /* write even bytes */              
            (*(vuint_32 *)(to_ptr)) = temp_data | 0xFF00FF00;
            /* write command to CFMCMD */
            ftsr_ptr->FCMD = MCF51XX_FTSR_FCMD_BURST_PROGRAM;
            /* run command and wait for it to finish (must execute from RAM) */     
            temp = _psp_get_sr();
            _psp_set_sr(temp | 0x0700);
            RunInRAM( (volatile uchar_ptr)&ftsr_ptr->FSTAT );
            _psp_set_sr(temp);
        } 
        else {  
            /* move write data to register */
            (*(vuint_32 *)(to_ptr)) = temp_data;
            
            /* write command to CFMCMD */
            ftsr_ptr->FCMD = MCF51XX_FTSR_FCMD_BURST_PROGRAM;
            /* run command and wait for it to finish (must execute from RAM) */     
            temp = _psp_get_sr();
            _psp_set_sr(temp | 0x0700);
            RunInRAM( (volatile uchar_ptr)&ftsr_ptr->FSTAT );                
            _psp_set_sr(temp);
        }
        /* Check for Errors */
        if (ftsr_ptr->FSTAT & (MCF51XX_FTSR_FSTAT_FPVIOL | MCF51XX_FTSR_FSTAT_FACCERR)) {
            _int_enable();
            return (FALSE);
        }
        
        /* init variables for next loop */
        to_ptr += BYTES_IN_WORD;
        byte_data_counter = 0;
        temp_data = 0xFFFFFFFF;
    }
    _int_enable();
    return (TRUE);  
}
Example #23
0
/*!
 * \private
 *
 * \brief Used by a task to create an instance of a lightweight event.
 *
 * \param[in] event_ptr Pointer representing location of the event.
 * \param[in] flags     Flags for the light weight event.
 * \param[in] user      User mode
 *
 * \return MQX_OK
 * \return MQX_EINVAL (lwevent is already initialized.)
 * \return MQX_LWEVENT_INVALID (In case of user mode, MQX tries to access
 * a lwevent with inappropriate access rights.)
 *
 * \see _lwevent_create
 * \see LWEVENT_STRUCT
 */
_mqx_uint _lwevent_create_internal
(
    LWEVENT_STRUCT_PTR  event_ptr,
    _mqx_uint           flags,
    bool             user
)
{
    KERNEL_DATA_STRUCT_PTR  kernel_data;
    LWEVENT_STRUCT_PTR      event_chk_ptr;

#if MQX_ENABLE_USER_MODE
    if (user && !_psp_mem_check_access_mask((uint32_t)event_ptr,
                                             sizeof(LWEVENT_STRUCT),
                                             MPU_UM_R, MPU_UM_RW) )
    {
        return MQX_LWEVENT_INVALID;
    }
#endif

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_lwevent_create, event_ptr);

    _QUEUE_INIT(&event_ptr->WAITING_TASKS, 0);
    event_ptr->VALUE = 0;
    event_ptr->FLAGS = flags;

    if (flags & LWEVENT_AUTO_CLEAR)
        event_ptr->AUTO = ~0;
    else
        event_ptr->AUTO = 0;

    _int_disable();

#if MQX_ENABLE_USER_MODE
    if (user)
    {
        if (kernel_data->USR_LWEVENTS.NEXT == NULL)
        {
            /* Initialize the light weight event queue */
            _QUEUE_INIT(&kernel_data->USR_LWEVENTS, 0);
        }
    }
    else
#endif
    {
        if (kernel_data->LWEVENTS.NEXT == NULL)
        {
            /* Initialize the light weight event queue */
            _QUEUE_INIT(&kernel_data->LWEVENTS, 0);
        }
    }

    event_ptr->VALID = LWEVENT_VALID;

#if MQX_CHECK_ERRORS
    /* Check if lwevent is already initialized */
#if MQX_ENABLE_USER_MODE
    if (user)
    {
        event_chk_ptr = (LWEVENT_STRUCT_PTR)((void *)kernel_data->USR_LWEVENTS.NEXT);
        while (event_chk_ptr != (LWEVENT_STRUCT_PTR)((void *)&kernel_data->USR_LWEVENTS))
        {
            if (event_chk_ptr == event_ptr)
            {
                _int_enable();
                _KLOGX2(KLOG_lwevent_create, MQX_EINVAL);
                return(MQX_EINVAL);
            }
            event_chk_ptr = (LWEVENT_STRUCT_PTR)((void *)event_chk_ptr->LINK.NEXT);
        }
    }
    else
#endif
    {
        event_chk_ptr = (LWEVENT_STRUCT_PTR) ((void *) kernel_data->LWEVENTS.NEXT);
        while (event_chk_ptr != (LWEVENT_STRUCT_PTR) ((void *) &kernel_data->LWEVENTS))
        {
            if (event_chk_ptr == event_ptr)
            {
                _int_enable();
                _KLOGX2(KLOG_lwevent_create, MQX_EINVAL);
                return (MQX_EINVAL);
            }
            event_chk_ptr = (LWEVENT_STRUCT_PTR) ((void *) event_chk_ptr->LINK.NEXT);
        }
    }
#endif

#if MQX_ENABLE_USER_MODE
    if (user)
    {
        _QUEUE_ENQUEUE(&kernel_data->USR_LWEVENTS, &event_ptr->LINK);
    }
    else
#endif
    {
        _QUEUE_ENQUEUE(&kernel_data->LWEVENTS, &event_ptr->LINK);
    }

    _int_enable();

    _KLOGX2(KLOG_lwevent_create, MQX_OK);
    return (MQX_OK);
}
Example #24
0
/*!
 * \brief Destroys the private message pool.
 * 
 * Any task can destroy the private message pool as long as all its messages have 
 * been freed.
 * 
 * \param[in] pool_id Pool to destroy.
 * 
 * \return MQX_OK
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * \return MSGPOOL_INVALID_POOL_ID (Pool_id does not represent a message pool 
 * that was created by _msgpool_create().)
 * \return MSGPOOL_ALL_MESSAGES_NOT_FREE (All messages in the message pool have 
 * not been freed.)
 * 
 * \warning Calls _mem_free(), which on error sets the task error code.
 * 
 * \see _msgpool_create
 * \see _msg_free
 * \see _msg_alloc
 * \see _mem_free      
 */ 
_mqx_uint _msgpool_destroy
(
    _pool_id pool_id
)
{ /* Body */
#if MQX_KERNEL_LOGGING || MQX_CHECK_ERRORS
    KERNEL_DATA_STRUCT_PTR   kernel_data;
#endif
#if MQX_CHECK_ERRORS
    MSG_COMPONENT_STRUCT_PTR msg_component_ptr;
#endif
    MSGPOOL_STRUCT_PTR       msgpool_ptr;
    MSGPOOL_BLOCK_STRUCT_PTR msgpool_block_ptr;
    MSGPOOL_BLOCK_STRUCT_PTR next_block_ptr;

#if MQX_KERNEL_LOGGING || MQX_CHECK_ERRORS
    _GET_KERNEL_DATA(kernel_data);
#endif

    _KLOGE2(KLOG_msgpool_destroy, pool_id);

#if MQX_CHECK_ERRORS
    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
    if (msg_component_ptr == NULL)
    {
        _KLOGX2(KLOG_msgpool_destroy, MQX_COMPONENT_DOES_NOT_EXIST);
        return MQX_COMPONENT_DOES_NOT_EXIST;
    } /* Endif */
#endif

    msgpool_ptr = (MSGPOOL_STRUCT_PTR)pool_id;
#if MQX_CHECK_VALIDITY
    if ( msgpool_ptr->VALID != MSG_VALID )
    {
        _KLOGX2(KLOG_msgpool_destroy, MSGPOOL_INVALID_POOL_ID);
        return MSGPOOL_INVALID_POOL_ID;
    } /* Endif */
#endif

    _int_disable();
    if (msgpool_ptr->SIZE == msgpool_ptr->MAX)
    {
        /* All messages currently returned, lets delete them */
        msgpool_ptr->SIZE = 0;
        msgpool_ptr->GROW_NUMBER = 0;
        _int_enable();

        msgpool_block_ptr = msgpool_ptr->MSGPOOL_BLOCK_PTR;
        while (msgpool_block_ptr != NULL)
        {
            next_block_ptr = msgpool_block_ptr->NEXT_BLOCK_PTR;
            _mem_free((void *)msgpool_block_ptr);
            msgpool_block_ptr = next_block_ptr;
        } /* Endwhile */

        msgpool_ptr->MSGPOOL_BLOCK_PTR = NULL;
        msgpool_ptr->VALID = 0;
        msgpool_ptr->MSGPOOL_TYPE = 0;
        _KLOGX2(KLOG_msgpool_destroy, MQX_OK);
        return MQX_OK;
    }
    else
    {
        _int_enable();
        _KLOGX2(KLOG_msgpool_destroy, MSGPOOL_ALL_MESSAGES_NOT_FREE);
        return MSGPOOL_ALL_MESSAGES_NOT_FREE;
    } /* Endif */

} /* Endbody */
Example #25
0
/*!
 * \brief Tests the event component for validity and consistency.
 *
 * \param[out] event_error_ptr Pointer to the lightweight event that has an
 * error if MQX found an error in the lightweight event component (NULL if no error
 * is found).
 * \param[out] td_error_ptr    TD on the lightweight event in error (NULL if no
 * error is found).
 *
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_LWEVENT_INVALID (A lightweight event was invalid.)
 * \return code from _queue_test() (Waiting queue for a lightweight event has an error.)
 *
 * \warning Cannot be called from an ISR.
 *
 * \see _lwevent_create
 * \see _lwevent_destroy
 */
_mqx_uint _lwevent_test
(
    void      **event_error_ptr,
    void      **td_error_ptr
)
{
    KERNEL_DATA_STRUCT_PTR  kernel_data;
    LWEVENT_STRUCT_PTR      event_ptr;
    _mqx_uint               result;
    _mqx_uint               queue_size;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_lwevent_test, event_error_ptr);

    *td_error_ptr = NULL;
    *event_error_ptr = NULL;

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        _KLOGX2(KLOG_lwevent_test, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return (MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    }/* Endif */
#endif

    /*
     * It is not considered an error if the lwevent component has not been
     * created yet
     */
    if (kernel_data->LWEVENTS.NEXT == NULL)
    {
        return (MQX_OK);
    } /* Endif */

    result = _queue_test((QUEUE_STRUCT_PTR) &kernel_data->LWEVENTS, event_error_ptr);
    if (result != MQX_OK)
    {
        _KLOGX3(KLOG_lwevent_test, result, *event_error_ptr);
        return (result);
    } /* Endif */

    event_ptr = (LWEVENT_STRUCT_PTR) ((void *) kernel_data->LWEVENTS.NEXT);
    queue_size = _QUEUE_GET_SIZE(&kernel_data->LWEVENTS);
    while (queue_size--)
    {
        if (event_ptr->VALID != LWEVENT_VALID)
        {
            result = MQX_LWEVENT_INVALID;
            break;
        } /* Endif */
        result = _queue_test(&event_ptr->WAITING_TASKS, td_error_ptr);
        if (result != MQX_OK)
        {
            break;
        } /* Endif */
        event_ptr = (LWEVENT_STRUCT_PTR) (void *) event_ptr->LINK.NEXT;
    } /* Endwhile */

    _int_enable();

    if (result != MQX_OK)
    {
        *event_error_ptr = (void *) event_ptr;
    } /* Endif */
    _KLOGX4(KLOG_lwevent_test, result, *event_error_ptr, *td_error_ptr);
    return (result);

}
Example #26
0
/*!
 * \brief Tests all the message poolsin the system for consistency and validity.
 *  
 * The function checks the validity of each message in each private and system 
 * message pool. It reports the first error that it finds.
 *  
 * \param[out] pool_error_ptr (Initialized only if an error is found.) If the 
 * message in a message pool has an error; one of the following:
 * \li A pointer to a pool ID if the message is from a private message pool.
 * \li A pointer to a system message pool if the message is from a system 
 * message pool.
 * \param[out] msg_error_ptr  Pointer to the message that has an error 
 * (initialized only if an error is found).
 * 
 * \return MQX_OK (all messages in all message pools passed)
 * \return MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.)
 * \return MSGQ_INVALID_MESSAGE (At least one message in at least one message 
 * pool failed.)
 * 
 * \warning Disables and enables interrupts.
 *  
 * \see _msgpool_create
 * \see _msgpool_create_system   
 */ 
_mqx_uint _msgpool_test
(
    void    **pool_error_ptr,
    void    **msg_error_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR      kernel_data;
    MSG_COMPONENT_STRUCT_PTR    msg_component_ptr;
    MSGPOOL_STRUCT_PTR          msgpool_ptr;
    MSGPOOL_BLOCK_STRUCT_PTR    msgpool_block_ptr;
    INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr;
    _mqx_uint                   i,j,raw_message_size;

    _GET_KERNEL_DATA(kernel_data);
    _KLOGE3(KLOG_msgpool_test, pool_error_ptr, msg_error_ptr);

    msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
#if MQX_CHECK_ERRORS
    if (msg_component_ptr == NULL)
    {
        _KLOGX2(KLOG_msgpool_test, MQX_COMPONENT_DOES_NOT_EXIST);
        return(MQX_COMPONENT_DOES_NOT_EXIST);
    } /* Endif */
#endif

    /* Check all the message pools */
    msgpool_ptr = msg_component_ptr->MSGPOOLS_PTR;
    i = msg_component_ptr->MAX_MSGPOOLS + 1;
    while (--i)
    {
        _int_disable();
        if (msgpool_ptr->VALID == MSG_VALID)
        {
            /* The pool has been created */

            /* Search through all of the message pool blocks for this pool */
            msgpool_block_ptr = msgpool_ptr->MSGPOOL_BLOCK_PTR;
            while (msgpool_block_ptr != NULL)
            {
                raw_message_size = msgpool_block_ptr->RAW_MESSAGE_SIZE;
                imsg_ptr = (INTERNAL_MESSAGE_STRUCT_PTR)
                msgpool_block_ptr->FIRST_IMSG_PTR;
                j = msgpool_block_ptr->NUM_MESSAGES + 1;
                while (--j)
                {
                    if ((imsg_ptr->VALID != MSG_VALID) ||
                                    (imsg_ptr->MSGPOOL_PTR != msgpool_ptr))
                    {
                        _int_enable();
                        *pool_error_ptr = msgpool_ptr;
                        *msg_error_ptr = imsg_ptr;
                        _KLOGX4(KLOG_msgpool_test, MSGQ_INVALID_MESSAGE, msgpool_ptr,
                                        imsg_ptr);
                        return(MSGQ_INVALID_MESSAGE);
                    } /* Endif */
                    imsg_ptr =(INTERNAL_MESSAGE_STRUCT_PTR)
                    ((unsigned char *)imsg_ptr + raw_message_size);
                } /* Endwhile */

                msgpool_block_ptr = msgpool_block_ptr->NEXT_BLOCK_PTR;
            } /* Endwhile */

        } /* Endif */
        _int_enable();
        msgpool_ptr++;
    } /* Endwhile */

    _KLOGX2(KLOG_msgpool_test, MQX_OK);
    return(MQX_OK);

} /* Endbody */
Example #27
0
_pool_id   _msgpool_create_internal
   (
      /*  [IN]  size of the messages being created  */
      uint_16  message_size,

      /*  [IN]  no. of messages in this pool  */
      uint_16  num_messages,

      /*  [IN]  no. of messages to grow pool by if empty */
      uint_16  grow_number,

      /*  [IN]  maximum number of messages allowed in pool */
      uint_16  grow_limit,

      /*  [IN]  whether this is a system pool or a regular pool */
      _mqx_uint  pool_type
   )
{ /* Body */
            KERNEL_DATA_STRUCT_PTR kernel_data;
            MSG_COMPONENT_STRUCT_PTR  msg_component_ptr;
   register MSGPOOL_STRUCT_PTR     msgpool_ptr;
   register MSGPOOL_STRUCT_PTR     temp_msgpool_ptr;
   register MSGPOOL_STRUCT_PTR     prev_msgpool_ptr;
   register _mqx_uint               i;
            _mqx_uint               result;

   _GET_KERNEL_DATA(kernel_data);
   msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);

#if MQX_CHECK_ERRORS
   if (message_size < sizeof(MESSAGE_HEADER_STRUCT)) {
      _task_set_error(MSGPOOL_MESSAGE_SIZE_TOO_SMALL);
      return ((_pool_id) 0);
   } /* Endif */
#endif

   /*
   ** Try to find an available slot in the array of msgpools for a new pool
   ** if MAX_MSGPOOLS_EVER has not yet reached MAX_MSGPOOLS then
   ** simply use MAX_MSGPOOLS_EVER as an index value and then increment it
   ** but if MAX_MSGPOOLS_EVER has reached MAX_MSGPOOLS then
   ** go back and search through the previously assigned headers to see
   ** if one has been deallocated and is available for use
   */
   if (msg_component_ptr == NULL) {
      result = _msg_create_component();
      msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data);
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
      if (msg_component_ptr == NULL) {
         _task_set_error(result);
         return ((_pool_id)0);
      } /* Endif */
#endif
   } /* Endif */

   _int_disable();
   if (msg_component_ptr->MAX_MSGPOOLS_EVER >= msg_component_ptr->MAX_MSGPOOLS) {
      msgpool_ptr = &msg_component_ptr->MSGPOOLS_PTR[0];
      for ( i=0; i < msg_component_ptr->MAX_MSGPOOLS; i++ ) {
         if (msgpool_ptr->VALID != MSG_VALID) {
            break;
         } /* Endif */
         msgpool_ptr++;
      } /* Endfor */
      if (i == msg_component_ptr->MAX_MSGPOOLS) {
         _int_enable();
         _task_set_error(MSGPOOL_OUT_OF_POOLS);
         return ((_pool_id)0);
      } /* Endif */
   } else {
      msgpool_ptr = &msg_component_ptr->MSGPOOLS_PTR[
         msg_component_ptr->MAX_MSGPOOLS_EVER++];
   } /* Endif */

   msgpool_ptr->VALID        = MSG_VALID;
   msgpool_ptr->MESSAGE_SIZE = message_size;
   msgpool_ptr->GROW_NUMBER  = 0;
   _int_enable();

   msgpool_ptr->MSGPOOL_BLOCK_PTR = NULL;
   msgpool_ptr->MSG_FREE_LIST_PTR = NULL;
   msgpool_ptr->NEXT_MSGPOOL_PTR  = NULL;
   msgpool_ptr->SIZE              = 0;
   msgpool_ptr->MAX               = 0;
   if ( grow_number == 0 ) {
      msgpool_ptr->GROW_LIMIT = num_messages;
   } else if (grow_limit == 0) {
      msgpool_ptr->GROW_LIMIT = 0xFFFF;
   } else {
      msgpool_ptr->GROW_LIMIT = grow_limit;
   } /* Endif */
   msgpool_ptr->MSGPOOL_TYPE  = pool_type;

   if (num_messages) {
      _msgpool_add_internal(msgpool_ptr, num_messages);

      /* no messages could be created, so abort pool creation */
      if (msgpool_ptr->SIZE == 0) {
         msgpool_ptr->VALID = 0;
         _task_set_error(MQX_OUT_OF_MEMORY);
         return ((_pool_id)0);
      } /* Endif */
   } /* Endif */

   msgpool_ptr->GROW_NUMBER       = grow_number;

   if ( pool_type == SYSTEM_MSG_POOL ) {
      /* We must insert the pool into the link list of system message pools,
      ** by order of size, smallest first.
      */

      _int_disable();
      prev_msgpool_ptr = msg_component_ptr->SMALLEST_MSGPOOL_PTR;
      if (prev_msgpool_ptr == NULL) {
         /* first entry in list */
         msg_component_ptr->SMALLEST_MSGPOOL_PTR = msgpool_ptr;
         msg_component_ptr->LARGEST_MSGPOOL_PTR  = msgpool_ptr;
      } else if (prev_msgpool_ptr->MESSAGE_SIZE >= msgpool_ptr->MESSAGE_SIZE){
         /* The new pool is smaller than that at head of list */
         msgpool_ptr->NEXT_MSGPOOL_PTR        = prev_msgpool_ptr;
         msg_component_ptr->SMALLEST_MSGPOOL_PTR = msgpool_ptr;
      } else {
         temp_msgpool_ptr = prev_msgpool_ptr->NEXT_MSGPOOL_PTR;
         while (temp_msgpool_ptr != NULL) {
            /* check the relative message sizes */
            if (temp_msgpool_ptr->MESSAGE_SIZE < msgpool_ptr->MESSAGE_SIZE){
               /* continue to walk down linked list */
               prev_msgpool_ptr = temp_msgpool_ptr;
               temp_msgpool_ptr = prev_msgpool_ptr->NEXT_MSGPOOL_PTR;
            } else {
               /* this entry belongs between prev_ptr and temp_msgpool_ptr */
               prev_msgpool_ptr->NEXT_MSGPOOL_PTR = msgpool_ptr;
               msgpool_ptr->NEXT_MSGPOOL_PTR      = temp_msgpool_ptr;
               break;
            } /* Endif */
         } /* Endwhile */
         if (temp_msgpool_ptr == NULL) {
            /* searched the list and this entry belongs at the bottom */
            prev_msgpool_ptr->NEXT_MSGPOOL_PTR  = msgpool_ptr;
            msg_component_ptr->LARGEST_MSGPOOL_PTR = msgpool_ptr;
         }/* Endif */
      } /* Endif */
      _int_enable();

   } /* Endif */

   return ((_pool_id)msgpool_ptr);

} /* Endbody */
Example #28
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 */
Example #29
0
_mqx_uint _lwsem_wait_ticks
   (
      /* [IN] the semaphore address */
      LWSEM_STRUCT_PTR sem_ptr,

      /* [IN] the number of ticks to delay, if 0, delay forever */
      _mqx_uint time_in_ticks
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR kernel_data;
   TD_STRUCT_PTR          td_ptr;
   _mqx_uint              result;
   
#if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI
    if (MQX_RUN_IN_USER_MODE) {
        return _usr_lwsem_wait_ticks(sem_ptr, time_in_ticks);
    }
#endif

   _GET_KERNEL_DATA(kernel_data);

   _KLOGE3(KLOG_lwsem_wait_ticks, sem_ptr, time_in_ticks);

#if MQX_CHECK_ERRORS
   if (kernel_data->IN_ISR) {
      _KLOGX2(KLOG_lwsem_wait_ticks, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
      return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
   } /* Endif */
#endif
#if MQX_CHECK_VALIDITY
   if (sem_ptr->VALID != LWSEM_VALID) {
      _KLOGX2(KLOG_lwsem_wait_ticks, MQX_INVALID_LWSEM);
      return(MQX_INVALID_LWSEM);
   } /* Endif */
#endif

   _INT_DISABLE();
   if (sem_ptr->VALUE <= 0) {
      td_ptr = kernel_data->ACTIVE_PTR;
      if (time_in_ticks == 0) {
         td_ptr->STATE = LWSEM_BLOCKED;
         td_ptr->INFO  = (_mqx_uint)&sem_ptr->TD_QUEUE;
         _QUEUE_UNLINK(td_ptr);
         _QUEUE_ENQUEUE(&sem_ptr->TD_QUEUE, &td_ptr->AUX_QUEUE);
         _sched_execute_scheduler_internal();  /* Let the other tasks run */
         /* Another task has posted a semaphore, and it has been tranfered to this 
         ** task.
         */
         result = MQX_OK;
      } else {
         PSP_ADD_TICKS_TO_TICK_STRUCT(&kernel_data->TIME, time_in_ticks, 
            &td_ptr->TIMEOUT);
         result = _lwsem_wait_timed_internal(sem_ptr, td_ptr);
      } /* Endif */
   } else {
      --sem_ptr->VALUE;
      /* Start CR 788 */
      result = MQX_OK;
      /* End  CR 788 */
   } /* Endif */

//#if MQX_COMPONENT_DESTRUCTION
   /* We must check for component destruction */
   if (sem_ptr->VALID != LWSEM_VALID) {
      _int_enable();
      /* The semaphore has been deleted */
      _KLOGX2(KLOG_lwsem_wait_ticks, MQX_INVALID_LWSEM);
      return(MQX_INVALID_LWSEM);
   } /* Endif */
//#endif

   _INT_ENABLE();

   _KLOGX2(KLOG_lwsem_wait_ticks, result);

   return(result);
   
}
Example #30
0
/*!
 * \brief Creates a new log.
 * 
 * Each entry in the log contains application-specified data, a timestamp (in 
 * absolute time), and a sequence number.
 * 
 * \param[in] log_number Log number to create (0 through 15).
 * \param[in] max_size   Maximum size of the data to be stored in _mqx_uints 
 * (includes LOG_ENTRY_STRUCT headers).
 * \param[in] flags      One of the following:
 * \li LOG_OVERWRITE (When the log is full, write new entries over oldest ones.)
 * \li 0 (When the log is full, do not write entries.)
 * 
 * \return MQX_OK
 * \return LOG_INVALID (Log_number exceeds 15)
 * \return MQX_INVALID_COMPONENT_BASE (Component is not valid.)
 * \return MQX_OUT_OF_MEMORY (MQX is out of memory.)
 * \return LOG_EXISTS (Log log_number has already been created.)
 * 
 * \warning Creates the log component if it was not created.
 * 
 * \see _log_create_component
 * \see _log_destroy
 * \see _log_read
 * \see _log_write
 * \see LOG_ENTRY_STRUCT 
 */ 
_mqx_uint _log_create
(
    _mqx_uint log_number,
    _mqx_uint max_size,
    uint_32   flags
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR   kernel_data;
    LOG_COMPONENT_STRUCT_PTR log_component_ptr;
    LOG_HEADER_STRUCT_PTR    log_header_ptr;
    _mqx_uint                result;

    _GET_KERNEL_DATA(kernel_data);

#if MQX_CHECK_ERRORS
    if (log_number >= LOG_MAXIMUM_NUMBER)
    {
        return(LOG_INVALID);
    } /* Endif */
#endif

    log_component_ptr = (LOG_COMPONENT_STRUCT_PTR)
    kernel_data->KERNEL_COMPONENTS[KERNEL_LOG];
    if (log_component_ptr == NULL)
    {
        result = _log_create_component();
        log_component_ptr = (LOG_COMPONENT_STRUCT_PTR)
        kernel_data->KERNEL_COMPONENTS[KERNEL_LOG];
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
        if (log_component_ptr == NULL)
        {
            return(result);
        } /* Endif */
#endif
    } /* Endif */

#if MQX_CHECK_VALIDITY
    if (log_component_ptr->VALID != LOG_VALID)
    {
        return(MQX_INVALID_COMPONENT_BASE);
    } /* Endif */
#endif

    log_header_ptr = (LOG_HEADER_STRUCT_PTR)
    _mem_alloc_system((_mem_size)(sizeof(LOG_HEADER_STRUCT) + max_size *
                                    sizeof(_mqx_uint)));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
    if (log_header_ptr == NULL)
    {
        return(MQX_OUT_OF_MEMORY);
    } /* Endif */
#endif
    _mem_set_type(log_header_ptr, MEM_TYPE_LOG);

    log_header_ptr->FLAGS = flags;
    log_header_ptr->FLAGS |= LOG_ENABLED;
    log_header_ptr->NUMBER = 1;
    log_header_ptr->MAX = max_size;
    log_header_ptr->SIZE = 0;
    log_header_ptr->LOG_WRITE = &log_header_ptr->DATA[0];
    log_header_ptr->LOG_READ = log_header_ptr->LOG_WRITE;
    log_header_ptr->LAST_LOG = log_header_ptr->LOG_WRITE;
    log_header_ptr->LOG_START = log_header_ptr->LOG_WRITE;
    log_header_ptr->LOG_END = &log_header_ptr->DATA[max_size];
    log_header_ptr->LOG_NEXT = NULL;

    _int_disable();
#if MQX_CHECK_ERRORS
    if (log_component_ptr->LOGS[log_number] != NULL)
    {
        _int_enable();
        _mem_free(log_header_ptr);
        return(LOG_EXISTS);
    } /* Endif */
#endif
    log_component_ptr->LOGS[log_number] = log_header_ptr;
    _int_enable();

    return(MQX_OK);

} /* Endbody */