Gu 04 WG Debugging and Peripherals
Gu 04 WG Debugging and Peripherals
"toolchainBinDir": "/home/walter/.platformio/packages/toolchain-gccarmnoneeabi/bin"
(Inside this folder you can find the gdb that we will use in the next steps)
How to debug using platformio IDE and HW
If you have multiple environments, before starting debugging you need to choose one.
To debug in hardware, simply choose the correct environment, using the PlatformIO: switch
project environment command:
You can also access this command from the status bar:
How to debug using platformio IDE and HW
To start the debugging, simply start it as you would do for a local program with vscode.
Choose the PIO Debug configuration that platformIO generated at project creation.
Set a breakpoint somewhere in your code and hit the green arrow to start debugging.
You will get all the usual functionalities gdb offers:
● Breakpoints
● Debug console
● Step by step execution
● Variables examiner
● Peripherals, Registers, memory and disassembly
How to debug using platformio IDE and HW
How to debug using platformio IDE and HW
Outline
So we will work with the first approach. The commands to execute are:
1 - Open renode monitor, create a machine and load the platform (using k64f.resc script)
2 - start a gdb server on renode, with machine StartGdbServer 3333
3 - Open gdb with the debug firmware ./arm-none-eabi-gdb firmware.elf
4 - Connect gdb in the host to the server with (gdb) target remote :3333
5 - Load your debug .elf firmware from renode using sysbus LoadELF @firmware.elf
6 - start simulation with (gdb) monitor start and (gdb) continue &
Loading the firmware
(monitor) include @scripts/single-node/k64f.resc
(K64F) machine StartGdbServer 3333
(K64F) showAnalyzer uart0
(K64F) sysbus LoadELF @.pio/build/frdm_k64f_renode_debug/firmware.elf
$ /home/walter/.platformio/packages/toolchain-gccarmnoneeabi/bin/arm-none-eabi-gdb
.pio/build/frdm_k64f_renode_debug/firmware.elf
GNU gdb (GNU Tools for Arm Embedded Processors 8-2018-q4-major) 8.2.50.20181213-git
. . .
NOTE: If you are following this slides offline, the commands above will fail because you don’t have a debug
firmware yet. Keep reading the next couple of slides.
Outline
We also saw that we can not rely on the (gdb) load command, and therefore we
can not rely on PlatformIO to generate a debug firmware automatically and load it.
https://docs.platformio.org/en/latest/projectconf/build_configurations.html
https://docs.platformio.org/en/latest/projectconf/section_env_debug.html#debug
-load-mode
Integrating platformio and renode for debugging
[env:frdm_k64f_renode_debug]
; custom settings for debugging with renode.
; automatic load using gdb does not work in this platform, so we manually
; compile a debug release and load it using renode.
; see https://github.com/renode/renode/issues/398
build_type = debug
debug_tool = custom
debug_load_mode = manual ; Disable automatic loading by platformio
debug_port = localhost:3333
debug_server = renode
--hide-log ; to avoid filling the debug console with renode logs
-e include @scripts/single-node/k64f.resc
-e sysbus LoadELF @$PROG_PATH
-e machine StartGdbServer 3333
debug_extra_cmds =
monitor start ; same as we did when using gdb manually, we start the simulation
Integrating platformio and renode for debugging
Integrating platformio and renode for debugging
Notes:
Platformio provides a debug_tool = renode option, but is not available for all
platforms.
https://docs.platformio.org/en/latest/plus/debug-tools/renode.html
For some platforms, the autoload from platformio (using gdb load) works, so
you don’t have to do it with renode. For this reason some examples you will
find online do not use the same procedure that we used.
Outline
Most of the peripherals already present and that you will implement are
written in C #.
Because all devices are connected to the same line, all devices need to have an unique
address.
Recap of I2C communication
To establish a communication between the master and one of the slaves, the
master has to:
● Take control of the bus with a Start
● Send the address of the slave (usually 7 bits)
● Indicate if the operation is Read or Write
● The 8 bit data can then be transmitted (with the corresponding ACKs)
● Finally the Stop is sent.
Outline
src/Infrastructure/src/Emulator/Peripherals/Peripherals/I2C
src/Infrastructure/src/Emulator/Peripherals/Peripherals/Sensors
I2C controller example: STM32F4
src/Infrastructure/src/Emulator/Peripherals/Peripherals/I2C/STM32F4_I2C.cs
namespace Antmicro.Renode.Peripherals.I2C
{
public sealed class STM32F4_I2C : SimpleContainer<II2CPeripheral>, IDoubleWordPeripheral,
IBytePeripheral, IKnownSize
{
We can therefore add this I2C controller to our platform (adding it to the sysbus).
To add the I2C to our platform we need to know:
- The address in the sysbus
- The Event and Error interrupts ID in the nvic
Address: 0x40005400
Event Interrupt position: 31
Error Interrupt position: 32
Model: Si7021
https://www.adafruit.com/product/3251
When referring to I2C devices, the address you find on the datasheet is usually the 7 bit
address.
However, when using the device, in the I2C protocol you need to use the 8 bit address,
which is just the 7 bit address and the R/W bit:
Therefore if you want to use multiple SI7021 sensors, you need to use some technique like
I2C channel multiplexer or multiple I2C ports. https://learn.adafruit.com/working-with-
multiple-i2c-devices
Some sensors allow configuration of the address. For example the TMP 102 allows you to
configure the address according to the value of the A0 PIN:
How to read data from the Si7021 sensor
From the datasheet, the required operations to take a
measurement are:
● Send command:
○ Start
○ Address
○ Write
○ Data: command
● Renode already provides a generic Interface for I2C peripherals, so we can simply inherit from it.
● Renode already provides a mechanism to list the commands our sensor can receive, we just need
to provide the handler.
namespace Antmicro.Renode.Peripherals.Sensors
{
public class SI70xx : II2CPeripheral, ITemperatureSensor,
IHumiditySensor
{
public SI70xx(Model model)
{
this.model = model;
commands = new I2CCommandManager<Action<byte[]>>();
outputBuffer = new Queue<byte>();
commands.RegisterCommand(MeasureHumidity, 0xE5);
commands.RegisterCommand(MeasureHumidity, 0xF5);
commands.RegisterCommand(MeasureTemperature, 0xE0);
Sensor model in renode: The environment
We need private members to hold the Humidity and Temperature raw values. Think of these values as the
environment value, that the sensor will measure when triggered.
We also need to provide public properties (setters and getters) that allow us to get and set human values from
the renode monitor and control the environment. (The conversion formulas are in the sensor datasheet.)
For our sensor, when the master requests a write, it is sending the sensor a command, so
we need to handle it.
Here we simply send the outputBuffer that we prepared in the previous step.
Notice there is only one Read method, as the variable to be read is prepared during the write
request.
Note that we do not add it directly to the sysbus (we can’t, our sensor interface does not
implement IBytePeripheral etc)
Make sure the address corresponds to the one in the datasheet (7 bit address).
Thankfully:
● STM32 provides the HAL (Hardware abstraction layer) to deal with the I2C
specification.
● You can find a driver for the si7021 (and other sensors), that uses the STM32
HAL here: https://github.com/belyalov/stm32-hal-libraries
● Zephyr also provides an abstraction layer and drivers for multiple sensors.
Demo: Testing.
Using renode for sensor modelling can speed up the validation of your algorithms.
i2c1.sensor_si7021 Temperature 10
sleep 5
i2c1.sensor_si7021 Temperature 15
sleep 5
i2c1.sensor_si7021 Temperature 20
sleep 5
You can also use python to describe more complex behaviors. Refer to:
https://renode.readthedocs.io/en/latest/basic/using-python.html
If you are working with multiple sensors measuring the same variable, you want
to be sure all are reading consistent data. Check how to use environments
https://renode.readthedocs.io/en/latest/basic/sensors.html