/*! * \brief Tests all the periodic queues and their lightweight timers for * validity and consistency. * * \param[out] period_error_ptr Pointer to the first periodic queue that has * an error (NULL if no error is found). * \param[out] timer_error_ptr Pointer to the first timer that has an error * (NULL if no error is found). * * \return MQX_OK (No periodic queues have been created or no errors found * in any periodic queues or timers.) * \return MQX_LWTIMER_INVALID (Period_ptr points to an invalid periodic queue.) * \return Error from _queue_test() (A periodic queue or its queue was in error.) * * \see _lwtimer_add_timer_to_queue * \see _lwtimer_cancel_period * \see _lwtimer_cancel_timer * \see _lwtimer_create_periodic_queue */ _mqx_uint _lwtimer_test ( void **period_error_ptr, void **timer_error_ptr ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; LWTIMER_STRUCT_PTR timer_ptr; LWTIMER_PERIOD_STRUCT_PTR period_ptr; _mqx_uint result; _GET_KERNEL_DATA(kernel_data); _KLOGE3(KLOG_lwtimer_test, period_error_ptr, timer_error_ptr); *period_error_ptr = NULL; *timer_error_ptr = NULL; /* * It is not considered an error if the lwtimer component has not been * created yet */ if (kernel_data->LWTIMERS.NEXT == NULL) { return (MQX_OK); } /* Endif */ result = _queue_test(&kernel_data->LWTIMERS, period_error_ptr); if (result != MQX_OK) { _KLOGX3(KLOG_lwtimer_test, result, *period_error_ptr); return (result); } /* Endif */ _int_disable(); period_ptr = (void *) kernel_data->LWTIMERS.NEXT; while ((void *) period_ptr != (void *) &kernel_data->LWTIMERS) { if (period_ptr->VALID != LWTIMER_VALID) { _int_enable(); *period_error_ptr = period_ptr; _KLOGX3(KLOG_lwtimer_test, MQX_LWTIMER_INVALID, period_ptr); return (MQX_LWTIMER_INVALID); } /* Endif */ result = _queue_test(&period_ptr->TIMERS, timer_error_ptr); if (result != MQX_OK) { _int_enable(); *period_error_ptr = period_ptr; _KLOGX4(KLOG_lwtimer_test, result, *period_error_ptr, *timer_error_ptr); return (result); } /* Endif */ timer_ptr = (void *) period_ptr->TIMERS.NEXT; while (timer_ptr != (void *) &period_ptr->TIMERS) { if (timer_ptr->VALID != LWTIMER_VALID) { *period_error_ptr = period_ptr; *timer_error_ptr = timer_ptr; _KLOGX4(KLOG_lwtimer_test, MQX_LWTIMER_INVALID, period_ptr, timer_ptr); return (MQX_LWTIMER_INVALID); } /* Endif */ timer_ptr = (void *) timer_ptr->LINK.NEXT; } /* Endwhile */ period_ptr = (void *) period_ptr->LINK.NEXT; } /* Endwhile */ _int_enable(); _KLOGX2(KLOG_lwtimer_test, MQX_OK); return (MQX_OK); } /* Endbody */
/*! * \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); }
uint32_t ENET_send ( /* [IN] the Ethernet state structure */ _enet_handle handle, /* [IN] the packet to send */ PCB_PTR packet, /* [IN] the protocol */ uint16_t type, /* [IN] the destination Ethernet address */ _enet_address dest, /* [IN] optional flags, zero = default */ uint32_t flags ) { ENET_CONTEXT_STRUCT_PTR enet_ptr = (ENET_CONTEXT_STRUCT_PTR)handle; ENET_HEADER_PTR packet_ptr; unsigned char *type_ptr; PCB_FRAGMENT_PTR frag_ptr; uint32_t swhdr, size, frags; uint32_t error; _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data); _KLOGM(_GET_KERNEL_DATA(kernel_data)); _KLOGE6(KLOG_ENET_send, handle, packet, type, dest, flags); if (flags & ENET_OPT_8021QTAG) { swhdr = ENET_FRAMESIZE_HEAD_VLAN; } else { swhdr = ENET_FRAMESIZE_HEAD; } /* ** Make sure the first fragment is long enough for the Ethernet ** frame header. This isn't strictly necessary, but it's impractical ** to split a 14-26 byte header over multiple fragments. */ #if MQX_CHECK_ERRORS if (packet->FRAG[0].LENGTH < swhdr) { ENET_INC_STATS(COMMON.ST_TX_DISCARDED); error = ENETERR_SEND_SHORT; goto ERROR; } #endif /* ** Make sure that no fragment exceeds a maximum packet length. ** We check every fragment because we want to prevent something ** like FRAG[0].LENGTH = 2000, FRAG[1].LENGTH = -1000. This ** situation would not be detected if we only check the total ** length. */ size = frags = 0; for (frag_ptr = packet->FRAG; frag_ptr->LENGTH; frag_ptr++) { #if MQX_CHECK_ERRORS if (frag_ptr->LENGTH > enet_ptr->MaxTxFrameSize) { ENET_INC_STATS(COMMON.ST_TX_DISCARDED); error = ENETERR_SEND_LONG; goto ERROR; } #endif size += frag_ptr->LENGTH; frags++; } /* ** Make sure that the total sum of the fragments doesn't exceed ** a maximum packet length. */ #if MQX_CHECK_ERRORS if (size > enet_ptr->MaxTxFrameSize) { ENET_INC_STATS(COMMON.ST_TX_DISCARDED); error = ENETERR_SEND_LONG; goto ERROR; } #endif /* ** Everything checks out -- fill in the header. */ packet_ptr = (ENET_HEADER_PTR)packet->FRAG[0].FRAGMENT; htone(packet_ptr->DEST, dest); htone(packet_ptr->SOURCE, enet_ptr->ADDRESS); type_ptr = packet_ptr->TYPE; if (flags & ENET_OPT_8021QTAG) { ENET_8021QTAG_HEADER_PTR tag_ptr = (ENET_8021QTAG_HEADER_PTR)(type_ptr+2); uint16_t tag; tag = ENET_GETOPT_8021QPRIO(flags) << 13; mqx_htons(type_ptr, ENETPROT_8021Q); mqx_htons(tag_ptr->TAG, tag); type_ptr = tag_ptr->TYPE; } if (flags & ENET_OPT_8023) { ENET_8022_HEADER_PTR llc_ptr = (ENET_8022_HEADER_PTR)(type_ptr+2); (void)mqx_htons(type_ptr, size - swhdr); mqx_htonc(llc_ptr->DSAP, 0xAA); mqx_htonc(llc_ptr->SSAP, 0xAA); mqx_htonc(llc_ptr->COMMAND, 0x03); mqx_htonc(&llc_ptr->OUI[0], 0x00); mqx_htonc(&llc_ptr->OUI[1], 0x00); mqx_htonc(&llc_ptr->OUI[2], 0x00); type_ptr = llc_ptr->TYPE; } mqx_htons(type_ptr, type); /* ** This function can be called from any context, and it needs mutual ** exclusion with itself, and with ENET_ISR(). */ ENET_lock_context(enet_ptr); error = (*enet_ptr->PARAM_PTR->ENET_IF->MAC_IF->SEND)(handle, packet, size, frags, flags); ENET_unlock_context(enet_ptr); if (error) { ERROR: PCB_free(packet); } _KLOGX4(KLOG_ENET_send, handle, packet, error); return error; }
/*! * \brief Tests all the message poolsin the system for consistency and validity. * * The function checks the validity of each message in each private and system * message pool. It reports the first error that it finds. * * \param[out] pool_error_ptr (Initialized only if an error is found.) If the * message in a message pool has an error; one of the following: * \li A pointer to a pool ID if the message is from a private message pool. * \li A pointer to a system message pool if the message is from a system * message pool. * \param[out] msg_error_ptr Pointer to the message that has an error * (initialized only if an error is found). * * \return MQX_OK (all messages in all message pools passed) * \return MQX_COMPONENT_DOES_NOT_EXIST (Message component is not created.) * \return MSGQ_INVALID_MESSAGE (At least one message in at least one message * pool failed.) * * \warning Disables and enables interrupts. * * \see _msgpool_create * \see _msgpool_create_system */ _mqx_uint _msgpool_test ( void **pool_error_ptr, void **msg_error_ptr ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; MSG_COMPONENT_STRUCT_PTR msg_component_ptr; MSGPOOL_STRUCT_PTR msgpool_ptr; MSGPOOL_BLOCK_STRUCT_PTR msgpool_block_ptr; INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr; _mqx_uint i,j,raw_message_size; _GET_KERNEL_DATA(kernel_data); _KLOGE3(KLOG_msgpool_test, pool_error_ptr, msg_error_ptr); msg_component_ptr = _GET_MSG_COMPONENT_STRUCT_PTR(kernel_data); #if MQX_CHECK_ERRORS if (msg_component_ptr == NULL) { _KLOGX2(KLOG_msgpool_test, MQX_COMPONENT_DOES_NOT_EXIST); return(MQX_COMPONENT_DOES_NOT_EXIST); } /* Endif */ #endif /* Check all the message pools */ msgpool_ptr = msg_component_ptr->MSGPOOLS_PTR; i = msg_component_ptr->MAX_MSGPOOLS + 1; while (--i) { _int_disable(); if (msgpool_ptr->VALID == MSG_VALID) { /* The pool has been created */ /* Search through all of the message pool blocks for this pool */ msgpool_block_ptr = msgpool_ptr->MSGPOOL_BLOCK_PTR; while (msgpool_block_ptr != NULL) { raw_message_size = msgpool_block_ptr->RAW_MESSAGE_SIZE; imsg_ptr = (INTERNAL_MESSAGE_STRUCT_PTR) msgpool_block_ptr->FIRST_IMSG_PTR; j = msgpool_block_ptr->NUM_MESSAGES + 1; while (--j) { if ((imsg_ptr->VALID != MSG_VALID) || (imsg_ptr->MSGPOOL_PTR != msgpool_ptr)) { _int_enable(); *pool_error_ptr = msgpool_ptr; *msg_error_ptr = imsg_ptr; _KLOGX4(KLOG_msgpool_test, MSGQ_INVALID_MESSAGE, msgpool_ptr, imsg_ptr); return(MSGQ_INVALID_MESSAGE); } /* Endif */ imsg_ptr =(INTERNAL_MESSAGE_STRUCT_PTR) ((unsigned char *)imsg_ptr + raw_message_size); } /* Endwhile */ msgpool_block_ptr = msgpool_block_ptr->NEXT_BLOCK_PTR; } /* Endwhile */ } /* Endif */ _int_enable(); msgpool_ptr++; } /* Endwhile */ _KLOGX2(KLOG_msgpool_test, MQX_OK); return(MQX_OK); } /* Endbody */
_mqx_uint _lwsem_test ( /* [OUT] the light weight semapohre in error */ pointer _PTR_ lwsem_error_ptr, /* [OUT] the td on a light weight semaphore in error */ pointer _PTR_ td_error_ptr ) { /* Body */ KERNEL_DATA_STRUCT_PTR kernel_data; LWSEM_STRUCT_PTR sem_ptr; _mqx_uint queue_size; _mqx_uint result; _GET_KERNEL_DATA(kernel_data); _KLOGE3(KLOG_lwsem_test, lwsem_error_ptr, td_error_ptr); *td_error_ptr = NULL; *lwsem_error_ptr = NULL; #if MQX_CHECK_ERRORS if (kernel_data->IN_ISR) { _KLOGX2(KLOG_lwsem_test, MQX_CANNOT_CALL_FUNCTION_FROM_ISR); return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR); }/* Endif */ #endif _int_disable(); result = _queue_test((QUEUE_STRUCT_PTR)&kernel_data->LWSEM, lwsem_error_ptr); if (result != MQX_OK) { _KLOGX3(KLOG_lwsem_test, result, *lwsem_error_ptr); return(result); } /* Endif */ sem_ptr = (LWSEM_STRUCT_PTR)((pointer)kernel_data->LWSEM.NEXT); queue_size = _QUEUE_GET_SIZE(&kernel_data->LWSEM); while (queue_size--) { if (sem_ptr->VALID != LWSEM_VALID) { result = MQX_INVALID_LWSEM; break; } /* Endif */ result = _queue_test(&sem_ptr->TD_QUEUE, td_error_ptr); if (result != MQX_OK) { break; } /* Endif */ sem_ptr = sem_ptr->NEXT; } /* Endwhile */ _int_enable(); if (result != MQX_OK) { *lwsem_error_ptr = (pointer)sem_ptr; } /* Endif */ _KLOGX4(KLOG_lwsem_test, result, *lwsem_error_ptr, *td_error_ptr); return(result); }