EKH05: unable to get more than 400Kbps from HaLowExample_spi bridged

Hi, dear MM support service!

I am using EKH05 as a bridge from my Linux PC to the Internet.

I see that the throughput is a bit lower than expected: no more than 400Kbps (Kbit per second).

I already checked that the various queues never get full, but I am unable to understand why e.g. the tcpip_thread sometimes lasts 700 ms or more.

The “spi_irq” thread lasts never more than 5ms.

The “drv” thread never lasts more than 6ms.

The TinyUSB thread I use to connect with the PC never lasts more than 2ms.

The evtLoop thread never lasts more than 2ms.

Despite of this, I see very long wait in the tcpip_thread for the tx to become available (sometimes the 1000ms timeout is hit).

The SPI is using DMA and using 40Mbps as frequency; there are no errors reported from spi on tx or rx.

I wonder if you have any suggestion about what to check to detect where the bottleneck is.

Many thanks for your help

Michele

Hmm interesting, do you have any more details on where the tcpip_thread is spending its time? EG is there a specific resource it is waiting on?

Are you testing in a region with duty cycle restrictions? (EU, JP etc)

How large is the packet pool size? Have you tried increasing the packet pool?

Have you tested the raw throughput across your linux ↔ EKH05 bridge? What’s that limit?

Hi, Idennis!

I tried setting MMPKTMEM_{TX, RX}_POOL_N_BLOCKS to 32 and I see no improvements in the throughput.

Now I try connecting the MM kit to my PC and using wireshark to check the timing of frames across the USB interface

Hi, a quick follow-up:

  • changing mmhal_spi_irq_poll_interval from 5000 to 10 and YAPS_STATUS_REG_READ_TIMEOUT_MS from 100 to 5 gives an increment from 400 to 500 kbps
  • this is strange because I see that the IRQ signal SPI_INT that goes to the EXTI15 firing morse_spi_irq_handler and giving spi_irq_semb is hit
  • I wonder if you can give me a timing reference about SPI_INT: how does it should behave?
  • do you think that the SPI interface sets a limit to the effective bandwidth of the system and that it would be preferable to work with the SDIO interface instead?

Hi, Idennis!

Many thanks for your help!

I have profiled the execution time immediately before and after the call tcpip_thread_handle_msg(msg); in the tcpip_thread and I have these stats:

duration [ms] min 0, max 1000, avg 7, num of samples 20309; num samples by duration spaced 20ms (19752,43,18,7,6,16,20,20,15,25,31,45,37,37,33, 204 >= 320ms)

delay between calls [ms] min 0, max 2038, avg 31, num of 20308, num samples by duration spaced 20ms (17909,702,353,233,96,70,73,47,34,44,50,25,21,24,21,606)

I have placed a profile check immediately before and after the mmwlan_tx_wait_until_ready call in themmnetif_tx routine, and I have the stats

duration min 0, max 1000, average 17, num of 9103 (8546,43,18,7,6,16,20,20,15,25,31,46,38,35,33,204)

pause between calls min 0, max 22092, average 71, num of 9102 (7841,459,354,190,63,30,20,28,9,14,3,9,4,3,3,72)

I have similar status for spi_irq, profile placed across the call to mmosal_semb_wait in the morse_spi_irq_main

duration min 0, max 7, average 0, num of 19356 (19356,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)

pause between calls min 0, max 2039, average 41, numof 19354 (13937,2648,874,376,243,159,133,98,67,65,54,22,19,26,22,611)

and driver_task_main, placed across mmosal_semb_wait

duration 0,7,0,42875 (42875,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)

pause 0,2038,18,42873 (37519,2598,869,376,239,155,134,97,68,63,55,21,21,25,22,611)

I have not yet found an evident reason for the low throughput; I assume it is low because it is 20 times lower than the nominal bandwidth of 9Mbps and I was expecting some more, around 1 or 2 Mbps at least. The test executed is a speedtest executed from Chrome of an Android smartphone or a Linux PC.

I am testing in EU

These are my settings for the TX/RX pool, now I’ll give a try increasing the size to 32 and I’ll let you know:

#define MMPKTMEM_TX_POOL_N_BLOCKS (20)

#define MMPKTMEM_RX_POOL_N_BLOCKS (23)

Many thanks again for your help

Michele

Hi, dear MM support service!

Many thanks for your help!

I checked with an oscilloscope while downloading The Guardian home page with wget, and I see that the data come from the HaLowLink2 typically no more frequently than one every 30ms:

wget --bind-address=192.168.2.69 -d ``www.theguardian.com

index.html.64 100%[=========================>] 1,41M 53,9KB/s in 27s

In the above picture, the trace 0, the orange one, is the chip select of the spi interface; when it gets thicker, there are data flowing between the STM32U585 and the MM.

As you can see, I have set a 10ms refresh period of the interface status.

The SPI_INT comes approx every 30 ms too.

The trace 1, the red one, is toggled every time the yaps.c instruction

if (driver_task_notification_check_and_clear(driverd, DRV_EVT_RX_PEND))

is checked

The trace 2, the yellow one, is called when the

if (morse_yaps_rx_handler(yaps))

instruction in yaps.c is executed, i.e. when DRV_EXT_RX_PEND is found true.

As you can see, on average the data come from the MM interface no more frequently than one every 30ms circa.

This is consistent with the throughput of about 400-500kbps I have from the wget.

I wonder if some setting exist to reduce this latency.

If you need other info, please do not hesitate to ask me!

Many thanks again!

Michele

Hi @michele

Have you been able to run our standard iperf test application (included in the CMSIS pack) and verified the maximum throughput there?

Unfortunately, I think you will find that you are being limited by the EU duty cycle (~2.8%).

There are APIs that will allow you to confirm the duty cycle statistics. See mmwlan_get_duty_cycle_stats at Morse Micro IoT SDK: WLAN Regulatory Database API

Depending on your application you could reconfigure to burst mode, which would give you full throughput for 100s each hour. However, I doubt this will make sense for a bridged interface.

Ah that’s your limit then. As Arien mentioned, the system is limited to only utilise 2.8% of possible airtime. This means packets are buffering up (in the HaLow chip) waiting until it is allowed to TX again - which slows your system down and is why you see mmwlan_tx_wait_until_ready being a blocking wait.

Unfortunately given the duty cycle limitations there’s not much spare bandwidth to squeeze out.

You could try dramatically increasing the TX pool to try and keep the datapath fed.
There is a bunch of spare RAM in the EKH05, you should be able to try a really big value to see if that changes much:

MMPKTMEM_TX_POOL_N_BLOCKS = 150

Many thanks for your replies, Idennis and Arien!

Hope you don’t mind if I further ask for clarifications:

  • as stated, I am currently experiencing a throughput of 500 kbps on a nominal bandwidth of 9 Mbps; I am using channel 2 (auto): 2 MHz BW, 864.0 MHz
    • on a 2.8% duty cycle limit per channel, 2 channels, I would expect:
      • 9Mbps * 2.8% = 250 kbps
      • 250 [kbps / channel] * 2 [channels] = 500 kbps
    • and this what I get
  • is this calculation correct?

Recently we used, here in EU, a HHU with Android an HaLow that was giving an effective bandwidth of 17 Mbps on short range, and 1 Mbps on a 500 meters range:

  • is there any chance we can get those numbers?

Best regards and thanks again

Michele

is this calculation correct?

The calcs seem reasonable?

You won’t be able to get these numbers in the EU with the regulatory restrictions