This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C1294NCPDT: EMAC0: Unsolicited UDP messages

Part Number: TM4C1294NCPDT

I have a question about how to properly call an unsolicited UDP message to transmit while using the lwip stack. 

I've read where the lwip stack should only be called using interrupts.  All of the examples I've looked through show what look to be solicited messages meaning a Receive followed by a Transmit. (i.e. synchronized with the SysTick() Interrupt) 

The operation I'm trying to implement is one where the application transmits ~ ever 4ms so the messages will be unsolicited.  The messages could occur during the SysTick() Interrupt of the lwip stack or it could be on another interrupt.    My question deals with properly calling one of these transmit operations using the lwip stack. 

I have something working but I'm not sure it's done correctly. (i.e. entering lwip through the interrupt stack).  

I'm using the udp_sendto() routine.  This code is extremely difficult to determine how it operates so I can't tell if this routine is actually setting a flag such that the next time the lwipEtherNetIntHandler() is called it will see a Transmit operation or it's causing the transmission to occur during the routine.   

Here is a dumbed down version of the code that I have working.  I'm not getting any errors but I don't think this error will tell me if the lwip stack was used correctly.  Can you tell me if I need to do anything special to ensure the transmission operation is utilizing the lwip stack correctly? (Hope this makes senses)

void Transmit_Dummy(void)

