8

This question is about embedded controllers. I want to initialize a const array in memory. But while storing this array in memory, I want to store it at a specific location say 0x8000. This way I want to occupy some amount of code memory so that later on during run time I can erase that portion and use it for my own other purpose. Basically I want do this:

const unsigned char dummy_string[] = "This is dummy string";

but the address of dummy_string should be in my hand. Like I can assign whatever address I want to it.

17
  • 1
    C or C++? The answer will be different for each one. Commented Jan 5, 2015 at 5:19
  • 1
    " and use it for my own other purpose" - code injection? Commented Jan 5, 2015 at 5:20
  • Can use mmap() specifying your address. The addresses are virtual though. Commented Jan 5, 2015 at 5:34
  • @cdhowie - i want to do this in C.but C++ will also fine Commented Jan 5, 2015 at 5:48
  • 1
    I suggest you instead split the process in two phases: (1) program the desired initial value in flash using a flash programmer; (2) access the value in runtime with simple cast: (volatile unsigned char *)0x8000. msp430 flash addresses can be read in the way as RAM addresses. writing requires erase + write though. Commented Jan 5, 2015 at 13:49

3 Answers 3

6

Use a pragma statement to place the variable into a named memory section. Then use the linker command script to locate the named memory section at the desired address.

I scanned through some MSP430 documentation and I think it might work something like this...

In the source code use #pragma DATA_SECTION.

#pragma DATA_SECTION(dummy_string, ".my_section")
const unsigned char dummy_string[] = "This is dummy string";

Then in the linker .cmd file do something like this.

MEMORY
{
    ...
    FLASH    : origin = 0x8000, length = 0x3FE0
    ...
}

SECTIONS
{
    ...
    .my_section    : {} > FLASH
    ...
}

If there are multiple sections located in FLASH then perhaps listing .my_section first will guarantee that it is located at the beginning of FLASH. Or maybe you should define a specially named MEMORY region, such as MYFLASH, which will contain only .my_section. Read the linker command manual for more ideas on how to locate sections at specific addresses.

Sign up to request clarification or add additional context in comments.

4 Comments

should I modify FLASH portion also?
Hi thanks a lot.I also found this: const unsigned char flash_mem[1024] __attribute__((location(0x8000)));
The FLASH origin and length in my answer are just examples. I don't know whether those values are appropriate for your board. The MEMORY{} block in the linker .cmd file defines the valid memory regions. The memory regions should not overlap. If you divide the original FLASH region into two regions named MYFLASH and FLASH then yes, you should change the FLASH region to remove the portion that you're assigning to MYFLASH so that they don't overlap.
If the __attribute__ statement works for you then great. I suspect that may be a feature specific to the GCC compiler and I wonder whether it would work with TI's compiler. With TI's compiler, you may need to use the #pragma statement like in my answer. (But I'm really not sure of that.)
1

Portable way is to use pointer to set address

  const unsigned char dummy_string[] = "This is dummy string";
  unsigned char* p = (unsigned char*)0x1234;

  strcpy(p, dummy_string);

Non-portable way is to use compiler/platform-specific instructions to set address. For example, for GCC on AVR one can use something like

  int data __attribute__((address (0x1234)));

5 Comments

P is pointer to unsigned char and it is initializing to RAM address.I just want to do this but P should point to flash memory address.& how can you assign 0x1234 without type casting to p?
@GujaratiLION Well, do you know flash address? Could you read it? Could you do something like char* p = (char*)FLASH_ADDRESS; cout << *p;
yes flash address is 0x8000.I got it from controller's data-sheet.and I can do what you said.but the point is in can I just have location 0x8000 in flash memory and not RAM and put whatever data want.
@GujaratiLION if it is inside your program address space, and you won't hit with access violation, then yes, you could do this. Again, first thing to check if you could read. Another question is if there is some system-like data which makes some structure out of flash - like filesystem or similar. If there is a filesystem here, you better access it via driver
hi,your second option actually works just need to use "location" instead "address" in CCS.but I still have doubt for your first option what if 0x1024 is flash memory address? strcpy would require runtime CPU control.btw thanks for your answer
0

From C and/or C++, just the way you have written in the question. Possibly add an extern to override C++'s const-is-static-by-default rule.

Then you will need to use a linker directive (.ld file perhaps) to force that symbol to a particular address in code flash/ROM.

Or, you can assume something outside the build process programs the memory, and your code just accesses it. Then you can do something like:

inline const unsigned char* dummy_string() { return (const unsigned char*)0x8000; }

1 Comment

but this will just give address 0x8000 to dummy_string.What if I want wite some data at 0x8000 and locations after that?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.