EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

How to define empty const in self defined flash segment?

Started by jean_randhah September 27, 2004
Hello everyone!

Somewhere in the back of my head  I remember a similar discussion
here 
on yahoo, but I could find relevant posts neither in my inbox nor in 
the yahoo archieve. Also Paul seems to be overworked as he has not
yet 
found time to answer to this problem.

I am using Crossworks (after having used IAR for 3 years) and am 
trying to declare constants in flash memory. For this I defined a new 
segment in the segment definition file which works fine with simple 
constants like:

#pragma constseg("FLASHDATA")
const char = 'x';
#pragma constseg(default)

However, if I try to do put a struct into this very same segement it 
won't work. I have several structs in flash memory (defined and 
undefined ones), but they all end up in IDATA0 or UDATA0, which means 
they will be copied into RAM at startup. This is by no means 
acceptable, as they are much larger than 2kB. Is this behaviour meant 
to be? What am I doing wrong?

Example of struct in flash (I have tried 'const struct' as well as 
'struct'):

#pragma constseg("FLASHDATA")
const struct {
const unsigned char   name[6];
const unsigned char   recordingMode;
const unsigned char   recordedVariable;
const unsigned short  switchConfig;
const   signed short  voltageA;
const   signed short  voltageB;
const unsigned short  dataLength;
const   signed long   data[MAX_SAMPLES];
} dataFile;
#pragma constseg(default)


I also noticed that there is a size limit on arrays, at least when 
defined as const. Is there a way around this?

I am gratefull for all hints!

-Jean-



Beginning Microcontrollers with the MSP430

> Somewhere in the back of my head  I remember a
similar discussion
> here
> on yahoo, but I could find relevant posts neither in my inbox nor in
> the yahoo archieve. Also Paul seems to be overworked as he has not
> yet
> found time to answer to this problem.
>
> I am using Crossworks (after having used IAR for 3 years) and am
> trying to declare constants in flash memory. For this I defined a new
> segment in the segment definition file which works fine with simple
> constants like:
>
> #pragma constseg("FLASHDATA")
> const char = 'x';
> #pragma constseg(default)
>
> However, if I try to do put a struct into this very same segement it
> won't work.


Hi Jean!

I have no idea how you would do it in Crossworks, but if you would
ever switch back to a modern version of IAR you can use the following:


#define MAX_SAMPLES 10

struct my_struct
{
const unsigned char   name[6];
const unsigned char   recordingMode;
const unsigned char   recordedVariable;
const unsigned short  switchConfig;
const   signed short  voltageA;
const   signed short  voltageB;
const unsigned short  dataLength;
const   signed long   data[MAX_SAMPLES];
} bar;

#pragma location="FLASHDATA"
const struct my_struct dataFile = {"john", 0, 1, 2, 3, 4, 5,
                                   {10, 9, 8, 7, 6, 5, 4, 3, 2, 1} };

    -- Anders Lindgren, IAR Systems
-- 
Disclaimer: Opinions expressed in this posting are strictly my own and
not necessarily those of my employer.

Jean,

This works for me in v1.2:

typedef struct 
{
const unsigned char   name[6];
const unsigned char   recordingMode;
const unsigned char   recordedVariable;
const unsigned short  switchConfig;
const   signed short  voltageA;
const   signed short  voltageB;
const unsigned short  dataLength;
const   signed long   data[MAX_SAMPLES];
} this_goes_in_info_flash_t;

#pragma constseg("INFO")
const this_goes_in_info_flash_t flash = { "HELLO" };
#pragma constseg(default)

If you remove the initialiser, you would need to use the zeroed segment
(as the data are zero):

#pragma zeroedseg("INFO")
const this_goes_in_info_flash_t flash = { "HELLO" };
#pragma zeroedseg(default)

Alternatively, use an extension:

const this_goes_in_info_flash_t flash @ "INFO";

Regards,

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for MSP430, ARM, and (soon) Atmel AVR processors 

