/*! * \brief Used by a task to clear the specified event bits in the ligtweight event. * * \param[in] event_ptr Pointer to the event. * \param[in] bit_mask Bit mask. Each bit represents an event bit to clear. * * \return MQX_OK * \return MQX_LWEVENT_INVALID (Lightweight event is not valid.) * * \see _lwevent_create * \see _lwevent_destroy * \see _lwevent_set * \see _lwevent_set_auto_clear * \see _lwevent_test * \see _lwevent_wait_for * \see _lwevent_wait_ticks * \see _lwevent_wait_until * \see _lwevent_get_signalled * \see LWEVENT_STRUCT */ _mqx_uint _lwevent_clear ( LWEVENT_STRUCT_PTR event_ptr, _mqx_uint bit_mask ) { _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data); #if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI if (MQX_RUN_IN_USER_MODE) { return _usr_lwevent_clear(event_ptr, bit_mask); } #endif _KLOGM(_GET_KERNEL_DATA(kernel_data)); _KLOGE3(KLOG_lwevent_clear, event_ptr, bit_mask); _INT_DISABLE(); #if MQX_CHECK_VALIDITY if (event_ptr->VALID != LWEVENT_VALID) { _int_enable(); _KLOGX2(KLOG_lwevent_clear, MQX_LWEVENT_INVALID); return (MQX_LWEVENT_INVALID); } /* Endif */ #endif event_ptr->VALUE &= ~bit_mask; _INT_ENABLE(); _KLOGX2(KLOG_lwevent_clear, MQX_OK); return (MQX_OK); }
/*! * \brief Used by a task to wait for the event for the number of ticks (in tick time). * * \param[in] event_ptr Pointer to the lightweight event. * \param[in] bit_mask Bit mask. Each set bit represents an event bit to wait for. * \param[in] all TRUE (wait for all bits in bit_mask to be set), FALSE * (wait for any bit in bit_mask to be set). * \param[in] tick_ptr Pointer to the maximum number of ticks to wait for the * events to be set. If the value is NULL, then the timeout will be infinite. * * \return MQX_OK * \return LWEVENT_WAIT_TIMEOUT (The time elapsed before an event signalled.) * \return MQX_LWEVENT_INVALID (Lightweight event is no longer valid or was never * valid.) * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.) * * \see _lwevent_create * \see _lwevent_destroy * \see _lwevent_set * \see _lwevent_set_auto_clear * \see _lwevent_clear * \see _lwevent_wait_ticks * \see _lwevent_wait_until * \see _lwevent_get_signalled * \see LWEVENT_STRUCT * \see MQX_TICK_STRUCT */ _mqx_uint _lwevent_wait_for ( LWEVENT_STRUCT_PTR event_ptr, _mqx_uint bit_mask, bool all, MQX_TICK_STRUCT_PTR tick_ptr ) { _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data); _mqx_uint result; #if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI if (MQX_RUN_IN_USER_MODE) { return _usr_lwevent_wait_for(event_ptr, bit_mask, all, tick_ptr); } #endif _KLOGM(_GET_KERNEL_DATA(kernel_data)); _KLOGE5(KLOG_lwevent_wait_for, event_ptr, bit_mask, all, tick_ptr); result = _lwevent_wait_internal(event_ptr, bit_mask, all, tick_ptr, FALSE); _KLOGX2(KLOG_lwevent_wait_for, result); return (result); }
/*! * \brief Creates a system message pool. * * Tasks can subsequently allocate messages from the pool by calling * _msg_alloc_system(). * * \param[in] message_size Size (in single-addressable units) of the messages * (including the message header) to be created for the message pool. * \param[in] num_messages Initial number of messages to be created for the * message pool. * \param[in] grow_number Number of messages to be added if all the messages * are allocated. * \param[in] grow_limit If grow_number is not equal to 0; one of the following: * \li Maximum number of messages that the pool can have. * \li 0 (Unlimited growth.) * * \return TRUE (Success.) or FALSE (Failure.) * * \warning Creates the message component if it was not previously created. * \warning On failure, calls _task_set_error() to set the task error code as * described for _msgpool_create(). * * \see _msgpool_create * \see _msgpool_destroy * \see _msg_alloc_system * \see _task_set_error * \see MQX_INITIALIZATION_STRUCT */ bool _msgpool_create_system ( uint16_t message_size, uint16_t num_messages, uint16_t grow_number, uint16_t grow_limit ) { /* Body */ _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data); _pool_id ret_value; _KLOGM(_GET_KERNEL_DATA(kernel_data)); _KLOGE5(KLOG_msgpool_create_system, message_size, num_messages, grow_number, grow_limit); ret_value = _msgpool_create_internal( message_size, num_messages, grow_number, grow_limit, SYSTEM_MSG_POOL ); _KLOGX2(KLOG_msgpool_create_system, ret_value == (_pool_id)0 ); if ( ret_value == (_pool_id)0 ) { return FALSE; } else { return TRUE; } /* Endif */ } /* 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 Adds the lightweight timer to the periodic queue. * * This function inserts the timer in the queue in order of increasing offset * from the queue's start time. * * \param[in] period_ptr Pointer to the periodic queue. * \param[in] timer_ptr Pointer to the lightweight timer to add to the queue, * must be smaller than queue. * \param[in] ticks Tick offset from the timers period to expire at. * \param[in] func Function to call when the timer expires. * \param[in] parameter Parameter to pass to the function. * * \return MQX_OK * \return MQX_LWTIMER_INVALID (Period_ptr points to an invalid periodic queue.) * \return MQX_INVALID_PARAMETER (Ticks is greater than or equal to the * periodic queue's period.) * * \see _lwtimer_cancel_period * \see _lwtimer_cancel_timer * \see _lwtimer_create_periodic_queue * \see LWTIMER_PERIOD_STRUCT * \see LWTIMER_STRUCT */ _mqx_uint _lwtimer_add_timer_to_queue ( LWTIMER_PERIOD_STRUCT_PTR period_ptr, LWTIMER_STRUCT_PTR timer_ptr, _mqx_uint ticks, LWTIMER_ISR_FPTR func, void *parameter ) { /* Body */ _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data); LWTIMER_STRUCT_PTR qe_ptr; _mqx_uint i; _KLOGM(_GET_KERNEL_DATA(kernel_data)); _KLOGE4(KLOG_lwtimer_add_timer_to_queue, period_ptr, timer_ptr, ticks); #if MQX_CHECK_ERRORS if (period_ptr->VALID != LWTIMER_VALID) { _KLOGX2(KLOG_lwtimer_add_timer_to_queue, MQX_LWTIMER_INVALID); return (MQX_LWTIMER_INVALID); } /* Endif */ if (ticks >= period_ptr->PERIOD) { _KLOGX2(KLOG_lwtimer_add_timer_to_queue, MQX_INVALID_PARAMETER); return (MQX_INVALID_PARAMETER); } /* Endif */ #endif timer_ptr->TIMER_FUNCTION = func; timer_ptr->PARAMETER = parameter; timer_ptr->PERIOD_PTR = period_ptr; timer_ptr->RELATIVE_TICKS = ticks; _int_disable(); /* Insert into queue in order of increasing offset from start time */ qe_ptr = (void *) &period_ptr->TIMERS.NEXT; i = _QUEUE_GET_SIZE(&period_ptr->TIMERS) + 1; while (--i) { qe_ptr = (void *) qe_ptr->LINK.NEXT; if (qe_ptr->RELATIVE_TICKS >= ticks) { qe_ptr = (void *) qe_ptr->LINK.PREV; break; } /* Endif */ } /* Endwhile */ timer_ptr->VALID = LWTIMER_VALID; _QUEUE_INSERT(&period_ptr->TIMERS, qe_ptr, &timer_ptr->LINK); _int_enable(); _KLOGX2(KLOG_lwtimer_add_timer_to_queue, MQX_OK); return (MQX_OK); } /* Endbody */
/*! * \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 ( void *msg_ptr ) { /* Body */ _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data); register INTERNAL_MESSAGE_STRUCT_PTR imsg_ptr; register MSGPOOL_STRUCT_PTR msgpool_ptr; _KLOGM(_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 */
/*! * \brief Creates a private message pool. * * Any task can allocate messages from the pool by calling _msg_alloc() with the * pool ID. * * \param[in] message_size Size (in single-addressable units) of the messages * (including the message header) to be created for the message pool. * \param[in] num_messages Initial number of messages to be created for the * message pool. * \param[in] grow_number Number of messages to be added if all the messages * are allocated. * \param[in] grow_limit If grow_number is not equal to 0; one of the following: * \li Maximum number of messages that the pool can have. * \li 0 (Unlimited growth.) * * \return Pool ID to access the message pool (success). * \return 0 (Failure.) * * \warning Creates the message component if it was not previously created. * \warning On failure, calls _task_set_error() to set one of the following task * error codes: * \li MSGPOOL_MESSAGE_SIZE_TOO_SMALL (Message_size is less than the size of the * message header structure.) * \li MQX_OUT_OF_MEMORY (MQX cannot allocate memory to create the message pool). * \li MSGPOOL_OUT_OF_POOLS (Maximum number of message pools have been created, * where the number is defined at initialization time in MAX_MSGPOOLS in the MQX * initialization structure.) * \li Task error codes from _mem_alloc_system() * \li Task error codes from _msg_create_component() * * \see _msgpool_create_system * \see _msgpool_destroy * \see _msg_alloc * \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 _msg_create_component * \see MQX_INITIALIZATION_STRUCT */ _pool_id _msgpool_create ( uint16_t message_size, uint16_t num_messages, uint16_t grow_number, uint16_t grow_limit ) { /* Body */ _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data); _pool_id result; _KLOGM(_GET_KERNEL_DATA(kernel_data)); _KLOGE5(KLOG_msgpool_create, message_size, num_messages, grow_number, grow_limit); result = _msgpool_create_internal(message_size, num_messages, grow_number, grow_limit, MSG_POOL); _KLOGX2(KLOG_msgpool_create, result); return(result); } /* 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 */
/*! * \brief Used by a task to wait for the event for the number of ticks. * * \param[in] event_ptr Pointer to the lightweight event. * \param[in] bit_mask Bit mask. Each set bit represents an event bit to wait for. * \param[in] all TRUE (wait for all bits in bit_mask to be set), * FALSE (wait for any bit in bit_mask to be set). * \param[in] timeout_in_ticks The maximum number of ticks to wait for the events * to be set. If the value is 0, then the timeout will be infinite. * * \return MQX_OK * \return LWEVENT_WAIT_TIMEOUT (The time elapsed before an event signalled.) * \return MQX_LWEVENT_INVALID (Lightweight event is no longer valid or was never * valid.) * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.) * * \see _lwevent_create * \see _lwevent_destroy * \see _lwevent_set * \see _lwevent_set_auto_clear * \see _lwevent_clear * \see _lwevent_wait_for * \see _lwevent_wait_until * \see _lwevent_get_signalled * \see LWEVENT_STRUCT */ _mqx_uint _lwevent_wait_ticks ( LWEVENT_STRUCT_PTR event_ptr, _mqx_uint bit_mask, bool all, _mqx_uint timeout_in_ticks ) { MQX_TICK_STRUCT ticks; _KLOGM(KERNEL_DATA_STRUCT_PTR kernel_data); _mqx_uint result; #if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI if (MQX_RUN_IN_USER_MODE) { return _usr_lwevent_wait_ticks(event_ptr, bit_mask, all, timeout_in_ticks); } #endif _KLOGM(_GET_KERNEL_DATA(kernel_data)); _KLOGE5(KLOG_lwevent_wait_ticks, event_ptr, bit_mask, all, timeout_in_ticks); if (timeout_in_ticks) { ticks = _mqx_zero_tick_struct; PSP_ADD_TICKS_TO_TICK_STRUCT(&ticks, timeout_in_ticks, &ticks); result = _lwevent_wait_internal(event_ptr, bit_mask, all, &ticks, FALSE); } else { result = _lwevent_wait_internal(event_ptr, bit_mask, all, NULL, FALSE); } /* Endif */ _KLOGX2(KLOG_lwevent_wait_ticks, result); 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; }