Skip to content

demotomohiro/picosdk4nim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PicoSDK4Nim

This is a library to write Nim code for Raspberry Pi Pico series and wraps Raspberry Pi Pico SDK.

There is already Raspberry Pi Pico SDK for Nim. Why created another tool?

By using this library with hidecmakelinker and write config.nims, you can build your code with nim c blink.nim and it doesn't require nimble. You can wrap C libraries related to Raspberry Pi Pico on Nim module and use it without adding code to build tools.

Requirements

git clone https://github.com/raspberrypi/pico-sdk.git --branch master --depth 1 --recurse-submodules --shallow-submodules
  • Build tools required by Raspberry Pi Pico SDK
    • For more details: https://github.com/raspberrypi/pico-sdk
    • Build or install OpenOCD if you want to use Picoprobe or Raspberry Pi Debug Probe
    • Install picotool if you use it. Pico SDK use it to create UF2 file, hash and sign binaries. If picotool is not installed, Pico SDK automatically download the source and build it. But it takes long time, and it is cached only for one project and it is built again when you compile other projects. If you installed picotool to a custom path, define PicotoolDir with the path to the directory containing picotool by adding -d:PicotoolDir=/path/to/picotool to nim command line options or switch("define", "PicotoolDir=/path/to/picotool") to config.nims. If you don't use picotool, define PicoNoPicotool so that Pico SDK don't build picotool.

How to install

Before installing picosdk4nim, make sure that build tools, CMake and Raspberry Pi Pico SDK are installed, and you can build example C code with CMakeLists.txt in https://github.com/raspberrypi/pico-sdk/blob/master/README.md

Install using nimble:

$ nimble install https://github.com/demotomohiro/picosdk4nim

or install pathX and hidecmakelinker, and clone the project and set Nim import path so that you can import modules in src directory:

$ git clone https://github.com/demotomohiro/picosdk4nim.git

How to use

Create config.nims with following content:

switch("define", "release")
switch("mm", "arc") # use "arc", "orc" or "none"
switch("define", "checkAbi")
switch("define", "useMalloc")
switch("cpu", "arm")
switch("os", "any")
switch("threads", "off")
# If you use C++ backend:
# "quirk" works with C++ backend and produce smallest code, but you would better to learn how it works.
#   See: https://nim-lang.org/araq/quirky_exceptions.html
#        https://github.com/nim-lang/Nim/issues/10713
# "setjmp" works with C++ backend but produced code is larger than quirk. It needs `switch("define", "noCppExceptions")`.
# "cpp" is the default when compiling with C++ backend. It works but produces largest code. You might need to use this when using C++ libraries that throw C++ exceptions.
# "goto" might not work with C++ backend.
#   See: https://github.com/nim-lang/Nim/issues/22686#issuecomment-1713374179
#switch("exceptions", "setjmp")
#switch("define", "noCppExceptions")

switch("gcc.linkerexe", "hidecmakelinker")
switch("gcc.cpp.linkerexe", "hidecmakelinker")
switch("gcc.exe", "void")
switch("gcc.cpp.exe", "void")
nimcacheDir().mkDir()

# If you want .uf2 file
switch("define", "PicoAddExtraOutput")

In main module, following code is needed:

import picosdk4nim
import hidecmakelinkerpkg/libconf

# Call this after importing all modules
writeHideCMakeToFile()

Then you can compile blink.nim with following command:

$ nim c -d:PicoSDKPath=/path/to/pico-sdk/ blink.nim

You can put -d:PicoSDKPath=/path/to/pico-sdk/ option as switch("define", "/path/to/pico-sdk") to config.nims in any directories Nim searches for .nims configuration files.

In default, output binary is compiled for Raspberry Pi Pico board. If you want to run it on other boards with RP series micro controllers, set the board name to PicoBoard build option. For example:

# Build for Raspberry Pi Pico W
$ nim c -d:PicoBoard=pico_w blink.nim

# Build for Raspberry Pi Pico 2
$ nim c -d:PicoBoard=pico2 blink.nim

This is a list of board names If you find the board name in the list, remove '.h' suffix and set it to PicoBoard.

