8bit variabile

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

8bit variabile

3,996 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by blasiis on Fri May 25 01:11:23 MST 2012
I use LPC1758
I have change the lpcxpresso from version .3.6.2 to 4.2.2
The problem is with scructure like this:

typedef struct
{
    uint8_t  var1;
    uint8_t  var2;
    uint8_t  var3;
    uint8_t  var4;         
    uint8_t  var5;         
} MY_STRUCT_T;
This structure with LPCXPRESSO 3.6.2 is large 5 byte, with LPCXpresso 4.2.2 is large 8 byte !!!
I cannot find the linker option for packet this struct.
Where is ?

Thanks
0 Kudos
Reply
31 Replies

3,294 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Thu May 31 03:45:01 MST 2012
Hmm. OK. I should have read the previous couple of posts properly and also built atomicdog's example before posting my previous answer.:rolleyes:

Anyway, in order to get all the byte element structs nicely packed together you need to...

1) Compile -Os.
2) Ensure that all the structs are in the same section. To do this, either give them all an initial value or don't give any of them an initial value at time of declaration.

Note that leaving the initial value "blank" versus setting the initial value to zero is not the same with regards to the compiler placing them into the same block of memory....

volatile MY_STRUCT_T xyz = {0,0,0,0,0} ;
volatile MY_STRUCT_T foo;

Thus you either want ...

volatile MY_STRUCT_T xyz = {0,0,0,0,0} ;
volatile MY_STRUCT_T foo  = {0,0,0,0,0};

or
volatile MY_STRUCT_T xyz;
volatile MY_STRUCT_T foo;


Regards,
CodeRedSupport
0 Kudos
Reply

3,294 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Thu May 31 03:42:21 MST 2012

Quote: atomicdog
If so it would be a reasonable option to store objects consecutively (when space is needed) without a 32 bit alignment boundary requirement.



As mentioned in #11 -fpack-struct is reducing your space requirements.

I've tested this several times and although this seems to be a good option to save RAM it's not working in real, optimized projects (=Release) :(

Since more code (Flash) is needed to save a few bytes in RAM, I think this option (as well as packing structures) isn't very useful.

Therefore I don't recommend to use this options if it's not really necessary  :)
0 Kudos
Reply

3,294 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Thu May 31 02:52:42 MST 2012
The C standard does not define the order that global variables will be placed in memory. Thus the layout of data in memory can change between compilers, and between compiler versions. If you want a fixed layout, then you need to put all the variables that you want in a defined order into a single structure. Generally though, the compiler will try to order globals so that they take up as little space in memory as possible - whilst still aligning them on their "natural size boundary" (ie a word variable like an int will be on a 4 byte boundary).

There are then two types of globals to consider - data (initialised) and bss (zero initialiased). Each of these are placed into their own sections within the image. These sections will both be placed so that they start on a 4 byte boundary by the linker. This means that it is quite possible that up to 3 bytes of padding may occur between the last item in the data section, and the first in bss section.

There was a change made to the managed linker script mechanism back around the time of LPCXpresso 3.6 to enforce this 4 byte alignment - as without it, bad things could happen in certain circumstances.

However the example posted by atomicdog has a simpler explanation than the linker script changes. Instead it highlights the reduction of code/data pulled in by default from the Redlib C library between LPCXpresso 3 and 4...

In LPCXpresso 3, a character array called [FONT=Courier New][SIZE=2] __ctype[/SIZE][/FONT] was being pulled in from Redlib. As this is a character array, it can be aligned onto a byte boundary. And hence no padding is needed between it and [FONT=Courier New][SIZE=2]dummy[/SIZE][/FONT].

In LPCXpresso 4, changes to the structure of Redlib mean that [FONT=Courier New][SIZE=2]__ctype [/SIZE][/FONT]is no longer pulled in, which causes the 3 bytes of padding after  [FONT=Courier New][SIZE=2]dummy [/SIZE][/FONT]at the end of the data section necessary to force 4 byte alignment to be seen.

