serial driver cpu load

Discussions and support about ChibiOS/HAL, the MCU Hardware Abstraction Layer.
User avatar
alex31
Posts: 380
Joined: Fri May 25, 2012 10:23 am
Location: toulouse, france
Has thanked: 38 times
Been thanked: 62 times
Contact:

serial driver cpu load

Postby alex31 » Wed Apr 19, 2023 2:14 pm

Hello,

using 21.11.3, I am surprised by the cpu load of using sdGet function :

° stm32F4 @ 168Mhz
° uart : 115200 bauds, 2400 bytes/ second on the line
° all _DBG_ stuff set to FALSE to minimise cpu load overhead
° STATISTIC enabled to measure cpu load

I have a thread which only call sdGet(TIME_INFINITE) in an infinite loop and that eat 2.5% of cpu, is it surprising or is it normal ?
It means more than 1500 cpu cycles/bytes, only for the thread, not counting the cpu cycles in the ISR.

trying to step in the function, I don't see anything obvious.

any idea ?
Alexandre

User avatar
Giovanni
Site Admin
Posts: 14458
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: serial driver cpu load

Postby Giovanni » Wed Apr 19, 2023 3:17 pm

Hi,

It is a buffered driver and you should consider time the spent for IRQ servicing, circular buffer management, context switch to the waiting thread and the non-negligible weight of statistics themselves (those inject code in an lot of critical places).

That number looks way too high anyway, are you confident it is an accurate measurement?

Note that on repository some bugs related to statistics have been fixed, there is a chance you are affected by that.

viewtopic.php?f=24&t=6208

Giovanni

User avatar
alex31
Posts: 380
Joined: Fri May 25, 2012 10:23 am
Location: toulouse, france
Has thanked: 38 times
Been thanked: 62 times
Contact:

Re: serial driver cpu load

Postby alex31 » Wed Apr 19, 2023 4:21 pm

That number looks way too high anyway, are you confident it is an accurate measurement?


I use the same shell thread command since a long time, and the numbers looks realistic, thread that does nearly nothing are close to 0%, only readBytes thread, which for the test does only a sdGet without using the value, rise at more that 2%

Code: Select all

addr    stack  frestk prio refs  state        time   percent        name
20001760 20000784    856  128    1  SLEEPING         1   0.00%          main
200016C0 2000166C    144    1    1     READY     25887   95.70%         idle
200022E8 200021D4    168  128    1  SLEEPING         1   0.00%          blinker
200020B0 20002034    344  128    1     READY       642   2.36%          readBytes
2001FFA0 2001FE84   3976  128    1   CURRENT         3   0.00%          Enhanced_shell
20001B48 20001AEC    400  129    1     WTMSG        15   0.04%          serialPrint
Interrupt Service Routine                          505   1.86%          ISR
cpu load = 4.29%


Note that on repository some bugs related to statistics have been fixed, there is a chance you are affected by that.


thanks for the link, the behavior is better, does not change the figures, but before the fix, the cpu load of thread start at zero and take time to reach an asymptote, with the fix, it's immediately good at startup, but nevertheless, still high.
Is there is a way to find if it's a side effect of statistics module usage, or if it is in the serial driver impl that CPU is spent ?

by the way, if I use an UARTDriver, reading one byte at a time with uartReceiveTimeout, the cpu load is roughly the same, just a little bit higher, which is odd since it has to manage DMA.

Alexandre

User avatar
Giovanni
Site Admin
Posts: 14458
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: serial driver cpu load

Postby Giovanni » Wed Apr 19, 2023 6:10 pm

Hi,

One byte at time means one interrupt for each byte anyway.

You could give a try to the SIO driver which is unbuffered, it relies on the internal HW FIFO. It is not yet available for the F4 sadly.

The statistics module injects code in chSysLock()/Unlock() and context switch which are very critical, this is why it can have a significant impact.

Giovanni

steved
Posts: 825
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 12 times
Been thanked: 135 times

Re: serial driver cpu load

Postby steved » Thu Apr 20, 2023 8:38 am

I've done a similar thing on an F7 at 168MHz, and think I was getting similar figures, albeit running the serial port at only 9600 baud. Unfortunately I don't seem to have noted any figures, and have put that project to one side for now. Somewhat different approach and environment, though:
All debug stuff enabled
Using modified serial driver which does a callback on received character, rather than buffering it
The receiver callback passes the character to a state machine (still within the ISR) which decodes the protocol and updates a buffer.
A thread is only activated when a valid packet is received.
So I still have the interrupt per character, but one thread switch per packet (8-20 characters), and doing a bit more processing in ISR than you.
Using 21.11.3, but don't recollect significant difference to earlier versions.

I'll check the figures if I get a chance.

Also intending to look at the SIO driver; sounds as if its done pretty much what I implemented in my modified serial driver.

User avatar
alex31
Posts: 380
Joined: Fri May 25, 2012 10:23 am
Location: toulouse, france
Has thanked: 38 times
Been thanked: 62 times
Contact:

Re: serial driver cpu load

Postby alex31 » Thu Apr 20, 2023 9:28 am

Thanks to all for the replies, I will rework my library (frsky fport bidirectional telemetry handler, will post it in contrib when finished) as suggested, with a state machine managed by the ISR and only post to thread complete messages. This will have a beneficial side effect : separate the state machine from the OS dependent code will make it more portable.

Alexandre


Return to “ChibiOS/HAL”

Who is online

Users browsing this forum: No registered users and 1 guest