Let's spin a stepper motor using ESP-IDF (FreeRTOS) on an ESP32!
Since the development environment is still chunky let's pay down that debt a bit
VSCode Espressif IDF
Error looking for python in system Source: Espressif IDF (Extension)
The python being used here is embedded into the esp-idf
package and vscode appears to be struggling to find it.
By updating the esp-idf.nix
package to expose python several environment variables can be exposed in the environment, which can be added to the vscode configuration using the ${env:PYTHONHOME}
convention.
In addition the esp32-toolchain.nix
was rebuilt extensively to parse the tools.json file and download several tools at once.
The onboarding sequence can be followed by outputting the resolved nix store paths into all of the options, unfortunately we cannot progress past "Verify Python packages requirements" due to the error
Python or pip have not been found in your environment
Using the classic "search for error message in source" the relevant code was found
The function signature
export async function getUnixPythonList(workingDir: string) {
return await utils.execChildProcess("which -a python python3", workingDir).then((result) => {
indicates which is being used, now to figure out workingDir
...
Using githubs code navigation we eventually arrive at
https://github.com/espressif/vscode-esp-idf-extension/blob/6ebdcfcaa2cf9527d3f98e1fb0fb521f9688f5d7/src/extension.ts#L443
Wouldn't it be handy to have a debugger?
Let's Build the extension from source
git clone https://github.com/espressif/vscode-esp-idf-extension.git
cd vscode-esp-idf-extension
yarn
yarn run compile
yarn run webpack
code .
Slapping a breakpoint, hitting f5 to debug and heck yah
Several iterations later the vscode settings file can be created: .vscode/settings.json
{
"idf.pythonBinPath": "${env:PYTHONHOME}/bin/python",
"idf.pythonSystemBinPath": "${env:PYTHONHOME}/bin/python",
"idf.toolsPath": "${env:IDF_TOOLS_PATH}",
"idf.showOnboardingOnInit": false
}
VSCode cpptools
Unable to start the C/C++ language server. IntelliSense features will be disabled. Error: Launching server using command /home/username/.vscode/extensions/ms-vscode.cpptools-0.26.3/bin/Microsoft.VSCode.CPP.Extension.linux failed.
The cpptools language server is distributed as a C# binary which inevitably doesn't work with nix.
This post by danbst provides a nixos configuration module for combining nix packaged extensions with vscode imperative ones.
Since I'm using home-manager I'll have to tweak things a bit. This issue shows how to load a custom module in a home-manager context and home.activation is an alternative to system.activationScripts
~/.config/nixpkgs/vscode.nix
{ config, pkgs, lib, system, ... }: {
options = {
vscode.extensions = lib.mkOption { default = []; };
vscode.user = lib.mkOption { }; # <- Must be supplied
vscode.homeDir = lib.mkOption { }; # <- Must be supplied
};
config = {
home.packages = [ pkgs.vscode ];
home.activation.fix-vscode-extensions = config.lib.dag.entryAfter ["writeBoundary"] ''
EXT_DIR=${config.vscode.homeDir}/.vscode/extensions
$DRY_RUN_CMD mkdir -p $EXT_DIR
$DRY_RUN_CMD chown ${config.vscode.user}:users $EXT_DIR
for x in ${lib.concatMapStringsSep " " toString config.vscode.extensions}; do
$DRY_RUN_CMD ln -sf $x/share/vscode/extensions/* $EXT_DIR/
done
$DRY_RUN_CMD chown -R ${config.vscode.user}:users $EXT_DIR
'';
};
}
~/.config/nixpkgs/home.nix
imports = [
./vscode.nix
];
vscode.user = "username";
vscode.homeDir = "/home/username";
vscode.extensions = with pkgs.vscode-extensions; [
ms-vscode.cpptools
];
$ home-manager switch
...
$ ls -la ~/.vscode/extensions
total 56
...
drwxr-xr-x 7 username users 4096 Mar 13 19:09 espressif.esp-idf-extension-0.1.4
lrwxrwxrwx 1 username users 129 Mar 17 14:10 ms-vscode.cpptools -> /nix/store/kp7xi1mjkqdydxn4f1mgz0f4wch4bif9-vscode-extension-ms-vscode-cpptools-0.25.1/share/vscode/extensions/ms-vscode.cpptools
...
Looks like both my existing and cpptools extensions exist. Woop!
After running idf.py build
vscode prompts me to use compile_commands.json to configure, which cleans up all unknown imports.
Hello World
Following this blog post
idf.py build && idf.py flash && idf.py monitor
...
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
It works!
System design
First AccelStepper was ported to esp-idf
Next a naive program was written
At first there was an error similar to:
/nix/store/2a43yf623akrizn37pq0rvr8raniwkck-esp-idf/components/freertos/queue.c:1449 (xQueueGenericReceive)- assert failed!
abort() was called at PC 0x40087e95 on core 0
0x40087e95: xQueueGenericReceive at /nix/store/2a43yf623akrizn37pq0rvr8raniwkck-esp-idf/components/freertos/queue.c:1449 (discriminator 3)
ELF file SHA256: 73475cea9f1397f10f2debd74eac34e1a827b5305effdcde4c45130a77dd38d5
Backtrace: 0x40084eb9:0x3ffb7070 0x4008522d:0x3ffb7090 0x40087e95:0x3ffb70b0 0x40087fe5:0x3ffb70f0 0x40082869:0x3ffb7110 0x40082955:0x3ffb7140 0x400d38d3:0x3ffb7160 0x400d2845:0x3ffb7180 0x4000bd83:0x3ffb71a0 |<-CORRUPTED
0x40084eb9: invoke_abort at /nix/store/2a43yf623akrizn37pq0rvr8raniwkck-esp-idf/components/esp32/panic.c:155
0x4008522d: abort at /nix/store/2a43yf623akrizn37pq0rvr8raniwkck-esp-idf/components/esp32/panic.c:172
0x40087e95: xQueueGenericReceive at /nix/store/2a43yf623akrizn37pq0rvr8raniwkck-esp-idf/components/freertos/queue.c:1449 (discriminator 3)
0x40087fe5: xQueueTakeMutexRecursive at /nix/store/2a43yf623akrizn37pq0rvr8raniwkck-esp-idf/components/freertos/queue.c:635
0x40082869: lock_acquire_generic at /nix/store/2a43yf623akrizn37pq0rvr8raniwkck-esp-idf/components/newlib/locks.c:157
0x40082955: _lock_acquire_recursive at /nix/store/2a43yf623akrizn37pq0rvr8raniwkck-esp-idf/components/newlib/locks.c:171
0x400d38d3: uart_write at /nix/store/2a43yf623akrizn37pq0rvr8raniwkck-esp-idf/components/vfs/vfs_uart.c:194
0x400d2845: esp_vfs_write at /nix/store/2a43yf623akrizn37pq0rvr8raniwkck-esp-idf/components/vfs/vfs.c:420 (discriminator 4)
This was due to forgetting to have a vTaskDelay in a task. This caused the printing to run multiple times while it was still shoving bits down the UART
I got many StackOverflow errors, this was solved by increasing the third parameter of xTaskCreate from 512 to 2048
After building and running the stepper was not spinning and all pins were reading HIGH. After much debugging the issue was fixed