英文:
How to remove unwanted data padding from custom sections on XC16
问题
It seems you're dealing with some alignment and padding issues when trying to place data in a specific section in your PIC24F firmware using XC16. Unfortunately, XC16 and the underlying toolchain have their own behavior when it comes to alignment and padding, and it can be challenging to control them entirely.
You've already explored various methods like #pragma pack
, __attribute__((packed(1)))
, and different project configurations. Since you're still encountering issues, it's possible that XC16 has its own internal mechanisms that may override these settings.
Without detailed knowledge of the specific toolchain behavior beyond my last training data in September 2021, it's challenging to provide a guaranteed solution. You may want to consult the XC16 documentation or seek help on relevant forums or communities where developers have experience with this specific toolchain and its quirks.
It's possible that there have been updates or insights in the XC16 community since my last update, so reaching out to fellow developers who specialize in PIC microcontrollers and XC16 might be your best approach to resolving this issue.
英文:
I am currently trying to dev a firmware for a PIC24F using the whole microchip stack (xc16, mcc, mplab X IDE, etc ...) (not necessarily relevant but i work on a debian 22)
Doesn't really matter why but i want to place some data on a specific section that i will place at specific location on my firmware.
Let's imagine i have a struct my_struct
defined in file.h
as follow :
#pragma pack(push, 1) // using pragma pack to pack the struct and avoid padding
typedef struct {
uint16_t magic;
uint32_t length;
uint32_t crc;
uint16_t word_1;
uint16_t word_2;
uint8_t byte_1;
uint8_t byte_2;
uint8_t byte_3;
uint8_t array[15];
} my_struct;
#pragma pack(pop)
then in my file.c
:
const my_struct __attribute__((section("my_section"))) instance = {
.magic = 0xbaba,
.crc = 0xbabababa,
.length = 0xbabababa,
.byte_1 = 0xba,
.byte_2 = 0xba,
.byte_3 = 0xba,
.word_1 = 0xbaba,
.word_2 = 0xbaba,
.array = {0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba }
};
When I create the object file file.o
,
I expect having a section my_section
of size 32 and filled with 0xBA. So I try to inspect the produced file.o
using objdump to ensure that the data are the one that I want
$ size -A file.o
section size addr
[...]
my_section 64 0
$ objdump -s -j my_section file.o
Contents of section my_section:
0000 ba00ba00 ba00ba00 ba00ba00 ba00ba00 ................
0010 ba00ba00 ba00ba00 ba00ba00 ba00ba00 ................
0020 ba00ba00 ba00ba00 ba00ba00 ba00ba00 ................
0030 ba00ba00 ba00ba00 ba00ba00 ba00ba00 ................
But it seems like XC16 added a 00
padding for each data byte and that it doubled the size of the section.
I know that padding is to keep data aligned for optimization purpose, but for this specific case, I really need those data to be packed and the size needs to be 32.
The issue is not only in file.o
, even if I go until the end of the compilation process, I manage to have the section located where i want (thanks to an updated linker script) but it still contains the unwanted padding. So i'm pretty sure the issue is not about linker, but about the compilation process itself
I tried a loooot of things, really.
I tried to pack the structure using :
#pragma pack(1)
(with or without push/pop)
I also tried to use __packed
or __atribute__((packed(1)))
I tried to add the aligned(1)
keyword, or the volatile
specifier
I even tried to use some uint32_t arr[8]
, uint16_t arr[16]
and uint8_t arr[32]
instead of a struct.
I tried a lot of mplab project configuration (i can't remember which ones, probably all of them)
I tried all those options separately and together ...
But nothing changes the output. I checked documentation or anything i could, but i can't make it work.
Is this even possible under xc16 or should i give up?
=== EDIT ===
Thanks to @pmacfarlane and @thebusybee, I dug a little further and here is what i found:
I declared two identical structs
- one (
s1
) with the__attribute__((used, section("my_section"))
, - the other (
s2
) with no attribute
when i compile and inspect file.o
I got the same output as before for the my_section
output, coming from s1
.
And some data has been added to the .const section, coming from s2
:
$ objdump -s -j .const file.o
Contents of section .const:
0000 ba00ba00 ba00ba00 ba00ba00 ba00ba00 ................
0010 ba00ba00 ba00ba00 ba00ba00 ba00ba00 ................
0020 ba00ba00 ba00ba00 ba00ba00 ba00ba00 ................
0030 ba00ba00 ba00ba00 ba00ba00 ba00ba00 ................
So nothing new here, but if I inspect the final elf, there is a difference :
$ objdump -s -j .const firmware.elf
Contents of section .const:
82cc baba0000 baba0000 baba0000 baba0000 ................
82dc baba0000 baba0000 baba0000 baba0000 ................
82ec baba0000 baba0000 baba0000 baba0000 ................
82fc baba0000 baba0000 baba0000 baba0000 ................
$ objdump -s -j my_section firmware.elf
Contents of section my_section:
0000 ba00ba00 ba00ba00 ba00ba00 ba00ba00 ................
0010 ba00ba00 ba00ba00 ba00ba00 ba00ba00 ................
0020 ba00ba00 ba00ba00 ba00ba00 ba00ba00 ................
0030 ba00ba00 ba00ba00 ba00ba00 ba00ba00 ................
Please note that i am using the default linker script for this example.
I tried to add some code in it , even to modify it entirely but, as nothing worked as expected, I went back to the default one.
For minimal reproducible purpose, i even ended up removing everything about section management, and the result stays the same. So i think the behaviors is coming from the xc16 linker default behavior and not from the linker script.
I would gladly add the linker script to the question but it is 3k lines long.
So, it looks like the linking process is packing ba00ba00 into baba0000 for built-in section such as .const
but not for my custom section.
Don't know if it's relevant, but I assumed that this would bring more information. Any hints ?
答案1
得分: 2
以下是您要翻译的内容:
为了将此线程标记为已解决,我将发布此答案,但不归功于我。
正如@thebusybee所指出的,问题是因为我使用的图片使用了24位字。
正如@pmacfarlane所说,解决方案在这个数据表中。
对于16位设备,在Flash存储器中使用了24位字。该架构支持将Flash的部分区域映射到数据空间中,但这种映射仅有16位宽,以适应数据空间的尺寸,除非使用__pack_upper_byte修饰符
因此,通过以下方式声明我的结构体:
__pack_upper_byte const my_struct __attribute__((section("my_section"))) instance = {
.magic = 0xbaba,
.crc = 0xbabababa,
.length = 0xbabababa,
.byte_1 = 0xba,
.byte_2 = 0xba,
.byte_3 = 0xba,
.word_1 = 0xbaba,
.word_2 = 0xbaba,
.array = {0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba }
};
我得到了
objdump -s -j my_section binary.elf
binary.elf: file format elf32-little
Contents of section my_section :
0000 bababa00 bababa00 bababa00 bababa00 ................
0010 bababa00 bababa00 bababa00 bababa00 ................
0020 bababa00 bababa00 baba0000
这比以前好多了,非常感谢您的帮助!
英文:
In order to mark this thread as resolved, I will post this answer, but the credit is not for me.
As pointed out by @thebusybee, the issue was coming from the fact that the pic I was using, uses 24bits words.
And as @pmacfarlane said, the solution was in this datasheet.
> For 16-bit devices, a 24-bit word is used in Flash memory. The architecture supports the
mapping of areas of Flash into the data space, but this mapping is only 16 bits wide to
fit in with data space dimensions, unless the __pack_upper_byte qualifier is used
So by declaring my struct as follows :
__pack_upper_byte const my_struct __attribute__((section("my_section"))) instance = {
.magic = 0xbaba,
.crc = 0xbabababa,
.length = 0xbabababa,
.byte_1 = 0xba,
.byte_2 = 0xba,
.byte_3 = 0xba,
.word_1 = 0xbaba,
.word_2 = 0xbaba,
.array = {0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba }
};
I ended up with
objdump -s -j my_section binary.elf
binary.elf: file format elf32-little
Contents of section my_section :
0000 bababa00 bababa00 bababa00 bababa00 ................
0010 bababa00 bababa00 bababa00 bababa00 ................
0020 bababa00 bababa00 baba0000
Which is way better than before, thank you very much for your help !
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论