/*! * \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 */
void _msgpool_add_internal ( /* [IN] a pointer to the message pool */ MSGPOOL_STRUCT_PTR msgpool_ptr, /* [IN] the number of messages to attempt to add */ uint_16 num_messages ) { /* Body */ INTERNAL_MESSAGE_STRUCT_PTR first_imsg_ptr; INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr; MSGPOOL_BLOCK_STRUCT_PTR msgpool_block_ptr; _mqx_int raw_message_size; _mqx_uint count; raw_message_size = sizeof(INTERNAL_MESSAGE_STRUCT) - sizeof(MESSAGE_HEADER_STRUCT) + msgpool_ptr->MESSAGE_SIZE; _MEMORY_ALIGN_VAL_LARGER(raw_message_size); msgpool_block_ptr = (MSGPOOL_BLOCK_STRUCT_PTR)_mem_alloc_system((_mem_size) ((raw_message_size*num_messages) + sizeof(MSGPOOL_BLOCK_STRUCT) + PSP_MEMORY_ALIGNMENT)); #if MQX_CHECK_MEMORY_ALLOCATION_ERRORS if (msgpool_block_ptr == NULL) { return; } /* Endif */ #endif _mem_set_type(msgpool_block_ptr, MEM_TYPE_MESSAGE_POOL_BLOCKS); msgpool_block_ptr->NEXT_BLOCK_PTR = NULL; msgpool_block_ptr->RAW_MESSAGE_SIZE = raw_message_size; msgpool_block_ptr->NUM_MESSAGES = num_messages; first_imsg_ptr =(INTERNAL_MESSAGE_STRUCT_PTR) ((uchar _PTR_)msgpool_block_ptr + sizeof(MSGPOOL_BLOCK_STRUCT)); first_imsg_ptr = (INTERNAL_MESSAGE_STRUCT_PTR) _ALIGN_ADDR_TO_HIGHER_MEM(first_imsg_ptr); msgpool_block_ptr->FIRST_IMSG_PTR = first_imsg_ptr; imsg_ptr = first_imsg_ptr; count = num_messages + 1; while (--count){ imsg_ptr->NEXT = NULL; /* Free list pointer */ imsg_ptr->VALID = MSG_VALID; imsg_ptr->FREE = TRUE; imsg_ptr->QUEUED = FALSE; imsg_ptr->MSGPOOL_PTR = msgpool_ptr; imsg_ptr->TD_PTR = NULL; if (count > 1) { /* imsg is in the middle of the list */ imsg_ptr->NEXT = (INTERNAL_MESSAGE_STRUCT_PTR) ((uchar _PTR_)imsg_ptr + raw_message_size); imsg_ptr = imsg_ptr->NEXT; }/* Endif */ } /* Endwhile */ /* Now make the pool entries available */ _int_disable(); msgpool_block_ptr->NEXT_BLOCK_PTR = msgpool_ptr->MSGPOOL_BLOCK_PTR; msgpool_ptr->MSGPOOL_BLOCK_PTR = msgpool_block_ptr; /* imsg_ptr here is the last message on the list */ imsg_ptr->NEXT = msgpool_ptr->MSG_FREE_LIST_PTR; msgpool_ptr->MSG_FREE_LIST_PTR = first_imsg_ptr; msgpool_ptr->SIZE += num_messages; msgpool_ptr->MAX += num_messages; _int_enable(); } /* Endbody */
_mqx_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 */
/*! * \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); }
/*! * \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); }
/*! * \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 */
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 */
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); }
/*! * \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 */
_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 */
/*! * \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 */
_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 */
_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 */
/*! * \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 */
void OS_Unlock(void) { _int_enable(); }
/*! * \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 */
/*! * \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; }
/*! * \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 */
/*! * \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 */
_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 */
/*! * \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); }
/*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); }
/*! * \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); }
/*! * \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 */
/*! * \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); }
/*! * \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 */
_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 */
_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 */
_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); }
/*! * \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 */