Index by title

AHBUARTplugin

AHBUart plugin screenshot example

General Description

The AHBUARTplugin is a root plugin which allows you to connect to any SOC using gaisler's AHBUART IP. The plugin is capable of scanning available serial port on the computer and measuring system clock if a DSU3 IP is also present. Before any transaction it will check if the device is still connected by reading at 0x80000000.

Python's specific features

Common methods

Methods list:



bool open (QString PortName, int baudrate)

Opens given PortName with given baudrate and returns true if success.
On Windows PortName is COMx where x is the port number.
On Linux PortName may be "/dev/ttySx" if you are using an integrated COM port or "/dev/ttyUSBx" if you are using an USB to RS232 converter. In both case x is the port number.

Example:

Here we will connect to target through /dev/ttyUSB0 at 3Mbaud and print success if we succeed.

proxy.loadSysDriver("AHBUARTplugin","AHBUARTplugin0")
if AHBUARTplugin0.open("/dev/ttyUSB0",3000000):
  print "success" 
else:
  print "failed" 

void close ()

Closes current port and tells child plugins that it is disconnected. If already disconnected, does nothing.


void updatePortList ()

Search for available serial port on the computer. This method isn't much useful in the python terminal since the list of serial ports will be used only for completion on the GUI.


int detectSpeed ()

Returns the system clock. This method will only work if a DSU3 IP is present on the soc and the timetag counter is counting.



APBUARTplugin

APB_UART_PLUGIN config panel
APB_UART_PLUGIN Terminal panel

General Description

The APB_UART_PLUGIN is a child plugin which allows you to print gaisler's APBUART output. Usually the APBUART is the default device where the printf are redirected which makes sense to print it in ascii in a terminal.
This plugin is able read the APBUART output either directly from it's output on a serial port or in FIFO debug mode with the root plugin. See illustration below.

Nominal connection over RS232 FIFO debug mode

Python's specific features

Common methods

Methods list:



void toggleUartState ()


void activate (bool flag)


void updateAPBUartsList ()


void setCurentAPBUart (int index)


void openUart ()


void closeUart ()


void setFifoDebugEnabled (bool enable)


void setAPBUartIndex (int index)


void setUARTPortNane (QString name)


void setUARTPortSpeed (int speed)



Features

Plugins

Register Editor

Python Console


How to write a SocExplorer plugin

Once you have installed SocExplorer from sources on your system, it should have added an new template to QtCreator. You can create a new plugin skeleton filling the wizard forms. Your plugin description is written in its qmake project file.
A SocExplorer plugin inherits from the socexplorerlugin base class which inherits from QDockWidget.

SocExplorerEngine services

Through SocExplorerEngine object you get some shared and centralized services.

Message logging

Instead of using printf inside a plugin to print some information, you can use this function:

void SocExplorerEngine::message(socexplorerplugin *sender, const QString &message, int debugLevel)

//From your plugin:

SocExplorerEngine::message(this,"Here is a message with a debug level of 2",2);

With this function you will centralize all the plugins messages and they will share the same formalism. Note that you can set the debug level of your message, if the message debugLevel is lower than SocEplorer loglevel then the message will be printed else it will be dropped.
To set the SocExplorer debug level you can use the -d option like this:

socexplorer -d 4 #all the message with a debug level or equal lower than 4 will be printed