When you add or change PicoBoard or PicoPlatform build option, please clear the Nim cache directory before building. -f option doesn't works in this case because it doesn't delete CMake build directory in Nim cache directory. If you didn't delete the Nim cache directory, you will get CMake error or C code are compiled with wrong compile options.

How to load and run a program on Raspberry Pi Pico

There several ways to loading a program to Pico to run and they are not different from programs compiled from C. See "Getting Started with the Raspberry Pi Pico-Series" in Raspberry Pi Pico SDK for more details.

Mount Pico as USB Mass Storage Device and copy .uf2 file

  1. Build your code with PicoAddExtraOutput so that *.uf2 file is generated
  2. Make sure Pico is disconnect from USB or other power source
  3. Hold down BOOTSEL button on Pico
  4. Connect Pico's USB port to your PC
  5. Release BOOTSEL button on Pico
  6. Pico should be recognized as USB storage on your PC
  7. Copy *.uf2 file to the storage

Loading .elf file to Pico using Picoprobe

Use another Pico as "Picoprobe" and wire it to main Pico. Use OpenOCD on your PC to load a program to Pico. You don't need to connect and disconnect Pico to USB port everytime you load updated program.

  1. Build your code so that *.elf file is generated
  2. Build or install OpenOCD (Read "Appendix A: Debugprobe" in Getting Started with the Raspberry Pi Pico-Series)
  3. If you use a second Pico or Pico 2 instead of Debug Probe, install picoprobe (Read Appedix A again) to it
  4. Wire Picoprobe to another Pico (Read Appedix A again)
  5. Set environment variable OPENOCD_PATH to OpenOCD directory so that $OPENOCD_PATH/src/openocd refers openocd executable
  6. Run following command (replace blink.elf to your *.elf file name):
    $ $OPENOCD_PATH/src/openocd -s $OPENOCD_PATH/tcl -f interface/cmsis-dap.cfg -c "adapter speed 5000" -f target/rp2040.cfg -c "program blink.elf verify reset exit"

Loading .elf file to Pico using Picoprobe without writing to flash memory

Requires Picoprobe, OpenOCD and GDB. Loaded program will be lost when Pico lost power or reset.

  1. Build your code with -d:PicoBinaryType=no_flash
  2. Install GDB (gdb-multiarch or arm-none-eabi-gdb)
  3. Build OpenOCD (Read Appendix A: Debugprobe in Getting Started with the Raspberry Pi Pico-Series)
  4. If you use a second Pico or Pico 2 instead of Debug Probe, install picoprobe (Read Appedix A again) to it
  5. Wire Picoprobe to another Pico (Read Appedix A again)
  6. Set environment variable OPENOCD_PATH to OpenOCD directory so that $OPENOCD_PATH/src/openocd refers openocd executable
  7. Run following command:
    $ $OPENOCD_PATH/src/openocd -s $OPENOCD_PATH/tcl -f interface/cmsis-dap.cfg -c "adapter speed 5000" -f target/rp2040.cfg
  8. Open another terminal and run following command (replace blink.elf to your *.elf file name):
    $ gdb-multiarch blink.elf
    If you use Gentoo Linux:
    $ arm-none-eabi-gdb blink.elf
  9. Connect to OpenOCD on GDB
    (gdb) target extended-remote localhost:3333
  10. Run following commands on GDB
    (gdb) monitor reset init
    (gdb) load
    (gdb) continue

When you change your code and build a new program, press 'c' key with ctrl key on GDB and run following commands again

(gdb) monitor reset init
(gdb) load
(gdb) continue

You can define User-defined Commands using define on GDB:

(gdb) define reload
>monitor reset init
>load
>continue
>end

This commands can be placed on GDB's initialization file.

Build options

There are build options on src/picosdk4nim.nim. They can be set with compiler option like -d:option=value or switch proc like switch("define", "option=value") on config.nims file.

Some of build options are corresponding to CMake build configurations/functions of Raspberry Pi Pico-series C/C++ SDK. List of these options are explained in Chapter 6~7 on Raspberry Pi Pico-Series C/C++ SDK.

About

Library to write Nim code for Raspberry Pi Pico

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages