3

I am facing the following problem. I am programming an ARM cortex M4 micro controller and I would like it to have a default value for IP address, netmask, gateway and so on. This default values should be changeable via serial communication AND the changes should be persistent. For example: default value for IP address and netmask are: 192.168.1.20 255.255.255.0 The user changes the address and netmask to 192.168.2.10 255.255.255.0 Now after disconnecting and reconnecting the unit to power supply the "default" values should be the user entered (192.168.2.10/255.255.255.0)

To solve this, I thought about using the so called work flash memory of my uC. This is a non-volatile memory which can be written using special commands. What I am trying to achieve is to define default values in the program code (as variables at the moment, or as defines later if possible) which are picked up by the linker and whose VALUE is put to the non-volatile memory (work flash) at address 0x200C000.

Right now my linker file looks like this:

MEMORY
{
    rom  (rx)  : ORIGIN = 0x00000000, LENGTH = 0x100000 /* 1MB */
    ram  (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 0x10000 /* 64K  */
    ram1 (rwx) : ORIGIN = 0x20038000, LENGTH = 0x10000  /* 64K  */
    wofl (rwx) : ORIGIN = 0x200C0000, LENGTH = 0x8000   /* 32K  */
}

...

.wifi_defaults :
{
    KEEP(*(.wifi_defaults*));
} > wofl

...

and the variable declaration in the source code (just for testing):

uint16_t __attribute__((section(".wifi_defaults"))) test= 0x00D0;

The .map file shows me:

.wifi_defaults  0x200c0000        0x2
 *(.wifi_defaults*)
 .wifi_defaults
                0x200c0000        0x2 ..\obj\HSFirmware.o
                0x200c0000                test

But when accessing the variable I am not getting the correct value, just the initial 0xFFFF which was returned even before starting to mess with the linker stuff.

I also tried to use a CONST in front of the variable declaration, which made no difference.

As far as I understand my code puts an uninitialized variable at the specified code segment. How can I put an initialized variable at the given address?

artless noise
  • 21,212
  • 6
  • 68
  • 105
Daniel
  • 101
  • 1
  • 1
  • 4
  • 2
    Un-programmed flash memory reads as 0xffff. How does the code/data get to the device? Also, you need routines to do the *special* sequence to program the code for the update. I would suggest that you do not try to initialize the data in 'flash'. Instead keep a default ROM copy (which seems to work/program). If you read 0xffff, then call you flash program routine to make it the default. Also you can provide an option to *restore defaults*. There are issues with the loading tools and binary format that need to be resolved otherwise. Please read about *VMA* and *LMA* in the LD documents. – artless noise Oct 12 '16 at 15:41
  • 1
    You should probably do a checksum/crc, etc of the flash configuration data. If it is bad, then you can use the defaults which will reside in ROM (and could be set via a define). The flash may go bad during normal use (lasts ~10 yrs?) and the user will at least still have a semi-functioning device if it goes bad and you use sensible defaults (as opposed to random garbage). – artless noise Oct 12 '16 at 15:47
  • Related:http://stackoverflow.com/questions/39892860/linker-script-does-not-skip-bytes-as-expected/39900613#39900613 The answer there might be answering this as well – tofro Oct 12 '16 at 16:12
  • artless noise, that is exatly what I implemented in the meantime. And while implementing I came to the same solution, that it would be beneficial to have the default data in ROM and write it to the flash in order to be able to restore factory defaults. Thanks for you comment. – Daniel Oct 14 '16 at 06:01
  • If you are flashing your device with a tools that knows how to write flash at 0x200C0000, it'll do it for you. Otherwise, I'd recomment the 1st comment of @artless noise. – hesham_EE Oct 14 '16 at 13:26

1 Answers1

0

You have missed the 'used' attribute to force the compiler to keep this variable.

By the way, in some posts I saw that it is not enough to avoid the link to throw away the section if there is no code that uses it (in your case, some code using the test variable).

Personally, I have tested it with GCC for ARM version 10.3.1, and it wasn't necessary.

Thus, in your example, it would be defined as following:

uint16_t __attribute__((section(".wifi_defaults")), used) test= 0x00D0;
Y.H.Cohen
  • 41
  • 7