CH32V307 : FPU + FreeRTOS

Toolchain/Clang

 Time to enable the FPU!

I've modified the  LLVM-embedded-toolchain-for-rv32 so that it builds both soft-ftp and hard-fp clang runtimes (it is a bit clunky but works).


FreeRTOS

WCH implementation

The FreeRTOS implementation saves this on the task stack : 

  • MEPC
  • [FPU]
  • Normal regs
  • MStatus

[FPU] depends on a compilation switch. 

It contains either all the FPU registers (the 32 of them) or nothing. Always.

This is problematic.

Saving all those registers is hitting the stack hard and it takes time.

Furthermore, that happens for all task switches  even if the FPU is not used.

Conversely, if you dont save the FPU registers and use the FPU in 2 different tasks, you'll get data corruption.

Naive improvement

I implemented a very naive change using the FS bits in mstatus.

These FS bits can have 2 interesting values : 

  • FPU never used (Off, original, clean)
  • FPU dirty (i.e. used at some point).

So, when the FS bits are "not used", you can skip saving/restoring the FPU registers for that task.

When they are "dirty", you need to save/restore the FPU registers

It is a bit naive, but is acceptable imho.

That involved changing the register layout a bit on the stack to this :

  • MEPC
  • MStatus
  • [FPU]
  • Normal regs
We have Mstatus available at a fixed position, so it can be checked to see the status of the FS bits.
The FPU registers are only saved to/out of the stack if the FS bits are dirty.

So we get the best of both worlds by paying a very small CPU overhead, mostly due to my ignorance of proper riscv assembly :
  • ~ 0 impact when you dont use the FPU
  • No corruption when you use them, but you pay the price
It can probably be better, as it is now it will get dirty if you use them only once in a task, but it is a good start.







Comments

Popular posts from this blog

Component tester with STM32 : Part 1 ADC, Resistor

Fixing the INA3221

INA3221, weird wiring