platformio / platformio-core

Your Gateway to Embedded Software Development Excellence :alien:
https://platformio.org
Apache License 2.0
7.92k stars 792 forks source link

Custom board with linker script for libOpenCM3 #474

Closed zserge closed 8 years ago

zserge commented 8 years ago

I'm trying to use platformio with custom boards (specifically, stm32f401rb).

I've created a JSON file describing my board like this:

{
        "my_stm32f401": {
                "build": {
                        "core": "stm32",
                        "extra_flags": "-DSTM32F4 -DSTM32F401xB -DSTM32F40_41xxx",
                        "f_cpu": "8000000L",
                        "ldscript": "stm32f401.ld",
                        "cpu": "cortex-m4",
                        "mcu": "stm32f401rbt6",
                        "variant": "stm32f401rb"
                },
                "frameworks": ["mbed", "cmsis", "spl", "libopencm3"],
                "name": "My STM32F401 Board",
                "platform": "ststm32",
                "upload": {
                        "maximum_ram_size": 65536,
                        "maximum_size": 131072
                },
                "url": "http://example.com",
                "vendor": "Myself"
        }
}

I use libopencm3 framework, it contains a "common" stm32f4 linker script which is supposed to be included like this (this is my stm32f401.ld from the config above):

MEMORY
{
    rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K
    ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
}

INCLUDE libopencm32_stm32f4.ld

So the question is - where should I put my custom ldscript for my custom board? I would prefer it to be next to my sources, in my project directory.

Currently the only working location was ~/.platformio/packages/frameworks/libopencm3/lib/stm32/f4/. Neither project root, nor src directory worked and printed the following error:

TypeError: coercing to Unicode: need string or buffer, NoneType found:
File "/usr/local/lib/python2.7/dist-packages/platformio/builder/main.py", line 141:
env.SConscript("$BUILD_SCRIPT")
File "/home/serge/.platformio/packages/tool-scons/script/../engine/SCons/Script/SConscript.py", line 551:
return _SConscript(self.fs, *files, **subst_kw)
File "/home/serge/.platformio/packages/tool-scons/script/../engine/SCons/Script/SConscript.py", line 260:
exec _file_ in call_stack[-1].globals
File "/usr/local/lib/python2.7/dist-packages/platformio/builder/scripts/ststm32.py", line 81:
target_elf = env.BuildProgram()
File "/home/serge/.platformio/packages/tool-scons/script/../engine/SCons/Environment.py", line 224:
return self.method(*nargs, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/platformio/builder/tools/platformio.py", line 50:
f.lower().strip() for f in env.get("FRAMEWORK", "").split(",")])
File "/home/serge/.platformio/packages/tool-scons/script/../engine/SCons/Environment.py", line 224:
return self.method(*nargs, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/platformio/builder/tools/platformio.py", line 192:
join("$PIOBUILDER_DIR", "scripts", "frameworks", "%s.py" % f)))
File "/home/serge/.platformio/packages/tool-scons/script/../engine/SCons/Script/SConscript.py", line 614:
return method(*args, **kw)
File "/home/serge/.platformio/packages/tool-scons/script/../engine/SCons/Script/SConscript.py", line 551:
return _SConscript(self.fs, *files, **subst_kw)
File "/home/serge/.platformio/packages/tool-scons/script/../engine/SCons/Script/SConscript.py", line 260:
exec _file_ in call_stack[-1].globals
File "/usr/local/lib/python2.7/dist-packages/platformio/builder/scripts/frameworks/libopencm3.py", line 171:
ldscript_path = find_ldscript(root_dir)
File "/usr/local/lib/python2.7/dist-packages/platformio/builder/scripts/frameworks/libopencm3.py", line 59:
assert isfile(ldscript)
File "/usr/lib/python2.7/genericpath.py", line 29:
st = os.stat(path)

And in fact during the first build my linker script in opencm3 source tree has been expanded and my include statement has been replaced by full contents of the libopencm32_stm32f4.ld.

ivankravets commented 8 years ago

You can specify full path in board's definition ("ldscript": "/full/path/to/script.ld",). Have you tried it?

zserge commented 8 years ago

