/*! * \brief Set the time slice in tick time. * * \param[in] task_id One of the following: * \n - Task ID for a task on this processor for which to set info. * \n - MQX_DEFAULT_TASK_ID (Set the time slice for the processor.) * \n - MQX_NULL_TASK_ID (Set the time slice for the calling task.) * \param[in] new_rr_interval_ptr Pointer to the new time slice (in tick time). * \param[out] old_rr_interval_ptr Pointer to the previous time slice (in tick time). * * \return Previous time slice (Success.) * \return MAX_UINT_32 * * \warning On failure, calls _task_set_error() to set the task error code to * MQX_SCHED_INVALID_TASK_ID. * * \see _sched_set_rr_interval * \see _sched_get_rr_interval * \see _sched_get_rr_interval_ticks * \see _task_set_error * \see MQX_TICK_STRUCT */ _mqx_uint _sched_set_rr_interval_ticks ( _task_id task_id, MQX_TICK_STRUCT_PTR new_rr_interval_ptr, MQX_TICK_STRUCT_PTR old_rr_interval_ptr ) { /* Body */ _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data); _mqx_uint result; _KLOGM(_GET_KERNEL_DATA(kernel_data)); _KLOGE2(KLOG_sched_set_rr_interval_ticks, task_id); result = _sched_set_rr_interval_internal(task_id, new_rr_interval_ptr, old_rr_interval_ptr); if (result != MQX_OK) { _task_set_error(result); } /* Endif */ _KLOGX2(KLOG_sched_set_rr_interval_ticks, result); 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); }
_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 */
pointer _partition_alloc_zero ( /* [IN] the partition from which to obtin the memory block */ _partition_id partition ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; PARTPOOL_STRUCT_PTR partpool_ptr = (PARTPOOL_STRUCT_PTR)partition; pointer result; _GET_KERNEL_DATA(kernel_data); _KLOGE2(KLOG_partition_alloc_zero, partition); result = _partition_alloc_internal(partpool_ptr, kernel_data->ACTIVE_PTR); #if MQX_CHECK_MEMORY_ALLOCATION_ERRORS if ( result == NULL ) { _KLOGX2(KLOG_partition_alloc_zero, result); return (result); } /* Endif */ #endif _mem_zero(result, (_mem_size)(partpool_ptr->BLOCK_SIZE - sizeof(INTERNAL_PARTITION_BLOCK_STRUCT))); _KLOGX2(KLOG_partition_alloc_zero, result); return (result); } /* Endbody */
/*! * \brief Cancels all the lightweight timers in the periodic queue. * * \param[in] period_ptr Pointer to the periodic queue to cancel. * * \return MQX_OK * \return MQX_LWTIMER_INVALID (Period_ptr points to an invalid periodic queue.) * * \see _lwtimer_add_timer_to_queue * \see _lwtimer_cancel_timer * \see _lwtimer_create_periodic_queue * \see LWTIMER_PERIOD_STRUCT */ _mqx_uint _lwtimer_cancel_period ( LWTIMER_PERIOD_STRUCT_PTR period_ptr ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; _GET_KERNEL_DATA(kernel_data); _KLOGE2(KLOG_lwtimer_cancel_period, period_ptr); #if MQX_CHECK_VALIDITY if (period_ptr->VALID != LWTIMER_VALID) { _KLOGX2(KLOG_lwtimer_cancel_period, MQX_LWTIMER_INVALID); return MQX_LWTIMER_INVALID; } /* Endif */ #endif _int_disable(); period_ptr->VALID = 0; _QUEUE_REMOVE(&kernel_data->LWTIMERS, period_ptr); _int_enable(); _KLOGX2(KLOG_lwtimer_cancel_period, MQX_OK); return (MQX_OK); } /* Endbody */
/*! * \brief Deletes the name and its associated number from the names database. * * \param[in] name The name to be deleted. * * \return MQX_OK * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an * ISR.) * \return MQX_COMPONENT_DOES_NOT_EXIST (Name component is not created.) * \return MQX_INVALID_COMPONENT_BASE (Name component data is not valid.) * \return NAME_TOO_SHORT (Name is 0 length string.) * \return NAME_TOO_LONG (Name is longer than NAME_MAX_NAME_SIZE.) * \return NAME_NOT_FOUND (Name is not in the names database.) * * \warning Cannot be called from an ISR. * * \see _name_add * \see _name_create_component * \see _name_find */ _mqx_uint _name_delete ( char *name ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; void *handle; _mqx_uint result; _GET_KERNEL_DATA(kernel_data); _KLOGE2(KLOG_name_delete, name); #if MQX_CHECK_ERRORS if (kernel_data->IN_ISR) { _KLOGX2(KLOG_name_delete, MQX_CANNOT_CALL_FUNCTION_FROM_ISR); return (MQX_CANNOT_CALL_FUNCTION_FROM_ISR); } /* Endif */ #endif /* MQX_CHECK_ERRORS */ handle = kernel_data->KERNEL_COMPONENTS[KERNEL_NAME_MANAGEMENT]; #if MQX_CHECK_ERRORS if (handle == NULL) { _KLOGX2(KLOG_name_delete, MQX_COMPONENT_DOES_NOT_EXIST); return (MQX_COMPONENT_DOES_NOT_EXIST); } /* Endif */ #endif /* MQX_CHECK_ERRORS */ result = _name_delete_internal(handle, name); _KLOGX2(KLOG_name_delete, result); return (result); } /* Endbody */
void _time_delay_for ( /* [IN] the number of ticks to delay */ register MQX_TICK_STRUCT_PTR ticks ) { /* Body */ register KERNEL_DATA_STRUCT_PTR kernel_data; register TD_STRUCT_PTR td_ptr; _GET_KERNEL_DATA(kernel_data); _KLOGE2(KLOG_time_delay_for, ticks); #if MQX_CHECK_ERRORS if (ticks == NULL) { _task_set_error(MQX_INVALID_PARAMETER); _KLOGX2(KLOG_time_delay_for, MQX_INVALID_PARAMETER); return; } /* Endif */ #endif td_ptr = kernel_data->ACTIVE_PTR; _INT_DISABLE(); /* Calculate time to wake up the task */ PSP_ADD_TICKS(ticks, &kernel_data->TIME, &td_ptr->TIMEOUT); _time_delay_internal(td_ptr); _INT_ENABLE(); _KLOGX1(KLOG_time_delay_for); } /* Endbody */
pointer _taskq_create ( /* [IN] the policy of this task queue (fifo or priority queueing) */ _mqx_uint policy ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; TASK_QUEUE_STRUCT_PTR task_queue_ptr; _GET_KERNEL_DATA(kernel_data); _KLOGE2(KLOG_taskq_create, policy); #if MQX_CHECK_ERRORS if (! ((policy == MQX_TASK_QUEUE_FIFO) || (policy == MQX_TASK_QUEUE_BY_PRIORITY))) { _task_set_error(MQX_INVALID_PARAMETER); _KLOGX2(KLOG_taskq_create, NULL); return (NULL); } /* Endif */ if (kernel_data->IN_ISR) { _task_set_error(MQX_CANNOT_CALL_FUNCTION_FROM_ISR); _KLOGX2(KLOG_taskq_create, NULL); return(NULL); }/* Endif */ #endif task_queue_ptr = (TASK_QUEUE_STRUCT_PTR)_mem_alloc_system((_mem_size) sizeof(TASK_QUEUE_STRUCT)); #if MQX_CHECK_MEMORY_ALLOCATION_ERRORS if (task_queue_ptr == NULL) { _KLOGX2(KLOG_taskq_create, NULL); return(NULL); } /* Endif */ #endif _mem_set_type(task_queue_ptr, MEM_TYPE_TASK_Q); task_queue_ptr->POLICY = policy; _QUEUE_INIT(&task_queue_ptr->TD_QUEUE, 0); task_queue_ptr->VALID = TASK_QUEUE_VALID; _int_disable(); if (kernel_data->KERNEL_TASK_QUEUES.NEXT == NULL) { /* Initialize the task queue */ _QUEUE_INIT(&kernel_data->KERNEL_TASK_QUEUES,0); } /* Endif */ _QUEUE_ENQUEUE(&kernel_data->KERNEL_TASK_QUEUES, task_queue_ptr); _int_enable(); _KLOGX2(KLOG_taskq_create, task_queue_ptr); return(task_queue_ptr); } /* Endbody */
_mqx_uint _taskq_suspend ( /* [IN] the task queue handle */ pointer users_task_queue_ptr ) { /* Body */ register KERNEL_DATA_STRUCT_PTR kernel_data; register TD_STRUCT_PTR td_ptr; register TASK_QUEUE_STRUCT_PTR task_queue_ptr = (TASK_QUEUE_STRUCT_PTR)users_task_queue_ptr; _GET_KERNEL_DATA(kernel_data); _KLOGE2(KLOG_taskq_suspend, users_task_queue_ptr); #if MQX_CHECK_ERRORS if (task_queue_ptr == NULL){ _KLOGX2(KLOG_taskq_suspend, MQX_INVALID_PARAMETER); return(MQX_INVALID_PARAMETER); } /* Endif */ if (kernel_data->IN_ISR) { _KLOGX2(KLOG_taskq_suspend, MQX_CANNOT_CALL_FUNCTION_FROM_ISR); return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR); }/* Endif */ #endif td_ptr = kernel_data->ACTIVE_PTR; _INT_DISABLE(); #if MQX_CHECK_VALIDITY if (task_queue_ptr->VALID != TASK_QUEUE_VALID) { _int_enable(); _KLOGX2(KLOG_taskq_suspend, MQX_INVALID_TASK_QUEUE); return(MQX_INVALID_TASK_QUEUE); } /* Endif */ #endif td_ptr->STATE = TASK_QUEUE_BLOCKED; _QUEUE_UNLINK(td_ptr); /* Remove task from ready to run queue */ td_ptr->INFO = (_mqx_uint)&task_queue_ptr->TD_QUEUE; if (task_queue_ptr->POLICY & MQX_TASK_QUEUE_BY_PRIORITY) { _sched_insert_priorityq_internal(&task_queue_ptr->TD_QUEUE, td_ptr); } else { _QUEUE_ENQUEUE(&task_queue_ptr->TD_QUEUE, td_ptr); } /* Endif */ _sched_execute_scheduler_internal(); /* Let the other tasks run */ _INT_ENABLE(); _KLOGX2(KLOG_taskq_suspend, MQX_OK); return( MQX_OK ); } /* Endbody */
/*! * \brief Marks the message as "free". * * Only the task that has the message as its resource can free the message. A * message becomes a task's resource when the task allocates the message, and it * continues to be a resource until the task either frees it or puts it in a * message queue. A message becomes a resource of the task that got it from a * message queue. * \n The function returns the message to the message pool from which it was * allocated. * * \param[in] msg_ptr Pointer to a message struct which is to be freed. * * \warning On failure, calls _task_set_error() to set one the following task * error codes: * \li MQX_INVALID_POINTER (Msg_ptr does not point to a valid message.) * \li MQX_NOT_RESOURCE_OWNER (Message is already freed.) * \li MSGQ_MESSAGE_IS_QUEUED (Message is in a queue.) * * \see _msgpool_create * \see _msgpool_create_system * \see _msgpool_destroy * \see _msg_alloc_system * \see _msg_alloc * \see _task_set_error * \see MESSAGE_HEADER_STRUCT */ void _msg_free ( pointer msg_ptr ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; register INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr; register MSGPOOL_STRUCT_PTR msgpool_ptr; _GET_KERNEL_DATA(kernel_data); _KLOGE2(KLOG_msg_free, msg_ptr); imsg_ptr = GET_INTERNAL_MESSAGE_PTR(msg_ptr); #if MQX_CHECK_VALIDITY if ( imsg_ptr->VALID != MSG_VALID ) { _KLOGX2(KLOG_msg_free, MQX_INVALID_POINTER); _task_set_error(MQX_INVALID_POINTER); return; } /* Endif */ #endif #if MQX_CHECK_ERRORS if (imsg_ptr->FREE) { _KLOGX2(KLOG_msg_free, MQX_NOT_RESOURCE_OWNER); _task_set_error(MQX_NOT_RESOURCE_OWNER); return; } /* Endif */ if (imsg_ptr->QUEUED) { _KLOGX2(KLOG_msg_free, MSGQ_MESSAGE_IS_QUEUED); _task_set_error(MSGQ_MESSAGE_IS_QUEUED); return; } /* Endif */ #endif msgpool_ptr = imsg_ptr->MSGPOOL_PTR; imsg_ptr->FREE = TRUE; imsg_ptr->QUEUED = FALSE; _INT_DISABLE(); /* Link onto the free list */ imsg_ptr->NEXT = msgpool_ptr->MSG_FREE_LIST_PTR; msgpool_ptr->MSG_FREE_LIST_PTR = imsg_ptr; ++msgpool_ptr->SIZE; _INT_ENABLE(); _KLOGX2(KLOG_msg_free, MQX_OK); } /* 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 */
void _time_dequeue_td ( /* [IN] the address of the task descriptor to be removed */ pointer td ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; TD_STRUCT_PTR td_ptr = (TD_STRUCT_PTR)td; _GET_KERNEL_DATA(kernel_data); _KLOGE2(KLOG_time_dequeue_td, td); _int_disable(); _TIME_DEQUEUE(td_ptr, kernel_data); _int_enable(); _KLOGX1(KLOG_time_dequeue_td); } /* Endbody */
/*! * \brief Cancels an outstanding timer request. * * \param[in] timer_ptr Pointer to the lightweight timer to cancel. * * \return MQX_OK * \return MQX_LWTIMER_INVALID (Timer_ptr points to either an invalid timer or * to a timer with a periodic queue.) * * \see _lwtimer_add_timer_to_queue * \see _lwtimer_cancel_period * \see _lwtimer_create_periodic_queue * \see LWTIMER_STRUCT */ _mqx_uint _lwtimer_cancel_timer ( LWTIMER_STRUCT_PTR timer_ptr ) { /* Body */ _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data); LWTIMER_PERIOD_STRUCT_PTR period_ptr; _KLOGM(_GET_KERNEL_DATA(kernel_data)); _KLOGE2(KLOG_lwtimer_cancel_timer, timer_ptr); #if MQX_CHECK_VALIDITY if (timer_ptr->VALID != LWTIMER_VALID) { _KLOGX2(KLOG_lwtimer_cancel_timer, MQX_LWTIMER_INVALID); return MQX_LWTIMER_INVALID; } /* Endif */ #endif period_ptr = timer_ptr->PERIOD_PTR; _int_disable(); #if MQX_CHECK_VALIDITY if (period_ptr->VALID != LWTIMER_VALID) { _int_enable(); _KLOGX2(KLOG_lwtimer_cancel_timer, MQX_LWTIMER_INVALID); return MQX_LWTIMER_INVALID; } /* Endif */ #endif timer_ptr->VALID = 0; if (timer_ptr == period_ptr->TIMER_PTR) { period_ptr->TIMER_PTR = (void *) timer_ptr->LINK.PREV; } /* Endif */ _QUEUE_REMOVE(&period_ptr->TIMERS, timer_ptr); _int_enable(); _KLOGX2(KLOG_lwtimer_cancel_timer, MQX_OK); return (MQX_OK); } /* Endbody */
void _task_ready_internal ( /* [IN] the address of the task descriptor to add */ TD_STRUCT_PTR td_ptr ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; register READY_Q_STRUCT_PTR ready_q_ptr; register TD_STRUCT_PTR old_tail_ptr; _GET_KERNEL_DATA(kernel_data); _KLOGE2(KLOG_task_ready, td_ptr); ready_q_ptr = td_ptr->MY_QUEUE; old_tail_ptr = ready_q_ptr->TAIL_READY_Q; /* ** Ready queues are ALWAYS allocated with higher priority queues in higher ** memory, thus we need to update the CURRENT_READY_Q field (which ** always points to the highest priority ready queue with a task ** on it. */ if ( (uchar _PTR_)ready_q_ptr > (uchar _PTR_)(kernel_data->CURRENT_READY_Q) ) { kernel_data->CURRENT_READY_Q = ready_q_ptr; } /* Endif */ td_ptr->STATE = READY; td_ptr->TD_PREV = old_tail_ptr; td_ptr->TD_NEXT = old_tail_ptr->TD_NEXT; old_tail_ptr->TD_NEXT = td_ptr; ready_q_ptr->TAIL_READY_Q = td_ptr; /* SPR P171-0020-01 add macro to zero tick structure */ #if MQX_HAS_TIME_SLICE MQX_ZERO_TICK_STRUCT(&td_ptr->CURRENT_TIME_SLICE); #endif /* END SPR */ _KLOGX1(KLOG_task_ready); } /* Endbody */
pointer _lwmem_alloc_system_from ( /* [IN] the pool to allocate from */ _lwmem_pool_id pool_id, /* [IN] the size of the memory block */ _mem_size size ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; pointer result; _GET_KERNEL_DATA(kernel_data); _KLOGE2(KLOG_lwmem_alloc_system_from, size); result = _lwmem_alloc_internal(size, SYSTEM_TD_PTR(kernel_data), pool_id, FALSE); _KLOGX2(KLOG_lwmem_alloc_system_from, result); return(result); } /* Endbody */
/*! * \brief Terminate the MQX application and return to the environment that * started the application. * * The function returns back to the environment that called _mqx(). If the * application has installed the MQX exit handler (_mqx_set_exit_handler()), * _mqx_exit() calls the MQX exit handler before it exits. By default, * _bsp_exit_handler is installed as the MQX exit handler in each BSP. * * \note It is important to ensure that the environment (boot call stack) the * MQX is returning to is in the consistent state. This is not provided by * distributed MQX BSPs, because the boot stack is reused (rewritten) by MQX * Kernel data. Set the boot stack outside of Kernel data section to support * correct _mqx_exit() functionality. * * \param[in] error Error code to return to the function that called _mqx(). * * \warning Behavior depends on the BSP. * * \see _mqx */ void _mqx_exit ( _mqx_uint error ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; _int_disable(); _GET_KERNEL_DATA(kernel_data); _KLOGE2(KLOG_mqx_exit, error); #if MQX_EXIT_ENABLED || MQX_CRIPPLED_EVALUATION kernel_data->USERS_ERROR = error; if (kernel_data->EXIT_HANDLER) { (*kernel_data->EXIT_HANDLER)(); }/* Endif */ MQX_LONGJMP( _mqx_exit_jump_buffer_internal, 1 ); #else while (TRUE) { } /* Endwhile */ #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); }
/*! * \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); }
/*! * \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); }
_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 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 */
_mqx_uint _timer_cancel ( /* [IN] id of the alarm to be cancelled */ _timer_id id ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; TIMER_COMPONENT_STRUCT_PTR timer_component_ptr; TIMER_ENTRY_STRUCT_PTR timer_entry_ptr; QUEUE_STRUCT_PTR queue_ptr; _GET_KERNEL_DATA(kernel_data); _KLOGE2(KLOG_timer_cancel, id); timer_component_ptr = kernel_data->KERNEL_COMPONENTS[KERNEL_TIMER]; #if MQX_CHECK_ERRORS if (timer_component_ptr == NULL) { _KLOGX2(KLOG_timer_cancel, MQX_COMPONENT_DOES_NOT_EXIST); return MQX_COMPONENT_DOES_NOT_EXIST; } /* Endif */ #endif #if MQX_CHECK_VALIDITY if (timer_component_ptr->VALID != TIMER_VALID) { _KLOGX2(KLOG_timer_cancel, MQX_INVALID_COMPONENT_BASE); return MQX_INVALID_COMPONENT_BASE; } /* Endif */ #endif #if MQX_CHECK_ERRORS if (id == 0) { _KLOGX2(KLOG_timer_cancel, MQX_INVALID_PARAMETER); return MQX_INVALID_PARAMETER; } /* Endif */ if (kernel_data->IN_ISR) { _KLOGX2(KLOG_timer_cancel, MQX_CANNOT_CALL_FUNCTION_FROM_ISR); return MQX_CANNOT_CALL_FUNCTION_FROM_ISR; } /* Endif */ #endif /* Gain exclusive access to the timer queues */ /* Start CR 1332 */ if (kernel_data->ACTIVE_PTR != timer_component_ptr->TIMER_TD_PTR) { if (_lwsem_wait(&timer_component_ptr->TIMER_ENTRIES_LWSEM) != MQX_OK) { _KLOGX2(KLOG_timer_cancel, MQX_INVALID_LWSEM); return(MQX_INVALID_LWSEM); } /* Endif */ } /*Endif */ timer_entry_ptr = _timer_find_entry_internal(timer_component_ptr, id); /* End CR 1332 */ if ((timer_entry_ptr == NULL) || (timer_entry_ptr->VALID != TIMER_VALID)) { if (kernel_data->ACTIVE_PTR != timer_component_ptr->TIMER_TD_PTR) { _lwsem_post(&timer_component_ptr->TIMER_ENTRIES_LWSEM); } /* Endif */ _KLOGX2(KLOG_timer_cancel, MQX_INVALID_PARAMETER); return MQX_INVALID_PARAMETER; } /* Endif */ if (timer_entry_ptr->MODE == TIMER_ELAPSED_TIME_MODE) { queue_ptr = &timer_component_ptr->ELAPSED_TIMER_ENTRIES; } else { queue_ptr = &timer_component_ptr->KERNEL_TIMER_ENTRIES; } /* Endif */ timer_entry_ptr->VALID = 0; timer_entry_ptr->ID = 0; if (kernel_data->ACTIVE_PTR != timer_component_ptr->TIMER_TD_PTR) { _QUEUE_REMOVE(queue_ptr, timer_entry_ptr); _mem_free(timer_entry_ptr); _lwsem_post(&timer_component_ptr->TIMER_ENTRIES_LWSEM); } /* Endif */ _KLOGX2(KLOG_timer_cancel, MQX_OK); return(MQX_OK); } /* Endbody */
/*! * \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 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 */ pointer _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; uint_16 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 ( ((uint_16)(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 (pointer)message_ptr; } /* Endif */ } /* Endif */ msgpool_ptr = msgpool_ptr->NEXT_MSGPOOL_PTR; } /* Endwhile */ _int_enable(); _KLOGX2(KLOG_msg_alloc_system, message_ptr); return (pointer)message_ptr; } /* Endbody */
_mqx_uint _lwsem_wait ( /* [IN] the semaphore address */ LWSEM_STRUCT_PTR sem_ptr ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; TD_STRUCT_PTR td_ptr; #if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI if (MQX_RUN_IN_USER_MODE) { return _usr_lwsem_wait(sem_ptr); } #endif _GET_KERNEL_DATA(kernel_data); _KLOGE2(KLOG_lwsem_wait, sem_ptr); #if MQX_CHECK_ERRORS if (kernel_data->IN_ISR) { _KLOGX2(KLOG_lwsem_wait, MQX_CANNOT_CALL_FUNCTION_FROM_ISR); return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR); } #endif #if MQX_CHECK_VALIDITY if (sem_ptr->VALID != LWSEM_VALID) { _KLOGX2(KLOG_lwsem_wait, MQX_INVALID_LWSEM); return(MQX_INVALID_LWSEM); } #endif _INT_DISABLE(); if (sem_ptr->VALUE <= 0) { td_ptr = kernel_data->ACTIVE_PTR; 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. */ } else { --sem_ptr->VALUE; } //#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, MQX_INVALID_LWSEM); return(MQX_INVALID_LWSEM); } /* Endif */ //#endif _INT_ENABLE(); _KLOGX2(KLOG_lwsem_wait, MQX_OK); return(MQX_OK); }
_mqx_uint _timer_create_component ( /* [IN] the task priority of the timer task */ _mqx_uint timer_task_priority, /* [IN] the stack size for the timer task */ _mqx_uint timer_task_stack_size ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; TIMER_COMPONENT_STRUCT_PTR timer_component_ptr; TASK_TEMPLATE_STRUCT timer_tt; _GET_KERNEL_DATA(kernel_data); _KLOGE2(KLOG_timer_create_component, timer_task_priority); #if MQX_CHECK_ERRORS if (kernel_data->IN_ISR) { _KLOGX2(KLOG_timer_create_component, MQX_CANNOT_CALL_FUNCTION_FROM_ISR); return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR); } /* Endif */ #endif _lwsem_wait((LWSEM_STRUCT_PTR)&kernel_data->COMPONENT_CREATE_LWSEM); if (kernel_data->KERNEL_COMPONENTS[KERNEL_TIMER] != NULL) { _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->COMPONENT_CREATE_LWSEM); _KLOGX2(KLOG_timer_create_component, MQX_OK); return(MQX_OK); } /* Endif */ /* Get the timer component data structure */ timer_component_ptr = _mem_alloc_system_zero( (_mem_size)sizeof(TIMER_COMPONENT_STRUCT)); #if MQX_CHECK_MEMORY_ALLOCATION_ERRORS if (timer_component_ptr == NULL) { _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->COMPONENT_CREATE_LWSEM); _KLOGX2(KLOG_timer_create_component, MQX_OUT_OF_MEMORY); return(MQX_OUT_OF_MEMORY); } /* Endif */ #endif _mem_set_type(timer_component_ptr, MEM_TYPE_TIMER_COMPONENT); _QUEUE_INIT(&timer_component_ptr->ELAPSED_TIMER_ENTRIES, 0); _QUEUE_INIT(&timer_component_ptr->KERNEL_TIMER_ENTRIES, 0); timer_tt.TASK_TEMPLATE_INDEX = 0; timer_tt.TASK_ADDRESS = _timer_task; if (timer_task_stack_size == 0) { timer_tt.TASK_STACKSIZE = TIMER_DEFAULT_STACK_SIZE; } else { timer_tt.TASK_STACKSIZE = timer_task_stack_size; } /* Endif */ if (timer_task_priority == 0) { timer_tt.TASK_PRIORITY = TIMER_DEFAULT_TASK_PRIORITY; } else { timer_tt.TASK_PRIORITY = timer_task_priority; } /* Endif */ timer_tt.TASK_NAME = "Timer Task"; timer_tt.TASK_ATTRIBUTES = 0; timer_tt.DEFAULT_TIME_SLICE = 0; kernel_data->KERNEL_COMPONENTS[KERNEL_TIMER] = timer_component_ptr; timer_component_ptr->TIMER_TID = _task_create(0, 0, (uint_32)&timer_tt); #if MQX_CHECK_ERRORS if (timer_component_ptr->TIMER_TID == MQX_NULL_TASK_ID) { _mqx_uint result; kernel_data->KERNEL_COMPONENTS[KERNEL_TIMER] = NULL; timer_component_ptr->VALID = 0; result = _task_get_error(); if (result == MQX_OK) { result = MQX_OUT_OF_MEMORY; } /* Endif */ _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->COMPONENT_CREATE_LWSEM); _mem_free(timer_component_ptr); _KLOGX2(KLOG_timer_create_component, result); return(result); }/* Endif */ #endif #if MQX_COMPONENT_DESTRUCTION kernel_data->COMPONENT_CLEANUP[KERNEL_EVENTS] = _timer_cleanup; #endif _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->COMPONENT_CREATE_LWSEM); _KLOGX2(KLOG_timer_create_component, MQX_OK); return(MQX_OK); } /* 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 _task_abort ( /* [IN] the task id of the task to abort */ _task_id task_id ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; TD_STRUCT_PTR td_ptr; pointer stack_ptr; _processor_number processor; _GET_KERNEL_DATA(kernel_data); _KLOGE2(KLOG_task_abort, task_id); if (task_id != MQX_NULL_TASK_ID) { processor = PROC_NUMBER_FROM_TASKID(task_id); if (processor != (_processor_number)kernel_data->INIT.PROCESSOR_NUMBER ) { #if MQX_IS_MULTI_PROCESSOR if ( kernel_data->IPC != NULL ) { _KLOGX2(KLOG_task_abort, MQX_OK); return( (*kernel_data->IPC)(FALSE, processor, KERNEL_MESSAGES, IPC_TASK_ABORT, 1, (_mqx_uint)task_id) ); } else { #endif _KLOGX2(KLOG_task_abort, MQX_INVALID_TASK_ID); return(MQX_INVALID_TASK_ID); #if MQX_IS_MULTI_PROCESSOR } /* Endif */ #endif }/* Endif */ }/* Endif */ td_ptr = (TD_STRUCT_PTR)_task_get_td(task_id); #if MQX_CHECK_ERRORS if ( (td_ptr == NULL) || (td_ptr == SYSTEM_TD_PTR(kernel_data)) ) { _KLOGX2(KLOG_task_abort, MQX_INVALID_TASK_ID); return( MQX_INVALID_TASK_ID ); } /* Endif */ #endif if (td_ptr == kernel_data->ACTIVE_PTR) { if (kernel_data->IN_ISR) { stack_ptr = (pointer)td_ptr->STACK_PTR; _PSP_SET_PC_OF_INTERRUPTED_TASK(stack_ptr, _task_exit_function_internal); } else { _task_exit_function_internal(); }/* Endif */ } else { _int_disable(); /* Task is not running */ stack_ptr = (pointer)td_ptr->STACK_PTR; _PSP_SET_PC_OF_BLOCKED_TASK(stack_ptr, _task_exit_function_internal); /* Start CR 1222 */ if (td_ptr->STATE & IS_ON_TIMEOUT_Q){ /* Remove from time queue (uses NEXT, PREV field) */ _TIME_DEQUEUE(td_ptr, kernel_data); /* End CR 1222 */ } else if (td_ptr->STATE & TD_IS_ON_QUEUE) { _QUEUE_REMOVE(td_ptr->INFO, td_ptr); /* Begin CR 1223 */ } else if((td_ptr->STATE & BLOCKED_ON_AUX_QUEUE) ==BLOCKED_ON_AUX_QUEUE){ /* We need to remove it here because _task_ready() below will change its state to READY */ _QUEUE_REMOVE(td_ptr->INFO, &td_ptr->AUX_QUEUE); } /* Endif */ /* End CR 1223 */ if (td_ptr->STATE & IS_BLOCKED) { _task_ready(td_ptr); } /* Endif */ _int_enable(); }/* Endif */ _KLOGX2(KLOG_task_abort, MQX_OK); 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 */ 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 _event_create_internal ( /* [IN] the string name for the event */ char _PTR_ name_ptr, /* [OUT] where the event pointer is */ EVENT_STRUCT_PTR _PTR_ event_ptr_ptr ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; register EVENT_COMPONENT_STRUCT_PTR event_component_ptr; register EVENT_STRUCT_PTR event_ptr; _mqx_uint result; _GET_KERNEL_DATA(kernel_data); _KLOGE2(KLOG_event_create, name_ptr); #if MQX_CHECK_ERRORS if (kernel_data->IN_ISR) { _KLOGX2(KLOG_event_create, MQX_CANNOT_CALL_FUNCTION_FROM_ISR); return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR); } /* Endif */ #endif event_component_ptr = (EVENT_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_EVENTS]; if (event_component_ptr == NULL) { result = _event_create_component(EVENT_DEFAULT_INITIAL_NUMBER, EVENT_DEFAULT_GROW_NUMBER, EVENT_DEFAULT_MAXIMUM_NUMBER); event_component_ptr = (EVENT_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_EVENTS]; #if MQX_CHECK_MEMORY_ALLOCATION_ERRORS if (event_component_ptr == NULL){ _KLOGX2(KLOG_event_create, result); return(result); } /* Endif */ #endif } /* Endif */ #if MQX_CHECK_VALIDITY if (event_component_ptr->VALID != EVENT_VALID){ _KLOGX2(KLOG_event_create, MQX_INVALID_COMPONENT_BASE); return(MQX_INVALID_COMPONENT_BASE); } /* Endif */ #endif event_ptr = (EVENT_STRUCT_PTR)_mem_alloc_system_zero( (_mem_size)sizeof(EVENT_STRUCT)); #if MQX_CHECK_MEMORY_ALLOCATION_ERRORS if (event_ptr == NULL) { _KLOGX2(KLOG_event_create, MQX_OUT_OF_MEMORY); return(MQX_OUT_OF_MEMORY); } /* Endif */ #endif _mem_set_type(event_ptr, MEM_TYPE_EVENT); _QUEUE_INIT(&event_ptr->WAITING_TASKS, EVENT_MAX_WAITING_TASKS); strncpy(event_ptr->NAME, name_ptr, (_mqx_uint)NAME_MAX_NAME_SIZE-1); event_ptr->NAME[NAME_MAX_NAME_SIZE-1] = '\0'; result = _name_add_internal(event_component_ptr->NAME_TABLE_HANDLE, event_ptr->NAME, (_mqx_uint)event_ptr); #if MQX_CHECK_ERRORS if (result != MQX_OK) { _mem_free(event_ptr); if (result == NAME_EXISTS) { _KLOGX2(KLOG_event_create, EVENT_EXISTS); return(EVENT_EXISTS); } else if (result == NAME_TABLE_FULL) { _KLOGX2(KLOG_event_create, EVENT_TABLE_FULL); return(EVENT_TABLE_FULL); } /* Endif */ _KLOGX2(KLOG_event_create, result); return(result); } /* Endif */ #endif event_ptr->VALID = EVENT_VALID; *event_ptr_ptr = event_ptr; _KLOGX2(KLOG_event_create, result); return(result); } /* Endbody */