> -----Original Message-----
> From: jean_randhah [mailto:jean@jean...] 
> Sent: 27 September 2004 11:51
> To: msp430@msp4...
> Subject: [msp430] How to define empty const in self defined 
> flash segment?
> 
> Hello everyone!
> 
> Somewhere in the back of my head  I remember a similar 
> discussion here on yahoo, but I could find relevant posts 
> neither in my inbox nor in the yahoo archieve. Also Paul 
> seems to be overworked as he has not yet found time to answer 
> to this problem.
> 
> I am using Crossworks (after having used IAR for 3 years) and 
> am trying to declare constants in flash memory. For this I 
> defined a new segment in the segment definition file which 
> works fine with simple constants like:
> 
> #pragma constseg("FLASHDATA")
> const char = 'x';
> #pragma constseg(default)
> 
> However, if I try to do put a struct into this very same 
> segement it won't work. I have several structs in flash 
> memory (defined and undefined ones), but they all end up in 
> IDATA0 or UDATA0, which means they will be copied into RAM at 
> startup. This is by no means acceptable, as they are much 
> larger than 2kB. Is this behaviour meant to be? What am I doing wrong?
> 
> Example of struct in flash (I have tried 'const struct' as well
as
> 'struct'):
> 
> #pragma constseg("FLASHDATA")
> const struct {
> const unsigned char   name[6];
> const unsigned char   recordingMode;
> const unsigned char   recordedVariable;
> const unsigned short  switchConfig;
> const   signed short  voltageA;
> const   signed short  voltageB;
> const unsigned short  dataLength;
> const   signed long   data[MAX_SAMPLES];
> } dataFile;
> #pragma constseg(default)
> 
> 
> I also noticed that there is a size limit on arrays, at least 
> when defined as const. Is there a way around this?
> 
> I am gratefull for all hints!
> 
> -Jean-
> 
> 
> 
> 
> ------------------------ Yahoo! Groups Sponsor 
> --------------------~-->
> $9.95 domain names from Yahoo!. Register anything.
> http://us.click.yahoo.com/J8kdrA/y20IAA/yQLSAA/CFFolB/TM
> --------------------------
> ------~-> 
> 
> .
> 
>  
> Yahoo! Groups Links
> 
> 
> 
>  
> 
> 
> 

Or, if you wanted to switch to Quadravox's AQ430, for less than the 
yearly maintenance fee of some other vendors:
======================struct my_struct
{
const unsigned char name[6];
const unsigned char recordingMode;
const unsigned char recordedVariable;
const unsigned short switchConfig;
const signed short voltageA;
const signed short voltageB;
const unsigned short dataLength;
const signed long data[MAX_SAMPLES];
};


const struct my_struct dataFile@0x2000 = {"john", 0, 1, 2, 3, 4, 5,
{10, 9, 8, 7, 6, 5, 4, 3, 2, 1} };
======================if you want to place your structure at address 0x2000.



Michel



--- In msp430@msp4..., Anders Lindgren <Anders.lindgren@i...> 
wrote:
> 
> > Somewhere in the back of my head  I remember a similar discussion
> > here
> > on yahoo, but I could find relevant posts neither in my inbox nor 
in
> > the yahoo archieve. Also Paul seems to be
overworked as he has not
> > yet
> > found time to answer to this problem.
> >
> > I am using Crossworks (after having used IAR for 3 years) and am
> > trying to declare constants in flash memory. For this I defined a 
new
> > segment in the segment definition file which
works fine with 
simple
> > constants like:
> >
> > #pragma constseg("FLASHDATA")
> > const char = 'x';
> > #pragma constseg(default)
> >
> > However, if I try to do put a struct into this very same segement 
it
> > won't work.
> 
> 
> Hi Jean!
> 
> I have no idea how you would do it in Crossworks, but if you would
> ever switch back to a modern version of IAR you can use the 
following:
> 
> 
> #define MAX_SAMPLES 10
> 
> struct my_struct
> {
> const unsigned char   name[6];
> const unsigned char   recordingMode;
> const unsigned char   recordedVariable;
> const unsigned short  switchConfig;
> const   signed short  voltageA;
> const   signed short  voltageB;
> const unsigned short  dataLength;
> const   signed long   data[MAX_SAMPLES];
> } bar;
> 
> #pragma location="FLASHDATA"
> const struct my_struct dataFile = {"john", 0, 1, 2, 3, 4, 5,
>                                    {10, 9, 8, 7, 6, 5, 4, 3, 2, 
1} };
> 
>     -- Anders Lindgren, IAR Systems
> -- 
> Disclaimer: Opinions expressed in this posting are strictly my own 
and
> not necessarily those of my employer.