Hmm... I guess I could, but it's kinda not portable, if other developers have fetched the same sources to a different path that will break the build. Can it be relative instead? Or can I use variable interpolation in that path string? On Jan 26, 2016 5:48 PM, "Ivan Kravets" notifications@github.com wrote:

You can specify full path in board's definition ("ldscript": "/full/path/to/script.ld",). Have you tried it?

— Reply to this email directly or view it on GitHub https://github.com/platformio/platformio/issues/474#issuecomment-174932204 .

ivankravets commented 8 years ago

ld looks for scripts in LIBPATH. You can dump PlatformIO build environment using platformio run -t envdump and find LIBPATH. As you can see, ~/.platformio/packages/ldscripts is added to this list. See https://github.com/platformio/platformio/blob/develop/platformio/builder/main.py#L99

To make portable project you need to take a look at extra_script. You can prepend here "current project directory" to LIBPATH and keep your specific LDScript in the root of the project.

ivankravets commented 8 years ago

Also, don't forget that you can change build environment on-the-fly using extra_script, including pre-defined board settings. See BOARD_OPTIONS environment variable.

zserge commented 8 years ago

Ok, extra_script can become a solution, but it looks like my extra script is evaluated after libopencm3.py fails at find_ldscript(path).. So I get a crash before I'm able to "patch" my environment.

On Tue, Jan 26, 2016 at 6:37 PM, Ivan Kravets notifications@github.com wrote:

Also, don't forget that you can change build environment on-the-fly using extra_script, including pre-defined board settings. See BOARD_OPTIONS environment variable.

— Reply to this email directly or view it on GitHub https://github.com/platformio/platformio/issues/474#issuecomment-174949886 .

"One must have a chaos inside oneself to give birth to a dancing star." - Thus Spoke Zarathustra

ivankravets commented 8 years ago

@valeros please remove assertion https://github.com/platformio/platformio/blob/develop/platformio/builder/scripts/frameworks/libopencm3.py#L59 and allow to specify own LD Script using extra_script.

zserge commented 8 years ago

Ok, just removing assert doesn't help it - the same exception appears later, in merge_ld_scripts. But a solution to my problem seems to be as simple as build_flags = -Wl,-T${PROJECTSRC_DIR}/stm32f401.ld in platformio.ini. Do you see any potential pitfalls with this?

Also, since now my custom build flag works, I wonder how can I trick the platformio to ignore the ldscript specified in board JSON configuration? Currently I specify a "common" linker script or any other ld script that exists in opencm3 sources, but it seems really ugly. Also, I can't just ignore the ldscript because JSON parser checks for this field.

ivankravets commented 8 years ago

build_flags = -Wl,-T${PROJECTSRC_DIR}/stm32f401.ld

This is GOOD approach. It should work in any case. @valeros will fix libopencm3 framework.

Also, since now my custom build flag works, I wonder how can I trick the platformio to ignore the ldscript specified in board JSON configuration? Currently I specify a "common" linker script or any other ld script that exists in opencm3 sources, but it seems really ugly. Also, I can't just ignore the ldscript because JSON parser checks for this field.

I've changed this issue to bug, we will fix all these things.

P.S: Have you tried Ukrainian PlatformIO IDE? :)

zserge commented 8 years ago

Круто, дякую! Доречі, такий сценарій як в мене мабуть буде дуже типовий, бо мало хто в продакшені використовує всякі ардуїни, здебільшого кастомні чіпи з малою пам’яттю, бо ціна і всяке таке. То може б детальніше в доках розписати що до чого...

With regards to the IDE - I'm a religious vim user, but Atom seems to be on the rise these days, so I'll definitely give it a try and spread the word about it in my team!

valeros commented 8 years ago

Hi @zserge! Please try development version with build_flags = -Wl,-T${PROJECTSRC_DIR}/stm32f401.ld

zserge commented 8 years ago

Yes, I confirm that this works. Thanks for such a quick fix!

ivankravets commented 8 years ago

@zserge

I'm a religious vim user,

I'm too :blush: I have opened issue to make project generator for VIM which will generate configs for YouCompleteMe, syntastic and etc. https://github.com/platformio/platformio/issues/467

I'll definitely give it a try and spread the word about it in my team!

Thanks a lot! :)