{

#define DUMMY_BUFFER_SIZE 38

struct pbuf *pTransmitBuffer;

uint32_t Dummy[DUMMY_BUFFER_SIZE];

volatile unsigned int ErrCode;

uint32_t DataSize;

DataSize = DUMMY_BUFFER_SIZE << 2;

//Allocate the pTransmitBuffer Size

pTransmitBuffer = pbuf_alloc(PBUF_TRANSPORT,DataSize,PBUF_RAM);

Dummy[0]=0x002CA800;

Dummy[1]=0x2C9A002C;

Dummy[3]=0x06002CA2;

Dummy[4]=0x002C1E00;

Dummy[5]=0x2AEC002A;

Dummy[6]=0xF4002A98;

Dummy[7]=0x0004FE00;

Dummy[8]=0x04FA002C;

Dummy[9]=0xF2002C9C;

Dummy[10]=0x002CE000;

Dummy[11]=0x2CFC002C;

Dummy[12]=0xD6002C0A;

Dummy[13]=0x002D6000;

Dummy[14]=0x2CC8002D;

Dummy[15]=0x2E002978;

Dummy[16]=0x0028D400;

Dummy[17]=0x34380029;

Dummy[18]=0xE4002A1C;

Dummy[19]=0x002A1C00;

Dummy[20]=0x29E40034;

Dummy[21]=0x380028D2;

Dummy[22]=0x00297800;

Dummy[23]=0x2CCC002C;

Dummy[24]=0x8E002CD0;

Dummy[25]=0x0005F400;

Dummy[26]=0x05FC002C;

Dummy[27]=0x48002EAE;

Dummy[28]=0x002AF200;

Dummy[29]=0x2B080029;

Dummy[30]=0xAC0028D8;

Dummy[31]=0x0028D800;

Dummy[32]=0x28AC002A;

Dummy[33]=0x08002AF2;

Dummy[34]=0x002EAE00;

Dummy[35]=0x0000002C;

Dummy[36]=0xE2002C04;

Dummy[37]=0x45444342;

//Copy the data to the payload

memcpy(pTransmitBuffer->payload, &Dummy[0],DataSize);

ErrCode = udp_sendto(pcb2, pTransmitBuffer,(ip_addr_t *)&g_ui32RemoteIPAddress,g_ui16RemotePort);

printf("\nErrorCode = ");

printf("%i\n",ErrCode);

printf("IPAddress = ");

DisplayIPAddress(g_ui32RemoteIPAddress);

printf("\nPort = ");

printf("%i",g_ui16RemotePort);

pbuf_free(pTransmitBuffer);

 

Thanks for your help,

 

Joe

  • Hi Joe,

      udp_sendto is the right API to transmit udp data. Did you have a chance to use the wireshark to see what you are transmitting on the network and if the node you are sending data to is receiving the data. If the receiving node is receiving the data then I think the LwIP stack has properly handled your transmission. 

      Here is a post that you might have looked at. Hope it will help you too. 

    https://e2e.ti.com/support/microcontrollers/other/f/908/t/723207

  • Hi Charles,

    I am using the socat tool and I was able to verify that the messages are being received correctly.  I'll take a look at that recommended post you are suggesting and see if they have a similar question but I've already done some digging and couldn't find anything.   I think if I knew more about when the actual transmission occurs, this would help in my understanding.

    Do you know if during one of those udp_send() routines it's setting a flag such that the transmission occurs during a SysTick or it's forced inside that routine?

    Thanks for the help,

    JC

  • Hi Joe,

      My understanding is that the LwIP transmission and callback functions are handled via the periodic timer. 

  • Hi Charles,

    I ran a test where I used a combination of 3 different break points.  My first Breakpoint was set on the line of code that calls the udp_sendto() command.  (Below is that snippet).  Once that breakpoint was hit, it was disabled and I set 2 other breakpoints.  One was set at the line of code just below the call to the udp_sendto() call and the other was inside the SysTick() Interrupt routine.  I was also using the socat - upd-listen:<port> command, to see when the transmission popped up.

    //Copy the data to the payload

    memcpy(pTransmitBuffer->payload, &Dummy[0],DataSize);

    ErrCode = udp_sendto(pcb2, pTransmitBuffer,(ip_addr_t *)&g_ui32RemoteIPAddress,g_ui16RemotePort);

    printf("\nErrorCode = ");

    printf("%i\n",ErrCode);

    What I expected to see was this once I started the operation.

    1.  Breakpoint inside the SysTick() is hit.

    2.  Continue to run the code.

    3.  Transmission

    4.  Break point is hit at the printf routine just below the udp_sendto() routine.

    What I saw was:

    1.  Transmission

    2.   Break point is hit at the printf routine just below the udp_sendto() routine.

    3.  Continue to run the code.

    4.  Breakpoint inside the SysTick() was hit.

    I ran this a number of times and it was the same operation.  It looks like the transmission occurs on-demand and independent of the normal entry of the lwip stack which seem to violate what is described as the correct use of the stack. 

    I've only seen one code example where the transmission is unsolicited and I didn't see anything that would indicate either a forced Interrupt on the EMAC0.  In other words, the code was similar to what I sent you. 

    Would you recommend disabling interrupts during the transmission?

    Thanks,

    Joe

  • Hi Joe,

      Please avoid using printf as it is a CIO that takes a lot of cycles to execute. The way the printf is implemented is utilizing the CPU's breakpoint. This will impact your real-time operation. See this wiki page for more details.  http://processors.wiki.ti.com/index.php/Tips_for_using_printf

      I will suggest you UARTprintf() instead. If you refer to the hello example in <TivaWare_Installation>/examples/ek-tim41294x/hello you can refer how to use the UARTprintf(). 

      I hope this post will be also helpful. 

    https://e2e.ti.com/support/microcontrollers/other/f/908/t/319674?Optimizing-UDP-in-lwIP-on-TIVA-how-to-determine-when-a-packet-has-been-sent-

  • Hi Joe,

      I have not heard back from you. I hope by removing the printf will make a difference in your result and also hope you had a chance to read about the impacts of using printf in the mentioned link. I will close this thread for now. If the issue is not resolved you can just write back to this thread again.

  • The printf wasn't really relevant to the questions but I think I found what I was looking for.  I found that the lwip stack is entered correctly using the Sys_Tick() interrupt and the EMAC0 interrupt.  When the udp_sendto() operation is called, it was unclear how the lwip stack was being utilized during this operation.  Buried way down deep in the code somewhere, I found the interrupt for the EMAC0 is being set which is allowing my "on-demand" transmission to be sent through the lwip stack.  Based on my knowledge of how the EMAC0 works and other posts I've seen, I have masked the other active interrupts before the udp_sendto() operation is started and unmasked them after the transmission is complete so the transmission is not interrupted mid message.  I still need to do additional testing but so far, the changes I made are working correctly and operating at the speed I was looking for.

    Thanks,

    Joe