Continue Discussion 25 replies
November 2019

yucheng

hi François Baldassari
thanks for your share, I want to check the .elf file, but I don’t know how to open the file to get your result
I’m using the Atmel studio.
thanks
:grinning:

1 reply
December 2019 ▶ yucheng

francois

Hi @yucheng, thanks for the note! I don’t quite understand what you are asking for. Are you trying to find the elf file in your build tree?

December 2019

bmcdonnell

What is the purpose of the if statement in the Reset_Handler (surrounding the for loop)? One points to ROM and the other to RAM, so I wouldn’t expect them to ever be equal.

December 2019

francois

@bmcdonnell this is to guard against the case where you’re running from RAM (rather than ROM) in which case those values would be the same. Some MCUs (e.g. dialog’s DA141580 BLE MCU) are set up that way.

1 reply
December 2019 ▶ francois

bmcdonnell

Thanks for the info. That makes sense.

Maybe add a comment to your code explaining that? Just a thought.

February 2020

chandan_bhatia

Thanks for nice article.

Recently I started reading this blog and its really helpful.

I mostly code in IDE so I am not familiar with commands line. Like you wrote some command to look into .elf file. I tried same. I was able to get address for function but unable to find _sbss, _ebss. Can you please help?

Also I am planing to learn commands line program for arm. Would be great if you can suggest any blog,

1 reply
February 2020 ▶ chandan_bhatia

francois

Hi @chandan_bhatia. _sbss, _ebss, and others are added in the linker script. We set that up in the next episode in the series. Check this out: https://interrupt.memfault.com/blog/how-to-write-linker-scripts-for-firmware.

May 2020

IrshadJs

Hi @francois , This is a very well written article. Thank you for your contribution.

June 2020

rookie

The dump of minimal.elf has the first two bytes as 0x0020 0x0020, so how is it that the stack pointer deduced in the following sentence is 0x20002000? Am I missing something

1 reply
July 2020 ▶ rookie

aushacker

Hi Rookie,
value is stored in little endian format i.e. least significant byte in lowest address.

1 reply
July 2020 ▶ aushacker

rookie

@aushacker so we will get 0x00200020, no?

1 reply
July 2020 ▶ rookie

aushacker

No, working L to R, LSB to MSB:
… … … 00
… … 20 00
… 00 20 00
20 00 20 00

1 reply
July 2020 ▶ aushacker

rookie

ooh right… 0x0020 is actually two bytes (in my head i somehow assumed it was a single byte) and so I was simply doing the first two steps of your explanation. Thanks

November 2020

k3rnl

Thank you @francois for sharing your knowledge through this article and this series.

I have a question about the initialisation of static variables in the Reset_Handler function.
I might be being pedantic, but would it make more sense to write:

    if (data_ptr != init_values_ptr ) { // I have changed this line
        for (; data_ptr < &_edata;) {
            *data_ptr++ = *init_values_ptr++;
        }
    }

instead of

if (init_values_ptr != data_ptr) {
    for (; data_ptr < &_edata;) {
        *data_ptr++ = *init_values_ptr++;
    }
}

since, we are setting the values at the addresses of the static variables with the init values, not the other way around?

1 reply
November 2020 ▶ k3rnl

francois

It is slightly better you are right. Thanks for the note!

1 reply
April 2021 ▶ francois

benravin

Hi Francois,

Thanks for the nice post. One question, always the const variable and global initialized variables are stored after the .text and in .rodata of .text section ?
I thought only the constant variables (const) are stored in .rodata.

1 reply
April 2021 ▶ benravin

francois

They’re both stored at the end of .text. What that section is called vary by linker script and by compiler. Typically only const ends up in rodata, and initialized variables are in .data which is both in ROM (init values) and in RAM (working memory).

July 2021

Stefan

Hi @francois the Adafruit CMSIS-DAP debug adapter you linked in your post appears to be discontinued. Can you recommend an alternative that’s compatible with both, the Metro M0 board and your series of blog posts? :slight_smile: Thanks!

July 2021

RyanEdward

@francois You referenced the Reset boot-up behavior as Section 5.9.2 of the Cortex-M3 TRM
For the Cortex-M4 TRM I cannot find anything similar. Would it be fine to just assume the same steps as in the Cortex-M3?

1 reply
July 2021 ▶ RyanEdward

francois

Yes, I noticed they removed that section for the M4 TRM. I think it’s moved to a ARM-v7m manual rather than specific core. In any case, it’s fine to use the same steps.

November 2021

RyanEdward

@francois Why is it uint32_t *init_values_ptr = &_etext; taken at the end of the text section and not uint32_t *init_values_ptr = &_stext; taken at the start of the text section?

From part 2:

.text :
    {
        KEEP(*(.vectors .vectors.*))
        *(.text.*)
        *(.rodata.*)
        _etext = .;
    } > rom
1 reply
March 2022

francois

Because initial values for data are added to flash after the .text section, this is what the AT > rom bit does. Since _etext points to the end of the text section, that’s where we expect the initialization values to be found. It would be better if we had a variable explicitly pointing to the address that AT > rom resolves to, but that’s not something you can do AFAIK.

May 2022

hubbardjw

François,

Could a Nucleo-G070RB be used for “From zero to main(): Bare metal C” in place of the Metro M0 Express and the CMSIS-DAP Adapter.

1 reply
May 2022

francois

I see no reason why not. You’ll need to change the memory map of course.

December 2023

dcabanis

Great article thanks.

I think you have a mistake in your pseudo code. For the Cortex-M0+ the IPSR size is 6 bits not 9 (M3/4/7). As a result the for loop in the pseudo code should be:
for i = 0 to 63 (not 511)

David.