Electronics > Microcontrollers

lwip - limiting CPU usage on STM32

(1/4) > >>

Scenario: STM32F4 with lwIP and freeRTOS

This particular device is inside a safe environment, which must never have an internet connection. Protocol errors, e.g. due to lost UDP packets, will be handled by another layer.

One weak point of this whole setup is the variable CPU load lwIP generates. Normally we have sparse UDP exchanges, one telegram every second or so. At an higher packet rate, e.g. TFTP transfers, lwIP really starts eating into the available CPU bandwidth.

What I have been looking for, but couldn't find a good answer to, is: How could we go about limitting the CPU bandwidth that lwIP may eat up?

One idea that came to my mind, is monitoring CPU load (WWDG+EWI (Early Wakeup Interrupt)) and dynamically changing the priority of / disabling the ETH Interrupt. WWDG+EWI would be rather simple to add, since the device only uses IWDG so far.

Any comments or better of the shelf solutions that I didn't find / think of?

edit 2201301639: corrected typo in headline

Can you shut off the interrupt if the lwIP buffer reaches a certain size (without cutting off a packet)?
Then the RTOS task priority should be lower, so it will not re-enable interrupt until that task has time to run and process the data.

But I guess that would need to be done within the interrupt itself.

--- Code: ---/**
 * @brief STM32F2 Ethernet MAC interrupt service routine
void ETH_IRQHandler(void)
   bool_t flag;
   uint32_t status;
   //Interrupt service routine prologue
   //This flag will be set if a higher priority task must be woken
   flag = FALSE;
   //Read DMA status register
   status = ETH->DMASR;
   //Packet transmitted?
   if((status & ETH_DMASR_TS) != 0)
      //Clear TS interrupt flag
      //Check whether the TX buffer is available for writing
      if((txCurDmaDesc->tdes0 & ETH_TDES0_OWN) == 0)
         //Notify the TCP/IP stack that the transmitter is ready to send
         flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
   //Packet received?
   if((status & ETH_DMASR_RS) != 0)
      //Clear RS interrupt flag
      //Set event flag
      nicDriverInterface->nicEvent = TRUE;
      //Notify the TCP/IP stack of the event
      flag |= osSetEventFromIsr(&netEvent);
   //Clear NIS interrupt flag
   //Interrupt service routine epilogue
--- End code ---

But how often can this interrupt occur?
I can't see it happening so much that it overtakes everything else. lwip should not be running until any higher priority tasks are finished.


--- Quote ---At an higher packet rate, e.g. TFTP transfers, lwIP really starts eating into the available CPU bandwidth.

--- End quote ---
Well, for TFTP, you can always ACK more slowly...Most of the IP protocols suites are sort of self-timed.  If you want them to use less CPU, adjust the ack timing.(and make sure things like the Nagel algorithm are turned on.  That'll optimize packetization based on performance as well as network bandwidth.)
(that's generic advice.  I'm not 100% certain that it applies to lwip, or how, but ... it should.)

capt bullshot:
Back in the days, I had a similar issue with LwIP.
What I did, afair, was to limit the processing rate of the incoming packets, by some artificial delay.

MAC -> chained DMA -> bottom half interrupt handler enables upper half handler by OS call -> upper half handler runs in OS context (insert delay here afair) sets up new DMA buffers, and processes received packet.

Anything else worked by itself then, reducing the OS load as a result.


--- Quote from: thm_w on January 28, 2022, 02:20:59 am ---...
But how often can this interrupt occur?
--- End quote ---

Whenever data appears at the Ethernet interface, which has either the correct IP address or is a broadcast. At 100Mbit this can be fairly often. This is the reason why I am looking for a way to throttle that interrupt.
You can reproduce the effect with any Ethernet tool that provides "stress testing". With "Packet Sender" that would be "intense traffic generator".


[0] Message Index

[#] Next page

There was an error while thanking
Go to full version