2023-03-05 12:21 PM
I've run into an issue with the section of the UserApp linker script which ensures that the binary size is a multiple of 16 bytes:
.align16 :
{
. = . + 1; /* _edata=. is aligned on 8 bytes so could be aligned on 16 bytes: add 1 byte gap */
. = ALIGN(16) - 1; /* increment the location counter until next 16 bytes aligned address (-1 byte) */
BYTE(0); /* allocate 1 byte (value is 0) to be a multiple of 16 bytes */
} > APPLI_region_ROM
This seems to fail for some binary sizes, where the following error is given:
ld.exe:STM32WB5MMGHX_FLASH.ld:139 cannot move location counter backwards (from 0000000008032340 to 000000000803233f)
If I change the size of the binary by adding some other command, the error goes away. I believe what's happening here is this:
I'm struggling to come up with an alternative to this which will ensure that the binary is a multiple of 16 bytes, but won't have the same issue.
Solved! Go to Solution.
2023-03-26 02:17 PM
Thanks for all your help. I think I've found the answer to my question.
It appears that LD normally does not create output sections with no contents, and presumably moving the location counter doesn't count as "contents". So the following replacement (provided by ST support) fixes the issue:
.align16 :
{
BYTE(0xAA);
. = ALIGN(16);
}
This does have the side effect of writing at least one byte (so binaries which are already a multiple of 16 bytes will have an additional 16 bytes added). However, it keeps everything in the linker script, and the extra padding shouldn't make a difference.
2023-03-16 07:43 AM
Would the following code fulfil the intended function of the original code, without the possibility of moving the location counter backward?
.align16 :
{
_padding = (16 - ((. + 1) % 16)) % 16;
. = . + _padding;
BYTE(0);
} > APPLI_region_ROM
2023-03-16 04:35 PM
.padding16 :
{
. = (( . + 0xF) & ~0xF);
} > APPLI_region_R
2023-03-21 05:35 PM
This doesn't seem to work. I think the problem is that the location counter gets moved forward, but no bytes are written, so there is no effect on the size of the file. This is why the solution I proposed rounds (. + 1) instead of (.), then adds a byte at the end.
Edit: It looks like my solution doesn't work, either, and I'm not quite sure why. For a particular binary, no padding gives a size of 63,526 bytes, ST's solution gives a size of 63,536 bytes (but fails for binaries whose size is a multiple of 16 bytes minus one), mine gives 63,542 bytes, and yours gives 63,526 bytes.
2023-03-21 07:34 PM
Well, life is short and we cannot afford any nonsense delay our progress.
Just pad the binary by brute force, for example using python.
padbyte = b'\xFF'
data = open("file.bin","rb").read()
required_size = (len(data) + 15) & 0xFFFFFFF0
if len(data) < required_size:
open("padded_file.bin","wb").write(data + padbyte * required_size - len(data))
2023-03-26 02:17 PM
Thanks for all your help. I think I've found the answer to my question.
It appears that LD normally does not create output sections with no contents, and presumably moving the location counter doesn't count as "contents". So the following replacement (provided by ST support) fixes the issue:
.align16 :
{
BYTE(0xAA);
. = ALIGN(16);
}
This does have the side effect of writing at least one byte (so binaries which are already a multiple of 16 bytes will have an additional 16 bytes added). However, it keeps everything in the linker script, and the extra padding shouldn't make a difference.