Giter Site home page Giter Site logo

orbuculum's Introduction

Build Linux binaries

Build Windows binaries

Build OSX binaries

Discord

Screenshot

This (main) is the development branch for V2.2.0. Development is generally done in feature branches and folded into main as those features mature.

Version 2.1.0 has recently been released and includes nice things like Python support, a decent quality Windows port and the ninja/meson build system. It also supports the full functionality of the ORBTrace Mini dongle.

ORBTrace, the FPGA based trace interface dongle, has now been moved into its own separate repository as it's grown considerably and really needs its own identity. History for ORBtrace until the split point is maintained here for provenance purposes, but new work is now done over in the new location.

The CHANGES file now tells you what's been done recently.

Orbuculum now has an active Discord channel at https://discord.gg/P7FYThy . Thats the place to go if you need interactive help.

An Orbuculum is a Crystal Ball, used for seeing things that would be otherwise invisible. A nodding reference to (the) BlackMagic (debug probe), BMP.

You can find information about using this suite at Orbcode, especially the 'Data Feed' section.

ORBTrace Mini is now available for debug and realtime tracing. Go to Orbcode for more info.

The code is in daily use and small issues are patched as they are found. The software runs on Linux, OSX and Windows. Any bugs in a release version are treated as high priority issues. Functional enhancements will also be folded in as time permits. Currently progress is reasonably rapid, and patches are always welcome.

What is it?

Orbuculum is a set of tools for decoding and presenting output flows from the Debug pins of a CORTEX-M CPU. Originally it only used the SWO pin but it now also supports hardware for parallel tracing through ORBtrace. Numerous types of data can be output through these pins, from multiple channels of text messages through to Program Counter samples. Processing these data gives you a huge amount of insight into what is really going on inside your CPU. The tools are all mix-and-match according to what you are trying to do. The current set is;

  • orbuculum: The main program which interfaces to the trace probe and then issues a network interface to which an arbitary number of clients can connect, by default on TCP/3443. This is used by a base interface to the target by other programmes in the suite. Generally you configure this for the TRACE tool you're using and then you can just leave it running and it'll grab data from the target and make it available to clients whenever it can. Note that some debug probes can now create an orbuculum-compatible interface on TCP/3443, and then you can connect the rest of the suite to that directly, without needing to use the orbuculum mux itself.

  • orbfifo: The fifo pump: Turns a trace feed into a set of fifos (or permanent files).

  • orbcat: A simple cat utility for ITM channel data.

  • orbdump: A utility for dumping raw SWO data to a file for post-processing.

  • orbmortem: A post mortem analysis tool (needs parallel trace data).

  • orbtop: A top utility to see what's actually going on with your target. It can also provide dot and gnuplot source data for perty graphics.

  • orbstat: An analysis/statistics utility which can produce KCacheGrind input files. KCacheGrind is a very powerful code performance analysis tool.

  • orbtrace: The fpga configuration controller for use with ORBtrace hardware.

  • orbzmq: ZeroMQ server.

  • orblcd: LCD emulator on the host computer.

There is also Python support in the pyorb repository.

A few simple use cases are documented in the last section of this document, as are example outputs of using orbtop to report on the activity of BMP while emitting SWO packets.

