Section Control

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have a collection of C-language data structures that must be ordered in SRAM at fixed distances from each other, so they appear at proper offsets during block transfers out of the device. I used the section attribute to force them into the .comm (COMMON) section, but I can't seem to control the order they appear in. I know I could add them as members of a parent C data structure, but is there a simpler way to do this? Thank you.

This topic has a solution.

Field the chicken, ignore the ball.

Last Edited: Wed. Jul 5, 2017 - 09:57 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I know I could add them as members of a parent C data structure, but is there a simpler way to do this?

Surely that IS the simplest way. While you could do something obnoxious like this:

__attribute__((section(".mysec1"))) int var1;
__attribute__((section(".mysec2"))) int var2;

then in the linker do:

--section-start=.mysec1=0x1234 --section-start=.mysec2=0x2345

to place one variable at 0x1234 and the other at 0x2345 this is just horrendous. I suppose you can quell some of the "noise" by #defining a macro to "hide" the __attribute__ and perhaps put the --section-start's into a local linker script but it is NOT pretty!

A struct{} however is! (though I guess you face the issue of calculating padding sizes?).

EDIT: You may be able to do something clever with uint8_t padding arrays and offsetof() perhaps? Or perhaps not - it would require self-reference before the structure definition is complete.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
union {
    struct {
        char pad[69];
        fred_t data; 
    } fred;

    struct {
        char pad[42];
        greg_t data;
    } greg;

    struct {
        char pad[666];
        hank_t data;
    } hank;
} ee_data __attribute__((section(".comm")));

International Theophysical Year seems to have been forgotten..
Anyone remember the song Jukebox Band?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

A struct{} however is! (though I guess you face the issue of calculating padding sizes?).

Bingo. This is sort of what I was trying to avoid, along with having to prefix references with the dot parent struct, and then having to always worry about precise padding sizes. The as directive ".comm symbol, length" works great, now if I could just fix the ordering...

Field the chicken, ignore the ball.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:

union {
    struct {
        char pad[69];
        fred_t data; 
    } fred;

    struct {
        char pad[42];
        greg_t data;
    } greg;

    struct {
        char pad[666];
        hank_t data;
    } hank;
} ee_data __attribute__((section(".comm")));

Thanks, I haven't ruled this out. Just making sure I haven't overlooked an attribute or as directive to avoid fiddling with structure names in all the source files. 'Preciate it.

Field the chicken, ignore the ball.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does anyone up there know if I could use the as directive, .struct, and how?

Maybe I'll throw in the towel and use a bunch of unnamed unions to eliminate dots, like this:

struct 
{
  //first structure in unnamed union of 64 bytes
  union 
  {
    struct Struct1 struct1;
    uint8_t block1[64];
  };
  
  //second struct in unnamed union of 32 bytes
  union 
  {
    struct Struct2 struct2;
    uint8_t block2[32];
  };

  //and so on...

} foo;

//This lets me access the members without mentioning the unions, like this:
foo.struct1.data=foo.struct2.data=10;
//and without having to calculate the padding sizes

I dunno, I still have to add the foo., but maybe this is all for the best. Already spent way too much time on it. Yawn.

Field the chicken, ignore the ball.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

extern char ee_data[777] __attribute__((section(.comm)))

#define fred (*(fred_t *)(ee_data+69))
#define greg (*(greg_t *)(ee_data+42))
#define hank (*(hank_t *)(ee_data+666))

International Theophysical Year seems to have been forgotten..
Anyone remember the song Jukebox Band?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks Mike. 4AM, really? You are pillar of the community! That is a clean way to go, but I have had location trouble with #define'd references in the Watch Window before, so I try to avoid it when possible. I'm sticking with your first suggestion for now. Just have to clean up a few thousand more references. BTW, what's an Iluvatar? What's a Valar? Thanks again.

Field the chicken, ignore the ball.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Happy 75th anniversary to one of the best movies ever made! Rick Blane [Bogart]: "Of all the gin joints, in all the towns, in all the world, she walks into mine."

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
enum {
    offset_greg=42,
    offset_fred=69,
    offset hank=666,

    pad_greg=offset_greg;
    pad_fred=offset_fred-offset_greg-sizeof(greg_t);
    pad_hank=offset_hank-offset_fred-sizeof(fred_t);
} ;

struct ee_data_s {
    char padg[pad_greg];
    greg_t greg;
    char padf[pad_fred];
    fred_t fred;
    char padh[pad_hank];
    hank_t hank;
} ee_data __attribute__((section(".comm")));

International Theophysical Year seems to have been forgotten..
Anyone remember the song Jukebox Band?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:

enum {
    offset_greg=42,
    offset_fred=69,
    offset hank=666,

    pad_greg=offset_greg;
    pad_fred=offset_fred-offset_greg-sizeof(greg_t);
    pad_hank=offset_hank-offset_fred-sizeof(fred_t);
} ;
struct ee_data_s {
    char padg[pad_greg];
    greg_t greg;
    char padf[pad_fred];
    fred_t fred;
    char padh[pad_hank];
    hank_t hank;
} ee_data __attribute__((section(".comm")));

In your travels, have you ever seen something like this: __attribute__ ((section ("MYSECT+48"))) - to actually place the data 48 bytes after MYSECT? It seems so close, yet, so far away. The actual result of this is that the compiler creates a new section label MYSECT+48, instead of just offsetting from MYSECT.

Field the chicken, ignore the ball.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

fsykes wrote:
In your travels, have you ever seen something like this: __attribute__ ((section ("MYSECT+48"))) - to actually place the data 48 bytes after MYSECT? It seems so close, yet, so far away. The actual result of this is that the compiler creates a new section label MYSECT+48, instead of just offsetting from MYSECT.
No.
What you want might be doable in assembly.

    .section .comm,"aw",@nobits
    .org 48
    .global ee_data
ee_data:
    org .+ee_data_size
extern struct {
    ....
} ee_data;

or

    .section .comm,"aw",@nobits
    .org greg_offset
greg:
    .global greg
    .org fred_offset
fred:
    .global fred
    .org hank_offset
hank:
    .global hank
    .org ee_data_size
extern fred_t fred;
extern greg_t greg;
extern hank_t hank;

International Theophysical Year seems to have been forgotten..
Anyone remember the song Jukebox Band?

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Some closure on this issue... I went with the Uber.data1, Uber.data2, approach. I defined macros like 'Data1' as Uber.data1, then replaced all occurences. It was a bit of work, but it seems readable and works. Thanks to all again.

Field the chicken, ignore the ball.