Speed Optimization -> missing VTaskSwitchContext

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
EdHa_4455331
Level 5
Level 5
25 replies posted 25 sign-ins 10 replies posted

I'm working on a PSOC6 project using FreeRTOS and emWin.

I really would like to boost the performance of the overall system, so I tried setting the compiler optimization option to SPEED. But when I do that I get

undefined reference to vTaskSwitchContext   port.c  line 423

Can anybody tell me why turning on the SPEED option causes this error. And better still, how to fix it?

Thanks,

Ed H.

0 Likes
1 Solution

Rakshith - The bad news is that the solutions suggested in the link you provided didn't fix the problem. The good news is that they did give a hint that allowed me to get this working. The culprit is the "Link time optimizations" in the compiler options. If this option is enabled with any optimization level other than NONE, the compiler throws the error. A pity I can't have both because the link time optimizations option did give me a minor boost in performance.

Alan - Not trying to increase the frame rate. Just trying to get a static display erased and updated at eye-blink speed. Still not there, but hopefully close enough. I could probably get to eye-blink speed if the PSOC 6 MCUs could do a 50MHz SPI Bus Speed. But the requirement for a minimum of 4X sampling appears to limit the SPI bus speed to 25MHz.

The actual display probably doesn't make much difference. The key players are the graphics interface IC in the display module and the SPI bus speed. That happens to be a Sitronix ST7789.

As to performance improvement: Before I got speed optimization working, my worst-case display took 0.651s to update. Now it is 0.485s. Now a lot of this time is being consumed by reading large bit maps from flash over the SPI bus and then sending them back out over the same bus to the LCD, and that is a fixed time that is independent of speed optimizations. I suspect that on a really MCU intensive task you may see even more of an improvement.

A couple of other words of advice:

1) If you use a flag to communicate between an interrupt handler and a background routine, be sure to tag it as volatile. Otherwise the optimizer will put them in different registers and not a shared memory location. I know - duuhhh - that is always what you are supposed to do.

2) This was a real quirk. The following lines of code that set the back light brightness via a pulse-width modulation block stopped working with speed optimization.  I had to add the 2us delay to make it work again. I probably have over looked a caveat somewhere in the documentation.

BacklightBrightness_TriggerKill();

Cy_SysLib_DelayUs(2);

BacklightBrightness_SetCompare0( (uint32_t)( compare_us  ) );

BacklightBrightness_TriggerStart();

View solution in original post

4 Replies
Rakshith
Moderator
Moderator
Moderator
250 likes received 1000 replies posted 750 replies posted

Hi Ed,

This appears to be a GCC and FreeRTOS specific issue.

I found the following discussions that might help you with your query -

https://stackoverflow.com/questions/38389702/prevent-gcc-lto-from-deleting-function

FreeRTOS won't build on GCC if Linker Time Optimization is set (issue for STM32 ARM CM-7 - port.c:42...

Please let me know if this helps.

Thanks and Regards,

Rakshith M B

Thanks and Regards,
Rakshith M B
0 Likes
AlanH_86
Employee
Employee
100 replies posted 50 replies posted 25 solutions authored

Are you trying to increase the frame rate on the display?

Which display are you using?

Id be curious to read how much the speed flag improved the performance.

Alan

0 Likes

Rakshith - The bad news is that the solutions suggested in the link you provided didn't fix the problem. The good news is that they did give a hint that allowed me to get this working. The culprit is the "Link time optimizations" in the compiler options. If this option is enabled with any optimization level other than NONE, the compiler throws the error. A pity I can't have both because the link time optimizations option did give me a minor boost in performance.

Alan - Not trying to increase the frame rate. Just trying to get a static display erased and updated at eye-blink speed. Still not there, but hopefully close enough. I could probably get to eye-blink speed if the PSOC 6 MCUs could do a 50MHz SPI Bus Speed. But the requirement for a minimum of 4X sampling appears to limit the SPI bus speed to 25MHz.

The actual display probably doesn't make much difference. The key players are the graphics interface IC in the display module and the SPI bus speed. That happens to be a Sitronix ST7789.

As to performance improvement: Before I got speed optimization working, my worst-case display took 0.651s to update. Now it is 0.485s. Now a lot of this time is being consumed by reading large bit maps from flash over the SPI bus and then sending them back out over the same bus to the LCD, and that is a fixed time that is independent of speed optimizations. I suspect that on a really MCU intensive task you may see even more of an improvement.

A couple of other words of advice:

1) If you use a flag to communicate between an interrupt handler and a background routine, be sure to tag it as volatile. Otherwise the optimizer will put them in different registers and not a shared memory location. I know - duuhhh - that is always what you are supposed to do.

2) This was a real quirk. The following lines of code that set the back light brightness via a pulse-width modulation block stopped working with speed optimization.  I had to add the 2us delay to make it work again. I probably have over looked a caveat somewhere in the documentation.

BacklightBrightness_TriggerKill();

Cy_SysLib_DelayUs(2);

BacklightBrightness_SetCompare0( (uint32_t)( compare_us  ) );

BacklightBrightness_TriggerStart();

You could use the QSPI SMIF for faster SPI's

As to your point (1) I have learned that the hardway a number of times... my Grandfather was called "Hardway Hawse"... so I suppose I came by it naturally.  At this point I only use RTOS primitives to talk between tasks... never shared memory.

As to your point (2)... that is curious.  I wonder why?  I typically down count on the pwms which means you can change the compare register without fear of something bad happening in this case.  Im 99% sure that if you do that you dont need to stop/start the PWM

0 Likes