How do we build it? Some surprises arise immediately.
The Readme in the examples and for the SDK are all but useless.
Some searches lead me to do what I would never have expected,
namely this:
git clone the above ... then cd pico-examples export PICO_SDK_PATH=../../pico-sdk/ mkdir build cd build cmake ..After you do that, from that "global" build directory, you can do:
make blinkWho would have guessed?
Here is the build output from "make blink"
So, we have a million subdirectories in the "build" directory now, but where the heck is blink.elf? It is in the directory "blink/blink.elf". There is a Makefile in there also, a 2352 line monster generated by cmake. We even have a blink.uf2 file! The tragic thing is that the build log says nothing about how this was generated.After doing all this, I make a trivial edit to blink.c then repeat the build to get:
[tom@trona build]$ make blink [ 0%] Performing build step for 'ELF2UF2Build' [100%] Built target elf2uf2 [ 0%] No install step for 'ELF2UF2Build' [ 0%] Completed 'ELF2UF2Build' [ 0%] Built target ELF2UF2Build [ 0%] Built target bs2_default [ 0%] Built target bs2_default_padded_checksummed_asm [ 0%] Building C object blink/CMakeFiles/blink.dir/blink.c.obj [ 0%] Linking CXX executable blink.elf [100%] Built target blinkThese steps would be worth studying in detail.
The Makefiles are gigantic monstrosities. They yield (I suppose) functionality, but inadvertantly produce obfuscation.
A brief study of the Makefile reveals a useful trick. Set VERBOSE to anything and you will get much more output, as follows:
touch ../blink/blink.c make VERBOSE=xxx blinkThis yields the output shown here.: Ignoring the gigantic link line, and replacing some long directory paths, the build ends as follows:
cd /u1/Projects/rp2040/pico-examples/build/blink /usr/bin/arm-none-eabi-objcopy -Oihex blink.elf blink.hex /usr/bin/arm-none-eabi-objcopy -Obinary blink.elf blink.bin /usr/bin/arm-none-eabi-objdump -h blink.elf > blink.dis /usr/bin/arm-none-eabi-objdump -d blink.elf >> blink.dis ../elf2uf2/elf2uf2 blink.elf blink.uf2So, "objcopy" is used in a variety of ways to extract and present information. Finally a tool "elf2uf2" is used to generate the uf2 file.
I boil down the all important link line as follows:
cd /u1/Projects/rp2040/pico-examples/build/blink /usr/bin/cmake -E cmake_link_script CMakeFiles/blink.dir/link.txt --verbose=xxx /usr/bin/arm-none-eabi-g++ -mcpu=cortex-m0plus -mthumb -O3 -DNDEBUG -Wl,--build-id=none --specs=nosys.specs -Wl,--wrap=sprintf -Wl,--wrap=snprintf -Wl,--wrap=vsnprintf -Wl,--wrap=__clzsi2 -Wl,--wrap=__clzdi2 -Wl,--wrap=__ctzsi2 -Wl,--wrap=__ctzdi2 -Wl,--wrap=__popcountsi2 -Wl,--wrap=__popcountdi2 -Wl,--wrap=__clz -Wl,--wrap=__clzl -Wl,--wrap=__clzll -Wl,--wrap=__aeabi_idiv -Wl,--wrap=__aeabi_idivmod -Wl,--wrap=__aeabi_ldivmod -Wl,--wrap=__aeabi_uidiv -Wl,--wrap=__aeabi_uidivmod -Wl,--wrap=__aeabi_uldivmod -Wl,--wrap=__aeabi_dadd -Wl,--wrap=__aeabi_ddiv -Wl,--wrap=__aeabi_dmul -Wl,--wrap=__aeabi_drsub -Wl,--wrap=__aeabi_dsub -Wl,--wrap=__aeabi_cdcmpeq -Wl,--wrap=__aeabi_cdrcmple -Wl,--wrap=__aeabi_cdcmple -Wl,--wrap=__aeabi_dcmpeq -Wl,--wrap=__aeabi_dcmplt -Wl,--wrap=__aeabi_dcmple -Wl,--wrap=__aeabi_dcmpge -Wl,--wrap=__aeabi_dcmpgt -Wl,--wrap=__aeabi_dcmpun -Wl,--wrap=__aeabi_i2d -Wl,--wrap=__aeabi_l2d -Wl,--wrap=__aeabi_ui2d -Wl,--wrap=__aeabi_ul2d -Wl,--wrap=__aeabi_d2iz -Wl,--wrap=__aeabi_d2lz -Wl,--wrap=__aeabi_d2uiz -Wl,--wrap=__aeabi_d2ulz -Wl,--wrap=__aeabi_d2f -Wl,--wrap=sqrt -Wl,--wrap=cos -Wl,--wrap=sin -Wl,--wrap=tan -Wl,--wrap=atan2 -Wl,--wrap=exp -Wl,--wrap=log -Wl,--wrap=ldexp -Wl,--wrap=copysign -Wl,--wrap=trunc -Wl,--wrap=floor -Wl,--wrap=ceil -Wl,--wrap=round -Wl,--wrap=sincos -Wl,--wrap=asin -Wl,--wrap=acos -Wl,--wrap=atan -Wl,--wrap=sinh -Wl,--wrap=cosh -Wl,--wrap=tanh -Wl,--wrap=asinh -Wl,--wrap=acosh -Wl,--wrap=atanh -Wl,--wrap=exp2 -Wl,--wrap=log2 -Wl,--wrap=exp10 -Wl,--wrap=log10 -Wl,--wrap=pow -Wl,--wrap=powint -Wl,--wrap=hypot -Wl,--wrap=cbrt -Wl,--wrap=fmod -Wl,--wrap=drem -Wl,--wrap=remainder -Wl,--wrap=remquo -Wl,--wrap=expm1 -Wl,--wrap=log1p -Wl,--wrap=fma -Wl,--wrap=__aeabi_lmul -Wl,--wrap=__aeabi_fadd -Wl,--wrap=__aeabi_fdiv -Wl,--wrap=__aeabi_fmul -Wl,--wrap=__aeabi_frsub -Wl,--wrap=__aeabi_fsub -Wl,--wrap=__aeabi_cfcmpeq -Wl,--wrap=__aeabi_cfrcmple -Wl,--wrap=__aeabi_cfcmple -Wl,--wrap=__aeabi_fcmpeq -Wl,--wrap=__aeabi_fcmplt -Wl,--wrap=__aeabi_fcmple -Wl,--wrap=__aeabi_fcmpge -Wl,--wrap=__aeabi_fcmpgt -Wl,--wrap=__aeabi_fcmpun -Wl,--wrap=__aeabi_i2f -Wl,--wrap=__aeabi_l2f -Wl,--wrap=__aeabi_ui2f -Wl,--wrap=__aeabi_ul2f -Wl,--wrap=__aeabi_f2iz -Wl,--wrap=__aeabi_f2lz -Wl,--wrap=__aeabi_f2uiz -Wl,--wrap=__aeabi_f2ulz -Wl,--wrap=__aeabi_f2d -Wl,--wrap=sqrtf -Wl,--wrap=cosf -Wl,--wrap=sinf -Wl,--wrap=tanf -Wl,--wrap=atan2f -Wl,--wrap=expf -Wl,--wrap=logf -Wl,--wrap=ldexpf -Wl,--wrap=copysignf -Wl,--wrap=truncf -Wl,--wrap=floorf -Wl,--wrap=ceilf -Wl,--wrap=roundf -Wl,--wrap=sincosf -Wl,--wrap=asinf -Wl,--wrap=acosf -Wl,--wrap=atanf -Wl,--wrap=sinhf -Wl,--wrap=coshf -Wl,--wrap=tanhf -Wl,--wrap=asinhf -Wl,--wrap=acoshf -Wl,--wrap=atanhf -Wl,--wrap=exp2f -Wl,--wrap=log2f -Wl,--wrap=exp10f -Wl,--wrap=log10f -Wl,--wrap=powf -Wl,--wrap=powintf -Wl,--wrap=hypotf -Wl,--wrap=cbrtf -Wl,--wrap=fmodf -Wl,--wrap=dremf -Wl,--wrap=remainderf -Wl,--wrap=remquof -Wl,--wrap=expm1f -Wl,--wrap=log1pf -Wl,--wrap=fmaf -Wl,--wrap=malloc -Wl,--wrap=calloc -Wl,--wrap=realloc -Wl,--wrap=free -Wl,--wrap=memcpy -Wl,--wrap=memset -Wl,--wrap=__aeabi_memcpy -Wl,--wrap=__aeabi_memset -Wl,--wrap=__aeabi_memcpy4 -Wl,--wrap=__aeabi_memset4 -Wl,--wrap=__aeabi_memcpy8 -Wl,--wrap=__aeabi_memset8 -Wl,-Map=blink.elf.map -Wl,--script=/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_standard_link/memmap_default.ld -Wl,-z,max-page-size=4096 -Wl,--gc-sections -Wl,--no-warn-rwx-segments -Wl,--wrap=printf -Wl,--wrap=vprintf -Wl,--wrap=puts -Wl,--wrap=putchar -Wl,--wrap=getchar CMakeFiles/blink.dir/blink.c.obj "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_stdlib/stdlib.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/hardware_gpio/gpio.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_platform/platform.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/hardware_claim/claim.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/hardware_sync/sync.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/hardware_irq/irq.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/hardware_irq/irq_handler_chain.S.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/common/pico_sync/sem.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/common/pico_sync/lock_core.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/common/pico_sync/mutex.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/common/pico_sync/critical_section.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/common/pico_time/time.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/common/pico_time/timeout_helper.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/hardware_timer/timer.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/common/pico_util/datetime.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/common/pico_util/pheap.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/common/pico_util/queue.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/hardware_uart/uart.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/hardware_clocks/clocks.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/hardware_pll/pll.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/hardware_vreg/vreg.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/hardware_watchdog/watchdog.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/hardware_xosc/xosc.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/hardware_divider/divider.S.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_runtime/runtime.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_printf/printf.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_bit_ops/bit_ops_aeabi.S.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_bootrom/bootrom.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_divider/divider.S.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_double/double_aeabi.S.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_double/double_init_rom.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_double/double_math.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_double/double_v1_rom_shim.S.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_int64_ops/pico_int64_ops_aeabi.S.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_float/float_aeabi.S.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_float/float_init_rom.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_float/float_math.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_float/float_v1_rom_shim.S.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_malloc/pico_malloc.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_mem_ops/mem_ops_aeabi.S.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_standard_link/crt0.S.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_standard_link/new_delete.cpp.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_standard_link/binary_info.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_stdio/stdio.c.obj" "CMakeFiles/blink.dir/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_stdio_uart/stdio_uart.c.obj" -o blink.elf ../pico-sdk/src/rp2_common/boot_stage2/bs2_default_padded_checksummed.SNotice buried in the midst of all this:
-Wl,--script=/u1/Projects/rp2040/pico-sdk/src/rp2_common/pico_standard_link/memmap_default.ld -Wl,-z,max-page-size=4096 -Wl,--gc-sections -Wl,--no-warn-rwx-segmentsThe linker script is also big (251 lines), and interesting.
I am somewhat distressed to see that g++ is used to do the linking (I have every hope of avoiding C++ in my dealings with the rp2040).
The stage 2 bootloader is what first got me interested in all of this. Note that the file is not located in the sdk distribution itself, the full path is:
/u1/Projects/rp2040/pico-examples/build/pico-sdk/src/rp2_common/boot_stage2/bs2_default_padded_checksummed.SAmusingly this is a block of binary information, regenerated as assembly code. To find out how this is generated, we will have to redo the original build step with VERBOSE set and dig out the relevant lines.
cd pico-examples export PICO_SDK_PATH=../../pico-sdk/ rm -rf build mkdir build cd build cmake .. make VERBOSE=xxx blinkThis goes quicker than you might think.
There are two topics of interest in this for me. First is "elf2uf2". Here I have tried to condense and simplify the "log" of what was done and I won't claim that I might no have made mistakes.
cd /u1/Projects/rp2040/pico-examples/build/elf2uf2 /usr/bin/cmake -E touch /u1/Projects/rp2040/pico-examples/build/blink/elf2uf2/src/ELF2UF2Build-stamp/ELF2UF2Build-configure make /usr/bin/cmake -S/u1/Projects/rp2040/pico-sdk/tools/elf2uf2 -B/u1/Projects/rp2040/pico-examples/build/elf2uf2 --check-build-system CMakeFiles/Makefile.cmake 0 /usr/bin/cmake -E cmake_progress_start /u1/Projects/rp2040/pico-examples/build/elf2uf2/CMakeFiles /u1/Projects/rp2040/pico-examples/build/elf2uf2//CMakeFiles/progress.marks make -f CMakeFiles/Makefile2 all make -f CMakeFiles/elf2uf2.dir/build.make CMakeFiles/elf2uf2.dir/depend /usr/bin/cmake -E cmake_depends "Unix Makefiles" /u1/Projects/rp2040/pico-sdk/tools/elf2uf2 /u1/Projects/rp2040/pico-sdk/tools/elf2uf2 /u1/Projects/rp2040/pico-examples/build/elf2uf2 /u1/Projects/rp2040/pico-examples/build/elf2uf2 /u1/Projects/rp2040/pico-examples/build/elf2uf2/CMakeFiles/elf2uf2.dir/DependInfo.cmake "--color=" make -f CMakeFiles/elf2uf2.dir/build.make CMakeFiles/elf2uf2.dir/build /usr/bin/c++ -I/u1/Projects/rp2040/pico-sdk/src/common/boot_uf2/include -std=gnu++14 -MD -MT CMakeFiles/elf2uf2.dir/main.cpp.o -MF CMakeFiles/elf2uf2.dir/main.cpp.o.d -o CMakeFiles/elf2uf2.dir/main.cpp.o -c /u1/Projects/rp2040/pico-sdk/tools/elf2uf2/main.cpp /usr/bin/cmake -E cmake_link_script CMakeFiles/elf2uf2.dir/link.txt --verbose=xxx /usr/bin/c++ CMakeFiles/elf2uf2.dir/main.cpp.o -o elf2uf2
cp blink.uf2 /run/media/tom/RPI-RP2/And the LED gets to blinking! And when I hit reset, it runs the blink demo every time, so this has successfully made its way to flash. A complete success.
The example source is in: pico-examples/build/blink
The example is built by: cd pico-examples/build ; make blink
The build results end up in: pico-examples/build/blink
Tom's electronics pages / [email protected]