Interrupt

From zero to main(): Bare metal C

Working on embedded software, one quickly develops a quasi-religious respect for the axioms of embedded C programming:


This is a companion discussion topic for the original entry at https://interrupt.memfault.com/blog/zero-to-main-1

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:

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?

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.

@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.

Thanks for the info. That makes sense.

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

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,

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.

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

1 Like

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

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

@aushacker so we will get 0x00200020, no?

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

1 Like

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

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?

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

A post was split to a new topic: ARMv8M Documentation