--- In msp430@msp4..., "Paul Curtis" <plc@r...> wrote:
> Jean,
> 
> This works for me in v1.2:
> 
> typedef struct 
> {
> const unsigned char   name[6];
> const unsigned char   recordingMode;
> const unsigned char   recordedVariable;
> const unsigned short  switchConfig;
> const   signed short  voltageA;
> const   signed short  voltageB;
> const unsigned short  dataLength;
> const   signed long   data[MAX_SAMPLES];
> } this_goes_in_info_flash_t;
> 
> #pragma constseg("INFO")
> const this_goes_in_info_flash_t flash = { "HELLO" };
> #pragma constseg(default)
> 
> If you remove the initialiser, you would need to use the zeroed 
segment
> (as the data are zero):
> 
> #pragma zeroedseg("INFO")
> const this_goes_in_info_flash_t flash = { "HELLO" };
> #pragma zeroedseg(default)

Ok the later one works for me now as well. Then I still have the 
initialized structs, that will not go into the code segment. I 
understand that I can use

#pragma dataseg("CODE")
my initialized struct
#pragma dataseg(default)

But of what use is the keyword const then?? Will I always have to 
differentiate between struct and none-struct? This will be quite a 
source of error during programming, espiecially when the next person 
to deal with the code does not know this by heart.

Any idea how to solve this:

> > I also noticed that there is a size limit on
arrays, at least 
> > when defined as const. Is there a way around this?

In detail, I have a struct that contains a very large array (beyond 
10000 elements). The compiler will tell me that this is too large.
"size of 'struct 5' too big"
It seems I will have to create seperate variables for that, as the 
compiler accepts large arrays on its own, just not inside a struct.
However this is not very convienent when I have more than one data 
file. Any ideas?

-Jean-



Just one more thing. If I use

#pragma zeroedseg("FLASHDATA")
const this_goes_in_info_flash_t flash;
#pragma zeroedseg(default)

then the variables will be initialized to zero, won't they? Well, this 
is definitly not what I want. However I could erase them at start of 
programm if they haven't been written with valid data yet and this 
data isn't zero.

-Jean-


Jean, 

> > typedef struct
> > {
> > const unsigned char   name[6];
> > const unsigned char   recordingMode;
> > const unsigned char   recordedVariable;
> > const unsigned short  switchConfig;
> > const   signed short  voltageA;
> > const   signed short  voltageB;
> > const unsigned short  dataLength;
> > const   signed long   data[MAX_SAMPLES];
> > } this_goes_in_info_flash_t;
> > 
> > #pragma constseg("INFO")
> > const this_goes_in_info_flash_t flash = { "HELLO" }; #pragma

> > constseg(default)
> > 
> > If you remove the initialiser, you would need to use the zeroed
> segment
> > (as the data are zero):
> > 
> > #pragma zeroedseg("INFO")
> > const this_goes_in_info_flash_t flash = { "HELLO" }; #pragma

> > zeroedseg(default)
> 
> Ok the later one works for me now as well. Then I still have 
> the initialized structs, that will not go into the code 
> segment. I understand that I can use
> 
> #pragma dataseg("CODE")
> my initialized struct
> #pragma dataseg(default)

