Bootloader functionality broken by GCC LTO

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

cross mob
GiFR_1080991
Level 2
Level 2
10 sign-ins 5 replies posted 5 sign-ins

Hi All,

I'm working with Creator 4.4 on a bootloader project for PSoC4 (component Bootloader_v1_60)
I experimented that enabling LTO (Link Time Optimization) on bootloader breaks its functionality.
I've done that to save flash space, but BootloaderHost gives error: "The flash row is not valid for the selected array".
I have known this problem since PSoC Creator 3.1.

This time I've spent quite some effort in searching for solutions and directly debugging the code.
I've finally found the reason and a solution that I want to share.

The reason is that one of LTO optimizations is a global constant propagation across all the linked objects.
In case of bootloader, the bad effect is the removal of pointers variables "Bootloader_1_SizeBytesAccess" and "Bootloader_1_ChecksumAccess",  preventing the usage of the correct values for "SizeBytes" and "Checksum".
GCC LTO forced constants because it doesn't know that the values are overwritten by the toolchain directly into HEX file.
Because of this the host command "REPORT_SIZE" always gets "startRow=0x0200", causing the error in BootloaderHost, as the Flash appears already full.

As effective workaround I modified Bootloader_1.h as follows:

 

//!extern const uint8  CYCODE Bootloader_1_Checksum;
//!extern const uint8  CYCODE  *Bootloader_1_ChecksumAccess;
extern const uint8  CYCODE __attribute__((externally_visible)) Bootloader_1_Checksum;
extern const uint8  CYCODE __attribute__((externally_visible)) *Bootloader_1_ChecksumAccess;

//!extern const uint32 CYCODE Bootloader_1_SizeBytes;
//!extern const uint32 CYCODE *Bootloader_1_SizeBytesAccess;
extern const uint32 CYCODE __attribute__((externally_visible)) Bootloader_1_SizeBytes;
extern const uint32 CYCODE __attribute__((externally_visible)) *Bootloader_1_SizeBytesAccess;

 

The GCC attribute "externally_visible" correctly prevents the optimization on these symbols.
I tried also the usage of attribute "used", but without success because it is skipped by compiler.

With the above fix I was able to test a working bootloader and save 768 bytes of flash (-16%) thanks to LTO.

I hope this could be of interest to someone.
I suggest to file an enhancement request so that this fix could be included in a future revision of Bootloader component.

Regards,
Giuliano

 

0 Likes
1 Reply
Alakananda_BG
Moderator
Moderator
Moderator
50 likes received 250 sign-ins 250 replies posted

Hi Giuliano,

Thank you for sharing the workaround.

Regards

Alakananda
0 Likes