Regards,
CodeRedSupport
0 Kudos
Reply

3,294 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by atomicdog on Thu May 31 01:40:08 MST 2012

Quote: gbm
As far as I can see in both cases the structure occupies 5 bytes and in both cases the next data item starts at the next boundary resulting from alignment requirements - 4 bytes, which results in padding the data space before the next item (NOT the structure) with 3 empty bytes. The only difference lies in the way of reporting these facts in listings by different compile versions.

I asked the basic question: how do you know you structure has the size of x bytes? The simplest answer is to show the value of sizeof operator.


I believe the OP wants unaligned and consecutive storage of the structures to save space. I don't think he's worried about the actual structure being incorrect.
I was under the impression that the cortex-m3 could do unaligned write/reads (yes/no?). If so it would be a reasonable option to store objects consecutively (when space is needed) without a 32 bit alignment boundary requirement.
0 Kudos
Reply

3,294 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by gbm on Thu May 31 00:30:25 MST 2012
As far as I can see in both cases the structure occupies 5 bytes and in both cases the next data item starts at the next boundary resulting from alignment requirements - 4 bytes, which results in padding the data space before the next item (NOT the structure) with 3 empty bytes. The only difference lies in the way of reporting these facts in listings by different compile versions.

I asked the basic question: how do you know you structure has the size of x bytes? The simplest answer is to show the value of sizeof operator.
0 Kudos
Reply

3,294 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by atomicdog on Thu May 31 00:15:15 MST 2012
With the same project I posted previously but with lpcxpresso_3.6.3_317 the map file now shows 5 bytes for the dummy, xyz, and foo structs.

Quote:
arm-none-eabi-gcc --version
arm-none-eabi-gcc.exe (Code Red/Red Suite/2009_01_C) 4.3.3
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.



.data.dummy    0x10000000        0x5 ./src/main.o
                0x10000000                dummy
 .data          0x10000005      0x204 c:/nxp/lpcxpresso_3.6.3_317/tools/bin/../lib/gcc/arm-none-eabi/4.3.3/../../../../arm-none-eabi/lib/thumb2\libcr_c.a(ctype.o)
                0x10000005                __ctype
                0x1000020c                . = ALIGN (0x4)
 *fill*         0x10000209        0x3 ff
                0x1000020c                _edata = .

.bss_RAM2       0x2007c000        0x0
 *(.bss.$RAM2*)
 *(.bss.$RamAHB32*)
                0x2007c000                . = ALIGN (0x4)

.bss            0x1000020c      0x370
                0x1000020c                _bss = .
 *(.bss*)
 .bss.xyz       0x1000020c        0x5 ./src/main.o
                0x1000020c                xyz
 *fill*         0x10000211        0x3 00
 .bss.i.2481    0x10000214        0x4 ./src/main.o
 .bss.foo       0x10000218        0x5 ./src/main.o
                0x10000218                foo
 .bss.sys_message
                0x1000021d       0x3c c:/nxp/lpcxpresso_3.6.3_317/tools/bin/../lib/gcc/arm-none-eabi/4.3.3/../../../../arm-none-eabi/lib/thumb2\libcr_c.a(alloc.o)
 *fill*         0x10000259        0x3 00
0 Kudos
Reply

3,294 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by atomicdog on Wed May 30 23:53:10 MST 2012
.data           0x10000000        0x8 load address 0x00002ca8
 FILL mask 0xff
                0x10000000                _data = .
 *(vtable)
 *(.data*)
 .data.dummy    0x10000000        0x8 ./src/main.o
                0x10000000                dummy
                0x10000008                . = ALIGN (0x4)
                0x10000008                _edata = .

.bss_RAM2       0x2007c000        0x0
 *(.bss.$RAM2*)
 *(.bss.$RamAHB32*)
                0x2007c000                . = ALIGN (0x4)

