lars_the_bear
Posts: 231
Joined: Thu Jan 28, 2021 8:13 pm

Re: Blink from scratch

Tue Feb 16, 2021 7:18 pm

nick.mccloud wrote:
Tue Feb 16, 2021 6:10 pm
You didn't say that you wanted to make UF2 files without CMake until after this post. Or if you did, for which I apologise, it wasn't obvious to me.
No, my bad. I probably wasn't clear. To me, avoiding the use of CMake, and understanding the build process properly, are variants of the same thing. I can't do the one without the other. I don't want to use CMake for two, somewhat related reasons: first, it conceals the details of the build, which I find interesting and want to understand. And, second, I just can't get it to do what seem to me to be perfectly straightforward things. If I could get it to do what I wanted, I might be prepared to stifle my annoyance at interesting technical details being concealed.

Kevin.

PS. I'm aware, to my chagrin, that I've hijacked another thread to complain about CMake. Sorry.

User avatar
nick.mccloud
Posts: 1280
Joined: Sat Feb 04, 2012 4:18 pm

Re: Blink from scratch

Tue Feb 16, 2021 7:26 pm

As I understand it, all CMake does is create the Make file - so you might want to dig through that.
Pico/RP2040 ≠ Arduino
Pico = hot rod kit car, Arduino = hot rod kit car wrapped in cotton wool with buoyancy aids & parachute

lars_the_bear
Posts: 231
Joined: Thu Jan 28, 2021 8:13 pm

Re: Blink from scratch

Tue Feb 16, 2021 8:33 pm

nick.mccloud wrote:
Tue Feb 16, 2021 7:26 pm
As I understand it, all CMake does is create the Make file - so you might want to dig through that.
It's incomprehensible. The machine-generated Makefiles reference all sorts of scripts and stuff, all scattered through the installation. It even -- or so it appears to me -- modifies the output of the compiler using Python scripts. The process is truly horrendous.

Kevin.

ejolson
Posts: 9782
Joined: Tue Mar 18, 2014 11:47 am

Re: Blink from scratch

Tue Feb 16, 2021 9:05 pm

lars_the_bear wrote:
Tue Feb 16, 2021 8:33 pm
nick.mccloud wrote:
Tue Feb 16, 2021 7:26 pm
As I understand it, all CMake does is create the Make file - so you might want to dig through that.
It's incomprehensible. The machine-generated Makefiles reference all sorts of scripts and stuff, all scattered through the installation. It even -- or so it appears to me -- modifies the output of the compiler using Python scripts. The process is truly horrendous.

Kevin.
I think it's interesting that
David Given wrote: Working with the Pico was an experience: the documentation is excellent, as is the C SDK. The SDK provides a set of libraries which are thin wrappers around the underlying hardware, making most features utter simplicity to use. Unlike the ESP8266’s libraries, the Pico SDK is unopinionated and doesn’t require you to use any of its features: if you want to talk directly to the hardware, you can (and in fact there’s library support for doing just this).
He then goes on to say
There are some niggles, such as the almost non-negotiable requirement to use cmake as your build system. cmake is pretty ghastly but to be honest build systems are always terrible, and cmake’s not the worst choice. Once I nerved myself to trust it, it was a breeze to use and the Pico SDK’s cmake addons make building binaries and flashable images trivial.
http://cowlark.com/2021-02-16-fuzix-pi-pico/

One should note that David has ported Fuzix, which is a Unix-like operating system established by Alan Cox, to the Pico. While more complicated than blink, I think David's comment that the use of cmake is almost non-negotiable when building images for the Pico is significant.

PiGraham
Posts: 5093
Joined: Fri Jun 07, 2013 12:37 pm
Location: Waterlooville

Re: Blink from scratch

Tue Feb 16, 2021 9:24 pm

ejolson wrote:
Tue Feb 16, 2021 9:05 pm

http://cowlark.com/2021-02-16-fuzix-pi-pico/

One should note that David has ported Fuzix, which is a Unix-like operating system established by Alan Cox, to the Pico. While more complicated than blink, I think David's comment that the use of cmake is almost non-negotiable when building images for the Pico is significant.
Interesting. Thanks for posting that. Quite a project!

Odd that he states
2MB of NAND flash on chip
When there is no flash on chip. But I guess he is more about software than precise details of hardware.

WestfW
Posts: 212
Joined: Tue Nov 01, 2011 9:56 pm

Re: Blink from scratch

Tue Feb 16, 2021 9:41 pm

this should be easy
Well, you could presumably use an SWD debug probe of some kind, and you wouldn't need to interact with the bootloader at all. AFAIK, most debuggers will understand .elf files directly.
Asking for how a reasonably detailed explanation of how the build process works, distinct from the tooling, doesn't seem to me to be a particularly big ask.
CMAKE and ELF2UF2 are not new tools from the Raspberry Pi people; they're standard tools from other places. Asking RPi to document them is a bit like asking them to document all of the gcc command-line switches. They HAVE documentation (perhaps not up to the standard of the rest of the Pico documentation.)

