_mqx_uint _msgq_get_count ( /* [IN] the id of the queue which is being checked for waiting msgs */ _queue_id queue_id ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; MSG_COMPONENT_STRUCT_PTR msg_component_ptr; register MSGQ_STRUCT_PTR msgq_ptr; INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr; register _mqx_uint pending; register uint_16 queue; _GET_KERNEL_DATA(kernel_data); _KLOGE2(KLOG_msgq_get_count, queue_id); 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); _KLOGX3(KLOG_msgq_get_count, MQX_COMPONENT_DOES_NOT_EXIST, 0); return(0); } /* Endif */ #endif if (queue_id == MSGQ_ANY_QUEUE) { _KLOGX3(KLOG_msgq_get_count, MQX_OK, kernel_data->ACTIVE_PTR->MESSAGES_AVAILABLE); return(kernel_data->ACTIVE_PTR->MESSAGES_AVAILABLE ); } /* Endif */ pending = 0; queue = QUEUE_FROM_QID(queue_id); if ( (PROC_NUMBER_FROM_QID(queue_id) == kernel_data->INIT.PROCESSOR_NUMBER) && VALID_QUEUE(queue) ) { msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue]; if ( msgq_ptr->QUEUE == (queue) ) { pending = msgq_ptr->NO_OF_ENTRIES; /* Check for short-cutted message ie not on q but could have been */ if (msgq_ptr->TD_PTR != NULL) { imsg_ptr = (INTERNAL_MESSAGE_STRUCT_PTR)msgq_ptr->TD_PTR->MESSAGE; if ((imsg_ptr != NULL) && (QUEUE_FROM_QID(imsg_ptr->MESSAGE.TARGET_QID) == queue)) { ++pending; } /* Endif */ } /* Endif */ } else { _task_set_error(MSGQ_QUEUE_IS_NOT_OPEN); } /* Endif */ } else { _task_set_error(MSGQ_INVALID_QUEUE_ID); } /* Endif */ _KLOGX2(KLOG_msgq_get_count, pending); return(pending); } /* Endbody */
_task_id _msgq_get_owner ( /* [IN] queue from which need to match the task id */ _queue_id queue_id ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; MSG_COMPONENT_STRUCT_PTR msg_component_ptr; register MSGQ_STRUCT_PTR msgq_ptr; _queue_number queue; _task_id task_id; _GET_KERNEL_DATA(kernel_data); _KLOGE2(KLOG_msgq_get_owner, queue_id); 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); _KLOGX3(KLOG_msgq_get_owner, MQX_NULL_TASK_ID, MQX_COMPONENT_DOES_NOT_EXIST); return(MQX_NULL_TASK_ID); } /* Endif */ #endif queue = QUEUE_FROM_QID(queue_id); #if MQX_CHECK_ERRORS if ((PROC_NUMBER_FROM_QID(queue_id) != kernel_data->INIT.PROCESSOR_NUMBER) || (! VALID_QUEUE(queue)) ) { _task_set_error(MQX_INVALID_PROCESSOR_NUMBER); _KLOGX3(KLOG_msgq_get_owner, MQX_NULL_TASK_ID, MQX_INVALID_PROCESSOR_NUMBER); return (MQX_NULL_TASK_ID); } /* Endif */ #endif msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue]; if (msgq_ptr->QUEUE != (queue)) { _task_set_error(MSGQ_QUEUE_IS_NOT_OPEN); _KLOGX3(KLOG_msgq_get_owner, MQX_NULL_TASK_ID, MSGQ_QUEUE_IS_NOT_OPEN); return (MQX_NULL_TASK_ID); } /* Endif */ task_id = msgq_ptr->TD_PTR->TASK_ID; _KLOGX3(KLOG_msgq_get_owner, task_id, MQX_OK); return (task_id); } /* Endbody */
/*! * \brief Gets the number that is associated with the name in the names database. * * \param[in] name Pointer to the name for which to get the associated number. * \param[out] number_ptr Pointer to the number. * * \return MQX_OK * \return MQX_COMPONENT_DOES_NOT_EXIST (Name component is not created.) * \return NAME_TOO_SHORT (Name is 0 length string.) * \return NAME_TOO_LONG (Name is longer than NAME_MAX_NAME_SIZE.) * \return MQX_INVALID_COMPONENT_BASE (Name component data are not valid.) * \return NAME_NOT_FOUND (Name is not in the names database.) * * \see _name_add * \see _name_create_component * \see _name_delete */ _mqx_uint _name_find ( char *name, _mqx_max_type_ptr number_ptr ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; void *handle; _mqx_uint result; _GET_KERNEL_DATA(kernel_data); _KLOGE3(KLOG_name_find, name, number_ptr); handle = kernel_data->KERNEL_COMPONENTS[KERNEL_NAME_MANAGEMENT]; #if MQX_CHECK_ERRORS if (handle == NULL) { _KLOGX2(KLOG_name_find, MQX_COMPONENT_DOES_NOT_EXIST); return (MQX_COMPONENT_DOES_NOT_EXIST); } /* Endif */ #endif /* MQX_CHECK_ERRORS */ result = _name_find_internal(handle, name, number_ptr); _KLOGX3(KLOG_name_find, result, *number_ptr); return (result); } /* Endbody */
/*FUNCTION*----------------------------------------------------- * * Function Name : _mem_alloc_align * Returned Value : pointer. NULL is returned upon error. * Comments : allocates an aligned block of memory * *END*---------------------------------------------------------*/ pointer _mem_alloc_align ( /* [IN] the size of the memory block */ _mem_size size, /* [IN] the alignment of the memory block */ _mem_size align ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; _mqx_uint error; pointer result; _GET_KERNEL_DATA(kernel_data); _KLOGE2(KLOG_mem_alloc, size); _INT_DISABLE(); result = _mem_alloc_internal_align(size, align, kernel_data->ACTIVE_PTR, (MEMPOOL_STRUCT_PTR)&kernel_data->KD_POOL, &error); /* update the memory allocation pointer in case a lower priority ** task was preempted inside _mem_alloc_internal */ kernel_data->KD_POOL.POOL_ALLOC_CURRENT_BLOCK = kernel_data->KD_POOL.POOL_FREE_LIST_PTR; _INT_ENABLE(); #if MQX_CHECK_ERRORS if (error != MQX_OK) { _task_set_error(error); } /* Endif */ #endif _KLOGX3(KLOG_mem_alloc_align, result, kernel_data->KD_POOL.POOL_BLOCK_IN_ERROR); return(result); }
pointer _msgq_receive_for ( /* [IN] id of the queue from which a message is to be received */ _queue_id queue_id, /* ** [IN] the number of ticks which can expire before ** this request times out */ MQX_TICK_STRUCT_PTR tick_ptr ) { /* Body */ #if MQX_KERNEL_LOGGING KERNEL_DATA_STRUCT_PTR kernel_data; #endif MESSAGE_HEADER_STRUCT_PTR message_ptr; _mqx_uint error; #if MQX_KERNEL_LOGGING _GET_KERNEL_DATA(kernel_data); _KLOGE3(KLOG_msgq_receive_for, queue_id, tick_ptr); #endif message_ptr = _msgq_receive_internal(queue_id, tick_ptr, MSG_TIMEOUT_RELATIVE, &error); #if MQX_KERNEL_LOGGING if ( (error == MQX_OK) && (message_ptr == NULL) ) { _KLOGX3(KLOG_msgq_receive_for, message_ptr, MSGQ_MESSAGE_NOT_AVAILABLE); } else if (error == MQX_OK) { _KLOGX5(KLOG_msgq_receive_for, message_ptr, message_ptr->TARGET_QID, message_ptr->SOURCE_QID, *(_mqx_uint_ptr)((uchar_ptr)message_ptr+ sizeof(MESSAGE_HEADER_STRUCT))); } else { _KLOGX3(KLOG_msgq_receive_for, message_ptr, error); } /* Endif */ #endif return (pointer)message_ptr; } /* Endbody */
/*! * \brief Installs the kernel ISR handler. The kernel ISR depends on the PSP. * * Some real-time applications need special event handling to occur outside the * scope of MQX. The need might arise that the latency in servicing an interrupt * be less than the MQX interrupt latency. If this is the case, an application can * use _int_install_kernel_isr() to bypass MQX and let the interrupt be serviced * immediately. * \n Because the function returns the previous kernel ISR, applications can * temporarily install an ISR or chain ISRs so that each new one calls the one * installed before it. * \n A kernel ISR must save the registers that it needs and must service the * hardware interrupt. When the kernel ISR is finished, it must restore the * registers and perform a return-from-interrupt instruction. * \n A kernel ISR cannot call MQX functions. However, it can put data in global * data, which a task can access. * * \note The function is not available for all PSPs. * * \param[in] vector Vector where the ISR is to be installed. * \param[in] isr_ptr Pointer to the ISR to install into the vector table. * * \return Pointer to the previous kernel ISR for the vector (Success.). * \return NULL * * \see _int_kernel_isr * \see _int_get_kernel_isr */ INT_KERNEL_ISR_FPTR _int_install_kernel_isr ( uint_32 vector, INT_KERNEL_ISR_FPTR isr_ptr ) { #if !MQX_ROM_VECTORS #if MQX_KERNEL_LOGGING KERNEL_DATA_STRUCT_PTR kernel_data; #endif INT_KERNEL_ISR_FPTR old_isr_ptr; uint_32 result_code; uint_32_ptr loc_ptr; #if MQX_KERNEL_LOGGING _GET_KERNEL_DATA(kernel_data); #endif _KLOGE3(KLOG_int_install_kernel_isr, vector, isr_ptr); #if MQX_CHECK_ERRORS result_code = MQX_OK; old_isr_ptr = NULL; if ( vector >= PSP_MAXIMUM_INTERRUPT_VECTORS ) { result_code = MQX_INVALID_VECTORED_INTERRUPT; } else { #endif loc_ptr = (uint_32_ptr)_int_get_vector_table(); old_isr_ptr = (INT_KERNEL_ISR_FPTR)loc_ptr[vector]; loc_ptr[vector] = (uint_32)isr_ptr; #if MQX_CHECK_ERRORS } /* Endif */ /* Set result code and return result. */ _task_set_error(result_code); #endif _KLOGX3(KLOG_int_install_kernel_isr, old_isr_ptr, result_code); return (old_isr_ptr); #else #if MQX_CHECK_ERRORS /* Set result code and return result. */ _task_set_error(MQX_INVALID_CONFIGURATION); #endif return NULL; #endif }
/*! * \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 */ pointer _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; uint_16 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 > (uint_16)(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((pointer)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 (pointer)message_ptr; } /* Endbody */
_mqx_uint _timer_test ( /* [OUT] the timer element in error */ pointer _PTR_ timer_error_ptr ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; TIMER_COMPONENT_STRUCT_PTR timer_component_ptr; QUEUE_STRUCT_PTR queue_ptr; TIMER_ENTRY_STRUCT_PTR element_ptr; _mqx_uint result; _GET_KERNEL_DATA(kernel_data); _KLOGE2(KLOG_timer_test, timer_error_ptr); *timer_error_ptr = NULL; timer_component_ptr = kernel_data->KERNEL_COMPONENTS[KERNEL_TIMER]; if (timer_component_ptr == NULL) { _KLOGX2(KLOG_timer_test, MQX_OK); return(MQX_OK); } /* Endif */ /* Gain exclusive access to the timer queues */ _lwsem_wait(&timer_component_ptr->TIMER_ENTRIES_LWSEM); result = _queue_test(&timer_component_ptr->ELAPSED_TIMER_ENTRIES, timer_error_ptr); if (result != MQX_OK) { _lwsem_post(&timer_component_ptr->TIMER_ENTRIES_LWSEM); _KLOGX3(KLOG_timer_test, result, *timer_error_ptr); return(result); } /* Endif */ result = _queue_test(&timer_component_ptr->KERNEL_TIMER_ENTRIES, timer_error_ptr); if (result != MQX_OK) { _lwsem_post(&timer_component_ptr->TIMER_ENTRIES_LWSEM); _KLOGX3(KLOG_timer_test, result, *timer_error_ptr); return(result); } /* Endif */ queue_ptr = (pointer)&timer_component_ptr->ELAPSED_TIMER_ENTRIES; element_ptr = (pointer)queue_ptr->NEXT; while (element_ptr != (pointer)queue_ptr) { #if MQX_CHECK_VALIDITY if (element_ptr->VALID != TIMER_VALID) { *timer_error_ptr = element_ptr; _lwsem_post(&timer_component_ptr->TIMER_ENTRIES_LWSEM); _KLOGX3(KLOG_timer_test, MQX_INVALID_COMPONENT_HANDLE, *timer_error_ptr); return(MQX_INVALID_COMPONENT_HANDLE); } /* Endif */ #endif element_ptr = (pointer)element_ptr->QUEUE_ELEMENT.NEXT; } /* Endwhile */ queue_ptr = (pointer)&timer_component_ptr->KERNEL_TIMER_ENTRIES; element_ptr = (pointer)queue_ptr->NEXT; while (element_ptr != (pointer)queue_ptr) { #if MQX_CHECK_VALIDITY if (element_ptr->VALID != TIMER_VALID) { *timer_error_ptr = element_ptr; _lwsem_post(&timer_component_ptr->TIMER_ENTRIES_LWSEM); _KLOGX3(KLOG_timer_test, MQX_INVALID_COMPONENT_HANDLE, *timer_error_ptr); return(MQX_INVALID_COMPONENT_HANDLE); } /* Endif */ #endif element_ptr = (pointer)element_ptr->QUEUE_ELEMENT.NEXT; } /* Endwhile */ _lwsem_post(&timer_component_ptr->TIMER_ENTRIES_LWSEM); _KLOGX2(KLOG_timer_test, MQX_OK); return(MQX_OK); } /* Endbody */
_mqx_uint _mutex_test ( /* [OUT] - the mutex in error */ pointer _PTR_ mutex_error_ptr ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; MUTEX_COMPONENT_STRUCT_PTR mutex_component_ptr; MUTEX_STRUCT_PTR mutex_ptr; _mqx_uint result; _GET_KERNEL_DATA(kernel_data); _KLOGE2(KLOG_mutex_test, mutex_error_ptr); *mutex_error_ptr = NULL; mutex_component_ptr = (MUTEX_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_MUTEXES]; if (mutex_component_ptr == NULL) { _KLOGX2(KLOG_mutex_test, MQX_OK); return(MQX_OK); } /* Endif */ if (mutex_component_ptr->VALID != MUTEX_VALID) { _KLOGX2(KLOG_mutex_test, MQX_INVALID_COMPONENT_BASE); return(MQX_INVALID_COMPONENT_BASE); } /* Endif */ _int_disable(); /* Make sure that the queue of mutexes is ok */ result = _queue_test(&mutex_component_ptr->MUTEXES, mutex_error_ptr); if (result != MQX_OK) { _int_enable(); _KLOGX3(KLOG_mutex_test, result, *mutex_error_ptr); return(result); } /* Endif */ mutex_ptr = (MUTEX_STRUCT_PTR)((pointer)mutex_component_ptr->MUTEXES.NEXT); while (mutex_ptr != (MUTEX_STRUCT_PTR) ((pointer)&mutex_component_ptr->MUTEXES)) { if (mutex_ptr->VALID != MUTEX_VALID) { _int_enable(); *mutex_error_ptr = mutex_ptr; _KLOGX3(KLOG_mutex_test, MQX_EINVAL, mutex_ptr); return(MQX_EINVAL); } /* Endif */ result = _queue_test(&mutex_ptr->WAITING_TASKS, mutex_error_ptr); if (result != MQX_OK) { _int_enable(); *mutex_error_ptr = mutex_ptr; _KLOGX3(KLOG_mutex_test, result, mutex_ptr); return(result); } /* Endif */ mutex_ptr = (MUTEX_STRUCT_PTR)((pointer)mutex_ptr->LINK.NEXT); } /* Endif */ _int_enable(); _KLOGX2(KLOG_mutex_test, MQX_OK); return(MQX_OK); } /* Endbody */
/*! * \brief Tests all the periodic queues and their lightweight timers for * validity and consistency. * * \param[out] period_error_ptr Pointer to the first periodic queue that has * an error (NULL if no error is found). * \param[out] timer_error_ptr Pointer to the first timer that has an error * (NULL if no error is found). * * \return MQX_OK (No periodic queues have been created or no errors found * in any periodic queues or timers.) * \return MQX_LWTIMER_INVALID (Period_ptr points to an invalid periodic queue.) * \return Error from _queue_test() (A periodic queue or its queue was in error.) * * \see _lwtimer_add_timer_to_queue * \see _lwtimer_cancel_period * \see _lwtimer_cancel_timer * \see _lwtimer_create_periodic_queue */ _mqx_uint _lwtimer_test ( void **period_error_ptr, void **timer_error_ptr ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; LWTIMER_STRUCT_PTR timer_ptr; LWTIMER_PERIOD_STRUCT_PTR period_ptr; _mqx_uint result; _GET_KERNEL_DATA(kernel_data); _KLOGE3(KLOG_lwtimer_test, period_error_ptr, timer_error_ptr); *period_error_ptr = NULL; *timer_error_ptr = NULL; /* * It is not considered an error if the lwtimer component has not been * created yet */ if (kernel_data->LWTIMERS.NEXT == NULL) { return (MQX_OK); } /* Endif */ result = _queue_test(&kernel_data->LWTIMERS, period_error_ptr); if (result != MQX_OK) { _KLOGX3(KLOG_lwtimer_test, result, *period_error_ptr); return (result); } /* Endif */ _int_disable(); period_ptr = (void *) kernel_data->LWTIMERS.NEXT; while ((void *) period_ptr != (void *) &kernel_data->LWTIMERS) { if (period_ptr->VALID != LWTIMER_VALID) { _int_enable(); *period_error_ptr = period_ptr; _KLOGX3(KLOG_lwtimer_test, MQX_LWTIMER_INVALID, period_ptr); return (MQX_LWTIMER_INVALID); } /* Endif */ result = _queue_test(&period_ptr->TIMERS, timer_error_ptr); if (result != MQX_OK) { _int_enable(); *period_error_ptr = period_ptr; _KLOGX4(KLOG_lwtimer_test, result, *period_error_ptr, *timer_error_ptr); return (result); } /* Endif */ timer_ptr = (void *) period_ptr->TIMERS.NEXT; while (timer_ptr != (void *) &period_ptr->TIMERS) { if (timer_ptr->VALID != LWTIMER_VALID) { *period_error_ptr = period_ptr; *timer_error_ptr = timer_ptr; _KLOGX4(KLOG_lwtimer_test, MQX_LWTIMER_INVALID, period_ptr, timer_ptr); return (MQX_LWTIMER_INVALID); } /* Endif */ timer_ptr = (void *) timer_ptr->LINK.NEXT; } /* Endwhile */ period_ptr = (void *) period_ptr->LINK.NEXT; } /* Endwhile */ _int_enable(); _KLOGX2(KLOG_lwtimer_test, MQX_OK); return (MQX_OK); } /* Endbody */
_task_id _task_create_blocked ( /* [IN] the processor upon which to create the task */ _processor_number processor_number, /* [IN] the task template index number for this task */ _mqx_uint template_index, /* [IN] the parameter to pass to the newly created task */ uint_32 parameter ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; TD_STRUCT_PTR td_ptr; #if MQX_IS_MULTI_PROCESSOR TASK_TEMPLATE_STRUCT_PTR task_template_ptr; #endif _task_id result; #if MQX_IS_MULTI_PROCESSOR boolean blocking; #endif _GET_KERNEL_DATA(kernel_data); _KLOGE4(KLOG_task_create_block, processor_number, template_index, parameter); #if MQX_CHECK_ERRORS if (template_index & SYSTEM_TASK_FLAG) { _task_set_error(MQX_INVALID_TEMPLATE_INDEX); _KLOGX3(KLOG_task_create_block, MQX_NULL_TASK_ID, MQX_INVALID_TEMPLATE_INDEX); return MQX_NULL_TASK_ID; } /* Endif */ #endif if (processor_number == 0 ) { processor_number = (_processor_number)kernel_data->INIT.PROCESSOR_NUMBER; #if MQX_CHECK_ERRORS } else if (processor_number > MQX_MAX_PROCESSOR_NUMBER) { _task_set_error(MQX_INVALID_PROCESSOR_NUMBER); _KLOGX3(KLOG_task_create_block, MQX_NULL_TASK_ID, MQX_INVALID_PROCESSOR_NUMBER); return MQX_NULL_TASK_ID; #endif } else if (processor_number != kernel_data->INIT.PROCESSOR_NUMBER) { #if MQX_IS_MULTI_PROCESSOR if ( kernel_data->IPC != NULL ) { #if MQX_TASK_CREATION_BLOCKS blocking = TRUE; #else blocking = FALSE; #endif if (template_index == 0) { /* Task template is pointed to by the parameter */ task_template_ptr = (TASK_TEMPLATE_STRUCT_PTR)parameter; (*kernel_data->IPC)(blocking, processor_number, KERNEL_MESSAGES, IPC_TASK_CREATE_WITH_TEMPLATE, 8L, task_template_ptr->TASK_TEMPLATE_INDEX, task_template_ptr->TASK_ADDRESS, task_template_ptr->TASK_STACKSIZE, task_template_ptr->TASK_PRIORITY, task_template_ptr->TASK_NAME, task_template_ptr->TASK_ATTRIBUTES, task_template_ptr->CREATION_PARAMETER, task_template_ptr->DEFAULT_TIME_SLICE ); } else { (*kernel_data->IPC)(blocking, processor_number, KERNEL_MESSAGES, IPC_TASK_CREATE, 3, processor_number, template_index, parameter); } /* Endif */ return(kernel_data->ACTIVE_PTR->INFO); } else { #endif _task_set_error(MQX_INVALID_PROCESSOR_NUMBER); _KLOGX3(KLOG_task_create_block, MQX_NULL_TASK_ID, MQX_INVALID_PROCESSOR_NUMBER); return MQX_NULL_TASK_ID; #if MQX_IS_MULTI_PROCESSOR } /* Endif */ #endif } /* Endif */ /* START CR 897 */ td_ptr = _task_build_internal(template_index, parameter, NULL, 0, FALSE); /* END CR 897 */ if (td_ptr != NULL) { td_ptr->STATE = BLOCKED; result = td_ptr->TASK_ID; } else { result = MQX_NULL_TASK_ID; }/* Endif */ _KLOGX3(KLOG_task_create_block, result, kernel_data->ACTIVE_PTR->TASK_ERROR_CODE); return(result); } /* 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); }
_mqx_uint _sched_set_policy ( /* [IN] the task whose policy is to change: ** NULL_TASK_ID => the current task ** DEFAULT_TASK_ID => the kernel defaults for task creation ** any other => the specified task */ _task_id task_id, /* [IN] the new scheduling policy */ _mqx_uint policy ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; TD_STRUCT_PTR td_ptr; _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 _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 */
_mqx_uint _lwsem_test ( /* [OUT] the light weight semapohre in error */ pointer _PTR_ lwsem_error_ptr, /* [OUT] the td on a light weight semaphore in error */ pointer _PTR_ td_error_ptr ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; LWSEM_STRUCT_PTR sem_ptr; _mqx_uint queue_size; _mqx_uint result; _GET_KERNEL_DATA(kernel_data); _KLOGE3(KLOG_lwsem_test, lwsem_error_ptr, td_error_ptr); *td_error_ptr = NULL; *lwsem_error_ptr = NULL; #if MQX_CHECK_ERRORS if (kernel_data->IN_ISR) { _KLOGX2(KLOG_lwsem_test, MQX_CANNOT_CALL_FUNCTION_FROM_ISR); return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR); }/* Endif */ #endif _int_disable(); result = _queue_test((QUEUE_STRUCT_PTR)&kernel_data->LWSEM, lwsem_error_ptr); if (result != MQX_OK) { _KLOGX3(KLOG_lwsem_test, result, *lwsem_error_ptr); return(result); } /* Endif */ sem_ptr = (LWSEM_STRUCT_PTR)((pointer)kernel_data->LWSEM.NEXT); queue_size = _QUEUE_GET_SIZE(&kernel_data->LWSEM); while (queue_size--) { if (sem_ptr->VALID != LWSEM_VALID) { result = MQX_INVALID_LWSEM; break; } /* Endif */ result = _queue_test(&sem_ptr->TD_QUEUE, td_error_ptr); if (result != MQX_OK) { break; } /* Endif */ sem_ptr = sem_ptr->NEXT; } /* Endwhile */ _int_enable(); if (result != MQX_OK) { *lwsem_error_ptr = (pointer)sem_ptr; } /* Endif */ _KLOGX4(KLOG_lwsem_test, result, *lwsem_error_ptr, *td_error_ptr); return(result); }
/*! * \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 */
/*! * \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 */