.bss            0x10000008      0x164
                0x10000008                _bss = .
 *(.bss*)
 .bss.xyz       0x10000008        0x8 ./src/main.o
                0x10000008                xyz
 .bss.foo       0x10000010        0x8 ./src/main.o
                0x10000010                foo
 .bss.i.2307    0x10000018        0x4 ./src/main.o
0 Kudos
Reply

3,294 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by blasiis on Wed May 30 05:24:41 MST 2012

Quote: CodeRedSupport
I, like Rob65, see your dummy structure of size 5 - not 8 as you claim.
If you want some help tracking down the issue that you are seeing, then please post an actual buildable project that shows up a size of 8.
Regards,
CodeRedSupport


My project is too complex and personal, i try to make a new example project
0 Kudos
Reply

3,294 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Wed May 30 03:36:26 MST 2012
As I said previously...


Quote:
If you want some help tracking down the issue that you are seeing, then please post an actual buildable project that shows up a size of 8.



Regards,
CodeRedSupport
0 Kudos
Reply

3,294 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by blasiis on Wed May 30 03:16:46 MST 2012

Quote: atomicdog
It looks like it has something to do with the gcc 'common variable' extension.
If [I]-fno-common[/I] is used or the struct is assigned a value then the map file shows 8 bytes.
So if it's a common variable even with no optimization the map file will show 5 bytes.



my compiler option is:
-O0 -g3 -Wall -c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections -Wa,-ahlnds=$(basename $(notdir $@)).asm -mcpu=cortex-m3 -mthumb

Optimization = None
C Dialet = compiler default
Use headers for C library = Redlib

MCU Assembler
Comamnd = arm-none-eabi-gcc
Option = -c -x assembler-with-cpp -DDEBUG -D__CODE_RED -D__REDLIB__ -g3 -mcpu=cortex-m3 -mthumb

MCU LINKER
Command = arm-none-eabi-gcc
option: " -Xlinker -Map=Poltrona.map -mcpu=cortex-m3 -mthumb -T "poltrona_Debug.ld"
0 Kudos
Reply

3,294 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by atomicdog on Tue May 29 11:39:12 MST 2012
It looks like it has something to do with the gcc 'common variable' extension.
If [I]-fno-common[/I] is used or the struct is assigned a value then the map file shows 8 bytes.
So if it's a common variable even with no optimization the map file will show 5 bytes.
0 Kudos
Reply

3,294 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Tue May 29 07:38:56 MST 2012
I, like Rob65, see your dummy structure of size 5 - not 8 as you claim.

If you want some help tracking down the issue that you are seeing, then please post an actual buildable project that shows up a size of 8.

http://support.code-red-tech.com/CodeRedWiki/ImportExport

Regards,
CodeRedSupport
0 Kudos
Reply

3,295 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by blasiis on Tue May 29 07:04:19 MST 2012

Quote: OXO
#pragma pack(push,1)
Should work ;)



No, unfortunately the size remain at 8 bytes
0 Kudos
Reply

3,295 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by OXO on Tue May 29 00:13:57 MST 2012
#pragma pack(push,1)

struct MY_STRUCT_T
{
uint8_t  var1;    
uint8_t  var2;    
uint8_t  var3;    
uint8_t  var4;             
uint8_t  var5;         
}

#pragma pack(pop)

Should work ;)
0 Kudos
Reply

3,295 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by atomicdog on Mon May 28 00:35:55 MST 2012
You can also try the -mstructure-size-boundary=n[COLOR=Black] cmd line option[/COLOR]. It's supposed to do what you want. I couldn't get it to work like I thought it should though.
0 Kudos
Reply

3,295 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by atomicdog on Mon May 28 00:28:47 MST 2012

Quote: blasiis
I don't understand the function of "packed" attribute, as I have not seen differences
__attribute__((packed))

If you have a struct with different variable types in it (like char, int, short, and double) then that's when the packed attribute should make the variables consecutive, and without any spacing between the variables. Without the packed attribute a char could basically take up 4 bytes. So the next variable wouldn't be right next to the actually char value. Needing the packed attribute is common with network protocols and needing to transmit data.
0 Kudos
Reply

