Skip to content

Commit

Permalink
Add semihosting support (SerialSemi and SemiFS) (#2670)
Browse files Browse the repository at this point in the history
Enable ARM-only semihosting mode.  This mode allows applications on the
Pico to write to the OpenOCD console and read and write files on the
host system (i.e. debugging dump information, etc.)

It is not very fast because of the way it uses breakpoints on the Pico
to communicate, but it is useful in cases when you want to get a single
file off of the Pico while debugging.

Note that this **requires** a connected OpenOCD and GDB or else the
semihosting will cause a system panic.
  • Loading branch information
earlephilhower authored Dec 5, 2024
1 parent f2d30ab commit 1725e21
Show file tree
Hide file tree
Showing 10 changed files with 600 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ For the latest version, always check https://github.com/earlephilhower/arduino-p
File Systems (SD, SDFS, LittleFS) <fs>
USB (Arduino and Adafruit_TinyUSB) <usb>
Multicore Processing <multicore>
Semihosting <semihosting>

RP2350 Specific Notes <rp2350>
RP2350 PSRAM <psram>
Expand Down
56 changes: 56 additions & 0 deletions docs/semihosting.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
Semihosting Support
===================

Using special debugger breakpoints and commands, the Pico can read and write to the debugging console as well
as read and write files on a development PC. The ``Semihosting`` library allows applications to use the
semihosting support as a normal filesystem or serial port.

**NOTE** Semihosting only works when connected to an OpenOCD + GDB debug session. Running an application
compiled for Semihosting without the debugger will cause a panic and hang the chip.

As of now, only ARM has support for Semihosting.

Running Semihosting on the Development Host
-------------------------------------------

Start OpenOCD normally from inside a directory that you can read and write files within (i.e. do not run from
``C:\\Program Files\\..`` on Windows where general users aren't allowed to write). The starting
directory will be where the Pico will read and write files using the ``SemiFS`` class.
Be sure to keep the terminal window you ran OpenOCD in open, because all ``SerialSemi`` input and output
will go to **that** terminal and not ``gdb``'s.

Start GDB normally and connect to the OpenOCD debugger and enable semihosting support

.. code::
(gdb) target extended-remote localhost:3333
(gdb) monitor arm semihosting enable
At this point load and run your ``ELF`` application as normal. Again, all ``SerialSemi`` output will go
to the **OpenOCD** window, not GDB.

See the ``hellosemi`` example in the ``Semihosting`` library.

SerialSemi - Serial over Semihosting
------------------------------------

Simply include ``<Semihosting.h>`` in your application and use ``SerialSemi`` as you would any other
``Serial`` port with the following limitations:

* Baud rate, bit width, etc. are all ignored
* Input is limited because ``read`` may hang indefinitely in the host and ``available`` is not part of the spec

SemiFS - Host filesystem access through Semihosting
---------------------------------------------------

Use ``SemiFS`` the same way as any other file system. Note that only file creation and renaming are supported, with
no provision for iterating over directories or listing files. In most cases simply opening a ``File`` and writing out
a debug dump is all that's needed:

.. code::
SemiFS.begin();
File f = SemiFS.open("debug.dmp", "w");
f.write(buffer, size);
f.close();
SerialSemi.printf("Debug dump nopw available on host.\n");
43 changes: 43 additions & 0 deletions libraries/Semihosting/examples/hellosemi/hellosemi.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// This example uses semihosting to send serial output to the OpenOcD screen
// and write binary files to the host system.
//
// Semihosting **ONLY** works with an OpenOCD and GDB setup. If you build
// and run a semihosting app without GDB connected, it **WILL CRASH**
//
// Start OpenOCD normally, but leave the terminal window visible because
// is it OpenOCD, not GDB, which will display the semihosting output.
// OpenOCD will also create files in the current working directory, so
// be sure it is a place you can find and write to.
//
// In GDB,connect to OpenOCD and then enable semihosting
// (gdb) target extended-remote localhost:3333
// (gdb) monitor arm semihosting enable

#ifdef __riscv
void setup() {
// No semihosting for RISCV yet
}
void loop() {
}
#else

#include <Semihosting.h>

int c = 0;

void setup() {
SerialSemi.begin();
SerialSemi.printf("HELLO, GDB!\n");
SemiFS.begin();
File f = SemiFS.open("out.bin", "w");
f.printf("I made a file!\n");
f.close();
SerialSemi.printf("Just wrote a file 'out.bin'\n");
}

void loop() {
SerialSemi.printf("SH Loop Count: %d\n", c++);
Serial.printf("USB Loop Count: %d\n", c++);
delay(1000);
}
#endif
18 changes: 18 additions & 0 deletions libraries/Semihosting/keywords.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#######################################
# Syntax Coloring Map
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################

SerialSemi KEYWORD1
SemiFS KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
#######################################

#######################################
# Constants (LITERAL1)
#######################################
10 changes: 10 additions & 0 deletions libraries/Semihosting/library.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name=Semihosting
version=1.0.0
author=Earle F. Philhower, III <[email protected]>
maintainer=Earle F. Philhower, III <[email protected]>
sentence=Semihosted serial and filesystem access for the Pico and OpenOCD
paragraph=Semihosted serial and filesystem access for the Pico and OpenOCD
category=Communications
url=https://github.com/earlephilhower/arduino-pico
architectures=rp2040
dot_a_linkage=true
Loading

0 comments on commit 1725e21

Please sign in to comment.