cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H743 Ethernert AIS Interrupt

ESawa.1
Associate III

Hey together,

I have a question regarding the STM32H7 ethernet interrupts. I have lwIP + freeRTOS running successfully on the device. All fixes which were indicated by @alister​ were applied and it runs quite stable. The strange part is that when I apply a massive load onto my device by sending a lot of packets to the device, sometime the AIS interrupt triggers. Most of the time this is causes by RBU, which I understand and I can solve. But sometime only the AIS flag is set in DMACSR register. How could this be? I thought the AIS is the OR combination of other errors which occured.

  • Can someone explain why this happens?

0693W00000VOMlzQAH.png0693W00000VOMmEQAX.pngBest regards,

Eric

4 REPLIES 4
alister
Lead

I haven't the answers. But something here might help...

>I thought the AIS is the OR combination of other errors which occured.

AIS is set when any of the error conditions it summarises occur. But it is sticky, which means it needs writing to clear.

AIS and NIS are documented as sticky and RBU and others are not. Possibly the documentation is incorrect. But it should not matter if the interrupt handler is coded well.

You mentioned my fixes (attached https://community.st.com/s/question/0D50X0000C6eNNSSQ2/bug-fixes-stm32h7-ethernet) were applied, which I am taking to mean you are not using my code.

For reliability, the code should take care to only read the ETH_DMACSR once and to only write and clear the status bits that it read. My code writes ETH_DMACSR the value it read. Whereas ST's code (at that time) writes all the status bits after its interrupt handling. You have to check that, as that would be unreliable because a status condition may assert between reading and writing the ETH_DMACSR and be cleared without being handled.

>when I apply a massive load onto my device 

For this reason I now suggest not enabling RBU interrupts. Your code can know whether it has run out of buffers and restart receive DMA when the next buffer is freed and DMA can be restarted even if it has not stopped by writing ETH_DMACRXDTPR for a small number of cycles. Whereas with RBU enabled in ETH_DMACIER, it requires a greater number of cycles to handle and, especially if buffers are few, it can beat such that the cycles to handle the RBUs would be better spent processing and freeing the receive buffers.

ESawa.1
Associate III

Hey alister,

thanks a lot for your reply. I really appreciate that you help to solve all the Ethernet Errors from ST's code base. For the stm32h7xx_hal_eth.c/.h I am using your code. Only the ethernetif is a little bit modified to solve our needs.

I have checked the read of ETH_DMACSR. It is correct, The code reads it once on the entry of the IRQ and clears then only the read bits. My comparison, if AIS is set without any other flag is immediatly after the read of ETH_DMACSR.

So it really looks like that AIS can occur "standalone", very strange. Could be really a wrong documentation.

But so far I have it quite stable by checking the status of the "run out of buffers" and then restart the DMA. Thanks for all your thoughts.

0693W00000WHZEFQA5.png0693W00000WHZEKQA5.png

>So it really looks like that AIS can occur "standalone"

Your posted code checks RBU isn't set, but doesn't check only AIS is set. Are you sure?

>But sometime only the AIS flag is set in DMACSR register. How could this be?

  1. Status bits ae being cleared somewhere else. Clearing status bits in more than one place would cause unreliable operation.
  2. A bug in your instrumenting.
  3. A bug in the silicon - slow of failing to clear, culminating in a spurious interrupt.

All the status bits summarized by AIS should be sticky and the ST driver is coded as thought they are. It's questionable whether AIS itself should be sticky as that invites races. I've neither looked for it nor observed it.

I'd suggest, describe a way to reproduce it, determine its rate of incidence and flag it to ST.

If the incidence is low, leave it and move on as it won't pay any bills.

ESawa.1
Associate III

Hey alister,

to be sure I changed my code just to track really only AIS is "standalone". Once with debugger enabled and once without. I also checked if anywhere else in the code, except the IRQ, is an write access to DMACSR. There isn't. So it's cleared only in the IRQ with the read status bits and once in the _ETH_Start() function. I tracked it with an Oszilloscope and with and without debugger it happens sometimes.

To determine the rate is hard. Just as a reference, I have 16 Rx Descriptors with 84 rx-buffers (fits to the MPU settings). My test-skript opens up to 15 parallel sockets to the STM32H7 and writes data as fast as it can. I force a run out of buffers and in this way also an RBU, by picking up only every 100ms data from the tcpip_thread. So the buffers are filled up for a long time. In this way I reach a heavy rate of RBUs to test stability of my RBU handling. This works stable without any problems.

Back to the rate of occurens. While I had 327 RBU, I had once AIS in standalone. So its really not that often but I was just wondering. By the way, if TCP_MSS is set to (1536 - 40) instead of the default TCP_MSS 536, it happens less often. But I guess this is due to the fact that I need less buffers with the bigger size.

So to reproduce it:

  • Allow up to 15 parallel sockets (using select to have only a single thread)
  • Wait in the function which receives data (after select) 100ms to force "run out of buffers"
  • Add the standalone check of AIS in the IRQ

Anyway, you are right, that it is not super critical as it runs stable so far. But I raised a case to the ST Team to see what they will answer. When I have an explanation I will post it here.

Thanks again for your support.

0693W00000WI0teQAD.png