How to ENET driver under MQX?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to ENET driver under MQX?

Jump to solution
1,397 Views
cencongsu
Contributor I

I used MQX4.2 for our product. And I need to transmit/receive raw Ethernet frame(start from MAC address), I read the ENET driver under /io/enet  and get so confused and don't know how to use the API, eg, ENET_send, ENET_find_receiver.  

And I can't find a document explaining these API on website, is it possible that someone can help me with this issue?

0 Kudos
Reply
1 Solution
883 Views
EAI
Contributor IV

Assume you wanted to send and receive a given packet type(say profinet type 0x8892) on Ethernet. This can be done with the Ethernet driver in MQX as follows:

Initialize the Ethernet driver as you would for use with RTCS. Obtain the Ethernet driver handle by calling ENET_get_device_handle(devno). 
 

Open the Ethernet driver for Profinet packets as follows:  ENET_open(device_handle, 0x8892, profinetRxCallback, callbackDataPtr); ); callbackDataPtr points to some memory where you can store data needed for the callback function. If your callback function does not need data, callbackDataPtr can be NULL.

Now, when a packet of type 0x8892is received by the Ethernet driver, the driver will call your callback as follows:  profinetRxCallback(pcb_ptr, callbackDataPtr)

The callback runs from within the ethernet ISR, so it should enqueue the pcb on a queue and wake up a task to service the pcb. 
The pcb contains a pointer to the message (pcb->FRAG[0].FRAGMENT) and the message length (pcb->FRAG[0].LENGTH). 
When done processing the message, call PCB_free(pcb) to return the PCB. 
 

To send a packet, you have to create a pcb_alloc function and a pcb_free function. A sample alloc function:

The pcb_alloc function might look like:

PCB_PTR myPcbAlloc(void)

{

   PCB_PTR pcb;

   uint8_t * frame;

   pcb = _mem_alloc_system(sizeof(*pcb));

   frame = _mem_alloc_system(MAX_PROFINET_PACKET_SIZE);

   pcb->FREE = myPcbFree;

   pcb->FRAG[0].LENGTH =  MAX_PROFINET_PACKET_SIZE;

   pcb->FRAG[0].FRAGMENT = frame;

   pcb->FRAG[1].LENGTH   = 0;

   pcb->FRAG[1].FRAGMENT = 0;

  

   return pcb;

}

And the free function would be:

void myPcbFree(PCB_PTR pcb)

{

   _mem_free(pcb->FRAG[0].FRAGMENT);

   _mem_free(pcb);

}

You would want to add error checking to these functions.

To send a packet, allocate a pcb, fill in the packet data, and call either ENET_send or ENET_send_raw. If you call ENET_send_raw, you are responsible for constructing the Ethernet header in the packet buffer. If you call ENET_send, the header will be constructed for you – but you still need to leave space in the packet buffer for the header.

View solution in original post

0 Kudos
Reply
2 Replies
884 Views
EAI
Contributor IV

Assume you wanted to send and receive a given packet type(say profinet type 0x8892) on Ethernet. This can be done with the Ethernet driver in MQX as follows:

Initialize the Ethernet driver as you would for use with RTCS. Obtain the Ethernet driver handle by calling ENET_get_device_handle(devno). 
 

Open the Ethernet driver for Profinet packets as follows:  ENET_open(device_handle, 0x8892, profinetRxCallback, callbackDataPtr); ); callbackDataPtr points to some memory where you can store data needed for the callback function. If your callback function does not need data, callbackDataPtr can be NULL.

Now, when a packet of type 0x8892is received by the Ethernet driver, the driver will call your callback as follows:  profinetRxCallback(pcb_ptr, callbackDataPtr)

The callback runs from within the ethernet ISR, so it should enqueue the pcb on a queue and wake up a task to service the pcb. 
The pcb contains a pointer to the message (pcb->FRAG[0].FRAGMENT) and the message length (pcb->FRAG[0].LENGTH). 
When done processing the message, call PCB_free(pcb) to return the PCB. 
 

To send a packet, you have to create a pcb_alloc function and a pcb_free function. A sample alloc function:

The pcb_alloc function might look like:

PCB_PTR myPcbAlloc(void)

{

   PCB_PTR pcb;

   uint8_t * frame;

   pcb = _mem_alloc_system(sizeof(*pcb));

   frame = _mem_alloc_system(MAX_PROFINET_PACKET_SIZE);

   pcb->FREE = myPcbFree;

   pcb->FRAG[0].LENGTH =  MAX_PROFINET_PACKET_SIZE;

   pcb->FRAG[0].FRAGMENT = frame;

   pcb->FRAG[1].LENGTH   = 0;

   pcb->FRAG[1].FRAGMENT = 0;

  

   return pcb;

}

And the free function would be:

void myPcbFree(PCB_PTR pcb)

{

   _mem_free(pcb->FRAG[0].FRAGMENT);

   _mem_free(pcb);

}

You would want to add error checking to these functions.

To send a packet, allocate a pcb, fill in the packet data, and call either ENET_send or ENET_send_raw. If you call ENET_send_raw, you are responsible for constructing the Ethernet header in the packet buffer. If you call ENET_send, the header will be constructed for you – but you still need to leave space in the packet buffer for the header.

0 Kudos
Reply
883 Views
soledad
NXP Employee
NXP Employee

Hello,

Unfortunately MQX APIs does not support raw sockets. However you can modify the library according your needs. You should look inside RTCS stack the way it works with network interfaces, or to inside ENET driver.

I would like to recommend look at MACNET_RX_ISR interrupt routine in macnet_receive.c file.

This is place where we receive interrupt from ENET module and we can start with processing of such data (like check of MAC address and verification of CRC)

Unfortunately, any change on the MQX or any library as RTCS is out of the free support scope.

Please check the below thread this may helps,

Sending data using "Raw Ethernet"

Have a great day,
Sol

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply