How do you align "const char" arrays to the start of a word (32 bit) address?

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

How do you align "const char" arrays to the start of a word (32 bit) address?

2,716 Views
mykepredko
Contributor IV

Hey folks,

 

I'm looking for the (EWL?) directive which will align a const char array (or some other data type) on a 32 bit boundary so that I can update it using the ColdFire Flash Module (CFM). 

 

ie:

 

const char TestFlags[] = {Byte0, Byte1, Byte2, Byte3, Byte4};

const char TestData[] = {Byte0, Byte1, Byte2, Byte3, Byte4};

 

In this case, I would like both "TestFlags" and "TestData" (which are both 5 bytes long) and any subsequent const char arrays to have their first four bytes located in a 32 bit word (so, the first address of TestData would be 8 bytes different from the first address of TestFlags). 

 

Is there another data type would work better or if there is some better way to specify the placement of the data blocks?  I would like to avoid using MQX's "FlashX" (I'll write my own driver) as it seems to have too much overhead. 

 

Ideally, I would like to place this data AFTER the linked code but have it included in the build so that:

a) If there is a mistake in my software, I don't start trashing application or MQX code

b) I can dynamically add to the blocks, if required. 

 

Thanx,

 

myke

0 Kudos
24 Replies

1,488 Views
mykepredko
Contributor IV

Sorry, I want to write a driver that will update individual words - for reading the data, I will point to the array (or other data structure) and read the data as a pointer to type int_8.

 

myke

0 Kudos

1,488 Views
JuroV
NXP Employee
NXP Employee

Use linker command file (.lcf).

Create new section in the code (see vectors.c for example, where a code (interrupt table) in that section is created).

In the lcf, use

. = ALIGN(4)

to align section to 4-byte boundary.

0 Kudos

1,488 Views
mykepredko
Contributor IV

Hi Juro,

 

Thank you for the reply.  I think I`m there, but I would appreciate it if you could review what I've done to make sure I have approached the issue correctly.  

 

First off, I made the following changes to intflash.lcf:

 

1.  I reduced the "rom" segment by 128k and added a new 128k segment of my own:

      rom (RX): ORIGIN = 0x00000420, LENGTH = 0x0001FBE0 # Code + Const data

      myfrom (RX): ORIGIN = 0x00020000, LENGTH = 0x00020000 # MyFiles - 128k

 

2.  I added the "myfiles" section to the file definition (copying "vectors", as you suggested) after the "rom" section in the lcf file:

    .myfiles :

    {

        ___MYFILES_ROM_START = .;

        *(.myfiles_rom)

        . = ALIGN (0x4);

    } > myfrom

 

I created a simple app to test the ability of data to be placed in the ROM at the specified location. 

Before the TASK_TEMPLATE_STRUCT statement, I first got the location of __MYFILES_ROM_START:

extern constint_8 __MYFILES_ROM_START[];

I then defined an 8 byte array in the "myfiles" section defined in the lcf:

#pragma define_section myfiles_rom ".myfiles_rom" far_absolute R__declspec(myfiles_rom) constint_8 dummyfiles[] = { 0, 1, 2, 3, 4, 5, 6, 7 };

In Main_task, I check the address of __MYFILES_ROM_START and it is 0x00020000, as is expected and the eight bytes listed above are burned into Flash at this address (I read them back as well as check with the memory browser). 

Comments?  I think I've done everything right but before I go forwards, I just want to make sure that I haven't done anything that will bite me on the bum later. 

Thanx,

myke

0 Kudos

1,488 Views
JuroV
NXP Employee
NXP Employee

Well, you created new segment "myfrom", it is not needed.

In your case, you have placed myfiles_rom at the beginning of that segment, which is 0x20000, so it's ok.

. = ALIGN (0x4);

makes that after your myfrom section, next section will be placed at 4B boundary (but there is nothing placed next, so this is useless).

 

You event don't need to create new segment. Just put your section to the rom segment, like .text section is placed there, something like (modified intflash.lcf):

 

 

   .main_application :   {      *(KERNEL)      *(S_BOOT)      *(IPSUM)      *(.text)      *(.init)      *(.fini)      *(.eini)      *(.ctors)      *(.dtors)      .= ALIGN(0x4);      *(.rodata)      .= ALIGN(0x4);      *(.rdata)      . = ALIGN(0x4);      *(.exception)      . = ALIGN(0x4);  #this will assure that myfiles_rom is aligned      *(.myfiles_rom)      . = ALIGN(0x04);      __exception_table_start__ = .;      EXCEPTION      __exception_table_end__ = .;      ___sinit__ = .;      STATICINIT      .= ALIGN(0x4);      __COPY_OF_DATA = .;   } > rom

 

 

Don't forget to have your data const.

0 Kudos

1,488 Views
mykepredko
Contributor IV

Hi Juro,

 

That works for this example, thanx for the simplification. 

 

Part of my requirement is to be able to dynamically write additional data into the Flash after the initial data.  Unfortunately, there is data placed after my initial 8 bytes. 

 

Can I relocate the two

      . = ALIGN(0x4);  #this will assure that myfiles_rom is aligned
      *(.myfiles_rom)

statements to the end of the list to allow the table to grow or is there another way to approch the problem?

 

Thanx, sorry for being a pain,

 

myke

0 Kudos

1,488 Views
JuroV
NXP Employee
NXP Employee

You are not obliged in .lcf to put to rom in one "table" - as you called it.

So, perhaps, you would have more "tables", both ending with ">rom" <-- so you will place the segment to the rom.

 

The answer to your question is: if there is nothing put to rom (">rom") in the .lcf and your section is the last one, then the rest is 'free' for you. Anyway, the section size is determined by compiler / linker, for example, if you have:

char some_data[1024];

in your section ABC, then it would take 1024 bytes.

 

At the end, use your .map file output (can be set in the project settings to generate this file) to see what is placed where after linking.

0 Kudos

1,488 Views
mykepredko
Contributor IV

Okay, I think we're closer, but there is a new problem. 

 

I restored the "rom" statement in the lcf to what was there originally and removed the "myfiles" segment:

    rom (RX): ORIGIN = 0x00000420, LENGTH = 0x0003FBE0 # Code + Const data

 

I then modified the myfiles Sections Segment (what I was calling a "table" above) to append to rom (when I tried a single > before, I got an error telling me to use a double

    .myfiles :

    {

        ___MYFILES_ROM_START = .;

        *(.myfiles_rom)

        . = ALIGN (0x4);

    } >> rom

 

Build and linking of the BSP and App were no problems, but when I program, I get an overlap of 8 bytes from the previous Flash block being programmed and the last one. 

 

When I look at the xmap file (I've been doing this all along), everything is okay, but for some reason, the next to last block is programming 8 more bytes than I would expect. 

 

Any ideas?  This seems to be exactly what I want to do. 

 

Thanx,

 

myke

 

0 Kudos

1,488 Views
mykepredko
Contributor IV

Hey Juro,

 

As an additional question.  Rather than aligning to 4 (to get the word start) wouldn't it be better to align to 2048 (the Flash page size)?  This way the entire Flash page could be erased, if it was necessary without endangering any other data that was programmed into the device. 

 

Thanx,

 

myke

0 Kudos

1,488 Views
mykepredko
Contributor IV

Arrggh.  My calculator (or maybe it's the operator) gave the wrong answer to 256k/32.  It should be 8,192 for the Flash page size not 2,048 that's quoted below. 

 

It's still the same question - I would think that it would be (potentially) advantageous to use this value for the ALIGN directive (it is also on a 4 byte boundary) to allow erasing of the Flash Page of the data without potentially affecting any code earlier in the Flash?

 

Thanx,

 

myke

0 Kudos

1,488 Views
JuroV
NXP Employee
NXP Employee

If you want to erase flash memory blocks, then for sure, go to it and do aligning, erase and write.

Otherwise, you would copy whole block to the RAM, rewrite some portion of the block in RAM, erase the block in the memory and write back...

0 Kudos

1,488 Views
mykepredko
Contributor IV

Hi Juro,

 

I was just thinking it would be "cleaner" if I didn't involve any actual code if I wanted to erase the blocks. 

 

Do you have any suggestions on the 8 byte overlap I'm seeing during programming?

 

Thanx,

 

myke

0 Kudos

1,488 Views
JuroV
NXP Employee
NXP Employee

Excuse me that my English is not 100%, but I don't understand your issue with overlapping (or aliasing) now. Can you describe it better? Thanks.

0 Kudos

1,488 Views
mykepredko
Contributor IV

Hi Juro,

 

Thanx for getting back to me. 

 

The problem is when I add the "myfiles" Section Segment to "rom" after ".main_application" like so:

 

    .main_application :

    {

        *(KERNEL)

        *(S_BOOT)

        *(IPSUM)

        *(.text)

        *(.init)

        *(.fini)

        *(.eini)

        *(.ctors)

        *(.dtors)

        .= ALIGN(0x4);

        *(.rodata)

        .= ALIGN(0x4);

        *(.rdata)

        . = ALIGN(0x4);

        *(.exception)

        . = ALIGN(0x4);

        __exception_table_start__ = .;

        EXCEPTION

        __exception_table_end__ = .;

        ___sinit__ = .;

        STATICINIT

 

        .= ALIGN(0x4);

        __COPY_OF_DATA = .;

    } > rom

 

# Add myfiles to Remaining portion of the Flash - Let's see where it goes

 

    .myfiles :

    {

        ___MYFILES_ROM_START = .;

        *(.myfiles_rom)

        . = ALIGN (0x4);

    } >> rom

 

The large const uint_8 has the header:

#pragma define_section myfiles_rom ".myfiles_rom" far_absolute R

__declspec (myfiles_rom) const uint_8 TFS[] = {

 

Build and link work successfully, but when I attempt to program linked bsp and application, I get the following error:

Downloading 0x00000418 bytes to be programmed at 0x00000000

Programming ....

Program Command Succeeded

Downloading 0x00006050 bytes to be programmed at 0x00000420

Programming ....

Program Command Succeeded

Downloading 0x00006050 bytes to be programmed at 0x00006470

Programming ....

Program Command Succeeded

Downloading 0x00003374 bytes to be programmed at 0x0000C4C0

Programming ....

Program Command Succeeded

Downloading 0x00000088 bytes to be programmed at 0x0000CA80

Programming ....

Error: Program failed. Flash driver reports the following error(s): Chip reported error during program. Please check that the sector you are programming is erased.

 

 

Error: command failed

 

In this example, 0xC4C0 + 0x3374 = 0xF834 which is a much larger overlap than I previously found (I would expect due to the changes I made to the bsp from when I first observed the problem and right now) but still illustrates the same issue. 

 

When I look at the xmap file's relevant sections, I don't see any reason why I am getting this overlap error:

#>0000CA7C __exception_table_start__ (linker command file)

# Exception index

0000CA7C 00000000 Exception Table Index ()

#>0000CA7C __exception_table_end__ (linker command file)

#>0000CA7C ___sinit__ (linker command file)

# Linker generated symbols

0000CA7C 00000004 static initializer (linker generated)

#>0000CA80 __COPY_OF_DATA (linker command file)

# .myfiles

#>0000CA80 ___MYFILES_ROM_START (linker command file)

0000CA80 00002DB4 .myfiles_rom TFS (Break_TFS.obj)

 

 

As I said, this problem goes away when I explicity locate the "myfiles" Section Segment explicitly in its own segment (from 0x20000 to 0x3FFFF). 

 

I hope this is sufficient.  I can send you source files off line if that would help.

 

Thanx (you`re English is pretty good),

 

