libopencm3 / libopencm3

Open source ARM Cortex-M microcontroller library
http://libopencm3.org/
GNU General Public License v3.0
3.06k stars 1.03k forks source link

Bootloader and genlink.py / devices.data #1117

Closed fornellas closed 4 years ago

fornellas commented 4 years ago

I'm working on a project that will have a bootloader on the first few kb of ROM, and the main program sitting in the rest of the memory, similar to the example bootloader.

Building the bootloader is straightforward, as its start ROM address matches what is at ld/devices.data. But building the main program, would require, based on the same device:

This can be accomplished by adding a new device to ld/devices.data for the main program, eg:

stm32f411?e*_main_program stm32f4 ROM_OFF=0x08000800 ROM=510K RAM=128K
stm32f411?e* stm32f4 ROM=512K RAM=128K
stm32f4 END ROM_OFF=0x08000000 RAM_OFF=0x20000000 CPU=cortex-m4 FPU=hard-fpv4-sp-d16

This however, has 2 problems. scripts/genlink.py creates duplicate defines:

<command-line>:0:0: warning: "_ROM" redefined
<command-line>:0:0: note: this is the location of the previous definition
<command-line>:0:0: warning: "_ROM_OFF" redefined
<command-line>:0:0: note: this is the location of the previous definition

and upstream ld/devices.data would need to have project specific stuff (_main_program).

The solution I see to better support this is:

I can send a PR with these changes, but I'd love to hear some opinions if there's a better approach to support bootloader + main program build.

adamheinrich commented 4 years ago

Is that enough? I typically end up defining some extra sections in flash/ram when implementing bootloader (for signature or shared data between bootloader and application) so this would only cover some of the linker script customizations.

fornellas commented 4 years ago

I suppose these could be achieved by having the base addresses for ram / rom available as defines, right?

karlp commented 4 years ago

The way I do this is simply not using the linker script generator. Just define your own file like this. (this is from an L1, you can substitute ccm and things if you like)

/* Define whatever layout you like */
MEMORY
{
    rom (rx) : ORIGIN = 0x08002000, LENGTH = 56K
    ram (rwx) : ORIGIN = 0x20000000, LENGTH = 32K
    eep (r) : ORIGIN = 0x08080000, LENGTH = 4K
}

INCLUDE ../common/cortex-m-generic.ld

The cortex-m-generic.ld has all the sections you need

fornellas commented 4 years ago

As things are, if we define a custom LDSCRIPT, we miss out on all compiler flags being automatically generated, and have to manually define them. Below are 2 cases explaining that.

One can obviously copy / paste what is needed, but it seems more reasonable to leverage what we can that's of the shelf from devices.data & genlink.py and build on top of that. This is what I went for on #1118.

libopencm3-templates

my-project/Makefile defines DEVICE and let:

This is very convenient as all compiler needs are generated only from the device name.

libopencm3-examples

Here's an example with a custom LDSCRIPT:

This means that all goodies we get for free at libopencm3-template have to be manually set up.

karlp commented 4 years ago

so, in theory, and in intent, you are allowed to be including genlink-configbut not genlink-rules, you can get the defines into CPPFLAGS and friends, but you won't get a generated LDSCRIPT. Is that enough, or is it broken, or does it need more work?

(It will still define the LDSCRIPT variable, so you set that to your custom one afterwards)

DEVICE=blah
include genlink-config.mk
LDSCRIPT=wop
fornellas commented 4 years ago

Yep, that works indeed. I ended up doing things a bit more clowny, but it is the same rational.

I'm closing this issue, thanks for the support!