_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 _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 */
/*! * \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 Set the time slice in milliseconds. * * \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] rr_interval New time slice (in milliseconds). * * \return old_rr_interval 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_ticks * \see _sched_get_rr_interval * \see _sched_get_rr_interval_ticks * \see _task_set_error */ uint32_t _sched_set_rr_interval ( _task_id task_id, uint32_t rr_interval ) { /* Body */ _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data); uint32_t old_rr_interval; MQX_TICK_STRUCT ticks; MQX_TICK_STRUCT old_ticks; _mqx_uint result; _KLOGM(_GET_KERNEL_DATA(kernel_data)); _KLOGE3(KLOG_sched_set_rr_interval, (_mqx_uint)task_id, rr_interval); #if MQX_CHECK_ERRORS /* Validate parameters */ if (0 == rr_interval) { _KLOGX2(KLOG_sched_set_rr_interval, MAX_UINT_32); _task_set_error( MQX_SCHED_INVALID_PARAMETER_PTR ); return (MAX_UINT_32); } /* Endif */ #endif /* Compute the number of tick events required to accomplish the least amount of time[ms]. */ /* tick_events = (required_time[ms] + (time_per_tick[ms] - 1)) / time_per_tick[ms]) --> * tick_events = ((required_time[ms] - 1) / time_per_tick[ms]) + 1 */ rr_interval--; /* Convert milliseconds to ticks, truncated */ PSP_MILLISECONDS_TO_TICKS_QUICK(rr_interval, &ticks); /* Resolve truncation by adding one tick. */ PSP_ADD_TICKS_TO_TICK_STRUCT(&ticks, 1, &ticks); result = _sched_set_rr_interval_internal(task_id, &ticks, &old_ticks); if (result != MQX_OK) { _task_set_error(result); _KLOGX2(KLOG_sched_set_rr_interval, MAX_UINT_32); return(MAX_UINT_32); } /* Endif */ old_rr_interval = PSP_TICKS_TO_MILLISECONDS(&old_ticks, &result); _KLOGX2(KLOG_sched_set_rr_interval, old_rr_interval); return(old_rr_interval); } /* 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 */
_mqx_uint _sched_get_rr_interval_ticks ( /* ** [IN] the task id to apply this to: ** NULL_TASK_ID => the current task ** DEFAULT_TASK_ID => the kernel default for task creation ** any other => the specified task */ _task_id task_id, /* ** [IN/OUT] the address where the current time slice time ** in ticks (_mqx_uint) is to be written */ MQX_TICK_STRUCT_PTR tick_ptr ) { /* Body */ register KERNEL_DATA_STRUCT_PTR kernel_data; TD_STRUCT_PTR td_ptr; _GET_KERNEL_DATA(kernel_data); #if MQX_CHECK_ERRORS /* Validate parameters */ if ( tick_ptr == NULL ) { _task_set_error( MQX_SCHED_INVALID_PARAMETER_PTR ); return( MQX_SCHED_INVALID_PARAMETER_PTR ); } /* Endif */ #endif /* Handle default case */ if ( task_id == MQX_DEFAULT_TASK_ID ) { *tick_ptr = kernel_data->SCHED_TIME_SLICE; } else { td_ptr = (TD_STRUCT_PTR)_task_get_td( task_id ); if ( td_ptr == NULL ) { _task_set_error( MQX_SCHED_INVALID_TASK_ID ); return( MQX_SCHED_INVALID_TASK_ID ); } /* Endif */ *tick_ptr = td_ptr->TIME_SLICE; } /* Endif */ return( 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 */
/*! * \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 */
/*! * \brief Gets a pointer to the kernel ISR for the specified vector number. The * kernel ISR depends on the PSP. * * \param[in] vector Vector number whose kernel ISR is requested. * * \return Pointer to the kernel ISR (Success.) * \return NULL * * \warning On failure, calls _task_set_error() to set the task error code: * \li MQX_INVALID_VECTORED_INTERRUPT * * \see _int_kernel_isr * \see _int_install_kernel_isr */ INT_KERNEL_ISR_FPTR _int_get_kernel_isr ( _mqx_uint int_vector ) { /* Body */ #if MQX_CHECK_ERRORS if ( int_vector >= PSP_MAXIMUM_INTERRUPT_VECTORS ) { _task_set_error(MQX_INVALID_VECTORED_INTERRUPT); return NULL; } /* Endif */ #endif #if defined (PSP_BOOKE) || defined( PSP_BOOKE_VLE) return _bsp_int_get_kernel_isr(int_vector); #else /* !PSP_BOOKE (Original exception model) */ #ifdef PSP_MPC566 return (INT_KERNEL_ISR_FPTR)(_int_get_vector_table() + (int_vector * 0x100)); #else return (INT_KERNEL_ISR_FPTR)(int_vector * 0x100); #endif #endif /* PSP_BOOKE */ } /* Endbody */
_mem_size _partition_get_total_size ( /* [IN] the partition to obtain information about */ _partition_id partition ) { /* Body */ PARTPOOL_STRUCT_PTR partpool_ptr = (PARTPOOL_STRUCT_PTR)partition; PARTPOOL_BLOCK_STRUCT_PTR partpool_block_ptr; register _mem_size size; uchar_ptr tmp_ptr; #if MQX_CHECK_VALIDITY if (partpool_ptr->POOL.VALID != PARTITION_VALID) { _task_set_error(PARTITION_INVALID); return 0; } /* Endif */ #endif size = 0; partpool_block_ptr = partpool_ptr->POOL.NEXT_POOL_PTR; while (partpool_block_ptr != NULL) { tmp_ptr = (uchar_ptr)partpool_block_ptr + sizeof(PARTPOOL_BLOCK_STRUCT); tmp_ptr = (uchar_ptr)_ALIGN_ADDR_TO_HIGHER_MEM(tmp_ptr); size += (_mem_size)(tmp_ptr - (uchar_ptr)partpool_block_ptr); partpool_block_ptr = partpool_block_ptr->NEXT_POOL_PTR; } /* Endif */ tmp_ptr = (uchar_ptr)partition + sizeof(PARTPOOL_STRUCT); tmp_ptr = (uchar_ptr)_ALIGN_ADDR_TO_HIGHER_MEM(tmp_ptr); size += (_mem_size)(tmp_ptr - (uchar_ptr)partition); return(size + partpool_ptr->BLOCK_SIZE * partpool_ptr->TOTAL_BLOCKS); } /* Endbody */
_mem_size _lwmem_get_free_internal ( /* [IN] which pool to get free size from */ _lwmem_pool_id pool_id ) { /* Body */ LWMEM_BLOCK_STRUCT_PTR block_ptr; _mem_size total_size; LWMEM_POOL_STRUCT_PTR mem_pool_ptr = (LWMEM_POOL_STRUCT_PTR)pool_id; #if MQX_CHECK_VALIDITY if (mem_pool_ptr->VALID != LWMEM_POOL_VALID) { _task_set_error(MQX_LWMEM_POOL_INVALID); return(0); } /* Endif */ #endif _int_disable(); block_ptr = mem_pool_ptr->POOL_FREE_LIST_PTR; while ( block_ptr != NULL ) { /* Provide window for higher priority tasks */ mem_pool_ptr->POOL_ALLOC_PTR = block_ptr; _int_enable(); _int_disable(); block_ptr = mem_pool_ptr->POOL_ALLOC_PTR; if (block_ptr == mem_pool_ptr->POOL_FREE_LIST_PTR) { total_size = 0; /* some task with higher priority did reset our loop pointer */ } /* Endif */ total_size += block_ptr->BLOCKSIZE; block_ptr = block_ptr->U.NEXTBLOCK; } /* Endwhile */ _int_enable(); return(total_size); } /* 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 */
/*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); }
/*! * \brief Get the time slice in tick time for the specified task. * * \param[in] task_id One of the following: * \n - Task on this processor for which to get info. * \n - MQX_DEFAULT_TASK_ID (Get the time slice for the processor.) * \n - MQX_NULL_TASK_ID (Get the time slice for the calling task.) * \param[in,out] tick_ptr Pointer to the time slice (in tick time). * * \return MQX_OK * \return MQX_SCHED_INVALID_PARAMETER_PTR (Time_ptr is NULL.) * \return MQX_SCHED_INVALID_TASK_ID (Task_id is not a valid task on this processor.) * * \warning On failure, calls _task_set_error() to set the task error codes (see * return Error Codes). * * \see _sched_get_rr_interval * \see _sched_set_rr_interval * \see _sched_set_rr_interval_ticks * \see _task_set_error * \see MQX_TICK_STRUCT */ _mqx_uint _sched_get_rr_interval_ticks ( _task_id task_id, MQX_TICK_STRUCT_PTR tick_ptr ) { /* Body */ register KERNEL_DATA_STRUCT_PTR kernel_data; TD_STRUCT_PTR td_ptr; _GET_KERNEL_DATA(kernel_data); #if MQX_CHECK_ERRORS /* Validate parameters */ if ( tick_ptr == NULL ) { _task_set_error( MQX_SCHED_INVALID_PARAMETER_PTR ); return( MQX_SCHED_INVALID_PARAMETER_PTR ); } /* Endif */ #endif /* Handle default case */ if ( task_id == MQX_DEFAULT_TASK_ID ) { *tick_ptr = kernel_data->SCHED_TIME_SLICE; } else { td_ptr = (TD_STRUCT_PTR)_task_get_td( task_id ); if ( td_ptr == NULL ) { _task_set_error( MQX_SCHED_INVALID_TASK_ID ); return( MQX_SCHED_INVALID_TASK_ID ); } /* Endif */ *tick_ptr = td_ptr->TIME_SLICE; } /* Endif */ return( MQX_OK ); } /* Endbody */
CORE_MUTEX_PTR _core_mutex_get(uint_32 core_num, uint_32 mutex_num ) { CORE_MUTEX_COMPONENT_PTR component_ptr = _core_mutext_get_component_ptr(); #if MQX_CHECK_ERRORS if (component_ptr == NULL) { _task_set_error(MQX_COMPONENT_DOES_NOT_EXIST); return NULL; } if (mutex_num>=SEMA4_NUM_GATES) { _task_set_error(MQX_INVALID_PARAMETER); return NULL; } if (core_num>=PSP_NUM_CORES) { _task_set_error(MQX_INVALID_PARAMETER); return NULL; } #endif return component_ptr->DEVICE[core_num].MUTEX_PTR[mutex_num]; }
CORE_MUTEX_PTR _core_mutex_create(uint_32 core_num, uint_32 mutex_num, uint_32 policy ) { CORE_MUTEX_PTR mutex_ptr; uint_32 result; mutex_ptr = _mem_alloc_system_zero(sizeof(*mutex_ptr)); #if MQX_CHECK_MEMORY_ALLOCATION_ERRORS if (mutex_ptr==NULL) { _task_set_error(MQX_OUT_OF_MEMORY); return NULL; } #endif result = _core_mutex_create_internal(mutex_ptr, core_num, mutex_num, policy, TRUE ); #if MQX_CHECK_ERRORS if (result != COREMUTEX_OK) { _mem_free(mutex_ptr); _task_set_error(result); mutex_ptr = NULL; } #endif return mutex_ptr; }
/*! * \brief This function creates a kernel component providing a lightweight log * service for all user tasks. * * The lightweight log component provides a maximum of 16 logs, all with the same * size of entries. Log number 0 is reserved for kernel log. * \n An application subsequently creates lightweight logs with _lwlog_create() or * _lwlog_create_at(). * * \return MQX_OK * \return MQX_OUT_OF_MEMORY (MQX is out of memory.) * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.) * * \warning Cannot be called from an ISR. * * \see _lwlog_create * \see _lwlog_create_at * \see _klog_create * \see _klog_create_at */ _mqx_uint _lwlog_create_component(void) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; LWLOG_COMPONENT_STRUCT_PTR log_component_ptr; _GET_KERNEL_DATA(kernel_data); #if MQX_CHECK_ERRORS if (kernel_data->IN_ISR) { _task_set_error(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 MQX_CHECK_ERRORS if (kernel_data->KERNEL_COMPONENTS[KERNEL_LWLOG] != NULL) { _lwsem_post((LWSEM_STRUCT_PTR) &kernel_data->COMPONENT_CREATE_LWSEM); return (MQX_OK); } /* Endif */ #endif #if MQX_LITE_VERSION_NUMBER log_component_ptr = &lwlog_struct; #else log_component_ptr = _mem_alloc_system_zero((_mem_size) sizeof(LWLOG_COMPONENT_STRUCT)); #if MQX_CHECK_MEMORY_ALLOCATION_ERRORS if (log_component_ptr == NULL) { _lwsem_post((LWSEM_STRUCT_PTR) &kernel_data->COMPONENT_CREATE_LWSEM); return (MQX_OUT_OF_MEMORY); } /* Endif */ #endif _mem_set_type(log_component_ptr, MEM_TYPE_LWLOG_COMPONENT); #endif /* MQX_LITE_VERSION_NUMBER */ kernel_data->KERNEL_COMPONENTS[KERNEL_LWLOG] = log_component_ptr; log_component_ptr->VALID = LWLOG_VALID; _lwsem_post((LWSEM_STRUCT_PTR) &kernel_data->COMPONENT_CREATE_LWSEM); return (MQX_OK); } /* Endbody */
_mqx_uint _partition_get_total_blocks ( /* [IN] the partition to obtain information about */ _partition_id partition ) { /* Body */ PARTPOOL_STRUCT_PTR partpool_ptr = (PARTPOOL_STRUCT_PTR)partition; #if MQX_CHECK_VALIDITY if (partpool_ptr->POOL.VALID != PARTITION_VALID) { _task_set_error(PARTITION_INVALID); return 0; } /* Endif */ #endif return(partpool_ptr->TOTAL_BLOCKS); } /* Endbody */
_mem_size _partition_get_block_size ( /* [IN] the partition to obtain information about */ _partition_id partition ) { /* Body */ PARTPOOL_STRUCT_PTR partpool_ptr = (PARTPOOL_STRUCT_PTR)partition; #if MQX_CHECK_VALIDITY if (partpool_ptr->POOL.VALID != PARTITION_VALID) { _task_set_error(PARTITION_INVALID); return 0; } /* Endif */ #endif return(partpool_ptr->BLOCK_SIZE - (_mem_size)sizeof(INTERNAL_PARTITION_BLOCK_STRUCT)); } /* Endbody */
/*! * \brief Gets a pointer to the kernel ISR for the specified vector number. The * kernel ISR depends on the PSP. * * \param[in] vector Vector number whose kernel ISR is requested. * * \return Pointer to the kernel ISR (Success.) * \return NULL * * \warning On failure, calls _task_set_error() to set the task error code: * \li MQX_INVALID_VECTORED_INTERRUPT * * \see _int_kernel_isr * \see _int_install_kernel_isr */ INT_KERNEL_ISR_FPTR _int_get_kernel_isr ( /* [IN] the vector number whose kernel ISR is wanted */ uint32_t vector ) { /* Body */ uint32_t vtor = SCB->VTOR; //value of Vector Table Offset Register #if MQX_CHECK_ERRORS if ( vector >= PSP_MAXIMUM_INTERRUPT_VECTORS ) { _task_set_error(MQX_INVALID_VECTORED_INTERRUPT); return NULL; } /* Endif */ #endif /* Note that VTOR bit indicating SRAM / ROM location is just a SRAM / ROM ** base address within Cortex memory map */ return (INT_KERNEL_ISR_FPTR) (vtor + 4 * vector); } /* Endbody */
pointer _mem_alloc_system_zero_uncached ( /* [IN] the size of the memory block */ _mem_size size ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; pointer result; _mqx_uint error; _GET_KERNEL_DATA(kernel_data); //_KLOGE2(KLOG_mem_alloc_system_zero_uncached, size); _INT_DISABLE(); result = _mem_alloc_internal(size, SYSTEM_TD_PTR(kernel_data), (MEMPOOL_STRUCT_PTR)&kernel_data->UNCACHED_POOL, &error); /* update the memory allocation pointer in case a lower priority ** task was preempted inside _mem_alloc_internal */ kernel_data->UNCACHED_POOL.POOL_ALLOC_CURRENT_BLOCK = kernel_data->UNCACHED_POOL.POOL_FREE_LIST_PTR; _INT_ENABLE(); #if MQX_CHECK_ERRORS if (error != MQX_OK) { _task_set_error(error); } /* Endif */ #endif if (result != NULL) { _mem_zero(result, size); } /* Endif */ //_KLOGX3(KLOG_mem_alloc_system_zero_uncached, result, kernel_data->UNCACHED_POOL.POOL_BLOCK_IN_ERROR); return(result); }
MQX_FILE_PTR _io_fopen ( /* [IN] the name of the device to open */ const char _PTR_ open_type_ptr, /* [IN] I/O initialization parameter to pass to the device initialization */ const char _PTR_ open_mode_ptr ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; MQX_FILE_PTR file_ptr; IO_DEVICE_STRUCT_PTR dev_ptr; char _PTR_ dev_name_ptr; char _PTR_ tmp_ptr; _mqx_int result; _GET_KERNEL_DATA(kernel_data); _lwsem_wait((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM); dev_ptr = (IO_DEVICE_STRUCT_PTR)((pointer)kernel_data->IO_DEVICES.NEXT); while (dev_ptr != (pointer)&kernel_data->IO_DEVICES.NEXT) { dev_name_ptr = dev_ptr->IDENTIFIER; tmp_ptr = (char _PTR_)open_type_ptr; while (*tmp_ptr && *dev_name_ptr && (*tmp_ptr == *dev_name_ptr)) { ++tmp_ptr; ++dev_name_ptr; } /* Endwhile */ if (*dev_name_ptr == '\0') { /* Match */ break; } /* Endif */ dev_ptr = (IO_DEVICE_STRUCT_PTR)((pointer)dev_ptr->QUEUE_ELEMENT.NEXT); } /* Endwhile */ _lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM); if (dev_ptr == (pointer)&kernel_data->IO_DEVICES.NEXT) { return(NULL); } /* Endif */ file_ptr = (MQX_FILE_PTR)_mem_alloc_system_zero((_mem_size)sizeof(MQX_FILE)); #if MQX_CHECK_MEMORY_ALLOCATION_ERRORS if (file_ptr == NULL) { return(NULL); } /* Endif */ #endif _mem_set_type(file_ptr, MEM_TYPE_FILE_PTR); file_ptr->DEV_PTR = dev_ptr; if (dev_ptr->IO_OPEN != NULL) { result = (*dev_ptr->IO_OPEN)(file_ptr, (char _PTR_)open_type_ptr, (char _PTR_)open_mode_ptr); if (result != MQX_OK) { _task_set_error(result); _mem_free(file_ptr); return(NULL); } /* Endif */ } /* Endif */ return(file_ptr); } /* Endbody */
/*FUNCTION**************************************************************** * * Function Name : _io_spi_read_write * Returned Value : Number of bytes read * Comments : * Claims the bus and performs SPI transfer by calling low level driver. * Returns number of bytes processed. * *END*********************************************************************/ static _mqx_int _io_spi_read_write ( /* [IN] The handle returned from _fopen */ MQX_FILE_PTR fd_ptr, /* Buffer containing bytes to write */ char *wrbuf, /* Buffer containing bytes read after transfer */ char *rdbuf, /* Byte length of each buffer */ uint32_t len ) { SPI_DEV_DATA_STRUCT_PTR dev_data; SPI_DRIVER_DATA_STRUCT_PTR driver_data; _mqx_int result; _mqx_int error_code; /* parameter sanity check */ if (len == 0 || ((wrbuf == NULL) && (rdbuf == NULL))) { return IO_ERROR; } dev_data = (SPI_DEV_DATA_STRUCT_PTR)(fd_ptr->DEV_DATA_PTR); driver_data = (SPI_DRIVER_DATA_STRUCT_PTR)(fd_ptr->DEV_PTR->DRIVER_INIT_PTR); if (!(dev_data->BUS_OWNER)) { error_code = _lwsem_wait(&(driver_data->BUS_LOCK)); if (error_code != MQX_OK) { _task_set_error(error_code); return IO_ERROR; } dev_data->BUS_OWNER = TRUE; dev_data->PARAMS_DIRTY = TRUE; } if (dev_data->PARAMS_DIRTY) { error_code = driver_data->DEVIF->SETPARAM(driver_data->DEVIF_DATA, &(dev_data->PARAMS)); if (error_code != MQX_OK) { _task_set_error(error_code); return IO_ERROR; } dev_data->PARAMS_DIRTY = FALSE; } if (driver_data->CS_CALLBACK) { error_code = driver_data->CS_CALLBACK(dev_data->PARAMS.CS, driver_data->CS_USERDATA); if (error_code != MQX_OK) { _task_set_error(error_code); return IO_ERROR; } } if ((wrbuf == NULL) && (dev_data->FLAGS & SPI_FLAG_FULL_DUPLEX)) { wrbuf = rdbuf; } result = driver_data->DEVIF->TX_RX(driver_data->DEVIF_DATA, (uint8_t *)wrbuf, (uint8_t *)rdbuf, len); #if BSPCFG_ENABLE_SPI_STATS /* update statistics */ if (result > 0) { int frames; frames = result / ((dev_data->PARAMS.FRAMESIZE + 7 ) / 8); if (rdbuf) dev_data->STATS.RX_PACKETS += frames; if (wrbuf) dev_data->STATS.TX_PACKETS += frames; } #endif return result; }
/*! * \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 */
/*! * \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 */
/*! * \brief Gets the number of free messages in the message pool. * * The function fails if either: * \li Message component is not created. * \li Pool_id is for a private message pool, but does not represent a valid one. * * \param[in] pool One of the following: * \li Private message pool for which to get the number of free messages. * \li MSGPOOL_NULL_POOL_ID (for system message pools). * * \return The number of free messages in the private message pool (success). * \return The number of free messages in all system message pools (success). * \return 0 (Success: No free messages.) * \return 0 (Failure: see Description.) * * \warning If pool_id does not represent a valid private message pool, calls * _task_set_error() to set the task error code to MSGPOOL_INVALID_POOL_ID * * \see _msgpool_create * \see _msgpool_destroy * \see _msg_free * \see _msg_alloc_system * \see _task_set_error * \see _msg_create_component */ _mqx_uint _msg_available ( _pool_id pool ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; MSG_COMPONENT_STRUCT_PTR msg_component_ptr; register MSGPOOL_STRUCT_PTR msgpool_ptr; _mqx_uint i; _mqx_uint count; _GET_KERNEL_DATA(kernel_data); msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data); #if MQX_CHECK_ERRORS if (msg_component_ptr == NULL) { return(0); } /* Endif */ #endif msgpool_ptr = msg_component_ptr->MSGPOOLS_PTR; #if MQX_CHECK_ERRORS if (msgpool_ptr == NULL) { return(0); }/* Endif */ #endif if (pool == MSGPOOL_NULL_POOL_ID) { count = 0; _INT_DISABLE(); i = msg_component_ptr->MAX_MSGPOOLS_EVER + 1; while ( --i ) { if ( #if MQX_CHECK_VALIDITY (msgpool_ptr->VALID == MSG_VALID) && #endif (msgpool_ptr->MSGPOOL_TYPE == SYSTEM_MSG_POOL)) { count += msgpool_ptr->SIZE; } /* Endif */ ++msgpool_ptr; } /* Endwhile */ _INT_ENABLE(); return count; } else { msgpool_ptr = (MSGPOOL_STRUCT_PTR)pool; if ( #if MQX_CHECK_VALIDITY (msgpool_ptr->VALID != MSG_VALID) || #endif (msgpool_ptr->MSGPOOL_TYPE != MSG_POOL) ) { _task_set_error(MSGPOOL_INVALID_POOL_ID); return (0); } /* Endif */ return (_mqx_uint)msgpool_ptr->SIZE; } /* Endif */ } /* Endbody */
/*TASK*----------------------------------------------------------------- * * Function Name : main_task * Returned Value : void * Comments : * *END------------------------------------------------------------------*/ void main_task(uint_32 temp) { int_32 error; HTTPD_STRUCT *server[BSP_ENET_DEVICE_COUNT]; extern const HTTPD_CGI_LINK_STRUCT cgi_lnk_tbl[]; extern const TFS_DIR_ENTRY tfs_data[]; HTTPD_PARAMS_STRUCT *params[BSP_ENET_DEVICE_COUNT]; _enet_address address[BSP_ENET_DEVICE_COUNT]; uint_32 phy_addr[BSP_ENET_DEVICE_COUNT]; uint_32 ip_addr[BSP_ENET_DEVICE_COUNT]; uint_32 i = 0; char* indexes[BSP_ENET_DEVICE_COUNT]; uint_8 n_devices = BSP_ENET_DEVICE_COUNT; #if DEMOCFG_USE_WIFI ENET_ESSID ssid; uint_32 mode;// = DEMOCFG_NW_MODE; uint_32 sectype;// = DEMOCFG_SECURITY; ENET_MEDIACTL_PARAM param; #endif #if RTCSCFG_ENABLE_IP6 IPCFG6_GET_ADDR_DATA data[RTCSCFG_IP6_IF_ADDRESSES_MAX]; char prn_addr6[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; uint_32 n = 0; uint_32 j = 0; #endif _int_install_unexpected_isr(); /*---------------- Initialize devices and variables ----------------------*/ _RTCSPCB_init = 4; _RTCSPCB_grow = 2; _RTCSPCB_max = 8; _RTCSTASK_stacksize = 4500; /*--------------------------- Init end -----------------------------------*/ PORT_PCR_REG(PORTC_BASE_PTR, 3) = PORT_PCR_MUX(5); // SIM_SOPT2 |= 3<<5; // 1k LPO error = RTCS_create(); if (error != RTCS_OK) { printf("RTCS failed to initialize, error = 0x%X\n", error); _task_block(); } _IP_forward = TRUE; for (i = 0; (i < n_devices) && (n_devices != 0); i++) { IPCFG_IP_ADDRESS_DATA ip_data; phy_addr[i] = i; ip_addr[i] = IPADDR(A,B,C+i,D); ENET_get_mac_address (phy_addr[i], ip_addr[i], address[i]); /* Init ENET device */ error = ipcfg_init_device (phy_addr[i], address[i]); if (error != RTCS_OK) { printf("IPCFG: Device n.%d init failed. Error = 0x%X\n", i, error); _task_set_error(MQX_OK); n_devices--; i--; continue; } #if RTCSCFG_ENABLE_IP4 ip_data.ip = ip_addr[i]; ip_data.mask = ENET_IPMASK; ip_data.gateway = 0; /* Bind IPv4 address */ //error = ipcfg_bind_staticip (phy_addr[i], &ip_data); error = ipcfg_bind_autoip (phy_addr[i], &ip_data); if (error != RTCS_OK) { printf("\nIPCFG: Failed to bind IP address. Error = 0x%X", error); _task_block(); } #endif /* RTCSCFG_ENABLE_IP4 */ indexes[i] = (char*) _mem_alloc(sizeof("\\index_x.html")); } error = _io_tfs_install("tfs:", tfs_data); #if DEBUG__MESSAGES printf("Preparing http servers...\n"); #endif for (i = 0; i < n_devices; i++) { params[i] = httpd_default_params(NULL); params[i]->af = HTTP_INET_AF; //IPv4+IPv6, set connection family from config.h #if RTCSCFG_ENABLE_IP6 params[i]->if_scope_id = HTTP_SCOPE_ID; // set interface number here. 0 is any . #endif if (params[i]) { sprintf(indexes[i], "\\index.html", i); params[i]->root_dir = (HTTPD_ROOT_DIR_STRUCT*)root_dir; params[i]->index_page = indexes[i]; printf("Starting http server No.%d on IP", i); /* ** If there is only one interface listen on any IP address ** so address can change in runtime (DHCP etc.) */ #if RTCSCFG_ENABLE_IP4 if ((i == 0) && (n_devices == 1)) { params[i]->address = INADDR_ANY; } else { params[i]->address = ip_addr[i]; } /* Print active ip addresses */ printf(" %d.%d.%d.%d", IPBYTES(ip_addr[i])); #endif #if RTCSCFG_ENABLE_IP6 while(!ipcfg6_get_addr_info_n(i, n, &data[n])) { n++; } while(j < n) { if(inet_ntop(AF_INET6, &data[j++].ip_addr, prn_addr6, sizeof(prn_addr6))) { /* Print active ip addresses */ #if RTCSCFG_ENABLE_IP4 printf("%s %s", (HTTP_INET_AF & AF_INET) ? " and" : "", prn_addr6); #else printf(" %s", prn_addr6); #endif } } #endif #if PSP_MQX_CPU_IS_MCF5223X params[i]->max_ses = 1; #else params[i]->max_ses = _RTCS_socket_part_max - 1; #endif server[i] = httpd_init(params[i]); } HTTPD_SET_PARAM_CGI_TBL(server[i], (HTTPD_CGI_LINK_STRUCT*)cgi_lnk_tbl); #if HTTPD_SEPARATE_TASK || !HTTPDCFG_POLL_MODE printf("..."); error = httpd_server_run(server[i]); if (error) { printf("[FAIL]\n"); } else { printf("[OK]\n"); } #endif } /* user stuff come here */ #if HTTPD_SEPARATE_TASK || !HTTPDCFG_POLL_MODE _task_create(0, SHELL_TASK, 0); _task_block(); #else printf("Servers polling started.\n") while (1) { for (i = 0; i < n_devices; i++) { httpd_server_poll(server[i], 1); } /* user stuff come here - only non blocking calls */ } #endif }
boolean _msgq_send_internal ( /* [IN] pointer to the message being sent by application */ MESSAGE_HEADER_STRUCT_PTR msg_ptr, /* [IN] is the calling task to be blocked after the call */ boolean blocking, /* [IN] the queue to put the message onto */ _queue_id target_qid ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; MSG_COMPONENT_STRUCT_PTR msg_component_ptr; register INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr; register MSGQ_STRUCT_PTR msgq_ptr; register TD_STRUCT_PTR td_ptr; MESSAGE_HEADER_STRUCT_PTR tmp_msg_ptr; register _mqx_uint state; register _queue_number queue; register _processor_number pnum; /* Start CR 2191 */ boolean swapped_msg; /* End CR 2191 */ _GET_KERNEL_DATA(kernel_data); 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); return(FALSE); } /* Endif */ if (msg_ptr == NULL) { _task_set_error(MSGQ_INVALID_MESSAGE); return(FALSE); } /* Endif */ #endif imsg_ptr = GET_INTERNAL_MESSAGE_PTR(msg_ptr); #if MQX_CHECK_ERRORS if (imsg_ptr->VALID != MSG_VALID){ /* An invalid message was input by the application. */ _task_set_error(MSGQ_INVALID_MESSAGE); return FALSE; } /* Endif */ #endif #if MQX_CHECK_ERRORS if (imsg_ptr->FREE || imsg_ptr->QUEUED){ /* Trying to send a free message, or one on a message queue. */ _task_set_error(MSGQ_INVALID_MESSAGE); return FALSE; } /* Endif */ #endif pnum = PROC_NUMBER_FROM_QID(target_qid); /* If processor number is zero then the message is for this processor */ if (pnum == 0) { /* Fix up the target QID in the message header */ msg_ptr->TARGET_QID = BUILD_QID(kernel_data->INIT.PROCESSOR_NUMBER, msg_ptr->TARGET_QID); } else if (pnum != kernel_data->INIT.PROCESSOR_NUMBER) { #if MQX_IS_MULTI_PROCESSOR IPC_MSG_ROUTING_COMPONENT_STRUCT_PTR ipc_msg_comp_ptr; ipc_msg_comp_ptr = (IPC_MSG_ROUTING_COMPONENT_STRUCT_PTR) kernel_data->KERNEL_COMPONENTS[KERNEL_IPC_MSG_ROUTING]; if (ipc_msg_comp_ptr && ipc_msg_comp_ptr->MSG_ROUTER) { return( (*ipc_msg_comp_ptr->MSG_ROUTER)(pnum, msg_ptr, blocking)); } else { #endif _msg_free(msg_ptr); _task_set_error(MSGQ_INVALID_QUEUE_ID); return FALSE; #if MQX_IS_MULTI_PROCESSOR }/* Endif */ #endif } /* Endif */ queue = QUEUE_FROM_QID(target_qid); #if MQX_CHECK_ERRORS if ( ! VALID_QUEUE(queue)) { _msg_free(msg_ptr); _task_set_error(MSGQ_INVALID_QUEUE_ID); return FALSE; } /* Endif */ #endif msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue]; if (msgq_ptr->QUEUE != queue) { msgq_ptr = NULL; } /* Endif */ #if MQX_CHECK_ERRORS if (msgq_ptr == NULL) { _msg_free(msg_ptr); _task_set_error(MSGQ_QUEUE_IS_NOT_OPEN); return FALSE; } /* Endif */ #endif _INT_DISABLE(); if ((msgq_ptr->MAX_ENTRIES == 0) || (msgq_ptr->NO_OF_ENTRIES < msgq_ptr->MAX_ENTRIES)) { /* End CR 2265 */ /* There is room on the queue, so add the msg. We need to check for room here even if the msg ends up being short-cutted to the receiver (via td_ptr->MESSAGE) in case msg_receive needs to enqueue the msg. */ if (msgq_ptr->TYPE == MSG_QUEUE) { /* THIS MESSAGE QUEUE IS ATTACHED TO A TASK */ /* check for pending receive ** if a receive is pending then satisfy the request ** and add the receiving task onto the ready-to-run queue */ td_ptr = msgq_ptr->TD_PTR; state = td_ptr->STATE & STATE_MASK; if ( (state == RCV_ANY_BLOCKED) || ((state == RCV_SPECIFIC_BLOCKED) && (td_ptr->INFO == queue))) { /* The task is blocked, waiting for a message */ td_ptr->MESSAGE = &imsg_ptr->MESSAGE; imsg_ptr->TD_PTR = td_ptr; _TIME_DEQUEUE(td_ptr,kernel_data); _TASK_READY(td_ptr,kernel_data); /* Now run the notification function */ if (msgq_ptr->NOTIFICATION_FUNCTION != NULL) { (*msgq_ptr->NOTIFICATION_FUNCTION)(msgq_ptr->NOTIFICATION_FUNCTION_PARAMETER); } /* Endif */ if (blocking) { if ( ! kernel_data->IN_ISR) { td_ptr = kernel_data->ACTIVE_PTR; td_ptr->STATE = SEND_BLOCKED; _task_block(); } /* Endif */ } else { /* ** if the highest priority ready task is not the ** same priority as the sending task, then a higher ** priority task was made ready and it has to be allowed ** to run. */ _CHECK_RUN_SCHEDULER(); /* Let a higher priority task run */ } /* Endif */ } else { /* The task is ready to run and pre-empted OR blocked and ** on a different queue. */ /* Start CR 2191 */ swapped_msg = FALSE; /* End CR 2191 */ if ((msg_ptr->CONTROL & MSG_PRIORITY_MASK) && (td_ptr->MESSAGE != NULL)) { /* Check the message in the TD */ tmp_msg_ptr = (MESSAGE_HEADER_STRUCT_PTR)td_ptr->MESSAGE; if ( (msg_ptr->CONTROL & MSG_HDR_URGENT) || /* Urgent messages first */ ( (! (tmp_msg_ptr->CONTROL & MSG_HDR_URGENT)) && /* Start CR 621 */ ( (_mqx_uint)(tmp_msg_ptr->CONTROL & MSG_HDR_PRIORITY_MASK) < (_mqx_uint)(msg_ptr->CONTROL & MSG_HDR_PRIORITY_MASK)) /* End CR 621 */ ) ) /* Higher priority messages first */ { /* Put new message into TD */ td_ptr->MESSAGE = msg_ptr; /* Start CR 2193 */ /* Set the new message's ownership to the receiving queue's TD */ imsg_ptr = GET_INTERNAL_MESSAGE_PTR(msg_ptr); imsg_ptr->TD_PTR = td_ptr; /* Old message which we pulled from TD, need to add to queue, below */ /* End CR 2193 */ msg_ptr = tmp_msg_ptr; imsg_ptr = GET_INTERNAL_MESSAGE_PTR(msg_ptr); /* Don't know the sender's TD for the swapped out msg, so set it to NULL; */ imsg_ptr->TD_PTR = NULL; /* Start CR 2191 */ /* Indicate that a swap occurred */ swapped_msg = TRUE; /* Set the queue to the swapped msg's queue. */ if (target_qid != msg_ptr->TARGET_QID) { queue = QUEUE_FROM_QID(msg_ptr->TARGET_QID); msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue]; /* This msg's queue was not full when it was short-cut, so we should not get here. Check anyway. */ if ((msgq_ptr->MAX_ENTRIES != 0) && (msgq_ptr->NO_OF_ENTRIES >= msgq_ptr->MAX_ENTRIES)) { /* Queue full, error */ _INT_ENABLE(); _msg_free(msg_ptr); _task_set_error(MSGQ_QUEUE_FULL); return FALSE; } /* Endif */ } /* Endif */ } /* Endif */ } /* Endif */ /* add the message */ _msgq_insert_message_internal(msgq_ptr, imsg_ptr, swapped_msg); if (msgq_ptr->TD_PTR){ ++(msgq_ptr->TD_PTR->MESSAGES_AVAILABLE); } /* Endif */ /* Now run the notification function */ if (msgq_ptr->NOTIFICATION_FUNCTION != NULL) { (*msgq_ptr->NOTIFICATION_FUNCTION)(msgq_ptr->NOTIFICATION_FUNCTION_PARAMETER); } /* Endif */ if (blocking && ! kernel_data->IN_ISR ) { td_ptr = kernel_data->ACTIVE_PTR; td_ptr->STATE = SEND_BLOCKED; _task_block(); } /* Endif */ } /* Endif */ } else { /* THIS IS A SYSTEM QUEUE NOT ATTACHED TO A TASK */ /* add the message to the queue */ _msgq_insert_message_internal(msgq_ptr, imsg_ptr, FALSE); /* Run the notification function. */ if ( msgq_ptr->NOTIFICATION_FUNCTION != NULL ) { (*msgq_ptr->NOTIFICATION_FUNCTION)(msgq_ptr->NOTIFICATION_FUNCTION_PARAMETER); } /* Endif */ } /* Endif */ } else { /* Queue full, error */ _INT_ENABLE(); _task_set_error(MSGQ_QUEUE_FULL); _msg_free(&imsg_ptr->MESSAGE); return FALSE; } /* Endif */ _INT_ENABLE(); return TRUE; /* Message sent 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 */
MESSAGE_HEADER_STRUCT_PTR _msgq_receive_internal ( /* [IN] id of the queue from which a message is to be received */ _queue_id queue_id, /* [IN] indication of the number of ticks which can expire before ** this request times out */ MQX_TICK_STRUCT_PTR timeout_tick_ptr, /* [IN] relative or absolute time specified in tick_ptr */ _mqx_uint mode, /* [OUT] where the error code is to be stored */ _mqx_uint_ptr error_ptr ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; MSG_COMPONENT_STRUCT_PTR msg_component_ptr; register TD_STRUCT_PTR td_ptr; MESSAGE_HEADER_STRUCT_PTR message_ptr; register INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr; register MSGQ_STRUCT_PTR msgq_ptr; _queue_number queue; *error_ptr = MQX_OK; _GET_KERNEL_DATA(kernel_data); #if MQX_CHECK_ERRORS if (kernel_data->IN_ISR) { _task_set_error(MQX_CANNOT_CALL_FUNCTION_FROM_ISR); *error_ptr = MQX_CANNOT_CALL_FUNCTION_FROM_ISR; return(NULL); }/* Endif */ #endif 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); *error_ptr = MQX_COMPONENT_DOES_NOT_EXIST; return(NULL); } /* Endif */ #endif message_ptr = NULL; td_ptr = kernel_data->ACTIVE_PTR; if (queue_id == MSGQ_ANY_QUEUE){ /* if queue_id is 0 than a receive from any queue is performed */ /* Does the task own a queue */ if (td_ptr->MSG_QUEUE_HEAD == NULL){ /* Does NOT */ _task_set_error(MSGQ_QUEUE_IS_NOT_OPEN); *error_ptr = MSGQ_QUEUE_IS_NOT_OPEN; return NULL; } /* Endif */ _INT_DISABLE(); if (td_ptr->MESSAGES_AVAILABLE == 0){ td_ptr->STATE = RCV_ANY_BLOCKED; td_ptr->INFO = queue_id; td_ptr->MESSAGE = NULL; if (mode == MSG_TIMEOUT_NONE) { _task_block(); } else if (mode == MSG_TIMEOUT_RELATIVE) { _time_delay_for(timeout_tick_ptr); } else { _time_delay_until(timeout_tick_ptr); } /* Endif */ /* ** SHORT CUT... ** The message send routine does not queue up a message in this case. ** the message is deposited directly into the task descriptor */ message_ptr = (MESSAGE_HEADER_STRUCT_PTR)td_ptr->MESSAGE; if (message_ptr == NULL){ /* A timeout has occurred */ #if MQXCFG_ENABLE_MSG_TIMEOUT_ERROR _task_set_error(MSGQ_MESSAGE_NOT_AVAILABLE); #endif } /* Endif */ td_ptr->MESSAGE = NULL; } else { /* Check all queues for an available entry .. There must be at least ** one entry available */ msgq_ptr = (MSGQ_STRUCT_PTR)td_ptr->MSG_QUEUE_HEAD; while (msgq_ptr != NULL){ if (msgq_ptr->NO_OF_ENTRIES){ /* dequeue the top entry */ DEQUEUE_TOP_MSG_ENTRY(msgq_ptr, imsg_ptr, message_ptr, td_ptr); break; } /* Endif */ msgq_ptr = msgq_ptr->NEXT_MSGQ_PTR; } /* Endwhile */ } /* Endif */ } else { /* RECEIVE from a specific qid */ 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(MSGQ_INVALID_QUEUE_ID); *error_ptr = MSGQ_INVALID_QUEUE_ID; return (pointer)message_ptr; } /* Endif */ #endif msgq_ptr = &msg_component_ptr->MSGQS_PTR[queue]; #if MQX_CHECK_ERRORS if ( msgq_ptr->QUEUE != queue ) { _task_set_error(MSGQ_QUEUE_IS_NOT_OPEN); *error_ptr = MSGQ_QUEUE_IS_NOT_OPEN; return message_ptr; } /* Endif */ if ( (msgq_ptr->TD_PTR != NULL) && (msgq_ptr->TD_PTR != td_ptr) ) { _task_set_error(MSGQ_NOT_QUEUE_OWNER); *error_ptr = MSGQ_NOT_QUEUE_OWNER; return message_ptr; } /* Endif */ #endif /* ** check the specified queue for an entry ** if not entry, then block until an entry is received or ** timeout occurs */ _INT_DISABLE(); if (msgq_ptr->NO_OF_ENTRIES == 0) { if (msgq_ptr->TD_PTR == NULL) { /* A system message queue, indicate none available */ message_ptr = NULL; } else { td_ptr->STATE = RCV_SPECIFIC_BLOCKED; td_ptr->INFO = queue; td_ptr->MESSAGE = NULL; if (mode == MSG_TIMEOUT_NONE) { _task_block(); } else if (mode == MSG_TIMEOUT_RELATIVE) { _time_delay_for(timeout_tick_ptr); } else { _time_delay_until(timeout_tick_ptr); } /* Endif */ message_ptr = (MESSAGE_HEADER_STRUCT_PTR)td_ptr->MESSAGE; if ( message_ptr == NULL ) { #if MQXCFG_ENABLE_MSG_TIMEOUT_ERROR _task_set_error(MSGQ_MESSAGE_NOT_AVAILABLE); #endif } else if ((message_ptr->TARGET_QID != queue_id) && (msgq_ptr->NO_OF_ENTRIES > 0)) { /* The original msg was swapped out in msgq_sendi() for a higher priority msg with a different target_qid. Enqueue this msg, and then dequeue the msg we need. */ register MSGQ_STRUCT_PTR tmp_msgq_ptr; register _queue_number tmp_queue; /* Get the msg's queue */ tmp_queue = QUEUE_FROM_QID(message_ptr->TARGET_QID); tmp_msgq_ptr = &msg_component_ptr->MSGQS_PTR[tmp_queue]; if ((tmp_msgq_ptr->MAX_ENTRIES == 0) || (tmp_msgq_ptr->NO_OF_ENTRIES < tmp_msgq_ptr->MAX_ENTRIES)) { /* the msg's queue has room */ imsg_ptr = GET_INTERNAL_MESSAGE_PTR(message_ptr); #if MQX_CHECK_ERRORS if (imsg_ptr->VALID != MSG_VALID){ /* An invalid message was input by the application. */ _task_set_error(MSGQ_INVALID_MESSAGE); message_ptr = NULL; } else #endif { /* enqueue the msg */ _msgq_insert_message_internal(tmp_msgq_ptr, imsg_ptr, TRUE); if (tmp_msgq_ptr->TD_PTR) { ++(tmp_msgq_ptr->TD_PTR->MESSAGES_AVAILABLE); } /* Endif */ /* now dequeue our queue's top entry */ DEQUEUE_TOP_MSG_ENTRY(msgq_ptr, imsg_ptr, message_ptr, td_ptr); } } else { /* Queue full, error - this should not happen since msgq_sendi() checks for room on the queue for all msgs, including short-cut msgs. */ _task_set_error(MSGQ_QUEUE_FULL); message_ptr = NULL; } } /* Endif */ td_ptr->MESSAGE = NULL; } /* Endif */ } else { /* dequeue the top entry */ DEQUEUE_TOP_MSG_ENTRY(msgq_ptr, imsg_ptr, message_ptr, td_ptr); } /* Endif */ } /* Endif */ _INT_ENABLE(); return message_ptr; } /* Endbody */