Managing peripherals base address (Plugn'Play)

You don't necessary know the address of the peripherals present in your soc when you write a plugin for SocExplorer. So SocEplorer allows you to enumerate the peripheral inside your soc at run-time and share their base address with other plugins.

To enumerate a device/peripheral:

int addEnumDevice(const QString& rootPlugin,int VID,int PID,qint32 baseAddress,const QString& name);

//From your plugin:
QString devname = SocExplorerEngine::getDevName(VID,PID); // If the device is known you will get it name
SocExplorerEngine::addEnumDevice(this,VID,PID,BaseAddress,devname);

Now to get a peripheral base address:

qint32 getEnumDeviceBaseAddress(const QString& rootPlugin,int VID,int PID,int count=0);
     //or
qint32 getEnumDeviceBaseAddress(socexplorerplugin* plugin,int VID,int PID,int count=0);

//From your plugin:
unsigned int DSUBASEADDRESS = SocExplorerEngine::self()->getEnumDeviceBaseAddress(this,0x01 , 0x004,0); //you will get the Grlib's DSU3 base address 

Loading a plugin from an other one

For example once you get successfully connected to the target through a root plugin you may want to automatically trigger an AMBA bus scan with the AMB plugin.

void loadChildSysDriver(socexplorerplugin *parent, const QString child);

//From your plugin:
socexplorerproxy::loadChildSysDriver(this,"AMBA_PLUGIN");


Linux setup

Please note that SocExplorer is still under development, so things are supposed to move, it can fail to build sometimes or be buggy. Feel free to send us some bug reports!

If you are using Fedora, you can directly install socexplorer from our repository here
Or alternatively here

Prerequisites

All the next steps can be distribution dependent SocExplorer development is done on Fedora 23, but is should work with any other one, feedback are welcome!

Building SocExplorer

Affected folders are:

Now you should have a working SocExplorer, you can continue to install plugins or start write your own plugins.

Building SocExplorer LPP's Plugins

If you are here it assume that you have an updated and working version of SocExplorer.
To get LPP's SocExplorer plugins you can either clone or download them from here":https://hephaistos.lpp.polytechnique.fr/rhodecode/HG_REPOSITORIES/LPP/INSTRUMENTATION/SocExplorerPlugins.

Then first you may want to build only the plugins you plan to use, for example the SpaceWire plugin rely on STAR-Dundee usb driver which isn't free so if you don't have it you can't use it. To disable a plugin you have to edit the top qmake project file "SocExplorer_Plugins.pro" and remove the plugin folder name inside or comment it. As example if we want to disable the SpwPlugin and the memcheckplugin:

The file was initially:

TEMPLATE = subdirs
CONFIG   += ordered

SUBDIRS = \
    ahbuartplugin \
    ambaplugin \
    APBUARTPLUGIN \
    dsu3plugin \
    genericrwplugin \
    memctrlrplugin \
    memcheckplugin

unix:SUBDIRS +=  spwplugin

Then it become:

TEMPLATE = subdirs
CONFIG   += ordered

SUBDIRS = \
    ahbuartplugin \
    ambaplugin \
    APBUARTPLUGIN \
    dsu3plugin \
    genericrwplugin \
    memctrlrplugin 


Peripheral XML Format

SocExplorer allows you to view and edit in live your SOC peripheral as long as you describe them in a dedicated XML file. Note that SocExplorer will automatically show your peripherals in the Register Explorer pane as soon as you enumerate them.


Pluginlist

Here is the SocExplorer plugin list, we try to keep it updated as much as possible.

Root capable plugins

AHBUART plugin

AHBUart plugin screenshot example


APBUART plugin

APBUart plugin screenshot example


Spacewire plugin

Spacewire plugin screenshot example


RMAP plugin

Paul Leroy



Child only plugins

genericrw plugin

genericrwplugin screenshot example

This plugin allows you to edit or view any memory space of your SOC. You can choose the start address and the number of bytes you want to read or write.


memctrl plugin

memctrl plugin screenshot example

This plugin checks the a memory space and say if it can read and write to this space without any error. To ensure that there is no aliasing problems it generates a random number sequence in RAM, writes it to the destination memory space then read it and compare what he read with what he writes. It can be useful to detect memory controller configuration mistakes or soldering issues.


AMBA plugin

AMBA plugin screenshot example

This plugin handles the Gaisler' s plug and play AMBA bus, you can use it to list the available peripherals. All detected peripheral information will be shared by SocExplorer to all the other plugins and available in Python. For more details have a look here


DSU3 plugin

This plugin allow to load code from an elf file into the leon3 and start it execution. This plugin is experimental and will change a lot before the release state.


Plugins

Motivations

SocExplorer software doesn't do anything alone, it is supposed to work with plugin extending its functionality. The development of SocExplorer is based on the observation that most of the SOCs are structured around a central memory bus with a direct addressing, so if you can get a read an write access to this bus you can do anything you want on your SOC. But for the same SOC you can have different way to connect to it, with a serial port, a jatg port, the rmap protocol over SapceWire... . On different SOCs you can use the same way to connect but you can have different layout or different peripherals list. To write less code we decide to make a plugin for each functionality and to use a hierarchical way to instantiate plugins. First you have to connect to your SOC with a compatible plugin we call the root plugin, this plugin will give the access for all its children plugins to the SOC. That's the first level of hierarchy, you can have more levels if for example on your SOC have a other memory buss you access from a bridge on the main one without direct addressing.
Note that you can also make fake root plugins if you just want to make plugin which can be instantiated alone, but doesn't provide any access to any child plugin.


Plugins Python API

All SocExplorer plugins expose some common functions and their own functions to the embedded Python terminal.

Common Functions

All this functions are either implemented in the base class socexplorerplugin or in the plugin itself. They are described with their C++ interface since they are dynamically wrapped in the Python context. To have a better understanding of how the arguments are converted between Python and C++ you can have a look here. You can call any of the following methods from any plugin instance; MyPluginInstance.Method(...).

Function list:

QVariantList Read (unsigned int address, unsigned int count)

Reads target memory at given address and return its content. On any root plugin it will read system memory and by default on child plugin it will forward request to parent plugin util it reach root plugin and read system bus.
Note that this function could be re-implemented on a child plugin and have a different behavior.

The returned list is a Word list which means that the smallest data you can read is a word(32 bits) and count is the number of words to read. The function respect host endianness so it will convert data depending on target endianness.

See also void Write (unsigned int address, QList<QVariant> dataList);


void Write (unsigned int address, QList<QVariant> dataList)

Writes given datalist at given address in target system bus. On any root plugin it will writes system memory and by default on child plugin it will forward request to parent plugin util it reach root plugin and writes system bus.
Note that this function could be re-implemented on a child plugin and have a different behavior.
The given list is a Word list which means that the smallest data you can write is a word(32 bits). The function respect host endianness so it will convert data depending on target endianness.

Example:

Let's consider we have a Leon3 with some RAM at 0x40000000 and we want to write 1 2 3 and 0xffffffff. We are connected to the target through rootplugin which can be replaced by the plugin are using.

  rootplugin.Write(0x40000000,[1,2,3,0xffffffff])

See also QVariantList Read (unsigned int address, unsigned int count);


void closeMe ()

Closes the plugin.


void activate (bool flag)

Activates the plugin GUI, this function is called by SocExplorer you may not call this function unless you know exactly what you do. By default if the plugin GUI is disabled, it means that the root plugin isn't connected to the target and that any operation on child plugin are forbidden.


void setInstanceName (const QString & newName)

This method will be removed from python context since it may not be used from python terminal.


bool dumpMemory (unsigned int address, unsigned int count, QString file)

Dumps the memory content at given address in given file. As for Read method it will read memory word by word and it will handle host and target endianness. The data will be written in ascii with the following format:

0x40000000: 0xad4c0136
0x40000004: 0x665b89c0
0x40000008: 0xabc04748
0x4000000c: 0x8e110724

Where left column is address and right column is the corresponding data word.

Example:

One interesting usage of this method is to dump memory space while your system is running to see if some memory space got modified. In this example we will load an elf file containing an executable to a Leon3 target through the AHBUARTplugin and dump the first 16 bytes before and after execution and compare them. We also assume that the device is attached to ttyUSB0.

proxy.loadSysDriver("AHBUARTplugin","AHBUARTplugin0")
proxy.loadSysDriverToParent("dsu3plugin","dsu3plugin0",AHBUARTplugin0) 
AHBUARTplugin0.open("/dev/ttyUSB0",3000000)
dsu3plugin0.openFile("/somePath/someElfFile")
dsu3plugin0.flashTarget()
AHBUARTplugin0.dumpMemory(0x40000000,16,"/somePath/First_dump.txt")
dsu3plugin0.run()
waitSomeTime()  # You can wait or process something or do whatever you want 
AHBUARTplugin0.dumpMemory(0x40000000,16,"/somePath/Second_dump.txt")

Then you can for example diff your two files:

  diff -u /somePath/First_dump.txt /somePath/Second_dump.txt

See also bool dumpMemory (unsigned int address, unsigned int count, QString file, const QString & format);


bool dumpMemory (unsigned int address, unsigned int count, QString file, const QString & format)

This function behaves like bool dumpMemory (unsigned int address, unsigned int count, QString file) except that it allows you to set output file format. Possible format are "srec", "bin" and "hexa".

See also bool dumpMemory (unsigned int address, unsigned int count, QString file, const QString & format);


bool memSet (unsigned int address, int value, unsigned int count)

Sets memory space with given value at given address, as for Write method it will write memory word by word and it will handle host and target endianness.

Example:

In this example we will first clear memory from 0x40000000 to 0x4000000C and then we will write 0x1234 from 0x40000010 to 0x4000002C

proxy.loadSysDriver("AHBUARTplugin","AHBUARTplugin0")
AHBUARTplugin0.open("/dev/ttyUSB0",3000000)
AHBUARTplugin0.memSet(0x40000000,0,4)
AHBUARTplugin0.memSet(0x40000010,0x1234,8)

bool loadbin (unsigned int address, QString file)


bool loadfile (abstractBinFile * file)



Python Debug

It is possible to use a Python debugger with SocExplorer, to do so you need to install winpdb (packaged on fedora).


SocExplorerPlot rpdb2 start

Winpdb attach

Note that you have to provide the same password than used to start the server!
You should get a list of running sessions like this:

Winpdb sessions list

And once connected, you should get this:

Winpdb connected

Winpdb with some breakpoints

Note that you need to click on the arrow to start debugging but SocExplorer will not evaluate the python file, you need to execute by dragging your file in the SocExplorer Python console, then have some fun!


Python tricks

Basic SocExplorer interaction

An interesting feature in SocExplorer is that you can drag and drop a python script in the terminal, it will execute it. First you can get some updated examples in the doc folder of SocExplorer source code.

Plugin related functions

SOC related functions

SocExplorer provided objects

SocExplorer plot

SocExplorerPlot is a wrapper to the QCustomPlot class, a simple and efficient plot widget. The following example should give you this result, please note that you will also need numpy library to run it.

SocExplorerPlot example


import numpy as np
freq1 = 30
freq2 = 300
time_step = 0.001

t_ini = -50 * 1.0/(max(freq1,freq2))
t_fin = -1 * t_ini

time_vec = np.arange(t_ini, t_fin, time_step)

#input signal
input_sig1 = np.sin(2 * np.pi * freq1 * time_vec)
input_sig2 = np.sin(2 * np.pi * freq2 * time_vec)
input_sig = input_sig1 + input_sig2

plot=PySocExplorer.SocExplorerPlot()
plot.setTitle("demo")
plot.setXaxisLabel("Time(s)")
plot.setYaxisLabel("Values")

Courbe1=plot.addGraph()
Courbe2=plot.addGraph()
Courbe3=plot.addGraph()

plot.setGraphData(Courbe1,time_vec.tolist(),input_sig1.tolist())
plot.setGraphData(Courbe2,time_vec.tolist(),input_sig2.tolist())
plot.setGraphData(Courbe3,time_vec.tolist(),input_sig.tolist())

pen=plot.getGraphPen(1)
pen.setWidth(1)
color=pen.color()
color.setRgb(0x00FF00)
pen.setColor(color)
plot.setGraphPen(1,pen)

pen=plot.getGraphPen(0)
pen.setWidth(1)
color=pen.color()
color.setRgb(0xFF0000)
pen.setColor(color)
plot.setGraphPen(2,pen)

plot.rescaleAxis()

  

TCP_Terminal_Client

Sometime you need to print some information while your python script is running, unfortunately SocExplorer isn't multi-threaded so you won't get any output until your script execution is finished. To solve this problem with SocExplorer setup you will get a small tcp terminal program which will run in a separated process. From one Python object you will be able to start the terminal process and to send it some data to print. Note that an other utilization of this terminal should be to deport the print outputs on a distant computer.

SocExplorerPlot example

SocExplorerPlot example

QhexSpinBox

QhexEdit


Test

$2^5$

$\omega = k^{2}$


SocExplorer Wiki

Child pages:

Win32 setup
Source code
RPM packages

General description

SocExplorer is an open source generic System On Chip testing software/framework. We write this software for the development and the validation of our instrument, the Low Frequency Receiver (LFR) for the Solar Orbiter mission. This instrument is based on an actel FPGA hosting a LEON3FT processor and some peripherals. To make it more collaborative, we use a plugin based system, the main executable is SocExplorer then all the functionality are provided by plugins. Like this everybody can provide his set of plugins to handle a new SOC or just a new peripheral. SocExplorer uses PythonQt to allow user to automate some tasks such as loading some plugins, configuring them and talking with his device. SocExplorer is provided under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

To install it

Reporting a bug

To report bugs, you need to register in our system them you can report bugs here.
If you don't want to register you can simply send a mail.

Use cases

Use case 1

In this case, the AHBUARTplugin and the memctrlplugin are loaded. The ahbuartplugin is called a root plugin because it is at the top of the plugin hierarchy, it makes the connection between SocExplorer and the AMBA bus. Talking through the root plugin, the memctrlplugin allows you to test some memory space at a given address.
SocExplorer use case 1

Use case 2

In this use case, the root plugin is the rmapplugin, this plugin allows you to talk through either the GRESB or the stardundee SpaceWire-USB Brick. The second loaded plugin is the genericrwplugin. This plugin is a simple hexadecimal editor, you can use it to view or edit any space of the SOC memory, see below in the SocExplorer screenshot.
SocExplorer use case 2

Videos

This video is quite outdated but gives a good overview of what SocExplorer is able to do.

Loading the player ...

If the video doesn't load you can directly watch it from here

Screenshots

SocExplorer running on Linux SocExplorer loading code on LFR

Updated over 4 years ago by Alexis Jeandet