3,295 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Mon May 28 00:13:20 MST 2012

Quote: blasiis

Anyway with no optimization in the LPCXpresso 3.6 I have size 5 and in the LPCXpresso 4.2 is 8 !!!



Strange - I just checked on 4.2.2 and your struct is 5 bytes long:

Allocating common symbols
Common symbol       size              file

_extra              0x4               c:/nxp/lpcxpresso_4.2.2_275/lpcxpresso/tools/bin/../lib/gcc/arm-none-eabi/4.5.1/../../../../arm-none-eabi/lib/thumb2\libcr_c.a(initio.o)
[COLOR=Red][B]dummy               0x5               ./src/main.o[/B][/COLOR]
__heaps             0x4               c:/nxp/lpcxpresso_4.2.2_275/lpcxpresso/tools/bin/../lib/gcc/arm-none-eabi/4.5.1/../../../../arm-none-eabi/lib/thumb2\libcr_c.a(__init_alloc.o)
__end_of_heap       0x4               c:/nxp/lpcxpresso_4.2.2_275/lpcxpresso/tools/bin/../lib/gcc/arm-none-eabi/4.5.1/../../../../arm-none-eabi/lib/thumb2\libcr_c.a(__init_alloc.o)
__Ciob              0x140             c:/nxp/lpcxpresso_4.2.2_275/lpcxpresso/tools/bin/../lib/gcc/arm-none-eabi/4.5.1/../../../../arm-none-eabi/lib/thumb2\libcr_c.a(stdio.o)



Optimization is set to "None (-O0)"  so there must be something wrong in your setup or project settings.

Rob
0 Kudos
Reply

3,295 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by blasiis on Sun May 27 23:38:23 MST 2012

Quote: atomicdog
You need to set optimization to -Os ( optimize for size).


Using -Os the size change to 5 ! Although there are other differences
I don't understand the function of "packed" attribute, as I have not seen differences
__attribute__((packed))

Anyway with no optimization in the LPCXpresso 3.6 I have size 5 and in the LPCXpresso 4.2 is 8 !!!


Thanks All
0 Kudos
Reply

3,295 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by atomicdog on Sun May 27 00:16:25 MST 2012
You need to set optimization to -Os ( optimize for size).
The issue isn't if the struct is packed or not. Since every member in your struct is 8 bits. The packed attribute doesn't remove the trailing bytes. It just removes the padding in between the member variables.
0 Kudos
Reply

3,295 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by atomicdog on Sat May 26 21:27:49 MST 2012

Quote: blasiis
In the map the dimension is 8
I need a strucyure not array.

 .data.dummy
                0x10000038        0x8 ./src/pippo.o
                0x10000038                dummy
I must modify also a compiler option ?


Are you sure you're looking at the correct/updated map file? It works for me.

typedef struct MY_STRUCT_T
{
uint8_t  var1;
uint8_t  var2;
uint8_t  var3;
uint8_t  var4;
uint8_t  var5;
} __attribute__((packed)) MY_STRUCT_T;
volatile MY_STRUCT_T dummy = {1,2,3,4,5};
 *(.data*)
 .data.dummy    0x10000000        0x5 ./src/main.o
                0x10000000                dummy
 *fill*         0x10000005        0x3 00
 .data.msg      0x10000008        0x4 ./src/main.o
arm-none-eabi-gcc -D__REDLIB__ -DDEBUG -DCR_INTEGER_PRINTF -D__CODE_RED -D__USE_CMSIS=CMSISv2p00_LPC11xx -I"C:\Users\John\Documents\RedSuiteNXP_4.1.0_281\workspace\CMSISv2p00_LPC11xx\inc" -Os -g -Wall -c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections -fno-common -std=gnu99 -mcpu=cortex-m0 -mthumb -MMD -MP -MF"src/main.d" -MT"src/main.d" -o"src/main.o" "../src/main.c"
0 Kudos
Reply