1
\$\begingroup\$

I think this is more related to GCC rather than ESP8266. I have been trying to put in a constant variable in read only memory section of ESP. The idea is to change the value directly in the binary image before flashing it on a new chip. In the code section, I have added,

const uint32_t device_address __attribute__((section(".device_addr"))) = 0x12345678;

The changes to the linker script in program.ld is; created a new memory region

device_addr_section :           org = 0x40202100, len = 0x04

In the SECTIONS region, added a new section

.addr_section: ALIGN(4)
{
    KEEP(*(.device_addr))
} >device_addr_section

When I compile the code with the new linker, I see the changes and allocation in the map file, but I cannot find the hex value 0x12345678 in the generated binary image. When I remove the attribute from the variable device_address, I do see that hex value in the generated binary image. The full memory region breakdown:

MEMORY
{
  dport0_0_seg :                        org = 0x3FF00000, len = 0x10
  dram0_0_seg :                         org = 0x3FFE8000, len = 0x14000
  iram1_0_seg :                         org = 0x40100000, len = 0x08000
/* irom0 section, mapped from SPI flash
  - Origin is offset by 0x2010 to create spacer for second stage bootloader image,
    header.

  - Length is max 8Mbit of mappable flash, minus start offset
*/
  irom0_0_seg :                         org = 0x40202010, len = (1M - 0x2020)
  device_addr_seg  (rx):                org = 0x40202100, len = 0x04
}

I haven't used GCC in the past any ideas and help would be appreciated.

Thanks, Nishant

\$\endgroup\$
  • \$\begingroup\$ Did you remove that memory section out of the main one? You can't just arbitrarily allocate bits of another section to a new section, you have to slice it up properly. Can you show your whole memory section so we can see what you are doing? \$\endgroup\$ – Majenko Nov 3 '16 at 12:38
  • \$\begingroup\$ I have added the memory section in my question. After your comment, I tried reversing the address locations of irom0_0_seg and device_addr_seg, but the result was still the same. \$\endgroup\$ – agnishant Nov 6 '16 at 10:54
1
\$\begingroup\$

You have this in your memory section:

irom0_0_seg :          org = 0x40202010, len = (1M - 0x2020)
device_addr_seg  (rx): org = 0x40202100, len = 0x04

That is a block of memory from 0x40202010 to 0x402FFFFF0. Within that you then have another block from 0x40202100 to 0x20202104.

.----------.
|0x40202010|
|          |
|0x40202100| <- Device address lost
\          \
\          \
|0x402FFFEC|
`----------'

That can't happen. You have one memory area (irom0_0_seg) completely covering the other (device_addr_seg) and anything in device_addr_seg will be overwritten by irom0_0_seg.

You have to set aside a specific area for your device address that is not within the irom0_0_seg. That means reducing the size of the irom0_0 segment to leave a space that you can populate with the device address.

You already have a small gap at the top (I don't know off hand why that is?), but if it's not used for something already then you can use it - otherwise you can expand it downwards and use the new space:

irom0_0_seg :          org = 0x40202010, len = (1M - 0x2030)
device_addr_seg  (rx): org = 0x402FFFE0, len = 0x04

.----------.
|0x40202010|
\          \
\          \
|0x402FFFDC|
+----------+
|0x402FFFE0| <- Device address here
|0x402FFFE4|
|0x402FFFE8|
|0x402FFFEC|
`----------'

The purpose of the memory map is to slice the memory up like a cake, or better still, a loaf of bread. You can't remove a slice from the middle of the loaf and keep the loaf as a single item - as soon as you remove the slice you end up with a slice and two smaller half-loaves. You were trying to remove the slice from the middle whilst still keeping it as a single big loaf - that's never going to be possible. So you do what any sensible person does when slicing bread up and cut a slice from one end, not the middle.

\$\endgroup\$
  • \$\begingroup\$ I did try changing the address and moving the device_add_seg out of the irom section, changed the address to 0x40202000 but the problem is still the same. When I ran objdump on the object file, beside section device_addr_seg I get the message CONTENTS, READONLY where as for others I get CONTENTS, ALLOC, LOAD, READONLY, DATA. This is what is causing the problem and I can't see any way to fix it up. \$\endgroup\$ – agnishant Nov 6 '16 at 16:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.