The data flowing from the SWO pin can be encoded either using NRZ (UART) or RZ (Manchester) formats. The pin is a dedicated one that would be used for TDO when the debug interface is in JTAG mode. We've demonstrated ITM feeds of around 4.3MBytes/sec on a STM32F427 via SWO with Manchester encoding running at 48Mbps. SWO with UART encoding is good for 62Mbaud. The encoding of UART is less efficient than Manchester so those speeds come out largely the same. Users are advised to use Manchester encoding if their probe supports it because the don't have to stress about data speeds (it's autobauding), clock changes or start/stop bits.

The data flowing from the TRACE pins is clocked using a separate TRACECLK pin. There can be 1-4 TRACE pins which obviously give you much higher bandwidth than the single SWO. Using ORBTrace We've demonstrated ITM feeds of around 12.5MBytes/sec on a STM32F427 via 4 bit parallel trace. These are not typos, it really does run that fast if you've got suitable hardware.

Whatever it's source, orbuculum takes this data flow and makes it accessible to tools on the host PC. At its core it takes the data from the source, decodes it and presents it on a network interface. The Orbuculum suite tools don't care if the data originates from a RZ or NRZ port, SWO or TRACE, or at what speed....that's all the job of the interface.

At the present time Orbuculum supports ten devices for collecting trace from the target;

  • the Black Magic Debug Probe (BMP)
  • the SEGGER JLink
  • generic USB TTL Serial Interfaces
  • FTDI High speed serial interfaces
  • OpenOCD (Add a line like tpiu config internal :3443 uart off 32000000 to your openocd config to use it.)
  • PyOCD (Add options like enable_swv: True, swv_system_clock: 32000000 to your pyocd.yml to use it.)
  • The ECPIX-5 ECP5 Breakout Board for parallel trace
  • Anything capable of saving the raw SWO data to a file
  • Anything capable of offering SWO on a TCP port
  • ORBTrace Mini

Note that current support for the ECPIX-5 breakout board is based on the original bob, the designs for which are in the orbtrace_hw repository. bob2 support will be added when we get around to it (probably when we decide we need USB3 support...unlikely to be yet a while).

For 'normal' users we highly reccomend the ORBTrace mini probe for the best experience using this stuff. That's not particularlly to make money (the designs are in the orbtrace_hw directory...feel free to build you own), but because that hardware has been tuned for the job to be done.

gdb setup files for each device type can be found in the Support directory. You'll find example get-you-going applications in the Orbmule repository including gdbinit scripts for OpenOCD, pyOCD and Blackmagic Probe Hosted. There are walkthroughs for lots of examples of the use of the orbuculum suite at Orbcode.

When using SWO Orbuculum can use, or bypass, the TPIU. The TPIU adds overhead to the datastream, but provides better synchronisation if there is corruption on the link. To include the TPIU in decode stack, provide the -t option on the command line. If you don't provide it, and the ITM decoder sees TPIU syncs in the datastream, it will complain and barf out. This is deliberate after I spent two days trying to find an obscure bug 'cos I'd left the -t option off. You can have multiple channels to the -t option, which is useful when you've got debug data in one stream and trace data in another.

Beware that in parallel trace the TPIU is mandatory, so therefore so is the -t option.

TPIU framing can be stripped either by individual applications or the orbuculum mux. When its stripped by the mux the data are made available on consecutive TCP/IP ports...so -t 1,2 would put stream 1 data out over TCP port 3443 and stream 2 over 3444, by default. Do not leave the first number out if you only want output from the second stream...that won't end well.

When in NRZ (UART) mode the SWO data rate that comes out of the chip must match the rate that the debugger expects. On the BMP speeds of 2.25Mbps are normal, TTL Serial devices tend to run a little slower but 921600 baud is normally acheivable. On BMP the baudrate is set via the gdb session with the 'monitor traceswo xxxx' command. For a TTL Serial device its set by the Orbuculum command line. Segger devices can normally work faster, but no experimentation has been done to find their max limits, which are probably it's dependent on the specific JLink you are using. ORBTrace Mini can operate with UART encoded SWO at up to 62MBits/sec. It also supports Manchester encoded SWO at up to 48Mbps. The advantage of Manch encoding is that there's no speed matching needed to use it, and it should continue to work correctly even if the target clock speed changes (e.g. when it goes into a low power mode). This is a good thing, and is the way we normally use SWO for day-job.

Configuring the Target

Generally speaking, you will need to configure the target device to output SWD or parallel data. You can either do that through program code, or through magic incantations in gdb. The gdb approach is flexible but a bit clunky. @novakov has created the libtrace repository which includes all the code needed to configure your target directly via progam code if you prefer to set things up that way.

If you want to go via gdb then in the support directory you will find a script gdbtrace.init which contains a set of setup macros for the SWO functionality. Full details of how to set up these various registers are available from Arm and you've got various options for the type of output generated, its frequency and it's content.

Using these macros means you do not need to change your program code to be able to use facilities like orbtop. Obviously, if you want textual trace output, you've got to create that in the program!

Information about the contents of this file can be found by importing it into your gdb session with source gdbtrace.init and then typing help orbuculum. Help on the parameters for each macro are available via the help system too (e.g. help enableSTM32SWO).

In general, you will configure orbuculum via your local .gdbinit file. Several example files are also in the Support directory.

Anyway, generically, a configuration looks like this;

source Support/gdbtrace.init            <---- Source the trace specific stuff
target extended-remote /dev/ttyACM0     <-
monitor swdp_scan                       <-
file ofiles/firmware.elf                <-
attach 1                                <---- Connect to the target
set mem inaccessible-by-default off     <-
set print pretty                        <-
load                                    <---- Load the program

start                                   <---- and get to main

# ---------- Using Stm32F1 as debuggee---------------------------
enableSTM32SWO                          <*--- turn on SWO output pin on CPU
# ----------ALTERNATIVELY, for Stm32F4 as debuggee----------------
enableSTM32SWO 4                        <*--- turn on SWO output pin on CPU
# ----------END OF ALTERNATIVE-----------------------------------

# ---------- EITHER, IF USING A BLUEPILL-------------------------
monitor traceswo 2250000                <*--- wakeup tracing on the probe
prepareSWO SystemCoreClock 2250000 1 0  <*--- Setup SWO timing (Bluepill case)

# ----------ALTERNATIVELY, FOR GENUINE BMP-----------------------
monitor traceswo                        <*--- Enable BMP traceswo output
prepareSWO SystemCoreClock 200000 0 1   <*--- Setup SWO timing (BMP case)
# ----------END OF ALTERNATIVE-----------------------------------

dwtSamplePC 1                           <-
dwtSyncTap 3                            <-
dwtPostTap 1                            <-
dwtPostInit 1                           <-
dwtPostReset 15                         <-
dwtCycEna 1                             <---- Configure Data Watch/Trace

ITMId 1                                 <-
ITMGTSFreq 3                            <-
ITMTSPrescale 3                         <-
ITMTXEna 1                              <-
ITMSYNCEna 1                            <-
ITMEna 1                                <---- Enable Instruction Trace Macrocell

ITMTER 0 0xFFFFFFFF                     <---- Enable Trace Ports
ITMTPR 0xFFFFFFFF                       <---- Make them accessible to user level code

Alternatively, if you're using parallel trace via ORBTrace remove the lines marked <*- above and replace them with the following;

enableSTM32TRACE                         <---- Switch on parallel trace on the STM32

...be careful to set the trace width to be the same as what you've configured on the FPGA. It defaults to four bits wide. While we're here it's worth mentioning the startETM command too, that outputs tracing data. That is needed for orbmortem.

In-code configuration

Trace components might also be configured directly from code running on MCU. Such approach is useful for setting up more invasive tracing or logging output.

CMSIS-compatible headers, provided by many chip vendors include all necessary type definitions and constants. However they are not the most straightforward, so it might be easier to use Orbcode's libtrace library: https://orbcode.github.io/libtrace/

Building on Linux

Dependencies

  • libusb-1.0
  • libczmq-dev
  • ncurses
  • libsdl
  • libelf-dev
  • libcapstone-dev

Build

In general you'll find recent binaries available for your platform as build artifacts from the Github Actions we run for CI. Just go to the 'Actions' menu in github and then grab the artifacts from the latest builds.

If you do want to build the system, then the command line to build the Orbuculum tool suite is:

>meson setup build
>ninja -C build

You may need to change the paths to your libusb files, depending on how well your build environment is set up. You might also want to change the install path, which defaults to putting everything under /usr/local by passing the appropriate path to meson with a command line such as meson setup --prefix=/usr build...we've had some feedback that Arch doesn't find libraries under /usr/local/lib, for example. It's also worth noting that Ubuntu comes with a pretty old version of meson so if you get errors you may need to install a more recent one via pip.

Permissions and Access

A udev rules files is included in Support/60-orbcode.rules The default installations will have already installed this to either /usr/local/lib/udev/rules.d or /usr/lib/udev/rules.d, but you may prefer to install it to /etc/udev/rules.d by hand, if required.

Building on OSX

Recipe instructions courtesy of FrankTheTank;

  • brew install libusb zmq sdl2

and finally;

export LDFLAGS="-L/usr/local/opt/binutils/lib"
export CPPFLAGS="-I/usr/local/opt/binutils/include"

You can also see notes under Issue #63 from Gasman2014 about building on a M1 mac. You need to watch out for Homebrew binutils...on a M1 Mac you must use the Apple binutils or you will get linker errors. All you need to do is move the homebrew binutils out of the way while you do the build....no big deal when you know about it.

Building on FreeBSD

Install dependencies:

  • pkg install capstone libzmq3 ncurses libelf ninja meson

then build as normal:

>meson setup build
>ninja -C build

Note that you will have to alter permissions of the device in /dev/usb (run usbconfig to find the numbers). This could be automated with a devd file.

Building on Windows

MinGW-w64 from MSys2 is recommended as environment for building Windows distribution. Easiest way to get proper MSys2/MinGW-w64 environment is to use Chocolatey (https://community.chocolatey.org/packages/msys2).

Dependencies

  • mingw-w64-x86_64-libusb
  • mingw-w64-x86_64-zeromq
  • mingw-w64-x86_64-meson
  • mingw-w64-x86_64-SDL2
  • mingw-w64-x86_64-toolchain (Ada and Fortran are not needed)
  • ninja
  • git

In MSys2/MinGW-w64 run command: pacman -S mingw-w64-x86_64-meson mingw-w64-x86_64-SDL2 ninja mingw-w64-x86_64-libusb mingw-w64-x86_64-toolchain mingw-w64-x86_64-zeromq git to install all required dependencies.

Note that at the moment the Windows build is using a forked libusb because of constraints in the upstream build opening multiple interfaces on the same device at the same time. Hopefully that situation is only temporary.

Build

The command line to build the Orbuculum tool suite is:

>meson setup build
>ninja -C build

In order to get single folder with Orbuculum and MinGW dependencies run:

>meson configure build --prefix A:/
>meson install -C ./build --destdir ./install --strip

--prefix A:/ is required to workaround how Meson constructs the install directory. Without it a deeply nested path will be generated instead of the clean build/install.

Orbuculum executables along with MinGW-w64 dependencies will be installed into build/install and can be transfered to different machine or used outside of MSys2 shell.

Using

The command line options for Orbuculum are available by running orbuculum with the -h option.

Simply start orbuculum with the correct options for your trace probe and then you can start of stop other utilities as you wish. A typical command to run orbuculum would be;

$ orbuculum --monitor 1000

In this case, because no source options were provided on the command line, input will be taken from a Blackmagic probe USB SWO feed, or from an ORBTrace mini if it can find one. It will start the daemon with a monitor reporting interval of 100ms. Orbuculum exposes TCP port 3443 to which network clients can connect. This port delivers raw TPIU frames to any client that is connected (such as orbcat, orbfifo or orbtop). The practical limit to the number of clients that can connect is set by the speed of the host machine....but there's nothing stopping you using another one on the local network :-) If you've got an orbtrace mini and you want to switch on power to your target and configure it for Manchester SWO, a suitable command would be;

$ orbuculum --monitor 1000 --orbtrace '-p vtref,3.3 -e vtref,on'

...this will re-initialise the probe if it gets disconnected at any time.

Information about command line options can be found with the -h option. Orbuculum itself is specifically designed to be 'hardy' to probe and target disconnects and restarts (y'know, like you get in the real world). In general the other programs in the suite will stay alive while orbuculum itself is available. The intention being to give you useful information whenever it can get it. Orbuculum does not require gdb to be running, but you may need a gdb session to start the output. BMP needs traceswo to be turned on at the command line before it capture data from the port, for example.

Its worth a quick word about how the orbuculum mux interacts with clients. Pretty obviously, clients need to keep up with the flow of data from a probe. For the case that a client doesn't then it will be disconnected. It's then free to reconnect again. When reading from a file (and we don't have the same timing constraints as we do when talking to a probe) then a slow client will be accomodated by slowing down the entire flow and waiting for the client to catch up. The easiest way to see this in action is to pause a client (e.g. CTRL-Z on an orbcat session)...you will see orbuculum's data transfer go to zero. When you re-start the client (e.g. fg to bring it back into the foreground) then it will carry on from where it left off and no client will lose data.

Command Line Options

For orbuculum, the specific command line options of note are;

-a, --serial-speed: [serialSpeed]: Use serial port and set device speed.

-E, --eof: When reading from file, ignore eof.

-f, --input-file [filename]: Take input from file rather than device.

-h, --help: Brief help.

-H, --hires: Use high resolution time. This limits probe interface timeouts to 1ms, which makes host-side timing more accurate, but at the expense of much higher load (literally perhaps x100). Use sparingly.

-m, --monitor: Monitor interval (in ms) for reporting on state of the link. If baudrate is specified (using -a) and is greater than 100bps then the percentage link occupancy is also reported.

-n, --serial-number: Set a specific serial number for the ORBTrace or BMP device to connect to. Any unambigious sequence is sufficient. Ignored for other probe types.

-o, --output-file [filename]: Record trace data locally. This is unfettered data directly from the source device, can be useful for replay purposes or other tool testing.

-O "<options>": Run orbtrace on each detected connection of a probe, with the specified options.

-p, --serial-port [serialPort]: to use. If not specified then the program defaults to Blackmagic probe.

-P, --pace [us delay]: between file blocks. Used to slow down orbuculum feeding from a file to a set of clients.

-s, --server [address]:[port]: Set address for explicit TCP Source connection, (default none:2332).

-t, --tpiu x,y,...: Remove TPIU formatting and issue streams x, y etc over incrementing IP port numbers.

Orbfifo

Note: orbfifo is not supported on Windows. Use orbzmq instead.

The easiest way to use the output from orbuculum is with one of the utilities such as orbfifo. This creates a set of fifos or permanent files in a given directory containing the decoded streams which apps can exploit directly. It also has a few other tricks up it's sleeve like filewriter capability. It used to be integrated into orbuculum but seperating it out splits the trace interface from the user space utilities, this is another Good Thing(tm).

A typical command line would be;

>orbfifo -b swo/ -c 0,text,"%c" -v 1

The directory 'swo/' is expected to already exist, into which will be placed a file 'text' which delivers the output from swo channel 0 in character format. Multiple -c options can be provided to set up fifos for individual channels from the debug device. The format of the -c option is;

>-c ChannelNum,ChannelName,FormatString

ChannelNum is 0..31 and corresponds to the ITM channel. The name is the one that will appear in the directory and the FormatString can present the data using any printf-compatable formatting you prefer, so, the following are all legal channel specifiers;

-c 7,temperature,"%d \260C\n"
-c 2,hexAddress,"%08x,"
-c 0,volume,"\l%d\b\n"

Be aware that if you start making the formatting or screen handling too complex its quite possible your machine might not keep up...and then you will loose data!

While you've got orbfifo running a further fifo hwevent will be found in the output directory, which reports on events from the hardware, one event per line as follows (note that the order of these has changed);

  • 0,[Status],[TS] : Time status and timestamp.
  • 1,[EventType],[ExceptionNumber] : Hardware exception. Event type is one of [Enter, Exit, Resume].
  • 2,[PCAddr] : Report Program Counter Sample.
  • 3,[DWTEvent] : Report on DWT event from the set [CPI,Exc,Sleep,LSU,Fold and Cyc].
  • 4,[Comp],[RW],[Data] : Report Read/Write event.
  • 5,[Comp],[Addr] : Report data access watchpoint event.
  • 6,[Comp],[Ofs] : Report data offset event.
  • 7 : Currently unused.
  • 8,[Status],[Address] : ISYNC event.

The command line options are;

-b, --basedir [basedir]: for channels, terminated with a trailing directory seperator, so if you put xyz/chan then all ITM software channels will end up in a directory xyz/chan. If xyz/chan doesn't exist, then the channel creation will fail silently.

-c, --channel [Number],[Name],[Format]: of channel to populate (repeat per channel) using printf formatting.

-E: When reading from file, terminate when file exhausts, rather than waiting for more data to arrive.

-f, --input-file [filename]: Take input from specified file (CTRL-C to abort from this).

-h, --help: Brief help.

-P, --permanent: Create permanent files rather than fifos - useful when you want to use the processed data later.

-s [address]:[port]: Set address for Source connection, (default localhost:3443).

-t, --tpiu: Use TPIU decoder. This will not sync if TPIU is not configured, so you won't see packets in that case.

-v, --verbose: Verbose mode 0==Errors only, 1=Warnings (Default) 2=Info, 3=Full Debug.

-W, --writer-path [path] : Enable filewriter functionality with output in specified directory (disabled by default).

Orbzmq

orbzmq is utility that connects to orbuculum over the network and outputs data from various ITM HW and SW channels that it find. This output is sent over ZeroMQ PUBLISH socket bound to specified URL. Each published message is composed of two parts: topic and payload. Topic can be used by consumers to filter incoming messages, payload contains actual message data - for SW channels formatted or raw data and predefined format for HW channels.

A typical command line would be like:

> orbzmq -l tcp://localhost:1234 -c 0,text,%c -c 1,raw, -c 2,formatted,"Value: 0x%08X\n" -e AWP,OFS,PC -v 1

orbzmq will create a ZeroMQ socket bound to address tcp://*:3442 (which means, all interfaces, tcp port 3442) and publish messages with topics: text, raw, formatted, hweventAWP, hweventOFS and hweventPC.

A simple python client can receive messsages in the following way:

import zmq


ctx = zmq.Context()
sock = ctx.socket(zmq.SUB)
sock.connect('tcp://localhost:3442')
sock.setsockopt(zmq.SUBSCRIBE, b'raw')
sock.setsockopt(zmq.SUBSCRIBE, b'formatted')
sock.setsockopt(zmq.SUBSCRIBE, b'hwevent') # subscribe to all hwevents

while True:
    [topic, msg] = sock.recv_multipart()
    if topic == b'raw':
        decoded = int.from_bytes(msg, byteorder='little')
        print(f'Raw: 0x{decoded:08X}')
    elif topic == b'formatted':
        print(msg.decode('ascii'),end="")
    elif topic.startswith(b'hwevent'):
        print(f'HWEvent: {topic} Msg: {msg}')

Command line options are:

-c, --channel [Topic],[Name],[Format]: of channel to populate (repeat per channel)

-e, --hwevent [event1],[event2]: Comma-separated list of published hwevents (Use all to include all hwevents)

-E, --eof: Terminate when the file/socket ends/is closed, or attempt to wait for more / reconnect

-f, --input-file [filename]: Take input from specified file

-h, --help: This help

-n, --itm-sync: Enforce sync requirement for ITM (i.e. ITM needsd to issue syncs)

-s, --server [server]:[port]: to connect to

-t, --tpiu [channel]: Use TPIU decoder on specified channel (normally 1)

-v, --verbose [level]: Verbose mode 0(errors)..3(debug)

-V, --version: Print version and exit

-z, --zbind [url]: ZeroMQ bind URL

Orblcd

orblcd lets you emulate an LCD panel on a host computer. This is useful for test and development purposes. Communication between the target and host occurs over two ITM channels, using a protocol defined in orblcd_protocol.h. You need to share a common version of this file between orblcd and your target.

1, 8, 16 and 24/32 bit lcd depths are supported. 1 and 24/32 bit are well tested, but 16 and 8 need a little bit more proving. There is no functional difference between 24 and 32 bit operation (there is no Alpha channel, although it's trivial to add if you want it).

On the target side, all that needs to be done is to tell the host the characteristics of the panel;

ITM_Send32(LCD_COMMAND_CHANNEL,ORBLCD_OPEN_SCREEN(XSIZE*8,YSIZE*16,ORBLCD_DEPTH_1));

Once the characteristics have been established, this same command will render any data received.

Once the link is established, then the target simply streams data to the host;

ITM_Send32(LCD_DATA_CHANNEL,<data word>);

For 1, 8 and 16 bit lcds multiple pixels are encoded into a single 32-bit word. Any pixels left at the end of a line are discarded. If that doesn't suit, then use the 24/32 bit channel mode to transfer pixels.

There is no limit on the amount of data that may be sent - the screen will not be rendered at the host until the next OPEN_SCREEN message is received. The target is free to move around the virtual lcd panel to update the contents anywhere it wishes (and new manipulation commands may be added into the shared header file orblcd_protocol.h).

By operating in this way, even if the host connects late it will quickly establish good quality comms with the target. See the vidout example in orbmule for an example of how to use the utility for 1-bit operation, or build the lcd_demo application with the orblcd video device as output for a 24-bit example with;

make GRAPHIC_LIBRARY=ORBLCD

-c, --channel [Number]: of first channel in pair containing display data (channel+1 is the command channel).

-f, --input-file [filename]: Take input from specified file.

-h, --help: Get help.

-n, --itm-sync: Enforce sync requirement for ITM (i.e. ITM needsd to issue syncs).

-s, --server [Server]:[Port]: to use.

-S, --sbcolour [Colour]: to be used for single bit renders, ignored for other bit depths.

-t, --tpiu [channel]: Use TPIU decoder on specified channel (normally 1).

-v, --verbose [level]: Verbose mode 0(errors)..3(debug).

-V, --version: Print version and exit.

-z, --size [Scale(float)]: Set relative size of output window (normally 1).

Orbcat

orbcat is a simple utility that connects to orbuculum over the network and outputs data from various ITM HW and SW channels that it finds. This output is sent to stdout so the program is very useful for providing direct input for other utilities. There can be any number of instances of orbcat running at the same time, and they will all decode data independently. They all get a seperate networked data feed. A typical use case for orbcat would be to act as a stdin for another program...an example of doing this to just replicate the data delivered over ITM Channel 0 would be

orbcat -c 0,"%c"

...note that any number of -c options can be entered on the command line, which will combine data from those individual channels into one stream. Command line options for orbcat are;

-c, --channel [Number],[Format]: of channel to populate (repeat per channel) using printf formatting. Note that the Name component is missing in this format because orbcat does not create fifos. beware not to have any extraneous spaces in this option, that generally ends up not doing what you want as its interpreted as a new option.

-C, --cpufreq [Frequency in KHz]: Set (scaled) speed of the CPU to convert CPU timestamps into time timestamps. When this option is set -Ts and -Tt will generate output in milliseconds and thousandths of a millisecond for an effective resolution of 1us, provided your target has been configured to generate timestamps. Note the frequency you set should be scaled according to the setting in the ITM Control register (/1, /4, /16 or /64).

-E, --eof: When reading from file, terminate when file exhausts, rather than waiting for more data to arrive.

-f, --input-file [filename]: Take input from specified file (CTRL-C to abort from this).

-g, --trigger [char]: Character to use to trigger timestamp generation. Default is newline. Target character is removed from the output stream and replaced with a newline followed by a timestamp in the format specified by -Tx. Control characters (e.g. newline \n or tab \t) can be specified as the trigger.

-h, --help: Brief help.

-n, --itm-sync: Enforce sync requirement for ITM (i.e. ITM needsd to issue syncs)

-s --server [server]:[port]: to connect to. Defaults to localhost:3443 to connect to the orbuculum daemon. Use localhost:2332 to connect to a Segger J-Link, or whatever other combination applies to your source.

-t, --tpiu: Use TPIU decoder. This will not sync if TPIU is not configured, so you won't see packets in that case.

-T, --timestamp [a|r|d|s|t]: Add absolute, relative (to session start), delta, system timestamp or system timestamp delta to output. Note that system timestamp and system timestamp delta are only available if your target is generating timestamps, otherwise they will read back as zero. A timestamp is generated on reception of the first character following the trigger char (Set with -gx). This means that even if the output is lengthy it is timestamped from when it started.

-v, --verbose [x]: Verbose mode level 0..3.

-w, --window [string]: Title for on-screen window.

Orbtop

Orbtop connects to orbuculum over the network and samples the Program Counter to identify where the program is spending its time. By default it will update its statistical output once per second. For code that matches to a function the the source file it will totalise all of the samples to tell you how much time is being spent in that function. Any samples that do not match to an identifiable function are reported as 'Unknown'.

As with Orbcat there can be any number of instances of orbtop running at the same time, which might be useful to perform sampling over different time horizons. A typical invocation line for orbtop would be;

orbtop -e ~/Develop/STM32F103-skel/ofiles/firmware.elf

...the pointer to the elf file is always needed for orbtop to be able to recover symbols from.

One useful command line option for orbtop (and indeed, for the majority of the rest of the suite) is -s localhost:2332, which will connect directly to any source you might have exporting SWO data on its TCP its port, with no requirement for the orbuculum multiplexer in the way.

Command line options for orbtop are;

-c, --cut-after [num]: Cut screen output after number of lines.

-d, --del-prefix [DeleteMaterial]: to take off front of filenames (for pretty printing).

-D, --no-demangle: Switch off C++ symbol demangling (on by default).

-e, --elf-file: Set elf file for recovery of program symbols. This will be monitored and reloaded if it changes.

-E, --exceptions: Include exception (interrupt) measurements.

-f, --input-file [Filename]: Take input from specified file

-g, --record-file [LogFile]: Append historic records to specified file on an ongoing basis.

-h, --help: Brief help.

-I, --interval [Interval]: Set integration and display interval in milliseconds (defaults to 1000 ms)

-j, --json-file [filename]: Output to file in JSON format (or screen if is '-')

-l, --agg-lines: Aggregate per line rather than per function

-n, --itm-sync: Enforce sync requirement for ITM (i.e. ITM needs to issue syncs)

-o, --output-file [filename]: Set file to be used for output history

-O, --objdump-opts [opts]: Set options to pass directly to objdump

-r, --routines <routines>: Number of lines to record in history file

-R, --report-file [filename]: Report filenames as part of function discriminator

-s, --server [server]:[port]: to connect to. Defaults to localhost:3443

-t, --tpiu: Use TPIU decoder. This will not sync if TPIU is not configured, so you won't see packets in that case.

-v, --verbose [x]: Verbose mode 0..3.

Its worth a few notes about interrupt measurements. orbtop can provide information about the number of times an interrupt is called, what its maximum nesting is, how many 'execution ticks' it's active for and what the spread is of those. Here's a typical combination output for a simple system;

 98.25%     1911 ** SLEEPING **
  0.25%        5 uart_xmitchars
  0.20%        4 up_serialin
  0.10%        2 up_doirq
  0.10%        2 up_interrupt
  0.10%        2 up_restoreusartint
  0.10%        2 uart_pollnotify
  0.10%        2 uart_write
  0.10%        2 nxsem_post
-----------------
 99.30%     1932 of 1945 Samples


 Ex |   Count  |  MaxD | TotalTicks  |  AveTicks  |  minTicks  |  maxTicks
----+----------+-------+-------------+------------+------------+------------
 11 |        1 |     1 |        263  |        263 |       263  |       263
 15 |      100 |     1 |      10208  |        102 |       100  |       210
 53 |      210 |     1 |      44752  |        213 |        97  |       479

[V-TH] Interval = 1002ms / 7966664 (~7950 Ticks/ms)

The top half of this display is the typical 'top' output, the bottom half is a table of active interrupts that have been monitored in the interval. Note that outputs are given in terms of 'ticks', and the number of cpu cycles that correspond to a tick is set by ITMTSPrescale. You will also need to set dwtTraceException and ITMTSEna to be able to use this output mode.

Orbmortem

To use orbmortem you must be using a parallel trace source such as ORBTrace Mini, and it must be configured to stream parallel trace info (clue; the startETM option).

The command line options of note are;

-a, --alt-addr-enc: Don't use alternate address encoding. Select this if decodes don't seem to arrive correctly. You can discover if you need this option by using the describeETM command inside the debugger.

-b, --buffer-len [Length]: Set length of post-mortem buffer, in KBytes (Default 32 KBytes)

-c, --editor-cmd [command]: Set command line for external editor ( %%f = filename, %%l = line). A few examples are;

 * emacs; `-c emacs "+%l %f"`
 * codium/VSCode; `-c codium  -g "%f:%l"`
 * eclipse; `-c eclipse "%f:%l"`

-D, --no-demangle: Switch off C++ symbol demangling

-d, --del-prefix [String]: Material to delete off front of filenames

-e, --elf-file [ElfFile]: to use for symbols and source

-E, --eof: When reading from file, terminate at end of file rather than waiting for further input

-f, --input-file [filename]: Take input from specified file rather than live from a probe (useful for ETB decode)

-h, --help: Provide brief help

-p, --trace-proto [protocol]: to use, where protocols are MTB or ETM35 (default). Note that MTB only makes sense from a file.

-s, --server [Server:Port]: to use

-t, --tpiu [channel]: Use TPIU to strip TPIU on specfied channel (normally best to let orbuculum handle this

Once it's running you will receive an indication at the lower right of the screen that it's capturing data. Hitting H will hold the capture and it will decode whatever is currently in the buffer. More usefully, if the capture stream is lost (e.g. because of debugger entry) then it will auto-hold and decode the buffer, showing you the last instructions executed. You can use the arrow keys to move around this buffer and dive into individual source files. Hit the ? key for a quick overview of available commands.

Reliability

A whole chunk of work has gone into making sure the dataflow over both the SWO link and parallel Trace is reliable....but it's pretty dependent on the debug interface itself. The TL;DR is that if the interface is reliable then Orbuculum will be. There are factors outside of our control (i.e. the USB bus you are connected to) that could potentially break the reliabilty but there's not too much we can do about that since the SWO link is unidirectional (no opportunity for re-transmits). Using ORBTrace We have transmitted gigabytes of date over SWO and TRACE links with no errors, which is pretty impressive when you consider the speeds we are talking about and the fact that there is no error detection or correction on the link itself.

As one example, ORBTrace Mini was configured with a target application sending out repeated strings at maximum speed over a 48Mbps SWO/Manch channel for an extended period of time. They were then collated and sorted by uniqueness, as follows;

$ time orbcat -c 0,"%c" | sort | uniq -c
      1 ABCDEFGHIJKLMNOPQRST
2385153869 ABCDEFGHIJKLMNOPQRSTUVWXYZ_*_abcdefghijklmnopqrstuvwxyz

real    490m37.616s
user    82m15.087s
sys    11m2.847s

That is 124.4GBytes of user to user transfer, 155.5GBytes of line transfer with no errors at 5.4MBytes/sec line, 4.32MBytes/sec user-to-user, assuming my math is holding up. If the wiring is reliable, the link will be. The equivalent test on the same chip using 4 bit parallel TRACE gives a user-to-user data rate of around 12.5MBytes/sec...at that point you're limited by the speed the CPU can put data out onto line rather than the capacity of the link itself.

Using SWO in Battle

SWO gives you a number of powerful new capabilities in your debug arsenal. Here are a few examples....if you have more to add please send us an email, or go take a look at orbcode.org.

Multi-channel Debug

The easiest and most obvious use of SWO is to give you multi-channel debug capability. By adding multiple '-c' definitions to the orbuculum comand line you can create multiple fifos which will each emit data of interest. So, for the simple case of two distinct serial streams, something like the following will suffice;

-c 0,out0,"%c" -c 1,out1,"%c"

...this will create two fifos in your output directory, out0 and out1, each with distinct output data. By default the CMSIS provided ITM_SendChar routine only outputs to channel0, so you will need a new routine that can output to a specified channel. Something like;

static __INLINE uint32_t ITM_SendChar (uint32_t c, uint32_t ch)
{
  if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk)  &&      /* Trace enabled */
      (ITM->TCR & ITM_TCR_ITMENA_Msk)                  &&      /* ITM enabled */
      (ITM->TER & (1ul << c)        )                    )     /* ITM Port c enabled */
  {
    while (ITM->PORT[c].u32 == 0);
    ITM->PORT[c].u8 = (uint8_t) ch;
  }
  return (ch);
}

Now, this works perfectly for chars, but you can also write longer values into the transit buffer so if, for example, you wanted to write 32 bit values from a calculation, just update the routine to take int32_t and change the channel definition to be something more like -c 4,calcResult,"%d". You'll find example routines in the orbmule/examples/simple repository.

Mixing Channels

It gets more complicated when you want to mix output from individual channels together. In this circumstance you can either write a bit of script to merge the channels together, or you can use orbcat to do the same thing from the command line. So if, for example, you wanted to merge the text from channel0 with the 32 bit values from channel 4, an orbcat line such as this would do the job;

orbcat -c 0,"%c" -c 4,"\nResult=%d\n"

...its obvious that the formatting of this buffer is completely dependent on the order in which data arrive from the target, so you might want to put some 'tags' or differentiators into each channel to keep them distinct - a typical mechanism might be to use commas to seperate the flows into different columns in a CSV file.

Multiple Simulteneous Outputs

Orbuculum will place fifos for any defined channels (plus the hardware event channel) in the specified output directory. It will simulteneously create a TCP server to which an arbitary number of clients can connect. Those clients each decode the data flow independently of orbuculum, so you can present the data from the target simulteneously in multiple formats (you might log it to a file while also processing it via a plot routine, for example). You can also use the source code for orbcat or orbtop as the basis for creating your own specific decoders (and I'd really appreciate a copy to fold into this suite too please!).

Using Orbtop

Orbtop is an example client to orbuculum which processes the PC sampling information to identify what routines are running at any point in time. This is essential information to understand what your target is actually doing and once you've got this data you'll find you become addicted to it! Just running orbtop with the details of your target binary is enough for orbtop to do its magic (along with information about the configuration of the incoming SWO stream, of course);

orbtop -t -i 9 -a -e firmware.elf

orbtop can aggregate per function or per program line. By default it aggregates per function but to work per-line just add the -l option...usually that gives you too much information though.

The amount (and indeed, presence) of sample data is set by a number of configuration options. These can be set from program code, but it's more flexible to set them from gdb. The main ones are;

  • dwtSamplePC : Enable or disable Program Counter sample generation
  • dwtPostTap : Set the count rate for the PC interval counter at either bit 6 or bit 10 of the main CPU clock.
  • dwtPostInit : set the initial value for the PC interval counter (this defines when the first sample is taken....you've got to be pretty precise if this is important to you!).
  • dwtPostReset : Set the reload value for the PC Interval Counter (higher values = slower counting).
  • dwtCycEna : Enable the cycle counter input (i.e. switch the whole thing on). You won't get far without this set!

The maximum speed at which you can generate samples is defined by the speed of your SWO connection but, with a 72MHz CPU, the slowest settings (dwtPostTap 1 and dwtPostReset 15) still generate about 4000 samples per second, so you will get useful information at that level of resolution. There is a risk that you could miss frequent, but short, routines if you're running too slow, so do vary the speeds to make sure you get consistent results...on the other hand running too fast will lead to flooding the SWO and potentially missing other important data such as channel output. You do not need to restart orbuculum or orbtop in order to change the parameters in gdb - just CTRL-C, change, and restart. With a setting of dwtPostReset 1 there are no overflows when using a async interface at 2.25Mbps, which equates to 35200 Program Counter samples per second.

Here's a typical example of orbtop output for a Skeleton application based on FreeRTOS with USB over Serial (CDC) support. This table is updated once per second;

 97.90%     4308 ** Sleeping **
  1.25%       55 USB_LP_CAN1_RX0_IRQHandler
  0.20%        9 xTaskIncrementTick
  0.13%        6 Suspend
  0.09%        4 SysTick_Handler
  0.06%        3 Resume
  0.06%        3 __WFI
  0.04%        2 vTaskSwitchContext
  0.04%        2 TIM_Cmd
  0.02%        1 prvAddCurrentTaskToDelayedList
  0.02%        1 xTaskResumeAll
  0.02%        1 vTaskDelay
  0.02%        1 PendSV_Handler
  0.02%        1 __ISB
  0.02%        1 taskIn
  0.02%        1 statsGetRTVal
  0.02%        1 taskOut
-----------------
            4400 Samples

orbtop can also generate graph output. You will find utilities to support this for gnuplot in the Support directory. Just start orbtop with the option -o <filename> to generate the output data and then run Support/orbtop_plot to generate the output. By default it generates pdf graphs once per second, but that's easily changed.

Dogfood

Orbuculum was pointed at a a BMP instance (running on a 72MHz STM32F103C8) both with and without SWO running in asynchronous mode at 2.25Mbps.

Firstly, without SWO;

 26.96%     1186 gdb_if_update_buf
 23.23%     1022 stm32f103_ep_read_packet
 21.82%      960 gdb_if_getchar_to
  6.66%      293 cdcacm_get_config
  6.54%      288 platform_timeout_is_expired
  5.61%      247 usbd_ep_read_packet
  4.86%      214 platform_time_ms
  3.90%      172 cdcacm_get_dtr
  0.13%        6 _gpio_clear
  0.06%        3 gpio_set_mode
  0.04%        2 swdptap_turnaround
  0.04%        2 swdptap_seq_out
  0.02%        1 swdptap_bit_in
  0.02%        1 swdptap_bit_in
  0.02%        1 swdptap_turnaround
  0.02%        1 platform_timeout_set
-----------------
            4399 Samples

...and then, with SWO running (note that in this second case the sample frequency had to be increased to be able to see the impact, which is reflected in dma1_channel5_isr and to a much lesser degree in trace_buf_drain). When this trace was taken the target was emitting nearly 18000 PC samples per second, encoded in TPIU frames.

 18.17%     3198 stm32f103_ep_read_packet
 17.35%     3054 gdb_if_getchar_to
 15.05%     2648 gdb_if_update_buf
 11.02%     1940 usbd_ep_read_packet
  9.24%     1627 platform_time_ms
  9.07%     1597 platform_timeout_is_expired
  7.93%     1396 cdcacm_get_dtr
  4.78%      842 cdcacm_get_config
  4.72%      831 dma1_channel5_isr
  1.52%      268 usb_copy_to_pm
  0.45%       80 stm32f103_poll
  0.17%       31 trace_buf_drain
  0.06%       12 usb_lp_can_rx0_isr
  0.05%        9 gpio_set_mode
  0.03%        7 swdptap_turnaround
  0.03%        7 swdptap_turnaround
  0.03%        7 _gpio_clear
  0.03%        7 usbd_poll
  0.03%        6 swdptap_seq_out_parity
  0.02%        5 swdptap_seq_out
  0.02%        4 swdptap_seq_in_parity
  0.01%        3 adiv5_swdp_low_access
  0.01%        2 swdptap_bit_in
  0.01%        2 swdptap_bit_out
  0.01%        2 _gpio_set
  (Anthing < 0.01% removed)
-----------------
           17594 Samples

Using orbuculum with other info Sources

As Karl Palsson pointed out in Issue #4 on github, all of the support tools just need a stream of 'clean' trace data. Normally that is provided by the network connection that orbuculum exports, but you can also use something like netcat to generate the stream for orbuculum or its clients. For example, from a file that is written to via something like openocd;

> tail -f swo.dump.log | nc -v -v -l 9999 -k

and then;

> ./ofiles/orbuculum -g 9999 -b md/ -c 0,text,"%c"

However, that's probably over-complicated now...just use the orbuculum -s option to hook to any source that is pumping out clean SWO data. This information is just left here to show the flexibilities you have got available.

Windows: concurrent debug and Orbuculum usage with Orbtrace

Due to issue in Libusb (libusb/libusb#1177 and libusb/libusb#1181) running orbuculum or OpenOCD (or any other tool using libusb to access CMSIS-DAP) will claim exclusively entrie Orbtrace device preventing other application from running (e.g. while orbuculum is running OpenOCD will fail to find debug probe). Some debug software might be able to fallback to HID interface of CMSIS-DAP, however this will be much slower than "proper" USB Bulk interface.

In order to ease pain of this issue, Orbuculum distribution for Windows built on Github (https://github.com/orbcode/orbuculum/actions/workflows/build-windows.yml?query=branch%3Amain) is built with patched libusb. While this alone might not be enough for debug applications to work properly (with USB build interface) at least Orbuculum itselt will not act hostile to other applications. In order to get debug application working with patched libusb there are two options:

  • Rebuild application with patched libusb (https://github.com/Novakov/libusb/tree/winusb-lazy-create-file) - harder to do but have the greatest chance of success
  • Replace libusb-1.0.dll bundled with debug application in use with libusb-1.0.dll from Orbuculum distribution - easier to do but might not work with all applications.

The later approach (file replacement) works fine for PyOCD (replace libusb-1.0.dll file in <venv>/Lib/site-packages/libusb_package) and fails to work with xPack OpenOCD (due to the way libftdi.dll is built).

Please report both success (this will increase chances of merging patch to upstream libusb) and failures (so we will be able to identify and fix issues introduced by patch) with this approach.

orbuculum's People

Contributors

alanbowman avatar alexian79 avatar augustofg avatar bissonex avatar danielo avatar devanlai avatar dfgweb avatar dpiegdon avatar dragonmux avatar florolf avatar j4cbo avatar jcbernack avatar karlp avatar lzptr avatar mubes avatar newam avatar niklaut avatar novakov avatar patrislav1 avatar petervdperk-nxp avatar salkinium avatar stoyan-shopov avatar syncena avatar tannewt avatar tech2077 avatar via avatar zx64 avatar zyp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

orbuculum's Issues

Develop:orbtop hard attempts to set serial config

ca5d22f introduces a hard explicit call to setSerialConfig on the socket fd. I don't even know what it's trying to do. orbtop doesn't need a serial port, and it sure doesn't seem relevant to the commit comment for ca5d22f?

It kinda looks like you bled some attempted functionality at running orbtop directly against a dump file, or a trace spew file, instead of via orbuculum, and broke "normal" usage? That would seem to be going against the whole principle of composing things aroudn orbuculum, and means you're going to be fixing the same sorts of things in every one of them. Are you sure that's what you're trying to do? Shouldn't orbtop just connect to the orbuculum service, and orbuculum takes care of how the data arrives?

Direction aside, this call completely fails on a normal socket, and exits.

mixup/typo with SWD/SWO

Is this a typo?

enableSTM32SWD <*--- turn on SWO output pin on CPU

In my understanding it should read enableSTM32SWO (?)

thanks

orbtop should provide immediate error about missing objdump

(For clarity, this is tested against b475ebb)

Currently:

> objdump.exe
'objdump.exe' is not recognized as an internal or external command,
operable program or batch file.
> echo %OBJDUMP%
%OBJDUMP% (i.e. env var is unset)
> dir /b simple.elf
simple.elf
> orbtop.exe -e simple.elf
(Program launches, only continuously reports "Could not read symbols" error despite elf existing)

Expected:

> orbtop.exe -e simple.elf
orbtop: Unable to find objdump. Add to path or set with OBJDUMP.
> set OBJDUMP=c:\armgcc\bin\arm-none-eabi-objdump.exe
> orbtop.exe -e simple.elf
(Program works properly)

Inconsistent results from orbfifo when reading from file and writing to permanent file

I was previously using an older version of orbuculum with this incantation (input trace file: raw.zip):
orbuculum -t -f raw.bin -P -e

and this worked very well without any issues. The expected output (obtained from the 1.13 release) is:

8,21,0x00003bc0
8,21,0x00003aa8
8,21,0x00003bc0
8,21,0x00003aa8
8,21,0x00003bc0
8,21,0x00003aa8
8,21,0x00003bc0
8,21,0x00003aa8
8,21,0x00003bc0
8,21,0x00003aa8
8,21,0x00003bc0
8,21,0x00003aa8
8,21,0x00003bc0
8,21,0x00003aa8
8,21,0x00003bc0
8,21,0x00003aa8
8,21,0x00003bc0

(this is the contents of the generated hwevents file)

Now I'm trying to do the same from the latest code (git main branch) and the results are inconsistent. Sometimes I get the same, sometimes I get a truncated version with fewer lines. My command line is:
orbfifo -t 1 -E -P --input-file raw.bin -c 0,blah,'%08x\n' -v 3

I do seem to always get the full output if I omit the -E option.
Another issue is that hwevent is either not generated at all, or empty, if I omit the -v 3 and/or -c 0... options. (I do not care about the 'blah' output file; hwevents is all I'm after.)

I poked around a bit and I suspect the truncation problem may lie here:

break;

because I move the _processBlock() prior to the RESULT_EOF / RESULT_ERROR check, then the output appears to always be complete. However trying to debug and observe what's happening when the output gets truncated seems to make the problem go away (maybe some race condition?).

orbtop: Exception number format, 0..N vs -16..N

orbtop is using numbers starting from 0 as exception number, it is also numbering scheme used in ARM docs. However typical definition of IRQn_Type enum will use negative numbers for exceptions and non-negative for interrupts (SysTick_IRQn = -1 and FirstInterrupt = 0).

While translating between these two schemes are trivial it is also easy for human being to make off-by-one error and mismatch interrupts (I imagine that two interrupts in active use can be next to each other so mistake will not be easy to spot).

I'm not sure that switching orbtop numbering to -16..N is the best choice but maybe adding some info ("subtract 16 to get IRQn_Type values") or configurable option?

Use O_NONBLOCK when opening serial port

Hi,

I've been playing around with Orbuculum on MacOS over the last week or two. I have a couple of tweaks in the pipeline to make it play nice on this platform but the main one is the addition of the O_NONBLOCK flag when opening a serial port.

The open(2) system call can block waiting for "carrier" with some USB CDC devices. Since there is no carrier (they're not modems) you need to open them with O_NONBLOCK, set CLOCAL (which orbuculum already does) then clear O_NONBLOCK using the F_GETFL/F_SETFL commands with fcntl(2).

The attached diff contains the fix and also format string fixes for uint64_t.

Steve
orbuculum.txt

Arch linux builds need a meson prefix

Got my orbtrace mini today and I've been speedrunning getting all the tooling going, coming from a SeggerGDBServer style setup.

Issue

Blindly following this repo's docs will lead overly keen Arch Linux users into a pretty typical error when any orb* tool tries to load liborb.so from the default install path /usr/local/lib/liborb.so.

orbtrace: error while loading shared libraries: liborb.so.0: cannot open shared object file: No such file or directory

Resolution

Arch Linux's packaging etiquette normally wants meson builds to be prefixed on /usr.

i.e. a more correct incantation for this repo's build is:

meson setup --prefix=/usr build

I'm happy to PR a note into the docs if you want.

Install more files on Linux

At the moment the meson install target only installs the executables and library.
In my opinion on Linux the Support/60-orbcode.rules should be installed to /lib/udev/rules.d/.
Also the Support/gdbtrace.init is useful enough to be placed in /usr/share/orbuculum/.
The need to manually copy this file could lead to people using outdated versions.

no support for asynchronous ITM

As far as I can tell from the code and from my experiments, you simply don't support ITM mode (no TPIU formatting) without synchronization packets.

This is a rather harsh requirement, even ARM says not to do this. "If a system is using an asynchronous serial trace port, ARM recommends it disables Synchronization packets to reduce the data stream bandwidth." (See armv7m architecture reference manual Section C1.7.1 "Synchronization support" (page 847 in my copy)

a few insertions of ITMDecoderForceSync( &_r.i, TRUE ); into orbcat/orbtop/orbdump improve things substantially, but that's probably not how you want to handle things permanently.

First contribution

Hi @mubes , I would like to start a list of activities, kind of 'first contributions' tasks, to get familiar with the orbcode tooling.Do you (or folks) have such list?

Build error

Unable to build:

make
 Compiling Src/itmDecoder.c
 Compiling Src/tpiuDecoder.c
 Compiling Src/generics.c
 Compiling Src/orbuculum.c
 Compiling Src/filewriter.c
 Compiling Src/ftdispi.c
Completed build of orbuculum
Completed build of orbcat
 Compiling Src/orbtop.c
 Compiling Src/symbols.c
Src/symbols.c: In function ‘SymbolLookup’:
Src/symbols.c:138:35: warning: implicit declaration of function ‘bfd_get_section_vma’; did you mean ‘bfd_set_section_vma’? [-Wimplicit-function-declaration]
  138 |     uint32_t workingAddr = addr - bfd_get_section_vma( s->abfd, s->sect );
      |                                   ^~~~~~~~~~~~~~~~~~~
      |                                   bfd_set_section_vma
Src/symbols.c:140:44: warning: passing argument 1 of ‘bfd_section_size’ from incompatible pointer type [-Wincompatible-pointer-types]
  140 |     if ( workingAddr <= bfd_section_size( s->abfd, s->sect ) )
      |                                           ~^~~~~~
      |                                            |
      |                                            bfd * {aka struct bfd *}
In file included from Inc/bfd_wrapper.h:44,
                 from Inc/symbols.h:38,
                 from Src/symbols.c:50:
/usr/include/bfd.h:1206:35: note: expected ‘const asection *’ {aka ‘const struct bfd_section *’} but argument is of type ‘bfd *’ {aka ‘struct bfd *’}
 1206 | bfd_section_size (const asection *sec)
      |                   ~~~~~~~~~~~~~~~~^~~
Src/symbols.c:140:25: error: too many arguments to function ‘bfd_section_size’
  140 |     if ( workingAddr <= bfd_section_size( s->abfd, s->sect ) )
      |                         ^~~~~~~~~~~~~~~~
In file included from Inc/bfd_wrapper.h:44,
                 from Inc/symbols.h:38,
                 from Src/symbols.c:50:
/usr/include/bfd.h:1206:1: note: declared here
 1206 | bfd_section_size (const asection *sec)
      | ^~~~~~~~~~~~~~~~
make: *** [Makefile:163: ofiles/Src/symbols.o] Ошибка 1

binutils version is 2.31.1-16

gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:hsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 9.3.0-11' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-mutex
Thread model: posix
gcc version 9.3.0 (Debian 9.3.0-11)
clang -v
clang version 9.0.1-12 
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/7
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/8
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/9
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.5.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/8
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/9
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/9
Candidate multilib: .;@m64
Selected multilib: .;@m64
Found CUDA installation: /usr/local/cuda-10.1, version 10.1




Segmentation fault when using DWT to watch data value

Hey, first, thanks so much for this awesome tool!

My only issue so far is that I run into a segmentation fault when I try to emit DWT events through the ITM.

My very simple test code on my nRF52840 Preview DK looks like that:

int32_t test = 0x1336;

void _DWT_enable() {
  CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
  ITM->LAR = 0xc5acce55;
  DWT->COMP2 = &test;
  DWT->FUNCTION2 |= (DWT_FUNCTION_EMITRANGE_Msk | (DWT_FUNCTION_FUNCTION_Msk & 0b0011));
}

int main() {

  _DWT_enable();

  while (true) {
 
    test++;

    nrf_delay_ms(1000);
         
  }
}

When I run Orbuculum it will receive a few bytes and then pretty much immediately segfault:

$ sudo ./orbuculum -s localhost:2332 -b swo/ -P -c 0,zero,"0x%08x\n" -v 3
Orbuculum V1.10 (Git 10BC7ACB Dirty, Built 2020-11-01 13:16:26+0000)
BasePath   : swo/
ForceSync  : true
Permafile  : true
SEGGER H&P : localhost:2332
Channels   :
         00 [zero] [zero]
         HW [Predefined] [hwevent]
Established Segger Link
RXED Packet of 144 bytes
Segmentation fault

Sometimes it manages to write a few lines into hwevent, sometimes not. If it does, it looks something like that:

6,2556,0,0x0002
6,46,0,0x0002

I didn't find any documentation on what this really means (is there any?) but according to the code that is a "offset write event" (is that correct? where would I find the data value and address? Or is this event not related at all?).

Running Orbuculum without any paramenters like: sudo ./orbuculum -s localhost:2332 segfaults as well.

Do you have an idea what causes the segfault?

orbtop should check provided elf exists before proceeding

(For clarity, this is tested against b475ebb)

Currently:

$ orbtop
Elf File not specified
$ cat justsomefilename
cat: justsomefilename: No such file or directory
$ orbtop -e justsomefilename
(program continues but complains about "Could not read symbols")
$ cat .
cat: .: Is a directory
$ orbtop -e .
(program continues without any errors)

Expected:

$ cat justsomefilename
cat: justsomefilename: No such file or directory
$ orbtop -e justsomefilename
orbtop: justsomefilename: No such file or directory
$ orbtop -e .
orbtop: .: Is a directory

Similarly for permission errors etc.

Devel missing fixes from master

Devel branch hasn't picked up fixes from master? It seems some of them were picked in with other changes, but others have been missed? eg, master's f6302c9 is included as part of the unrelated 6f0880e on Devel. It's at least missing the segfault on orbdump, but the way you've been using git makes it almost impossible to track what you have actually included where.

Orbtrace doesn't work correctly for me

I am trying out orbtrace with an iCE40HX-8K Breakout Board.

Building and flashing worked and orbuculum seems to talk to the FPGA fine as well.

First issue that arised was:

Orbuculum V1.10 (Git 0146E353 Dirty, Built 2020-11-30 12:40:35+0000)
BasePath   : 
ForceSync  : true
Permafile  : false
Orbtrace   : 4 bits width
Using TPIU : true (ITM on channel 1)
Channels   :
         00 [info] [info]
         HW [Predefined] [hwevent]
Port opened
All parameters configured
orbuculum: Src/nwclient.c:221: nwclientSend: Assertion `len' failed.
Aborted

That was quickly fixed by recompiling with WITH_NWCLIENT=0, since I don't need it. But you may want to check that out (maybe it is related to the root problem below).

Now I get:

orbuculum -o 4 -c 0,info,"%c" -v 3
Orbuculum V1.10 (Git 0146E353 Dirty, Built 2020-12-10 12:54:20+0000)
BasePath   : 
ForceSync  : true
Permafile  : false
Orbtrace   : 4 bits width
Using TPIU : true (ITM on channel 1)
Channels   :
         00 [info] [info]
         HW [Predefined] [hwevent]
Port opened
All parameters configured
RXED frame of 0/900 full packets (  0%)    
RXED frame of 0/900 full packets (  0%)    
RXED frame of 0/900 full packets (  0%)    
RXED frame of 0/900 full packets (  0%)    
RXED frame of 0/900 full packets (  0%)    
...

Heartbeat is blinking. Same thing with only 1 bit width.
I am not sure what this output means. Can it be that I am just stupid and didn't wire it correctly? Do I need to configure something special in the code or gdb, besides enabling ITM and TRCENA? I am using a NRF52840 Preview DK.

orbtop segfaults if elf file disappears while running

I'll try and find and fix this myself if I run into it again, but filing it so it doesn't get forgotten.

It's not terrible behaviour, it's just not a very graceful exit :) (I'm presuming exiting is about the only sane thing to do. It could stay there saying "unable to open file" forever, but not sure that's better)

orbtop exception tick count wrong for nested instructions

I'm debugging an stm32f427 target using an orbtrace mini, and noticed that the tick counts for the interrupt in question according to orbtop are significantly smaller than a cycle count in code of the exception's running, even taking into account the nested interrupts running during the interrupt. Digging into orbtop, it looks like an exception trace "Resume" is taken to mean rolling up the entire exception stack to nothing, but that does not seem to be what the actual trace output is doing:

1,1,Enter,External,28
0,0,13
1,2,Enter,External,57
0,0,2690
1,1,Exit,External,57
0,0,960
1,1,Resume,External,28
0,0,7
1,2,Enter,External,57
0,0,4409
1,1,Exit,External,57
0,0,961
1,2,Resume,External,28
0,0,7
1,1,Enter,External,57
0,0,4401
1,3,Exit,External,57
0,0,965
1,2,Resume,External,28
0,0,7
1,2,Enter,External,54
0,0,3950
1,2,Exit,External,54
0,0,361
1,6,Resume,External,28
0,0,7
1,2,Enter,External,57
0,0,80
1,2,Exit,External,57
0,0,965
1,1,Resume,External,28
0,0,7
1,2,Exit,External,28
0,0,412

In the above example, 28 is the interrupt I'm trying to measure, and 57 occurs a few times during it as a higher priority. orbtop maxTicks appears to be only giving me the max single instance of 28 between the 57s, but really the exception is underway for the entire above trace.

Modifying orbtop like:

@@ -302,12 +304,12 @@ void _handleException( struct excMsg *m, struct ITMDecoder *i )
             break;
 
         case EXEVENT_RESUME: /* Unwind all levels of exception (deals with tail chaining) */
-            while ( ( _r.currentException != NO_EXCEPTION ) && ( _r.erDepth ) )
+            while ( ( _r.currentException != m->exceptionNumber ) && ( _r.erDepth ) )
             {
                 _exitEx( _r.timeStamp );
             }
 
-            _r.currentException = NO_EXCEPTION;
+//            _r.currentException = NO_EXCEPTION;
             break;

produces numbers far more aligned with my own measurements. Am I misunderstanding something about the meaning of the trace messages, or is this the correct way to handle these events?

orbtrace : add support for the 1bitsquared icebreaker fpga board

The icebreaker has a ICE40UP5K-SG48 on it, seems like a good candidate for a port. Would probably have to leave off sump or reduce the number of pins in the analyser.

My first pass at pin assignment looks like this, but I need to move to the other FT2232 port.

# Trace signals PMOD1A 1-4, 10
set_io traceDin[0]              4  
set_io traceDin[1]              2
set_io traceDin[2]             47
set_io traceDin[3]             45
set_io traceClk                44

# SPI connection to PC

# FT2232H pin 40
set_io spitx            18    # SPI MISO
# FT2232H pin 39
set_io spirx            9     # SPI MOSI
# FT2232H pin 38
set_io spiclk           6     # SPI CLK
# FT2232H pin 41
set_io rstIn            19     # SPI CS pin of FT2232H

# Oscillator clock for FPGA PLL
set_io clkIn        35    # connected to 12MHz xtal

# LEDs (G & RGB)
set_io sync_led        37
set_io txOvf_led       39
set_io txInd_led       40
set_io heartbeat_led   41

orbtop CPU usage increases over time

Target: tm4c129x @ 120Mhz
Interface: jlink pro
middleware: openocd

The Jlink is running at 20M, with SWO speed autodetected, (openocd reports 41M, but that's... clearly not correct)

I'm using DWT PC sampling with the 1024 divider, and it all works nicely. I've got some ITM channels for debug as well, all values are as expected. the Bottom of the orbtop screen shows no overflows, but lots of samples, as expected for this sort of setup.

95.89%   112588 of  117116  Samples

[-S-H] Interval = 999ms

however, over time the ortbtop process CPU usage crawls up until it pegs a CPU, and eventually stops processing. I've used perf record -p $(pidof orbtop) to capture CPU usage early: (using something like 5-10% at this point)

Samples: 8K of event 'cycles:Pu', Event count (approx.): 4895560717
Overhead  Command  Shared Object     Symbol
  28.30%  orbtop   orbtop            [.] _handlePCSample
  27.92%  orbtop   orbtop            [.] _consolodateReport
   7.93%  orbtop   orbtop            [.] _routines_sort_fn
   7.28%  orbtop   liborb.so.2.1.0   [.] ITMPump
   4.36%  orbtop   [vdso]            [.] __vdso_gettimeofday

Then, later, when it was using ~40% cpu

Samples: 43K of event 'cycles:Pu', Event count (approx.): 44954534996
Overhead  Command  Shared Object     Symbol
  76.78%  orbtop   orbtop            [.] _consolodateReport 
  14.27%  orbtop   orbtop            [.] _routines_sort_fn
   5.43%  orbtop   orbtop            [.] _handlePCSample
   0.76%  orbtop   liborb.so.2.1.0   [.] ITMPump
   0.45%  orbtop   [vdso]            [.] __vdso_gettimeofday

During this time, orbtop's output itself has remained stable, showing steady ~100k samples per interval, with the target processor doing the "same" thing as before...

I suspect that overtime, I'm simply seeing more and more slightly different addresses, and that's making this hash sort in "consolidate": https://github.com/orbcode/orbuculum/blob/main/Src/orbtop.c#L371 take an unreasonable amount of time.

however, I'm afraid I don't know enough about the mechanisms here to try and work on a fix for this at this point.

CP2102 details

Hi, nice work you're doing! I'm trying to run this with CP2102 but no luck so far

my orbuculum command is

orbuculum -b swo/ -v 3 -a /dev/ttyUSB0 -s 115200

for gdb

prepareSWD 72000000 115200 1 0

followed by

https://github.com/mubes/orbuculum/blob/master/Support/gdbinits/gdbinit-bmp#L35

The result is I can see the data on scope and when using screen but no output from orbcat.

Also tried with 921600 baudrate (both in gdb and for orbuculum, also with TPIU on/off).

I'm also going to try with BluePill and F4 discovery flashed with BMP, managed to flash HX8K board as well but no data from parallel trace yet. Will report soon.

Extraneous arguments in meson.build file

I'm trying to build orbuculum from source, from the main branch. I get the following error:

$ meson setup build
The Meson build system
Version: 0.56.2
Source dir: /home/j-hui/extern/orbuculum
Build dir: /home/j-hui/extern/orbuculum/build
Build type: native build
Project name: orbuculum
Project version: undefined
C compiler for the host machine: ccache cc (gcc 10.2.1 "cc (Debian 10.2.1-6) 10.2.1 20210110")
C linker for the host machine: cc ld.bfd 2.35.2
Host machine cpu family: x86_64
Host machine cpu: x86_64
Run-time dependency threads found: YES
Found pkg-config: /usr/bin/pkg-config (0.29.2)
Run-time dependency libusb-1.0 found: YES 1.0.24
Run-time dependency libzmq found: YES 4.3.4
Run-time dependency sdl2 found: YES 2.0.14

meson.build:3:0: ERROR: Expected 1 arguments, got 2.

A full log can be found at /home/j-hui/extern/orbuculum/build/meson-logs/meson-log.txt

The problem appears to be from the dependencies section, which invokes dependency('ncurses', 'ncursesw'). I'm able to work around the problem with either of the following changes:

-    dependency('ncurses', 'ncursesw')
+    dependency('ncurses')

or

-    dependency('ncurses', 'ncursesw')
+    dependency('ncurses', fallback: ['ncursesw'])

but I'm wondering if I'm doing something wrong in the first place?

Thanks!

Windows CLI output has corrupted characters

Hi,

Thanks for providing this great tool!

When using the provided win64 releases (tested v2.1.0), some part of the outputs of the tools appear to be corrupted. Maybe this is an issue with wrong character encodings?

Examples:

orbuculum -m 1000 -s localhost:50001
←[1F←[K←[1;33m     0 ←[0m Bits/sec ←[0m
←[1F←[K←[1;33m     0 ←[0m Bits/sec ←[0m
←[1F←[K←[1;33m     0 ←[0m Bits/sec ←[0m
←[1F←[K←[1;33m     0 ←[0m Bits/sec ←[0m```

orbtop -e test.elf
←[1;33mLoaded test.elf
←[0m←[2J←[;HConnected...
←[2J←[;H←[1;33m 61.57% ←[1;34m    1849 ←[1;36m** Sleeping **←[0m
←[1;33m 33.99% ←[1;34m    1021 ←[1;36mvApplicationIdleHook←[0m
←[1;33m  2.33% ←[1;34m      70 ←[1;36mFLEXCOMM1_DriverIRQHandler←[0m
←[1;33m  0.79% ←[1;34m      24 ←[1;36mprvIdleTask←[0m
←[1;33m  0.46% ←[1;34m      14 ←[1;36mFLEXCOMM_GetInstance←[0m
←[1;33m  0.19% ←[1;34m       6 ←[1;36mCTIMER_GetStatusFlags←[0m
←[1;33m  0.13% ←[1;34m       4 ←[1;36mSPI_MasterTransferNonBlocking←[0m
←[1;33m  0.13% ←[1;34m       4 ←[1;36mprvCheckTasksWaitingTermination←[0m
←[0m-----------------
←[1;33m 99.59% ←[1;34m    2992 ←[0mof ←[1;33m 3003 ←[0m Samples

←[0m[←[1;31mV←[1;32mS←[0m-←[1;36mH←[0m] ←[0mInterval = ←[1;33m998←[0mms

Thanks!

make Error

typing make after cloning gives the following error

/bin/sh: ofiles/git_version_info.h: No such file or directory
make: *** [get_version] Error 1

mac osx sierra
kindly help.

Add option to build without the fifos.

There are some circumstances where orbuculum only needs to be a network multiplexer and the fifos are not needed. Add an option to make this possible.

Building on Mac M1

Not an issue but perhaps worth noting the following issues and adding to the documentation?

  1. Homebrew on macOS now installs into /opt/homebrew/ so you need to adjust paths inn the Makefile appropriately.
  2. If you have installed binutils with Homebrew, this will not build on M1 without deactivating them.

So need to (1) edit the Makefile:85 to

 ifdef OSX
    INCLUDE_PATHS += -I/opt/homebrew/include/libusb-1.0
    LDLIBS = -L. -L/opt/homebrew/lib -lusb-1.0 -ldl -lncurses -lpthread -lintl -L$(OLOC) -l$(ORBLIB)

and (2) need to (at least temporarily) move aside any binutils installed in /opt/homebrew/opt/binutils
mv /opt/homebrew/opt/binutils ~/binutils

Develop branch doesn't build with WITH_FPGA=0

You guys really need a travis or something build that tries building various modes for you :)

in orbuculum.c:1099 we have

   /* Start the filewriter */
    IF_WITH_FIFOS( fifoFilewriter( _r.f, options.filewriter, options.fwbasedir ) );

and it would seem that options.fwbasedir is "file writer base dir" ? or at least, that'swhat the fifoFilewriter method expects.

However, in the options struct at line 136:

    /* FPGA Information */
    IF_INCLUDE_FPGA_SUPPORT( char *fwbasedir );          /* Where the firmware is stored */

Which seems to be something else?

It's not actually used anywhere though, it's never set either, not by any of the command line options. Given these amgiuities, I can make it compile by just

diff --git a/Src/orbuculum.c b/Src/orbuculum.c
index 785bb39..012e32b 100644
--- a/Src/orbuculum.c
+++ b/Src/orbuculum.c
@@ -1096,7 +1096,7 @@ int main( int argc, char *argv[] )
 #endif
 
     /* Start the filewriter */
-    IF_WITH_FIFOS( fifoFilewriter( _r.f, options.filewriter, options.fwbasedir ) );
+    IF_WITH_FIFOS( fifoFilewriter( _r.f, options.filewriter, NULL ) );
 
 #ifdef INCLUDE_FPGA_SUPPORT
 

But I don't know what the "real" fix is I'm sorry.

Feature request: Command line option to switch colour palettes

The default colour palette for the Orb tools is not ideal when used with a pale window background; the light colours (e.g. yellow, cyan, green) are more or less illegible:

Screenshot 2020-12-20 at 15 26 12

There's a compile-time option to switch off colourisation, but it would be nice to have a command line option to select from some built-in palettes.

orbuculum writes weird files when ITM trace is heavily loaded

I had too much data being written to ITM software trace ports, which resulted in ITM Overflow messages as expected. However what I didn't expect is that orbuculum wrote a bunch of weirdly named files to the working directory:

petteri@oddish:tmp$ ls -l
total 116
-rw-r--r-- 1 petteri petteri 110254 Apr 29 10:55 swo_log.bin

petteri@oddish:tmp$ orbuculum -f swo_log.bin
ITM Overflow (1)
ITM Overflow (2)
ITM Overflow (3)
ITM Overflow (4)
....
Request for write on descriptor 1 while file closed
Request for write on descriptor 6 while file closed
Request for write on descriptor 6 while file closed
Request for write on descriptor 6 while file closed
Request for write on descriptor 3 while file closed
Attempt to write to descriptor 7 while open writing 4
...

petteri@oddish:tmp$ ls -l
total 360
-rw-r--r-- 1 petteri petteri      0 Apr 29 10:56 '~'
-rw-r--r-- 1 petteri petteri      2 Apr 29 10:56 '~}'$'\367\272'
-rw-r--r-- 1 petteri petteri      2 Apr 29 10:56 '~'$'\256'
-rw-r--r-- 1 petteri petteri      3 Apr 29 10:56 '<'
-rw-r--r-- 1 petteri petteri      0 Apr 29 10:56 '>'
-rw-r--r-- 1 petteri petteri      0 Apr 29 10:56 ''$'\343'
-rw-r--r-- 1 petteri petteri      0 Apr 29 10:56 ''$'\376'
-rw-r--r-- 1 petteri petteri      5 Apr 29 10:56 ''$'\352'
-rw-r--r-- 1 petteri petteri     18 Apr 29 10:56 ''$'\377'
-rw-r--r-- 1 petteri petteri      0 Apr 29 10:56 ''$'\276'
-rw-r--r-- 1 petteri petteri      2 Apr 29 10:56 ''$'\326'
-rw-r--r-- 1 petteri petteri     17 Apr 29 10:56 ''$'\372'
-rw-r--r-- 1 petteri petteri      0 Apr 29 10:56 ''$'\254'
-rw-r--r-- 1 petteri petteri      0 Apr 29 10:56 ''$'\354'
-rw-r--r-- 1 petteri petteri      0 Apr 29 10:56 ''$'\374'
-rw-r--r-- 1 petteri petteri      0 Apr 29 10:56 ''$'\367'
-rw-r--r-- 1 petteri petteri     10 Apr 29 10:56 ''$'\303'
-rw-r--r-- 1 petteri petteri      3 Apr 29 10:56 ''$'\274'
-rw-r--r-- 1 petteri petteri      0 Apr 29 10:56 ''$'\356'
-rw-r--r-- 1 petteri petteri      0 Apr 29 10:56 ''$'\256'
-rw-r--r-- 1 petteri petteri      0 Apr 29 10:56 ''$'\254\367'
-rw-r--r-- 1 petteri petteri      9 Apr 29 10:56 ''$'\372\367\272'
-rw-r--r-- 1 petteri petteri      0 Apr 29 10:56 ''$'\327\017\356'
-rw-r--r-- 1 petteri petteri      0 Apr 29 10:56  4
-rw-r--r-- 1 petteri petteri      2 Apr 29 10:56  l
-rw-r--r-- 1 petteri petteri 110254 Apr 29 10:55  swo_log.bin

I think the file should be properly synchronized etc., so I'm wondering what causes the weird files.
I've attached the swo_log.bin. I've been using git revision 1fda426.
swo_log.bin.gz

Orbuculum fails to connect to J-LINK GDB Server on Windows.

OS: Windows 10
J-LINK: On board of an nrf52840DK
jlinkgdbservercl -select USB -device nRF52840_xxAA -endian little -if SWD -speed 4000 -noir -LocalhostOnly -nologtofile

GDB:

target remote localhost:2331
monitor reset
monitor SWO EnableTarget 0 8000000 0xff 0
prepareSWO 64000000 8000000
... other standard setups to enable PC sampling ...

orbuculum -s localhost:2332 -m 1000 -v3 outputs

orbuculum version a4d410b-dirty
Report Intv    : 1000 mS
NW SERVER H&P  : localhost:2332
Use/Strip TPIU : False
Established NW Server Link
Lost NW Server Link
Established NW Server Link
 No active connection

pretty much immediatly.

However, orbtop can connect fine using orbtop -s localhost:2332

Let me know if there is anything I can help with. Love the project ❤️

Discussion: RTIC Scope and orbuculum

Hello. This is a notice of another project which aims to accomplish similar goals as orbuculum. My aim here is to establish a line of communication that may eventually lead to some cross-pollination that would hopefully improve both projects.


As part of my thesis which I'm currently wrapping up I have been working with ITM on Cortex-M platforms where RTIC is used. This has collimated into a toolset named RTIC Scope. Unfortunately, I did not discover orbuculum until later later into the thesis and only just recently realized that I have effectively reimplemented some features which orbuculum already offers. While orbuculum seems to be a more generally applicable UNIX-style toolset, RTIC Scope instead exclusively fits into the Rust ecosystem by offering a cargo subcommand which aims to do it all:

  1. build your firmware with cargo;
  2. recover some metadata;
  3. optionally flash your target with the firmware and reset it;
  4. collect trace data from the target using SWO or the embedded trace buffer;
  5. map trace information to RTIC tasks (i.e. resolve raw ITM data);
  6. save trace packets to file for port-mortem analysis; and
  7. forward resolved trace information to frontends which can do whatever they like (display something in a GUI, save traces in a database, etc.).

The whole point of the toolset is to remove any end-user overhead: if an application is written in RTIC, RTIC Scope should allow instant insight into the system without any setup. We're some ways away from zero end-user overhead in the project's current state, however.

Interface-wise RTIC Scope currently supports any targets probe-rs supports and serial devices on which a raw ITM data-stream is expected.

Aside from the cargo subcommand work has been made on APIs for configuring ITM tracing target-side and host-side (via probe-rs), and an ITM protocol decoding library has been written.

The next big feature for RTIC Scope would be a graphical display of the trace data which orbuculum would appear to offer via orbtop and orbstat. I'll be taking a look at these in the coming weeks and see if they can be combined with RTIC Scope.


Now that we're aware of eachother I look forward to any eventual cross-pollination between the two projects.

Cheers.

Missing Libiberty on Mac OS X

I would like to know if there's any alternative to libiberty on Mac OS X as i'm unable to compile orbuculum since clang and macport gcc-7 don't have the libiberty library.

bumpy , daplink ?

Assume stuff !

Will this work with bumpy : https://github.com/electronut/ElectronutLabs-Bumpy ?

Will it work with any DAPlink probes ? The firmware ( https://github.com/ARMmbed/DAPLink ) seems to have SWO (UART / NRZ only), but it doesn't seem to be enabled for any hardware. I have a FRDM-K64F board (w/ K20DX chip) that runs DAPlink, so I could test with that.

The IBDAP hardware seems to have SWO : https://www.adafruit.com/product/2764 , https://www.hackster.io/armstart/ibdap-affordable-cmsis-dap-jtag-swd-debug-probe-e6d9a4 ... but can't find the firmware source.

Dunno if these have SWO : https://l-tek.si/web-shop/cmsis-dap-debug-probe/ , https://os.mbed.com/platforms/SWDAP-LPC11U35/

Thanks !

'ARM_INS_ERET' not in /usr/include/capstone/arm.h

$ cat /etc/os-release 
NAME="Linux Mint"
VERSION="20.3 (Una)"
ID=linuxmint
ID_LIKE=ubuntu
PRETTY_NAME="Linux Mint 20.3"

$ sudo apt install libusb-1.0-0-dev libczmq-dev libncurses-dev libsdl2-dev libelf-dev libcapstone-dev

$ meson --version
1.4.0

$ git log
commit 7968f96ef92a00b42123bf794442d54005284db3 (HEAD -> main, origin/main, origin/HEAD)
Author: Vegard Storheil Eriksen <[email protected]>
Date:   Tue Mar 26 00:23:45 2024 +0100

    Python interface moved to pyorb repo.

meson setup build is successful

Click to expand
$ meson setup build
The Meson build system
Version: 1.4.0
Source dir: /home/alex/git/orbuculum
Build dir: /home/alex/git/orbuculum/build
Build type: native build
Project name: orbuculum
Project version: 2.1.0
C compiler for the host machine: ccache cc (gcc 9.4.0 "cc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0")
C linker for the host machine: cc ld.bfd 2.34
Host machine cpu family: x86_64
Host machine cpu: x86_64
Run-time dependency threads found: YES
Found pkg-config: YES (/usr/bin/pkg-config) 0.29.1
Run-time dependency libusb-1.0 found: YES 1.0.23
Run-time dependency libzmq found: YES 4.3.2
Run-time dependency sdl2 found: YES 2.0.10
Run-time dependency ncurses found: YES 6.2.20200212
Run-time dependency capstone found: YES 3.0.5
Run-time dependency libelf found: YES 0.176

Executing subproject libdwarf 

libdwarf| Project name: libdwarf
libdwarf| Project version: 0.7.0
libdwarf| C compiler for the host machine: ccache cc (gcc 9.4.0 "cc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0")
libdwarf| C linker for the host machine: cc ld.bfd 2.34
libdwarf| C++ compiler for the host machine: ccache c++ (gcc 9.4.0 "c++ (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0")
libdwarf| C++ linker for the host machine: c++ ld.bfd 2.34
libdwarf| Compiler for C supports arguments -Wpointer-arith: YES
libdwarf| Compiler for C supports arguments -Wmissing-declarations: YES
libdwarf| Compiler for C supports arguments -Wstrict-prototypes: YES
libdwarf| Compiler for C supports arguments -Wcomment: YES
libdwarf| Compiler for C supports arguments -Wformat: YES
libdwarf| Compiler for C supports arguments -Wuninitialized: YES
libdwarf| Compiler for C supports arguments -Wshadow: YES
libdwarf| Compiler for C supports arguments -Wno-long-long: YES
libdwarf| Compiler for C supports arguments -Wfloat-compare: NO
libdwarf| Compiler for C supports arguments -Wsign-compare: YES
libdwarf| Compiler for C supports arguments -Wno-missing-field-initializers: YES
libdwarf| Compiler for C supports arguments -fno-omit-frame-pointer: YES
libdwarf| Compiler for C supports arguments -fvisibility=hidden: YES
libdwarf| Compiler for C supports function attribute unused: YES
libdwarf| Has header "fcntl.h" : YES
libdwarf| Has header "inttypes.h" : YES
libdwarf| Has header "malloc.h" : YES
libdwarf| Has header "stdint.h" : YES
libdwarf| Has header "sys/stat.h" : YES
libdwarf| Has header "unistd.h" : YES
libdwarf| Checking for type "uint64_t" : YES
libdwarf| Checking for type "uintptr_t" : YES
libdwarf| Checking for type "intptr_t" : YES
libdwarf| Has header "libelf.h" : YES
libdwarf| Has header "libelf/libelf.h" : NO
libdwarf| Has header "elf.h" : YES
libdwarf| Run-time dependency zlib found: YES 1.2.11
libdwarf| Run-time dependency libzstd found: NO (tried pkgconfig)
libdwarf| subprojects/libdwarf-0.7.0/test/meson.build:112: WARNING: Project targets '>=0.56' but uses feature deprecated since '0.56.0': meson.source_root. use meson.project_source_root() or meson.global_source_root() instead.
libdwarf| Program python3 found: YES (/home/alex/.local/pipx/venvs/meson/bin/python)
libdwarf| Message: Elf
libdwarf| subprojects/libdwarf-0.7.0/test/meson.build:137: WARNING: Project targets '>=0.56' but uses feature deprecated since '0.56.0': meson.build_root. use meson.project_build_root() or meson.global_build_root() instead.
libdwarf| Message: PE
libdwarf| Message: Macos
libdwarf| Program sh found: YES (/usr/bin/sh)
libdwarf| Configuring config.h using configuration
libdwarf| Configuring libdwarf.pc using configuration
libdwarf| Build targets in project: 26
libdwarf| WARNING: Deprecated features used:
libdwarf| * 0.56.0: {'meson.build_root', 'meson.source_root'}
libdwarf| Subproject libdwarf finished.

Build targets in project: 39

libdwarf 0.7.0

  Configuration Options Summary:
    OS               : linux
    BuildOS-BigEndian: no
    libelf support   : yes
    libdwarf         : always (zlib: yes) always (libzstd: no)
    dwarfdump        : always
    libdwarfp        : no
    dwarfgen         : no
    dwarfexample     : no
    documentation    : no

  Directories:
    prefix           : /usr/local
    bindir           : /usr/local/bin
    libdir           : /usr/local/lib/x86_64-linux-gnu
    incdir           : /usr/local/include
    pkgincdir        : /usr/local/include/libdwarf
    datadir          : /usr/local/share
    pkgdatadir       : /usr/local/share/libdwarf

  Compilation
    compilation      : ninja
    installation     : ninja install

orbuculum 2.1.0

  Subprojects
    libdwarf: YES 3 warnings

Found ninja-1.10.0 at /usr/bin/ninja
$ ninja -C build
[....]

FAILED: orbmortem.p/Src_loadelf.c.o 
ccache cc -Iorbmortem.p -I. -I.. -I../Inc -I../Inc/external -Isubprojects/libdwarf-0.7.0/src/lib/libdwarf -I../subprojects/libdwarf-0.7.0/src/lib/libdwarf -I/usr/include/libusb-1.0 -I/usr/include/pgm-5.2 -I/usr/include/SDL2 -I/usr/include/capstone -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -O0 -g -DLINUX -ggdb -D_GNU_SOURCE -DSCREEN_HANDLING -Wno-error=deprecated-declarations -include uicolours_default.h -include uicolours_default.h -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 -D_REENTRANT -isystem /usr/include/mit-krb5 -pthread -MD -MQ orbmortem.p/Src_loadelf.c.o -MF orbmortem.p/Src_loadelf.c.o.d -o orbmortem.p/Src_loadelf.c.o -c ../Src/loadelf.c
../Src/loadelf.c: In function ‘symbolDisassembleLine’:
../Src/loadelf.c:1042:33: error: ‘ARM_INS_ERET’ undeclared (first use in this function); did you mean ‘ARM64_INS_ERET’?
 1042 |         *ic |=  ( ( insn->id == ARM_INS_ERET ) ) ? LE_IC_JUMP | LE_IC_IRET : 0;
      |                                 ^~~~~~~~~~~~
      |                                 ARM64_INS_ERET
../Src/loadelf.c:1042:33: note: each undeclared identifier is reported only once for each function it appears in
[261/271] Compiling C object orbtrace.p/Src_symbols.c.o
../Src/symbols.c:120:36: warning: unknown option after ‘#pragma GCC diagnostic’ kind [-Wpragmas]
  120 |     #pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
      |                                    ^~~~~~~~~~~~~~~~~~~~~~~~
../Src/symbols.c:1064:36: warning: unknown option after ‘#pragma GCC diagnostic’ kind [-Wpragmas]
 1064 |     #pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
      |                                    ^~~~~~~~~~~~~~~~~~~~~~~~
[263/271] Compiling C object orblcd.p/Src_orblcd.c.o
ninja: build stopped: subcommand failed.

Do I have an older version of something?

Build error in Xubuntu 18.04 : `cannot find -liberty`

I cloned the repo and tried building the main branch which resulted in this:

make WITH_FPGA=0 
 Compiling Src/generics.c
 Compiling Src/itmDecoder.c
 Compiling Src/tpiuDecoder.c
 Compiling Src/msgDecoder.c
 Compiling Src/msgSeq.c
Completed build of orb
 Compiling Src/orbuculum.c
 Compiling Src/filewriter.c
 Compiling Src/fifos.c
 Compiling Src/nwclient.c
/usr/bin/ld: cannot find -liberty
collect2: error: ld returned 1 exit status
Makefile:218: recipe for target 'orbuculum' failed
make: *** [orbuculum] Error 1

I was able to fix it (and meet other deps except FPGA) with :

sudo apt install binutils-dev libelf-dev libiberty-dev

Thanks for this software :)

Waiting List

Please add your name to this list if you're interested in joining the waiting list for hardware. This isn't a hard committent, we'll let you know things like cost before you sign on the dotted line!

STM32 specific?

Hi all,

I'm wondering if this solution is limited to be used with STM32 as stated in the command
"enableSTM32SWD <*--- turn on SWO output pin on CPU"

thansk!

file input runs and exits before clients can connect

I'm trying to use the file input mode with the output file written by openocd. (So that I can get the SWO data from say, stlink instead of having to have an extra usb-uart) but a) it doesn't follow the file, it just reads it once, and b) it simply reads the file, passes it to "all" clients and exits. It does this... very quickly. Far far far faster than one could possibly run any of the other orb tools to actually connect and be one of these clients :)

Orbmortem save to file not working

We are trying to save the captured instruction trace with orbmortem. The help menu says that you should use the S key for this, but after typing the filename and hitting 'enter' the file isn't created anywhere. I would expect for the file to be saved in the current working directory, but I see nothing.

Am I missing something?

Thanks,
Augusto.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.