myke

0 Kudos

1,488 Views
JuroV
NXP Employee
NXP Employee

The question is, what is programmer attempting to write here:

 

Downloading 0x00003374 bytes to be programmed at 0x0000C4C0

Programming ....

Program Command Succeeded

 

Can you also paste more from your xmap file?

0 Kudos

1,488 Views
mykepredko
Contributor IV

Hi Juro,

 

Here is the xmap file + the lcf (zipped together) that I am using. 

 

Currently the error is:

Downloading 0x00003F4C bytes to be programmed at 0x0000C4C0

 Programming ....

 Program Comand Succeeded

Downloading 0x00000088 bytes to be programmed at 0x0000EC4C

 Programming ....

Error: Program failed.  Flash driver reports the following error(s): Chip reported error during program.  Please check that the sector you are programming is erased. 

 

If you add 0x3F4C to 0xC4C0, you get 0xF9BC, which is past 0xEC4C and when programming is attempted at 0xEC4C, it would find that some of the words are already programmed. 

 

Thanx for your help,

 

myke

0 Kudos

1,488 Views
JuroV
NXP Employee
NXP Employee

Now I can see...

You are placing your .myfiles after the .main_application, but there is also located a copy od data:

.main_application_data : AT(__COPY_OF_DATA)

 

Use this:

 

.myfiles :    {       . = __COPY_OF_DATA + SIZEOF(.main_application_data);       ___MYFILES_ROM_START = .;        *(.myfiles_rom)        . = ALIGN (0x4);                     
       __MYFILES_ROM_END = .;
     } >> rom

   # Locate the ROM copy table into ROM after the initialized data
   _romp_at = __MYFILES_ROM_END;



or, even better as I suggested https://community.freescale.com/message/69853#69853

 

0 Kudos

1,488 Views
mykepredko
Contributor IV

Hi Juro,

 

I made the changes but got the message:

>Size of the application has exceeded the capability of this license.

>Contact your authorized distributor or Freescale to purchase a full version

>of the tools.

 

This is strange because when I use exactly the same files that I was using with explicitly setting the myfiles segment, I get a total of 0x11a80 (72,320 decimal) bytes - which is a *lot* less than the 128k limit for the license.  Unfortunately, there is no xmap file for me to see if I can figure out where things are getting placed. 

 

With the "even better" approach, I had a problem with the space used for the ".myfiles_rom" was limited to what was in the initial image and could not grow (which is why I wanted to place this block at the end of all the code). 

 

Sorry - any other ideas I can try? 

 

myke

0 Kudos

1,488 Views
JuroV
NXP Employee
NXP Employee

1. Try to do my "best approach" - just to see if it fits your memory (to produce xmap)- because the size of code should be the same as with the next approach.

2. Can you show me what is in your myfiles_rom?

0 Kudos

1,488 Views
mykepredko
Contributor IV

Hi Juro,

 

I've repeated the test.  The attached .zip file contains, the xmap file, the lcf that I am using and "Break_TFS.c" which is representative data generated by the system and is linked into the total build. 

 

Using this method, the "myfiles" data is stored at 0x10324 and runs to 0x130d8.  At 0x130d8, the linker is putting in additional data - I would like to have everything following myfiles to be unprogrammed (all 0xFFFFFFFF). 

 

Thanx for your help,

 

myke

0 Kudos

1,488 Views
JuroV
NXP Employee
NXP Employee

I really don't know where the problem with 128k license might be. Try ro revert to my advise with the second approach (not the best one) and to do build once again. With only difference: try to have TFS[] to have 1 byte of size.

0 Kudos