Data should not go into CODE.  You create a separate data segment and
place it in that, then use section placement to group them after the
CODE segment.  CODE is fore pure code.

> But of what use is the keyword const then?? Will I
always 
> have to differentiate between struct and none-struct? 

No.  Const == "non-changing".  

> This 
> will be quite a source of error during programming, 
> espiecially when the next person to deal with the code does 
> not know this by heart.

The symbol browser is a simple way to find out where things are placed.
Or just use the @ notation and not the pragmas and problem solved.

> Any idea how to solve this:

Use the @ notation.

> > > I also noticed that there is a size
limit on arrays, at 
> least when 
> > > defined as const. Is there a way around this?

There isn't a size limit on arrays, const or not, other than that
prescribed by the ANSI standard.

static char x[30000]; // OK by ISO
static char x[32769]; // Not OK by ISO

> In detail, I have a struct that contains a very
large array 
> (beyond 10000 elements). The compiler will tell me that this 
> is too large.
> "size of 'struct 5' too big"

I'm sure it will.  If your array is too large according to the ISO
standard, the compiler correctly diagnoses it.

> It seems I will have to create seperate variables
for that, 
> as the compiler accepts large arrays on its own, just not 
> inside a struct.
> However this is not very convienent when I have more than one 
> data file. Any ideas?

The index into *any* array is an **int** (not an **unsigned**), as
required by ISO (e.g. scn 6.7.5.2).  An expression p[i] is equivalent to
p+i which is translated to (unsigned char *)p + sizeof(*p)*i.  Thus,
i*sizeof(*p) cannot overflow, hence the maximum size of an array is
MAX_INT / sizeof([0]).  Hence, you cannor have an array with more than
32767 elements on an MSP430.

It might be inconvenient, but it's a compliance requirement.

Regards,

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for MSP430, ARM, and (soon) Atmel AVR processors 

Jean, 

> #pragma zeroedseg("FLASHDATA")
> const this_goes_in_info_flash_t flash;
> #pragma zeroedseg(default)
> 
> then the variables will be initialized to zero, won't they? 

They won't be initialised to zero, no.  The runtime system only
initialises UDATA0 (see crt0.asm) on startup.  There are two instances
of "initialized to zero": what's loaded into FLASH by the loader
when
you press Run and what is initialised to zero by the runtime system when
the program starts executing.

Now, the flash variable above will *not* be initalized to zero by the
runtime system.  If you want the variable to be left "untouched" the
blank FFs of the flash not overwritten, then you should set the the
FLASHDATA section as a "no-load" section in the section_placement.xml
file.

> Well, this is definitly not what I want. However I
could 
> erase them at start of programm if they haven't been written 
> with valid data yet and this data isn't zero.

I've described what you need to do above.  Set the section placement up
so that FLASHDATA is a no-load section so the loader won't try to load
the section into flash, and the runtime system won't initialize the data
as they are not in the UDATA0 section.

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for MSP430, ARM, and (soon) Atmel AVR processors 

Paul,

> Data should not go into CODE.  You create a
separate data segment 
and
> place it in that, then use section placement to
group them after the
> CODE segment.  CODE is fore pure code.

Sorry, I meant the CONST segment not CODE.

> > > > I also noticed that there is a size
limit on arrays, at 
> > least when 
> > > > defined as const. Is there a way around this?
> 
> There isn't a size limit on arrays, const or not, other than that
> prescribed by the ANSI standard.
> 
> static char x[30000]; // OK by ISO
> static char x[32769]; // Not OK by ISO
> 
> > In detail, I have a struct that contains a very large array 
> > (beyond 10000 elements). The compiler will tell me that this 
> > is too large.
> > "size of 'struct 5' too big"
> 
> I'm sure it will.  If your array is too large according to the ISO
> standard, the compiler correctly diagnoses it.
> 
> > It seems I will have to create seperate variables for that, 
> > as the compiler accepts large arrays on its own, just not 
> > inside a struct.
> > However this is not very convienent when I have more than one 
> > data file. Any ideas?
> 
> The index into *any* array is an **int** (not an **unsigned**), as
> required by ISO (e.g. scn 6.7.5.2).  An expression p[i] is 
equivalent to
> p+i which is translated to (unsigned char *)p
+ sizeof(*p)*i.  Thus,
> i*sizeof(*p) cannot overflow, hence the maximum size of an array is
> MAX_INT / sizeof([0]).  Hence, you cannor have an array with more 
than
> 32767 elements on an MSP430.

