Tutorial command for playing demos, etc

With the addition of the user macros loaded from disk, I thought it might be time to add the tutorial command as well.

The goal of this command is to ‘play’ simple tutorial scripts for demonstrating how to use the bus pirate, or how to use a specific chip. The tutorials are saved on the internal flash storage. # marks comments, which are displayed as instructions. Everything else is printed on a fake command prompt and (will) wait for the user to hit enter (or x for exit).

There’s some of the same issues here as the user macros. The command prompt and input/output queues are tightly tied together, so injecting the commands is a bit of a hack. It did not, for example, pause :slight_smile:



It turned out to be really easy to tie the tutorial command into the command line handling stuff.

  • Command/syntax lines now pause and wait for enter.
  • The command is fully editable as if you were on the normal command line.
  • Proper mode prompt shown

I squealed a bit when I used it, it had that wow factor.

The latest build has the tutorial command. Here’s a sample .tut test.zip (261 Bytes)


  • Help
  • Show “hit to continue, x to exit” before the first command prompt
  • make a non-pause option and alias it as “script”
# Welcome to the Bus Pirate 5 getting started tutorial!
# The Bus Pirate is useful for learning about a new chip or sensor
# without setting up a full development toolchain and writing code.
# It also has a bunch of useful hardware that gets you started fast.
# Before we being, make sure nothing is connected to the Bus Pirate IO pins.
# "modes" are different protocols like 1-wire, I2C, SPI, etc.
# The startup mode is HiZ, a safe mode where everything is disabled.
# Change modes with the 'm' command. Add -h to many command for help.
# Let's see the mode help
m -h
# Now let's change to HiZ mode to start the tutorial. 
# Type m then hit enter.
# You will see the mode selection menu. Type 1 then enter to choose HiZ
# The command prompt should now look like this: HiZ>
# This is a safe mode, hardware and pins are all disabled.
# Now enter SPI mode. Use the m command and choose SPI from the menu.
# The command prompt should now look like this: SPI>
# The Bus Pirate has a power supply with 1-5volt output.
# An optional programmable fuse sets a current limit from 0-500mA.
# Enable the power supply with the W command. Let's check the W command help.
W -h
# W accepts two optional parameters: votlage and current limit.
# If you don't specify a voltage, you will be prompted for one.
# Let's set the voltage to 3.3V and the current limit to 200mA.
W 3.3 200
# The power supply should now be enabled. It's disabled with the w command.
# The Bus Pirate has onboard pull-up resistors, enabled with the P command. 
# The pull-up resistors are useful for I2C and other open-drain protocols.
# The pull-up resistors are now enabled. The display should show 3.3V on all pins.
# Disable the pull-up resistors with the p command.
# The Bus Pirate has a built-in frequency generator, enabled with the g command.
# help
# help mode
# help -h
# commands (dummy?)
# pin movement
# Bus Syntax
# Disk commands: ls, mkdir, cd, cd .., rm, cat, hex
# Output formatting
# convert number formats with =
= 0x05
# Basic number entry?

As an aid to new users, and a way to test the tutorial command, I’ve started a Bus Pirate walk through.

I would super welcome any suggestions about what exactly should be covered.

  • getting help should be central
  • Changing mode
  • Power pullups, pins
  • Number entry (convert formats)
  • Bus syntax
  • Output formatting?

Probably an easier first tutorial may be duplicating the LED tutorial, but an overall intro seems like a good first step.

I’ve already noticed some issues with random freezing during menu prompts. I’m debugging that now.

Also: @Dreg suggested exit, and replay/redo commands. That’s going to be a bit more challenging because of how the command line parser works.

1 Like

Tutorial mode causes hardfaults (on core two???) when something tries to open a file. For example when entering a mode and checking the saved settings.

#define FF_FS_LOCK 5

Common solution seems to be increase the number of open files and directories in FATFS, but that didn’t help.

One time I make it through the setup menu (load file), but then it faulted on saving at the end of config.


Maybe I need to deal with this? I’m at a loss for the moment, so will revisit this in a bit.

I think we have to set the reentrant flag for multicore machines. Sooner or later we will have 2 cores one reading a file and one writing a file at the same time. I have implemented it using mutext. @ian do you want me to push this one on the same branch that contains my USBMS changes?

1 Like

Yes, please, that would be super helpful.

At the moment, core 2 shouldn’t touch the file system. I find this bug a bit confusing.

Done… I submitted a pull request

Thank you. I applied the commits to a new branch for testing.This and the disk ownership updates are next on my list.

Is there an advantage in using mutex for spi instead of spinlock? I don’t have a lot of experience with multiple cores.

What you have implemented is a mutex, providing the exact same functionality as the pico mutex. However, their implementation uses a shared spinlock when possible, which saves resources(only 32 spinlocks are in the hardware and only 8 are available to user code). Their busy loop is more elaborate. They disable interrupts like your commented out variant and it checks the inter core event queue, which can help in eliminating some deadlocks. At the end of the day, I believe that if they wrote a mutex and you need a mutex, it makes sense to use theirs.

1 Like

Interestingly switching to their mutex unveiled some potential bugs. The initialization of the spinlock was too late in main() because originally I got a runtime error telling me that an uninitialized mutex was used. I moved the init code ahead of that use and this error went away. The other non problem but interesting nonetheless is that there is a mutex exit call without a corresponding mutex enter at init time. So I see an added benefit in their assertions placed in the mutex code

1 Like

I missed the fact that amux.c also uses a hand writted mutex. It makes sense to convert it to a pico mutex as well.

1 Like

Thank you so much for the explanation. That all makes sense. I will use this from now on.

I picked up the spinlock from working with the PICO queue for a few FIFO ring buffers. I had to modify the stock queue for reasons I don’t immediately recall. Maybe I should update that to use mutex? I understood it as “the way to get an atomic bit”, but mutex looks much better.

I read the queue code, and they are right in using a spinlock, because the time to hold the lock is extremely short, spinlock is the way to go. When you just want to atomically update a state, spinlocks are lower cost than mutexes. I admit that the code looks more complicated but for the queue it is worth it.

1 Like

With FatFS set to minimum (shared buffer), along with the changes from @phdussud, tutorials no longer seem to freeze when there are competing file operations. Thank you so much, I’m not sure how long it would have taken me to figure out the stack overflow on my own.

You are welcome. It is a pleasure to work with you on such cool device.