Hello again. I am fully recovered from Covid. It's time to keep marching forward.
After finishing several projects based on Atmel's 328P MCU (a 328P based complex LFO is here, for instance), it was time to move to a new MCU family--something faster and more powerful.
Contenders for this next evolutionary step in my AudioDiWHY journey were ST Systems' STM32 MCU's and development boards--there are a lot of them--and Espressif's ESP32.
Instead I chose Raspberry Pi's RP2040, the processor found in their PICO development board--mostly because the RP2040 was in stock pretty much everywhere I looked and is extremely affordable.
I chose RP2040 because it's the underdog? |
TOOLCHAIN TIME
Here's how I got an RP2040 C/C++ toolchain up and running on Ubuntu 20.04 Linux.
I targeted the Raspberry Pi Pico development board. It's inexpensive and well documented, and a toolchain that works with the Pico should work with whatever other RP2040-based PCB's I use for future projects.
For this toolchain I needed software and hardware to write and debug RP2040 firmware (I code in C, mostly), compile the code, and upload the firmware onto the RP2040.
I recently set up an Ubuntu 20.04 virtual machine running on VMWARE Workstation Pro 16 on a Windows 10 NUC computer (post about my bench setup is here). I decided to go with this Ubuntu Linux VM for developing on the Pico--I don't use Linux as much at my day job as I'd like, so I'll use it here.
There are many videos and posts about setting up a Linux RP2040 toolchain. The Shawn Hymel YouTube series here proved useful, as were the posts here and here; and the official PDF here. Also, The PDF for the RP2040 SDK is here.
My Ubuntu build was "desktop"--that was my starting point....
First I sudo apt-install'd the software I thought I needed:
(from my home directory….)
mkdir pico
cd pico
sudo apt install git #installs git
git clone -b master https://github.com/raspberrypi/pico-sdk.git
cd
pico-sdk
git submodule update --init
sudo apt upgrade
sudo apt install gcc-arm-none-eabi
sudo apt install libstdc++-arm-none-eabi-newlib
sudo apt install build-essential
sudo apt install cmake # version 3.18.4-2ubuntu1
Can we use RPi's WGET?
To install a RP2040 toolchain on a Raspberry Pi, the RP Foundation provides a wget statement to build the entire toolchain with minimal end user interaction. It's here--go to page 4.
We are not using a Raspberry Pi, rather Ubuntu, which is very close, so this "gee whiz it's easy!" single script approach might have worked. Or would it?
A common Linux trick is to remove the wget from the command, copy the rest of it into your browser, and see what happens.
Here it the resulting URL:
https://raw.githubusercontent.com/raspberrypi/pico-setup/master/pico_setup.sh
Following this URL I saw a shell script....fascinating....and begs the question: who is Liam? regardless, I chased down how the script worked and decided it would be safer to build the Ubuntu part of the toolchain "by hand".
Back to it: To get the system to locate the SDK files for RP2040, I needed to add this via the command line to the Ubuntu PC:
echo 'export PICO_SDK_PATH=$HOME/pico/pico-sdk' | sudo tee -a
/etc/profile.d/pico-sdk.sh
To make that command take effect, I rebooted my Linux virtual machine, but I could have run this additional command:
source /etc/profile
With all this in place, I could compile the example sketches found in ~/pico/examples, build from the command line, drag the UF2 file to the PICO, and--we have BLINK!
We are headed in the right direction.
OK--next question: what IDE to use?
I could write the C code using something like VIM (or Pico--different PICO....) but what fun would that be?
I chose Visual Studio Code, the free (!!) multiplatform, multilanguage IDE from my bestest, smartest, most capitalistic buddies at Microsoft....a kinder gentler Microsoft, the one that no longer misses its meds--is Microsoft finally turning swords into plowshares?
Nope.
Here are the commands I used install and configure VSCODE, I got these from this webpage.
sudo apt install code #install vscode for Ubuntu
code –install-extension marus25.cortex-debug
code –install-extension ms-vscode.cmake-tools
code –install-extension ms-vscode.cpptools
OK, one of the plug-ins needed for VSCode is CMAKE ("cmake-tools"). What is that?
ENTER CMAKE
It's a high level language--yes! an entire scripting language of its own--used to create Makefiles and perform essential software building/compiling automation. CMAKE's webpage is here. Think autotools on steriods.
But--I got frustrated quickly with CMAKE.
Most CMAKE videos and webpages were either geared toward total newbies like me and only discussed basics, like creating a Makefile for a single "hello world.c" file, or were extremely, and I mean extremely, complicated.
For software development shops, needing to compile, test and deploy complex software, CMAKE can do everything--however, CMAKE might be overkill for DIY folks trying to blink LEDs?
In my case CMAKE kept throwing errors. It couldn't find the Pico SDK. This should be easy!
I wasted over 3 hours trying to get this to work.
To get to the bottom of this frustrating issue, I ended up buying a CMAKE book on Amazon (the book I got is the one here).
With that in hand, I figured out the issue (see the "export source" statement above, that alone shoul have worked, but didn't, and the export $PATH statement provided by RP foundation didn't work for me--nor did tweaking path variables in VSCODE).
I am still not sure what caused the issue, or what fixed it, exactly--this should have been a really easy fix; it's just an export statement, but for some reason it wouldn't work for a very long time, then started working for reasons unknown.
Whatever--there is a whole career scripting CMAKE, right? To learn more, the original CMAKE guy talks about his whole enchilada, here.
Monkey CMAKE, Monkey C-DO
CMAKE requires a single script in the project's root to work--called CMakeLists.txt. No, you can't rename this file. No, you can't move it to some other folder.
Here is the CMakeLists.txt I got to work for a blinkcl.c test program, which, well, blinks a damn LED.
######
cmake_minimum_required(VERSION 3.13)
#include the cmake build functions from pico SDK
include(pico_sdk_import.cmake)
#project name and code here
project(BLINKCL C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
#bring in this function to add cmake Pico SDK functionality to build
pico_sdk_init()
#list out files used
add_executable(${PROJECT_NAME}
blinkcl.c add.c
)
#create extra uf2 etc files to copy to PICO via USB
pico_add_extra_outputs(${PROJECT_NAME})
#linker needs to use these libraries
target_link_libraries(${PROJECT_NAME}
pico_stdlib
)
###################
You may want to change the project name ("BLINKCL") and filenames ("blinkcl.c", "add.c") if you want to use the CMakeLists.txt files below as a basis for your own projects.
And! One more thing--you don't need to list out .h files in CMakeLists.txt if they are in the same directory as your .c files.
Blink me up, Scotty?
My goal was to have 2 .c files, one .h file and everything else needed to build a multifile blink project.
Here's the code:
#################################
#blinkcl.c
#include "pico/stdlib.h"
#include "add.h"
int main() {
uint16_t time;
time = add2nums(100,100);
const uint LED_PIN = PICO_DEFAULT_LED_PIN;
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
while (true) {
gpio_put(LED_PIN, 1);
sleep_ms(time);
gpio_put(LED_PIN, 0);
sleep_ms(100);
}
}
#############################
#add.c
#include "add.h"
uint16_t add2nums(uint16_t a, uint16_t b) {
uint16_t x = (a + b);
return x;
}
I built the firmware from these files without having to leave VSCODE.
Yes the add.h file, the add2nums function, etc. are not needed, but I wanted to make sure the toolchain could deal with multiple .h and .c files. Yes, it could.
A tip, mentioned everywhere online when CMAKE is being discussed: if I altered my CMakeLists.txt file, I had to delete the entire build directory in my BLINKCL project folder then build the software again. Yes, I saw this, over and over.
Last thing I did was get USB serial working for simple debugging. I wanted to know the value of variable x?
printf("x is: %d",x);
This is very basic debugging.
It turned out to be pretty easy. I had to add this to the bottom of the CMakeLists.txt, rename the project, and rename .c files used:
#control USB output--1 means on.
pico_enable_stdio_usb(${PROJECT_NAME} 1)
pico_enable_stdio_uart(${PROJECT_NAME} 0)
Then I used this bash script from terminal to get minicom going.
#!/bin/bash
sudo minicom -b 115200 -o -D /dev/ttyACM0
- The serial port won't work (and minicom will close immediately) if there is no UF2 file loaded on the dev board.
- Same if the printf or whatever is generating serial data is incorrectly crafted in code--just because it compiles doesn't mean it will work.
- I upload a USB serial UF2 on the RP2040 dev board--it has a printf() statement for instance.
- this sends "hello world" or whatever out the USB port for a computer to display via a terminal program.
- The Windows machine sees new USB serial traffic
- An interrupt is sent to the Windows OS (?? How does this really work? I paid for a support ticket at VMware, to have them explain--but the tech seemed unwilling or unable do that beyond pointing me to the documents I've already linked in this post. If I get time, I may dig into this more and try to reverse engineer vmware "USB passthrough" technology, to better understand it, beyond the dreaded "plug it in and it just works" excuse)
- I choose "USB needs to appear on the VM" from the VMware USB passthrough UI.
- Windows puts a VMware USB driver on the newly found port (?), giving up control of it.
- ttyASM0 is created on Ubuntu, hopefully. This is the /dev file created when Ubuntu sees a CDC USB device, which apparently is what the passed through USB is.
- I load up minicom and can (on a good day) see the serial output via /dev/ttyASM0.
This could be cleaned up....maybe a breakout board for UART is needed, with LEDs for TX and RX activity? I already fabricated a better looking serial cable. That might be good enough. |
Bravo!! Some things I am going to try myself!
ReplyDelete