a completely generic linker like the one in arm-none-eabi won't even produce a meaningful binary that can be passed to elf2uf2 unless it knows something about the memory map of the target device.
This is true of any microcontroller. And we do know about the memory map of the target device - that's all in the datasheet.
The SDK build process uses a script "pico_standard_link/memmap_default.ld" with a heap of memory location and size definitions to feed the linker.
And there is a similar default .ld file for any other thing that you compile for. Not many people really understand all of its content, any more than they understand the actual internal format of a .elf file.
It seems to me that the road from an object file to a UF2 file is a long, tortuous one, with no signposts.
Not much more so than the road from object file to .hex or .bin file for any other microcontroller. Or for that matter, the process of actually loading an object file into the user address space on something like a linux system.
We need to know how to use the ARM toolchain to produce ELF files that are palatable to elf2uf2. That tool _does_ require a second stage bootloader (whatever it is), else it bombs. I don't know what else it needs -- I haven't got past the "second stage bootloader" problem yet.
Loading code into most ARM microcontrollers involves something like a secondary bootloader. This is because the flash memory that you're writing to is controlled by some sort of "flash memory controller" that is proprietary to the vendor rather than part of the ARM core, and thus requires specific and varied code to write to it. Since the RP2040 writes its code in an external flash chip, it has an additional complication that you want it to support at least several varieties of such chips. And you have to put the chip back into XIP mode after code is loaded.


Other complications in the build process are due to wanting to access the ROM code for floating point and etc. I wish all the "-Wl,--wrap=__xxx" that end up in the link statement were hidden somewhere instead, since they really clutter up understanding the build logs...

I'll see if I can come up with a trivial build example.

lars_the_bear
Posts: 231
Joined: Thu Jan 28, 2021 8:13 pm

Re: Blink from scratch

Tue Feb 16, 2021 9:54 pm

WestfW wrote:
Tue Feb 16, 2021 9:41 pm
Loading code into most ARM microcontrollers involves something like a secondary bootloader. This is because the flash memory that you're writing to is controlled by some sort of "flash memory controller" that is proprietary to the vendor rather than part of the ARM core, and thus requires specific and varied code to write to it. Since the RP2040 writes its code in an external flash chip, it has an additional complication that you want it to support at least several varieties of such chips. And you have to put the chip back into XIP mode after code is loaded.
Sure. I understand (now) the role of this "second stage bootloader", but I don't really see why it needs to be built from source in every build. For a specific chip it's not going to change (I guess) and it's only 256 bytes long.

I'm also trying to work out an example but, sadly, I have a day-job ;)

Kevin

PS. Although the UF2 format is generic, I think elf2uf2 is specific to the Pico SDK. At least, the source has a bunch of literals in that I don't think are generic, like:

#define FLASH_START 0x10000000u

Similarly, although CMake is widely used, it's the way that the Pico SDK uses CMake that I find baffling (well, I find CMake baffling in general, to be honest).

WestfW
Posts: 212
Joined: Tue Nov 01, 2011 9:56 pm

Re: Blink from scratch

Tue Feb 16, 2021 11:39 pm

the way that the Pico SDK uses CMake that I find baffling
Most build systems seem to grow in incomprehensibility until they are baffling. I have a particular dislike for "automatically-generated" Makefiles. :-( (Although, the hand-created Makefile for a large project I used to work on also reach the baffling stage; you had to find one of the few experts at the company if you thought it needed some sort of change.)

Did you see Section 2.8.2.x in the RP2040 data sheet? It goes into the boot sequence in some detail (including the second stage)
I don't really see why it needs to be built from source in every build.
I don't think it does. It just decides NOT to build it, with great verbosity :-( If you turn on verbose build output, you'll see:
(Hmm. It does seem to build a separate copy for each project, though.)
/Library/Developer/CommandLineTools/usr/bin/make -f blink/CMakeFiles/ELF2UF2Build.dir/build.make blink/CMakeFiles/ELF2UF2Build.dir/depend
cd /Volumes/MacOS/HD-Users/BillW/src-import/pico-examples/build && /Applications/CMake.app/Contents/bin/cmake -E cmake_depends "Unix Makefiles" /Volumes/MacOS/HD-Users/BillW/src-import/pico-examples /Volumes/MacOS/HD-Users/BillW/src-import/pico-examples/blink /Volumes/MacOS/HD-Users/BillW/src-import/pico-examples/build /Volumes/MacOS/HD-Users/BillW/src-import/pico-examples/build/blink /Volumes/MacOS/HD-Users/BillW/src-import/pico-examples/build/blink/CMakeFiles/ELF2UF2Build.dir/DependInfo.cmake --color=
/Library/Developer/CommandLineTools/usr/bin/make -f blink/CMakeFiles/ELF2UF2Build.dir/build.make blink/CMakeFiles/ELF2UF2Build.dir/build
[ 0%] Performing build step for 'ELF2UF2Build'
cd /Volumes/MacOS/HD-Users/BillW/src-import/pico-examples/build/elf2uf2 && /Library/Developer/CommandLineTools/usr/bin/make
/Applications/CMake.app/Contents/bin/cmake -S/Volumes/MacOS/HD-Users/BillW/src-import/RPi-pico/tools/elf2uf2 -B/Volumes/MacOS/HD-Users/BillW/src-import/pico-examples/build/elf2uf2 --check-build-system CMakeFiles/Makefile.cmake 0
/Applications/CMake.app/Contents/bin/cmake -E cmake_progress_start /Volumes/MacOS/HD-Users/BillW/src-import/pico-examples/build/elf2uf2/CMakeFiles /Volumes/MacOS/HD-Users/BillW/src-import/pico-examples/build/elf2uf2//CMakeFiles/progress.marks
/Library/Developer/CommandLineTools/usr/bin/make -f CMakeFiles/Makefile2 all
/Library/Developer/CommandLineTools/usr/bin/make -f CMakeFiles/elf2uf2.dir/build.make CMakeFiles/elf2uf2.dir/depend
cd /Volumes/MacOS/HD-Users/BillW/src-import/pico-examples/build/elf2uf2 && /Applications/CMake.app/Contents/bin/cmake -E cmake_depends "Unix Makefiles" /Volumes/MacOS/HD-Users/BillW/src-import/RPi-pico/tools/elf2uf2 /Volumes/MacOS/HD-Users/BillW/src-import/RPi-pico/tools/elf2uf2 /Volumes/MacOS/HD-Users/BillW/src-import/pico-examples/build/elf2uf2 /Volumes/MacOS/HD-Users/BillW/src-import/pico-examples/build/elf2uf2 /Volumes/MacOS/HD-Users/BillW/src-import/pico-examples/build/elf2uf2/CMakeFiles/elf2uf2.dir/DependInfo.cmake --color=
/Library/Developer/CommandLineTools/usr/bin/make -f CMakeFiles/elf2uf2.dir/build.make CMakeFiles/elf2uf2.dir/build
make[5]: Nothing to be done for `CMakeFiles/elf2uf2.dir/build'.
[100%] Built target elf2uf2
I think elf2uf2 is specific to the Pico SDK.
Hmm. Could be; other people using UF2 seem to use a python script... (eg https://github.com/microsoft/uf2/blob/m ... uf2conv.py )

WestfW
Posts: 212
Joined: Tue Nov 01, 2011 9:56 pm

Re: Blink from scratch

Sat Feb 20, 2021 10:12 am

I have it pared down to this:

Code: Select all

/usr/local/gcc-arm-8-2019-q3/bin/arm-none-eabi-g++  \
-march=armv6-m -mcpu=cortex-m0plus -mthumb -O3 -DNDEBUG  \
-Wl,--build-id=none --specs=nosys.specs -nostartfiles -nostdlib \
-Wl,--script=/Volumes/MacOS/HD-Users/BillW/src-import/RPi-pico/src/rp2_common/pico_standard_link/memmap_no_flash.ld  \
CMakeFiles/test.dir/test.c.obj \
CMakeFiles/test.dir/Volumes/MacOS/HD-Users/BillW/src-import/RPi-pico/src/rp2_common/pico_standard_link/crt0.S.obj  \
CMakeFiles/test.dir/Volumes/MacOS/HD-Users/BillW/src-import/RPi-pico/src/rp2_common/pico_bootrom/bootrom.c.obj  \
-Wl,-defsym -Wl,exit=0x5  \
-o testmin.elf 

elf2uf2/elf2uf2 testmin.elf testmin.uf2
assumes that the individual obj files have been built via CMAKE with CMakefiles.txt containing:

Code: Select all

cmake_minimum_required(VERSION 3.13)
include(pico_sdk_import.cmake)
project(test_project)
pico_sdk_init()
add_executable(test
    test.c
)
pico_add_extra_outputs(test)
pico_set_binary_type(test no_flash)
set (pico_bare_metal 1)
target_link_libraries(test pico_stdlib)
And Source code:

Code: Select all

#include <stdint.h>
#include <hardware/resets.h>

#define PICO_BUILD 1

#ifdef PICO_BUILD
#  define IOBUS 0xD0000000
#  define LED_BUILTIN 25
#  define LED_BITMASK (1<<LED_BUILTIN)
#  define ALLOUTPUTS LED_BITMASK
#  define DIR *(uint32_t *)(IOBUS+0x20)
#  define OUT *(uint32_t *)(IOBUS+0x10)
#  define CONFIG 0x40014000
// Default clock is internal ring oscillator at ~6MHz
#  define CLOCK 6000000
void io_init() {
    unreset_block_wait(RESETS_RESET_PADS_BANK0_BITS |     // turn on GPIO
                       RESETS_RESET_IO_BANK0_BITS);
    *(uint32_t*)(CONFIG+(LED_BUILTIN*8)+4) = 5; // set pin to IO func
}
#endif

// Guess how many cycles per loop for the delay function.
#define CYCLEGUESS 10

void __attribute__((noinline)) delay()
{
    for (volatile int i=0; i < CLOCK/CYCLEGUESS; i++) {
    }
}

int main() {
    io_init();
    DIR = ALLOUTPUTS;
    while (1) {
        OUT = LED_BITMASK;
        delay();
        OUT = 0;
        delay();
    }
}

Return to “SDK”