Ok, I did not know about this limit set by the ANSI standard.
Also, I must have had a typo somewhere at the end of a constant 
placement. The initialized structs are all in place now.

I tried to compile two different things:

#pragma zeroedseg("FLASHDATA")
const signed long flash_array[10000];
#pragma zeroedseg(default)

this should require 40000 byte as size of long is 4. The compiler does 
this without any complaint.

#pragma zeroedseg("FLASHDATA")
const struct {
const unsigned char   name[6];
const unsigned char   recordingMode;
const unsigned char   recordedVariable;
const unsigned short  switchConfig;
const   signed short  voltageA;
const   signed short  voltageB;
const unsigned short  dataLength;
const   signed long   data[10000];
} dataFile;
#pragma zeroedseg(default)

this will produce the error:
"size of 'struct 5' too big"

I can see that the index within the struct exceeds 32767 bytes. The 
single array does so as well!?!

Is there a significant difference?

-Jean-



I'm not an expert at this but I see you have not given your constants
any values.

I use IAR and just had a similar requirement to put a bunch of constants in
flash.

try this...

#pragma constseg("FLASHDATA")
const struct {
const unsigned char   name[6] = {0x01,0x02,0x03,0x04};
const unsigned char   recordingMode = RM;
const unsigned char   recordedVariable= RVar;
const unsigned short  switchConfig = SC;
const   signed short  voltageA = VA;
const   signed short  voltageB = VB;
const unsigned short  dataLength = dL;
const   signed long   data[MAX_SAMPLES]= Data;
} dataFile;
#pragma constseg(default)

Ted

  ----- Original Message ----- 
  From: jean_randhah 
  To: msp430@msp4... 
  Sent: Monday, September 27, 2004 7:51 AM
  Subject: [Norton AntiSpam] [msp430] How to define empty const in self defined
flash segment?


  Hello everyone!

  Somewhere in the back of my head  I remember a similar discussion
  here 
  on yahoo, but I could find relevant posts neither in my inbox nor in 
  the yahoo archieve. Also Paul seems to be overworked as he has not
  yet 
  found time to answer to this problem.

  I am using Crossworks (after having used IAR for 3 years) and am 
  trying to declare constants in flash memory. For this I defined a new 
  segment in the segment definition file which works fine with simple 
  constants like:

  #pragma constseg("FLASHDATA")
  const char = 'x';
  #pragma constseg(default)

  However, if I try to do put a struct into this very same segement it 
  won't work. I have several structs in flash memory (defined and 
  undefined ones), but they all end up in IDATA0 or UDATA0, which means 
  they will be copied into RAM at startup. This is by no means 
  acceptable, as they are much larger than 2kB. Is this behaviour meant 
  to be? What am I doing wrong?

  Example of struct in flash (I have tried 'const struct' as well as 
  'struct'):

  #pragma constseg("FLASHDATA")
  const struct {
  const unsigned char   name[6];
  const unsigned char   recordingMode;
  const unsigned char   recordedVariable;
  const unsigned short  switchConfig;
  const   signed short  voltageA;
  const   signed short  voltageB;
  const unsigned short  dataLength;
  const   signed long   data[MAX_SAMPLES];
  } dataFile;
  #pragma constseg(default)


  I also noticed that there is a size limit on arrays, at least when 
  defined as const. Is there a way around this?

  I am gratefull for all hints!

  -Jean-




  .




        
             
       
       


------
  . 







The 2024 Embedded Online Conference