Does anyone know if the following "naughty" (implementation dependent) construct would work "correctly" on the ARM Cortex M4, compiled with arm-gcc-embedded?
Didn't find your answer? Ask the community — no account required.
L
Lasse Langwadt Christensen
Den tirsdag den 23. februar 2016 kl. 20.18.11 UTC+1 skrev bitrex:
that would depend on what you mean by correctly and what endianness you have
-Lasse
J
John Devereux
I am not an expert (ask on comp.arch.embedded) but my understanding is that this sort of thing is guaranteed by the EABI (bugs aside).
John Devereux
J
John Devereux
Oh yes CM4 is generally little endian, and that does not seem to match the struct!
John Devereux
B
bitrex
I'm new to coding for the processor, and I had been having a little trouble determining what the endianness of the thing actually _is_...
B
bitrex
Well, I'd like to be able to increment the uint32_t, and then access the individual bytes through the union such that say if we have 0xAABBCCDD in the uint32_t, I'll have 0xAA in integer_high, 0xBB in integer_low, etc.
T
Tauno Voipio
At least those Cortexes I have used, (Atmel, Philips, STM) are definitively little-endian.
-TV
L
Lasse Langwadt Christensen
the bytes are in the wrong order for a little-endian cpu, don't know of any M4 that isn't little-endian
And it don't think it'll compile unless you name the struct
-Lasse
D
David Brown
I can't even figure out why it would be considered "naughty" at all. The only implementation-dependent aspects I can see are the alignment of the parts (on the ARM, 8-bit, 16-bit and 32-bit types all have "natural" alignments), and the ordering of the bitfields (which is low bits first
- guaranteed by the ARM EABI, and thus consistent across compilers).
B
bitrex
"Naughty" if one wants to port the code as-is to another architecture, I guess.
B
bitrex
I believe ISO C11 permits anonymous structs in general, and gcc supports them now in C++, C99, everything...
T
Tim Wescott
First:
Yes, it'll work as long as you want the least significant byte to be named "integer_high" and the most significant byte to be named "frac_low".
Second:
You need to name the bitfield. I'll assume you've named it "bits" -- i.e., phase_accumulator.bits.frac_high.
This will be portable, and integer_high(phase_accumulator) should read as easily (or more so) as phase_accumulator.bits.integer_high.
Tim Wescott
Wescott Design Services
http://www.wescottdesign.com
L
Lasse Langwadt Christensen
you are right, the anonymous struct does compile with the version of arm-none-eabi-gcc I have here
-Lasse
B
bitrex
Does it complain if you do -pedantic?
D
David Brown
I would say "non-portable" rather than "naughty". "Naughty" implies that this might not work in some circumstances, or perhaps depends on undefined behaviour. This is merely non-portable and relies on implementation-dependent behaviour (which happens to be defined by the ARM EABI, and thus should apply to all ARM compilers).
L
Lasse Langwadt Christensen
I get a warning that ISO C99 doesn't support unnamed structs/unions
and about a trillion warning from cmsis code
-Lasse
D
David Brown
True.
Not necessary true, assuming you are using C11 (rather than C++), or gcc or clang, or any other compiler that supports anonymous structs as an extension. Since this is specifically for the ARM, and not meant to be portable, it is perhaps not unreasonable to use an extension that is available the most common tools for that target. But that's a decision for the OP to make.
No, these functions are not a good substitute. First, they do not do the same thing if "phase_accumulator" is used as a volatile - and such bitfield structures are usually used for hardware registers where volatile is relevant. Using the bitfields, accesses to the separate fields will be done as 8-bit accesses - using the functions, they will be 32-bit accesses.
Second, your functions give read-only access, not read-write access - another set is needed for writing. Those are messy.
sumg ting does not look correct? Assuming I understand what you're after.
struct _phase_acc { union { uint32_t phase_accumulator_full }; union { uint_8 integer_high:8, integer_low:8, frac_high:8, frc_low : 8; }; } phase_accumulator;
You can include a condition to test for the second union to determine the endious of the platform to correctly compile the code for the bit field order. The above struct should overlay to generate a single 32 bit image.
Jamie
I
Ian Collins
typo..
typo..
No, it won't. You have two 32 bit unions members of a struct, witch gives a 64 bit struct.
Ian Collins
D
David Brown
In that case you have the ordering wrong. The Cortex M devices are all strictly little-endian, and the EABI requires little-endian bitfield order too (it is possible for the bitfields to be in a different endian order than multi-byte data - the bitfield endianness is a choice for the ABI and/or compiler).
Join the Discussion
Have something to add? Share your thoughts — no account required.
Didn't find your answer?
Ask the community — no account required
Report Content
You are reporting this content to the moderators. They will look at it
ASAP.