Skip to content

Commit a8f90e8

Browse files
Docs
1 parent 125bc5b commit a8f90e8

File tree

3 files changed

+77
-0
lines changed

3 files changed

+77
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ Read the [Contributing Guide](https://github.com/earlephilhower/arduino-pico/blo
137137
* printf (i.e. debug) output over USB serial
138138
* Transparent use of PSRAM globals and heap (RP2350 only)
139139
* ARM or RISC-V (Hazard3) support for the RP2350
140+
* Semihosted serial and file system access
141+
* GPROF profiling support
140142

141143
The RP2040 PIO state machines (SMs) are used to generate jitter-free:
142144
* Servos

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ For the latest version, always check https://github.com/earlephilhower/arduino-p
4444
USB (Arduino and Adafruit_TinyUSB) <usb>
4545
Multicore Processing <multicore>
4646
Semihosting <semihosting>
47+
Profiling (GPROF) <profiling>
4748

4849
RP2350 Specific Notes <rp2350>
4950
RP2350 PSRAM <psram>

docs/profiling.rst

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
Profiling Applications with GPROF
2+
=================================
3+
4+
Applications running on the Pico can be profiled using GNU GPROF to show where the CPU is using its time
5+
on the device and how often certain functions are called. It does this by recompiling the application
6+
and adding a small preamble to each function built to identify what functions call what others (and
7+
how frequently). It also uses the ``SYSTICK`` exception timer to sample and record the PC 10,000 times
8+
per second. When an application is complete, the recorded date can be dumped to the host PC as a
9+
``gmon.,out`` file which can be processed by ``arm-none-eabi-gprof`` into useful date.
10+
11+
s histogram of PCs and tally of function caller/callees can take a significant amount of RAM, from 100KB
12+
to 10000KB depending on the size of the application. As such, while the RP2040 **may** be able to
13+
profile small applications, this is only really recommended on the RP2350 with external PSRAM. The
14+
profiler will automatically use PSRAM when available.
15+
16+
Profiling also adds procesing overhead in terms of the periodic sampling and the function preambles.
17+
In most cases there is no reason to enable (and many reasons to disable) profiling when an application
18+
is deployed to the field.
19+
20+
To transfer the ``GMON.OUT`` data from the Pico to the host HP can be done by having the application
21+
write it out to an SD card or a LittleFS filesystem which is then manually dumped, but for ease of use
22+
semihosting can be used to allow the Pico (under the control of OpenOCD and GDB) to write the
23+
``gmon.out`` file directly on the host PC, ready for use.
24+
25+
**NOTE** Semihosting only works when connected to an OpenOCD + GDB debug session. Running an application
26+
compiled for Semihosting without the debugger will cause a panic and hang the chip.
27+
28+
As of now, only ARM has support for Semihosting or GPROF.
29+
30+
31+
Enabling Profiling in an Application
32+
------------------------------------
33+
34+
The ``Tools->Profiling->Enabled`` menu needs to be selected to enable profiling support in GCC. This will
35+
add the necessary preamble to every function compiled (**Note** that the ``libpico`` and ``libc`` will not
36+
be instrumented because they are pre-built so calls from them will not be fully instrumented. However,
37+
PC data will still be grabbed and decoded from them at runtime.)
38+
39+
The application will automatically start collecting profiling data even before ``setup`` starts in this
40+
mode. It will continue collecting data until you stop and write out the profiling data using
41+
``rp2040.writeProfiling()`` to dump to the host, a file, serial port, etc.
42+
43+
For example, an application which does all its processing in ``setup()`` might look like:
44+
45+
.. code:: cpp
46+
47+
#include <SemiFS.h>
48+
void setup() {
49+
SerialSemi.printf("BEGIN\n");
50+
do_some_work_that_takes_a_long_time_with_many_function_calls();
51+
// Do lots of other work...
52+
// Now all done...
53+
SerialSemi.printf("Writing GMON.OUT\n");
54+
SemiFS.begin();
55+
File gmon = SemiFS.open("gmon.out", "w");
56+
rp2040.writeProfiling(&gmon);
57+
gmon.close();
58+
SerialSemi.printf("END\n");
59+
}
60+
void loop() {}
61+
62+
63+
Collecting and Analyzing Profile Data
64+
-------------------------------------
65+
66+
Running this application under `semihosting <semihosting>`_ GDB and OpenOCD generates a ``gmon.out`` file
67+
in the OpenOCD current working directory. This file, combined with the ``ELF`` binary build in the
68+
IDE and loaded through GDB, can produce profiler output using
69+
70+
.. code::
71+
72+
$ /path/to/arm-none-eabi/bin/arm-none-eabi-gprof /path/to/sketch.ino.elf /path/to/gmon.out
73+
74+
See the ``rp2040/Profiling.ino`` example for more details.

0 commit comments

Comments
 (0)