platformio / platformio-core

Your Gateway to Embedded Software Development Excellence :alien:
https://platformio.org
Apache License 2.0
7.84k stars 789 forks source link

Integrate with Renode Simulation Framework for load and debug #3401

Closed carlosedp closed 3 years ago

carlosedp commented 4 years ago

What kind of issue is this?

What is Renode?

Renode is an open source software development framework with commercial support from Antmicro that lets you develop, debug and test multi-node device systems reliably, scalably and effectively.

Renode is a fantastic tool to simulate applications on multiple boards. As an example, it supports boards from STMicro and some RISC-V boards like SiFive HiFive1, Kendryte K210 and many more.

Full board list: https://renode.readthedocs.io/en/latest/introduction/supported-boards.html

This integration would be the best of both worlds where one can develop in PlatformIO and debug/simulate on Renode without requiring hardware. Renode is available for Windows, Mac and Linux just adjusting the execution path.

I've started testing the available options and identified Renode can be started as a Telnet server (over a choosen port) and issued commands to it.

As an example to run the HiFive 1 ZephyrOS Hello World project, I did (on MacOS):

  1. Open Renode with Telnet option: /Applications/Renode.app/Contents/MacOS/macos_run.command -P 1234
  2. Connected to the Renode Telnet server: telnet 1234
  3. Loaded the HiFive1 board script: include @scripts/single-node/sifive_fe310.resc
  4. Started Renode remote debugger port: machine StartGdbServer 3333 True
  5. Loaded my "Hello World" ELF binary built on PlatformIO: sysbus LoadELF @/Users/cdepaula/Documents/PlatformIO/Projects/200303-171147-zephyr-hello-world/.pio/build/hifive1/firmware.elf
  6. Start simulation with: start
image

To start over, issue the command Clear on Renode console.

Another option is loading Renode with command line execute parameters as:

/Applications/Renode.app/Contents/MacOS/macos_run.command \
    -e "include @scripts/single-node/sifive_fe310.resc" \
    -e "machine StartGdbServer 3333 True" \
    -e "sysbus LoadELF @/Users/cdepaula/Documents/PlatformIO/Projects/200303-171147-zephyr-hello-world/.pio/build/hifive1/firmware.elf" \
    -e "start"

I successfully integrated the PlatformIO debugger to an existing instance of Renode by adding debug_port = localhost:3333 to platformio.ini on my project. Added a test breakpoint and interacted with the debugging on the simulation:

  1. Open Renode with Telnet option: /Applications/Renode.app/Contents/MacOS/macos_run.command -P 1234
  2. Connected to the Renode Telnet server: telnet 1234
  3. Loaded the HiFive1 board script: include @scripts/single-node/sifive_fe310.resc
  4. Started Renode remote debugger port: machine StartGdbServer 3333 True

From there, I clicked the debugger "Play" and PlatformIO built and loaded my application into Renode.

image

Continued the breakpoint:

image

I just was not able to "Reset" and start over via debugging or software without issuing the Clear command on Renode and loading everything from start (it's fast though).

I'm wiling to help writing this support if I can get some tips.

carlosedp commented 4 years ago

Cc. @PiotrZierhoffer @pdp7 @pgielda @mgielda Hope this drives interest :)

carlosedp commented 4 years ago

Currently the macos_run.command has a small bug that will be fixed soon.

carlosedp commented 4 years ago

I've successfully made it work with no changes to PlatformIO Core, just by configuring the right bits on the project platformio.ini.

On Mac, I've installed Renode and made a link from ` to/usr/local/bin/renode` to have it in the Path. This still requires the fix from the issue linked on previous comment.

My platformio.ini file is:

[env:hifive1]
platform = sifive
framework = zephyr
board = hifive1
monitor_speed = 115200
# Settings to integrate with Renode upload and debug
upload_command = renode -e "include @scripts/single-node/sifive_fe310.resc" -e "machine StartGdbServer 3333 True" -e "sysbus LoadELF @$SOURCE" -e "start"
debug_tool = custom
debug_port = localhost:3333
debug_server = renode
    -e
    include @scripts/single-node/sifive_fe310.resc
    -e
    machine StartGdbServer 3333 True
debug_extra_cmds =
    monitor start

And the integration for both running/uploading and also debugging worked perfectly as seen below:

Alt text

ivankravets commented 4 years ago

@carlosedp thanks for the great research! It can be easy integrated in PlatformIO. It will look for you as:

[env:hifive1]
platform = sifive
framework = zephyr
board = hifive1
monitor_speed = 115200
upload_tool = renode
debug_tool = renode

We will back soon to this issue!

carlosedp commented 4 years ago

Nice thing is that Renode has support for more boards that are also supported by PlatformIO: https://renode.readthedocs.io/en/latest/introduction/supported-boards.html

carlosedp commented 4 years ago

Hey @ivankravets, I'm still fine-tuning the parameters and let you know. I have the serial console working too.

mgielda commented 4 years ago

Hi @carlosedp glad to see this! I already had an integration with pio written up internally and was thinking how to make this public, so glad you went along and did this ;)

We were busy with the Renode 1.9 relase which just went out this week - https://github.com/renode/renode/releases/tag/v1.9.0 - but now that it's past, happy to support this effort - @PiotrZierhoffer bringing to your attention.

ivankravets commented 4 years ago

Hi @mgielda ,

The only thing which we need for PlatformIO Core is a default GDB init config. See examples:

The rest integration work should be done on the dev-platform side (https://github.com/platformio/platform-sifive), if we mean SiFive. We will help with this. So, what should be GDB_RENODE_INIT_CONFIG?

In the example above which works for @carlosedp if was:

GDB_RENODE_INIT_CONFIG = """
define pio_reset_halt_target
    monitor reset halt
end

define pio_reset_run_target
    monitor reset
end

target extended-remote $DEBUG_PORT
monitor init
$LOAD_CMDS
pio_reset_halt_target
$INIT_BREAK
monitor start
"""

We plan to release PIO Core 4.3.0 next week. So, it would be great to have support for Renode.

carlosedp commented 4 years ago

In my config, I've been able to both build/upload and debug. Also connect to the simulation over console (via telnet) with:

[env:hifive1]
platform = sifive
board = hifive1
framework = zephyr
## ----- Settings below are for Antmicro Renode integration ----- ##
# Monitor port for Renode integration
monitor_port = socket://localhost:1234
# Upload settings for Renode integration
upload_command = renode $UPLOAD_FLAGS
upload_flags =
    -e include @scripts/single-node/sifive_fe310.resc
    -e machine StartGdbServer 3333 True
    -e emulation CreateServerSocketTerminal 1234 \"externalUART\"
    -e connector Connect uart0 externalUART
    -e sysbus LoadELF @$SOURCE
    -e start
# Debug settings for Renode integration
debug_tool = custom
debug_port = localhost:3333
debug_server = renode
    -e include @scripts/single-node/sifive_fe310.resc
    -e machine StartGdbServer 3333 True
    -e emulation CreateServerSocketTerminal 1234 "externalUART"
    -e connector Connect uart0 externalUART
debug_extra_cmds =
    monitor start

Works perfectly. Do you folks think on any additional features that could be included?

One thing I couldn't address that maybe @PiotrZierhoffer and @mgielda could help is to restart the debugging and "reset" the simulated board. Is it possible withou issuing a Clear command and starting over?

carlosedp commented 4 years ago

Guys, I'm seeing some problems debugging the console application on Renode.

On PlatformIO debug console I see the output below that I understand combined both PlatformIO and Renode outputs:

Processing hifive1 (platform: sifive; board: hifive1; framework: zephyr)
--------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/sifive/hifive1.html
PLATFORM: SiFive 2.0.3 > HiFive1
HARDWARE: FE310 320MHz, 16KB RAM, 16MB Flash
DEBUG: Current (custom) On-board (ftdi, qemu)
PACKAGES:
 - framework-zephyr 2.20100.200220 (2.1.0)
 - framework-zephyr-civetweb 0.20100.190807 (2.1.0)
 - framework-zephyr-fatfs 0.20100.190522 (2.1.0)
 - framework-zephyr-libmetal 0.20100.190530 (2.1.0)
 - framework-zephyr-littlefs 0.20100.190811 (2.1.0)
 - framework-zephyr-lvgl 0.20100.190812 (2.1.0)
 - framework-zephyr-mbedtls 0.20100.191006 (2.1.0)
 - framework-zephyr-mcumgr 0.20100.190528 (2.1.0)
 - framework-zephyr-mipi-sys-t 0.20100.191024 (2.1.0)
 - framework-zephyr-nffs 0.20100.190523 (2.1.0)
 - framework-zephyr-open-amp 0.20100.190612 (2.1.0)
 - framework-zephyr-openthread 0.20100.191024 (2.1.0)
 - framework-zephyr-segger 0.20100.190421 (2.1.0)
 - framework-zephyr-tinycbor 0.20100.191016 (2.1.0)
 - tool-cmake 3.15.5
 - tool-dtc 1.4.7
 - tool-gperf 3.1.0
 - tool-ninja 1.9.0
 - toolchain-riscv 1.80300.190927 (8.3.0)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 0 compatible libraries
Scanning dependencies...
No dependencies
Building in debug mode
Checking size .pio/build/hifive1/firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [===       ]  31.9% (used 5232 bytes from 16384 bytes)
Flash: [          ]   0.2% (used 25736 bytes from 16777216 bytes)
========================= [SUCCESS] Took 1.38 seconds =========================
Reading symbols from /Users/cdepaula/Documents/PlatformIO/Projects/Test/.pio/build/hifive1/firmware.elf...
PlatformIO Unified Debugger -> http://bit.ly/pio-debug
PlatformIO: debug_tool = custom
PlatformIO: Initializing remote target...
18:48:07.3470 [INFO] Loaded monitor commands from: /Applications/Renode.app/Contents/MacOS/./scripts/monitor.py
18:48:07.7633 [INFO] Including script: /Applications/Renode.app/Contents/MacOS/scripts/single-node/sifive_fe310.resc
18:48:07.7791 [INFO] System bus created.
18:48:08.2766 [DEBUG] Segment size automatically calculated to value 64KiB
18:48:08.2771 [DEBUG] Segment size automatically calculated to value 64KiB
18:48:08.2772 [DEBUG] Segment size automatically calculated to value 64KiB
18:48:08.3881 [DEBUG] Segment size automatically calculated to value 16MiB
18:48:08.6191 [INFO] sysbus: Loaded SVD: /var/folders/dv/d24tqkhn7zg55vj4ttrqq35m0000gp/T/renode-4287/178316e5-fb43-4b0c-83b4-935b1cf7a3e2.tmp. Name: FE310. Description: E31 CPU Coreplex, high-performance, 32-bit RV32IMAC core
      .
18:48:08.6460 [DEBUG] sysbus: Loading ELF /var/folders/dv/d24tqkhn7zg55vj4ttrqq35m0000gp/T/renode-4287/e70ddab6-e9ef-4eec-aea4-ebfc4fb40786.tmp.
18:48:08.6605 [INFO] sysbus: Loading segment of 20520 bytes length at 0x20400000.
18:48:08.6779 [DEBUG] sysbus: Segment loaded.
18:48:08.6780 [INFO] sysbus: Loading segment of 324 bytes length at 0x20405028.
18:48:08.6781 [DEBUG] sysbus: Segment loaded.
18:48:08.6782 [INFO] sysbus: Loading segment of 7944 bytes length at 0x80000148.
18:48:08.6788 [DEBUG] sysbus: Segment loaded.
18:48:08.7051 [INFO] cpu: Setting PC value to 0x20401BC4.
18:48:08.9003 [INFO] SiFive-FE310: GDB server with all CPUs started on port :3333
__start () at /Users/cdepaula/.platformio/packages/framework-zephyr/soc/riscv/riscv-privilege/common/vector.S:24
24      la t0, __irq_wrapper
No such command or device: init
Loading section vector, size 0x10 lma 0x20400000
Loading section exceptions, size 0x258 lma 0x20400010
Loading section text, size 0x59f8 lma 0x20400268
Loading section sw_isr_table, size 0x200 lma 0x20405c60
Loading section devconfig, size 0x84 lma 0x20405e60
Loading section rodata, size 0x42c lma 0x20405ee4
Loading section datas, size 0xc0 lma 0x20406310
Loading section initlevel, size 0x84 lma 0x204063d0
Loading section _k_mutex_area, size 0x14 lma 0x20406454
Loading section _k_queue_area, size 0x20 lma 0x20406468
Start address 0x20400000, load size 25736
Transfer rate: 612 KB/sec, 1715 bytes/write.
No such command or device: reset
Temporary breakpoint 1 at 0x20400920: file src/main.c, line 9.
18:48:19.0902 [INFO] SiFive-FE310: Machine started.
Starting emulation...
PlatformIO: Initialization completed
PlatformIO: Resume the execution to `debug_init_break = tbreak main`
PlatformIO: More configuration options -> http://bit.ly/pio-debug
18:48:20.4027 [DEBUG] cpu: Added hook @ 0x20400920
18:48:20.4429 [WARNING] plic: Unhandled write to offset 0x200000, value 0x0.
18:48:20.4433 [WARNING] gpioInputs: Unhandled write to offset 0x38, value 0x0.
18:48:20.4446 [WARNING] gpioInputs: Unhandled read from offset 0x3C.
18:48:20.4446 [WARNING] gpioInputs: Unhandled write to offset 0x3C, value 0x0.
18:48:20.4446 [WARNING] gpioInputs: Unhandled read from offset 0x38.
18:48:20.4446 [WARNING] gpioInputs: Unhandled write to offset 0x38, value 0x10000.
18:48:20.4447 [WARNING] gpioInputs: Unhandled read from offset 0x3C.
18:48:20.4447 [WARNING] gpioInputs: Unhandled write to offset 0x3C, value 0x0.
18:48:20.4447 [WARNING] gpioInputs: Unhandled read from offset 0x38.
18:48:20.4447 [WARNING] gpioInputs: Unhandled write to offset 0x38, value 0x20000.
18:48:20.4447 [WARNING] gpioInputs: Unhandled read from offset 0x3C.
18:48:20.4447 [WARNING] gpioInputs: Unhandled write to offset 0x3C, value 0x0.
18:48:20.4448 [WARNING] gpioInputs: Unhandled read from offset 0x38.
18:48:20.4448 [WARNING] gpioInputs: Unhandled write to offset 0x38, value 0x4.
18:48:20.4449 [WARNING] gpioInputs: Unhandled read from offset 0x3C.
18:48:20.4449 [WARNING] gpioInputs: Unhandled write to offset 0x3C, value 0x0.
18:48:20.4449 [WARNING] gpioInputs: Unhandled read from offset 0x38.
18:48:20.4450 [WARNING] gpioInputs: Unhandled write to offset 0x38, value 0x8.
18:48:20.4450 [WARNING] gpioInputs: Unhandled read from offset 0x3C.
18:48:20.4450 [WARNING] gpioInputs: Unhandled write to offset 0x3C, value 0x0.
18:48:20.4450 [WARNING] gpioInputs: Unhandled read from offset 0x38.
18:48:20.4451 [WARNING] gpioInputs: Unhandled write to offset 0x38, value 0x10.
18:48:20.4451 [WARNING] gpioInputs: Unhandled read from offset 0x3C.
18:48:20.4452 [WARNING] gpioInputs: Unhandled write to offset 0x3C, value 0x0.
18:48:20.4452 [WARNING] gpioInputs: Unhandled read from offset 0x38.
18:48:20.4452 [WARNING] gpioInputs: Unhandled write to offset 0x38, value 0x20.
18:48:20.4453 [WARNING] gpioInputs: Unhandled read from offset 0x3C.
18:48:20.4453 [WARNING] gpioInputs: Unhandled write to offset 0x3C, value 0x0.
18:48:20.4453 [WARNING] gpioInputs: Unhandled read from offset 0x38.
18:48:20.4453 [WARNING] gpioInputs: Unhandled write to offset 0x38, value 0x200.
18:48:20.4454 [WARNING] gpioInputs: Unhandled read from offset 0x3C.
18:48:20.4455 [WARNING] gpioInputs: Unhandled write to offset 0x3C, value 0x0.
18:48:20.4455 [WARNING] gpioInputs: Unhandled read from offset 0x38.
18:48:20.4455 [WARNING] gpioInputs: Unhandled write to offset 0x38, value 0x400.
18:48:20.4501 [DEBUG] sysbus: Write value 0x60000 to PRIC:PLLCFG (0x10008008).
18:48:20.4502 [DEBUG] sysbus: Write value 0x100 to PRIC:PLLOUTDIV (0x1000800C).
18:48:20.4508 [WARNING] sysbus: [cpu: 0x20402DF0] (tag: 'PRCI_PLLCFG') ReadDoubleWord from non existing peripheral at 0x10008008, returning 0xFFFFFFFF.
18:48:20.4508 [DEBUG] sysbus: Write value 0xFFFFFFFF to PRIC:PLLCFG (0x10008008).
18:48:20.4508 [WARNING] sysbus: [cpu: 0x20402E00] (tag: 'PRCI_HFROSCCFG') ReadDoubleWord from non existing peripheral at 0x10008000, returning 0xFFFFFFFF.
18:48:20.4508 [DEBUG] sysbus: Write value 0xBFFFFFFF to PRIC:HFROSCCFG (0x10008000).
18:48:20.4622 [WARNING] gpioInputs: Unhandled write to offset 0x10, value 0x0.
18:48:20.4623 [WARNING] gpioInputs: Unhandled write to offset 0x18, value 0x0.
18:48:20.4623 [WARNING] gpioInputs: Unhandled write to offset 0x20, value 0x0.
18:48:20.4623 [WARNING] gpioInputs: Unhandled write to offset 0x28, value 0x0.
18:48:20.4623 [WARNING] gpioInputs: Unhandled write to offset 0x30, value 0x0.
18:48:20.4623 [WARNING] gpioInputs: Unhandled write to offset 0x40, value 0x0.
18:48:20.4643 [DEBUG] sysbus: Read value 0x0 from QSPI2:FCTRL (0x10034060).
18:48:20.4644 [DEBUG] sysbus: Write value 0x0 to QSPI2:FCTRL (0x10034060).
18:48:20.4653 [DEBUG] sysbus: Read value 0x0 from QSPI1:FCTRL (0x10024060).
18:48:20.4654 [DEBUG] sysbus: Write value 0x0 to QSPI1:FCTRL (0x10024060).
18:48:20.4725 [DEBUG] cpu: Executing hooks registered at address 0x20400920

Temporary breakpoint 1, main () at src/main.c:9
9       printk("Hello! I'm running Zephyr %s on %s, a %s board.\n\n ", KERNEL_VERSION_STRING, CONFIG_BOARD, CONFIG_ARCH);
18:48:20.4855 [WARNING] sysbus: Tried to access bytes at non-existing peripheral in range <0x10013100, 0x100133FF>.
18:48:20.4862 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x0.
18:48:20.4862 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x1.
18:48:20.4863 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x2.
18:48:20.4863 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x3.
18:48:20.4863 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x4.
18:48:20.4863 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x5.
18:48:20.4863 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x6.
18:48:20.4863 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x7.
18:48:20.4863 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x8.
18:48:20.4863 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x9.
18:48:20.4864 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0xA.
18:48:20.4864 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0xB.
18:48:20.4864 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0xC.
18:48:20.4864 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0xD.
18:48:20.4864 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0xE.
18:48:20.4865 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0xF.
18:48:20.4865 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x10.
18:48:20.4865 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x11.
18:48:20.4866 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x12.
18:48:20.4866 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x13.
18:48:20.4866 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x14.
18:48:20.4866 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x15.
18:48:20.4866 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x16.
18:48:20.4867 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x17.
18:48:20.4867 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x18.
18:48:20.4867 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x19.
18:48:20.4867 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x1A.
18:48:20.4867 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x1B.
18:48:20.4867 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x1C.
18:48:20.4867 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x1D.
18:48:20.4867 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x1E.
18:48:20.4868 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x1F.
18:48:20.4868 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x20.
18:48:20.4868 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x21.
18:48:20.4868 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x22.
18:48:20.4868 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x23.
18:48:20.4868 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x24.
18:48:20.4869 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x25.
18:48:20.4869 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x26.
18:48:20.4869 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x27.
18:48:20.4869 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x28.
18:48:20.4870 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x29.
18:48:20.4870 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x2A.
18:48:20.4870 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x2B.
18:48:20.4870 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x2C.
18:48:20.4870 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x2D.
18:48:20.4870 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x2E.
18:48:20.4871 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x2F.
18:48:20.4871 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x30.
18:48:20.4871 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x31.
18:48:20.4872 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x32.
18:48:20.4872 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x33.
18:48:20.4873 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x34.
18:48:20.4873 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x35.
18:48:20.4873 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x36.
18:48:20.4873 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x37.
18:48:20.4873 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x38.
18:48:20.4874 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x39.
18:48:20.4874 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x3A.
18:48:20.4874 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x3B.
18:48:20.4874 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x3C.
18:48:20.4874 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x3D.
18:48:20.4875 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x3E.
18:48:20.4875 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x3F.
18:48:20.4875 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x40.
18:48:20.4875 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x41.
18:48:20.4875 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x42.
18:48:20.4876 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x43.
18:48:20.4876 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x44.
18:48:20.4876 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x45.
18:48:20.4876 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x46.
18:48:20.4876 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x47.
18:48:20.4877 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x48.
18:48:20.4877 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x49.
18:48:20.4877 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x4A.
18:48:20.4877 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x4B.
18:48:20.4878 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x4C.
18:48:20.4878 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x4D.
18:48:20.4878 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x4E.
18:48:20.4878 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x4F.
18:48:20.4878 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x50.
18:48:20.4879 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x51.
18:48:20.4879 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x52.
18:48:20.4879 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x53.
18:48:20.4879 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x54.
18:48:20.4879 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x55.
18:48:20.4879 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x56.
18:48:20.4880 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x57.
18:48:20.4880 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x58.
18:48:20.4880 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x59.
18:48:20.4880 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x5A.
18:48:20.4880 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x5B.
18:48:20.4881 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x5C.
18:48:20.4881 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x5D.
18:48:20.4881 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x5E.
18:48:20.4881 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x5F.
18:48:20.4881 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x60.
18:48:20.4881 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x61.
18:48:20.4882 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x62.
18:48:20.4882 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x63.
18:48:20.4882 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x64.
18:48:20.4882 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x65.
18:48:20.4882 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x66.
18:48:20.4883 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x67.
18:48:20.4883 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x68.
18:48:20.4883 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x69.
18:48:20.4883 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x6A.
18:48:20.4883 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x6B.
18:48:20.4883 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x6C.
18:48:20.4884 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x6D.
18:48:20.4884 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x6E.
18:48:20.4884 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x6F.
18:48:20.4884 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x70.
18:48:20.4884 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x71.
18:48:20.4884 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x72.
18:48:20.4885 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x73.
18:48:20.4885 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x74.
18:48:20.4885 [WARNING] uart0: Attempt to read Byte from peripheral that doesn't support Byte interface. Offset 0x75.

And it doesn't reach my breakpoint a couple lines below and stops here:

image

This is my code:

#include <zephyr.h>
#include <version.h>
#include <string.h>
#include <sys/printk.h>
#include <console/console.h>

void main(void)
{
    printk("Hello! I'm running Zephyr %s on %s, a %s board.\n\n ", KERNEL_VERSION_STRING, CONFIG_BOARD, CONFIG_ARCH);

    console_getline_init();
    printk("Enter a line finishing with Enter:\n");

    while (1)
    {
        printk("> ");
        char *s = console_getline();

        printk("Typed line: %s\n", s);
        printk("Last char was: 0x%x\n", s[strlen(s) - 1]);
    }
}

The weird thing is that I got it working a while back, now it doesn't anymore. I tried removing Renode cache dir but same thing...any ideas?

carlosedp commented 4 years ago

Found it! I had to add --hide-log to Renode debug command:

debug_server = renode
    --hide-log
    -e include @scripts/single-node/sifive_fe310.resc
    -e machine StartGdbServer 3333 True
    -e emulation CreateServerSocketTerminal 1234 "externalUART"
    -e connector Connect uart0 externalUART

Then it worked fine. I think @mgielda might need to point the debug commands since the logs show some commands as not existing like init and reset.

@ivankravets during the debug, if I hover on some variables or defines I get some errors like shown here:

image
pgielda commented 4 years ago

As for "init" and "reset" those seem to be openocd commands, send via gdb using "monitor"command (its a transport to underlying server, not part of the GDB spec). Since its openocd-specific it does not do anything in Renode. You could potentially define functions like that in your renode script to get rid of the error and potentially do something when they're executed.

carlosedp commented 4 years ago

I've successfully made the integration to use STM32F4 with Arduino:

image
; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:disco_f407vg]
platform = ststm32
board = disco_f407vg
framework = arduino
## ----- Settings below are for Antmicro Renode integration ----- ##
# Monitor port for Renode integration
monitor_port = socket://localhost:1234
monitor_speed = 115200
# Upload settings for Renode integration
# Here we use uart2 that is the default UART attached in Arduino
# We have to open the UART2 window since the detfault is opening uart4
upload_command = renode $UPLOAD_FLAGS
upload_flags =
    -e include @scripts/single-node/stm32f4_discovery.resc
    -e machine StartGdbServer 3333 True
    -e emulation CreateServerSocketTerminal 1234 \"externalUART\"
    -e connector Connect uart2 externalUART
    -e showAnalyzer uart2
    -e sysbus LoadELF @$SOURCE
    -e start
# Debug settings for Renode integration
debug_tool = custom
debug_port = localhost:3333
debug_server = renode
    --hide-log
    -e include @scripts/single-node/stm32f4_discovery.resc
    -e machine StartGdbServer 3333 True
    -e emulation CreateServerSocketTerminal 1234 "externalUART"
    -e connector Connect uart2 externalUART
    -e showAnalyzer uart2
debug_extra_cmds =
    monitor start

@ivankravets, I understand we need a new GDB script without the init and reset commands as Peter said.

On customizing the ini for Renode upload and debug, I think we need some parameters to be flexible depending on the board.

For example on the HiFive1, we use the script @scripts/single-node/sifive_fe310.resc and on STM32F4 @scripts/single-node/stm32f4_discovery.resc.

Also on HiFive1 the default UART is uart0 and on STM32F4 it's uart2 (at least in Arduino). Since the default STM32F4 script opens the uart4 console window by default, I've added the command -e showAnalyzer uart2 to open uart2 in this case.

We could have customized the stm32f4_discovery.resc script, with correct uarts and etc. Since we are using the default scripts that come with Renode, I had to to this manually.

pgielda commented 4 years ago

We are accidentaly working on a Monitor function called "alias" that will allow for custom commands to be easily defined "per script" or even "per machine". Stay tuned.

pgielda commented 4 years ago

Hi @carlosedp -- just heads up that the alias feature is now in Renode master branch. It allows you to define anything as an alias, e.g.: alias reset "machine Reset" This will create a new command "reset" which will magically make gdb command "mon reset" work, etc. Can also take arguments so e.g. alias print "echo" Will allow you to do: print "Hello World" in Renode monitor / scripts. It supports scoping (can be global alias and per machine).

ivankravets commented 4 years ago

Sorry for the delay from our side. We follow this thread, thanks for the ideas!

I tried yesterday Renode on my Mac and found a few issues:

  1. The Renode's macos_run.command hardcoded to /Library/Frameworks/Mono.framework. I don't install 3rd party frameworks into the OS scope. It allows me to easily migrate between different macOS versions. I installed Mono framework with brew install mono.
  2. Brew's mono does not work too because the script uses mono64, there is no mono64. I tried to replace these lines in macos_run.command and it seems works now. As a minimum, ./macos_run.command -h.

I've never used Mono/C#, I'm a noob here. Sorry.


@pgielda please help with the next questions as for the renode.zip archive:

1) Are these binaries independent of an operating system? 2) Does it mean that the only 1 requirement for us will be Mono framework? So, if we have mono on Unix and .Net on Windows, we can use the same binaries from "bin"? 3) We have own CDN network with prebuilt packages. It helps developers to work on a project and to do not worry about packages. PlatformIO does this work automatically and maintains updates.. So, if there is a new Renode, we publish it into our Registry, and if it is compatible with SemVer requirement of dev-platform, developers receive this update automatically. No need to reinstall it again. The question: is it possible for us to have 1 renode-x.y.z.tar.gz which will contain universal mono's-bin folder and different launch scripts depending on OS type?

Thanks!

P.S: @carlosedp did great work! His work and article helped me a lot to realize that it should be a very easy integrated Renode into PlatformIO. Yes, it works now. The only what we want to do - to automate everything. The developer set in project debug_tool = renode and PlatformIO does the rest work automatically, starts Renode's GDB server, configure renode upload command, etc.

PiotrZierhoffer commented 4 years ago

Hey @ivankravets

About your issues: we never focused on Mono from brew as it used to be quite old and we needed a relatively fresh release. That's why our docs point to Mono website. Apparently, they do not have consistent packaging policies here.

We can definitely revisit that - using Mono from brew would be, in general, much easier. We will look at the startup scripts to make it work.

If you stumble upon similar problems in future, please feel free to let us know via Renode issues.

And regarding the questions you asked:

  1. Renode is not platform independent yet - the "zip" from the release page is a Windows package (I will try to rename it to be more specific). There are also deb/rpm/pkg.tar.xz packages for Debian/Fedora/Arch and dmg for macOS. The reason for that is that some part of the code is in C or uses OS-specific features (like host-to-guest networking).

    In future we are planning on creating a cross-platform release as well, but it is not there yet.

  2. On Windows you don't need Mono, you just need the .NET Framework 4.7, which is rather a common thing to have nowadays. Mono is required for macOS and Linux. There are some other Linux-specific requirements as well, listed here: https://github.com/renode/renode#installing-dependencies

  3. As I said before, the cross-platform package is not there yet, but if there is interest we can investigate this further

ivankravets commented 4 years ago

A few updates from PlatformIO side:

1. Renode package & CDN

We publish Renode package into our CDN (currently, we use @bintray). It is much faster than Github's Amazon S3. PlatformIO will automatically install Renode on the user machine into an isolated environment depending on the host machine. We have own package manager and dev-platform declares own dependencies. For example, SiFive dev-platform can use Renode 1.9 where St STM32 Renode 1. PlatformIO resolves this automatically.

We prepared packages and deployed them to https://bintray.com/beta/#/platformio/dl-packages/tool-renode?tab=files

2. GDB Configuration

We added this GDB configuration for our PIO Unified Debugger. When user press "start debugging " or run from CLI pio debug --interface gdb, we automatically start Renode in the background and provide a bridge between IDEs and GDB clients.

Please check this configuration https://github.com/platformio/platformio-core/blob/develop/platformio/commands/debug/initcfgs.py#L127

If you will have any changes later, please inform us or do PR. A shortcut GDB command named pio_reset_run_target is used by PlatformIO IDE or VSCode and CLion. It allows developers to do "hot-restart" of debugging session without restarting of GDB client and Debug server. It's very convenient for complex projects.

3. Renode's GDB server state

We had the problem with running Renode in the background. It's indeed our issue. The only we start GDB server, we try to connect to it. We have had problems with existing debugging server before which we support (J-Link, OpenOCD, pyOCD, etc.). Renode has different behavior. It starts the process and tries to download something from the Internet (my firewall reports me). So, and... the only when it downloaded dependencies, it starts GDB server. I'm not an expert here. Maybe it makes sense to start a socket server at the beginning and buffer income commands as openOCD and other tools do.

Nevertheless, it's not a blocker for us. We did a workaround and introduced support for server.ready_pattern. Currently, it is set to GDB server with all CPUs started on port. So, if you change this value in the next releases, please inform us. Thanks!

4. Renode logging

A simple quesiton - how to reduce logging? For example, to show everything below INFO+? Like, errors, warning, info, but not debug...

5. UART Console

I have not managed to get output in telnet from this example https://github.com/platformio/platform-sifive/tree/develop/examples/zephyr-synchronization

What is the correct configuration? I used this

[env:hifive1-revb]
platform = https://github.com/platformio/platform-sifive.git
framework = zephyr
board = hifive1-revb
build_type = debug
monitor_speed = 115200
debug_init_break = tbreak bg_thread_main
debug_tool = renode
pio debug --interface gdb -x .pioinit

# and 

nc localhost 1234

The configuration for Renode server is default by SiFive dev-platform => https://github.com/platformio/platform-sifive/blob/develop/platform.py#L105


We have not released SiFive dev-platform yet. It would be good to close all the questions before. Then we can add support for Kendryte and STM32.

Thanks in advance!

carlosedp commented 4 years ago

Hey Ivan, thanks for the release! The sifive-platform release required to support this right? Also the integration with Renode is only for Debug and not Upload?

To reduce the amount of logs, just pass -e logLevel 3 for printing errors only. Check https://renode.readthedocs.io/en/latest/basic/logger.html.

To get the console, I've used:

monitor_port = socket://localhost:1234
monitor_speed = 115200

But faced the problem from https://github.com/platformio/platformio-core/issues/3421.

I've successfully added integration to the Kendryte K210 using FreeRTOS. One problem tho is that PIO tried to upload firmware.bin instead of firmware.elf. For this I needed to change the upload argument from @$SOURCE to @$PROJECT_BUILD_DIR/$PIOENV/$PROGNAME".elf". I also had to add upload_port = /dev/ttyUSB0 otherwise PIO didn't upload to Renode even by overriding by using upload_command.

The complete config became:

; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:sipeed-maix-go]
platform = kendryte210
board = sipeed-maix-go
framework = kendryte-freertos-sdk
## ----- Settings below are for Antmicro Renode integration ----- ##
# Monitor port for Renode integration
monitor_port = socket://localhost:1234
monitor_speed = 115200
# Upload settings for Renode integration
upload_port = /dev/ttyUSB0
upload_command = renode $UPLOAD_FLAGS
upload_flags =
    -e include @scripts/single-node/kendryte_k210.resc
    -e machine StartGdbServer 3333 True
    -e logLevel 3                       ; Loglevel = Errors
    -e emulation CreateServerSocketTerminal 1234 \"externalUART\"
    -e connector Connect uart externalUART
    ; -e sysbus LoadELF @$SOURCE        ; Does not work on K210-FreeRTOS
    -e sysbus LoadELF @$PROJECT_BUILD_DIR/$PIOENV/$PROGNAME".elf"
    -e start
# Debug settings for Renode integration
debug_tool = custom
debug_port = localhost:3333
debug_server = renode
    --hide-log
    -e include @scripts/single-node/kendryte_k210.resc
    -e machine StartGdbServer 3333 True
    -e logLevel 3           ;Loglevel = Errors
    -e emulation CreateServerSocketTerminal 1234 "externalUART"
    -e connector Connect uart externalUART
debug_extra_cmds =
    monitor start
carlosedp commented 4 years ago

Hi @ivankravets, any news on this? Can I help with something?

ivankravets commented 4 years ago

Sorry for the delay. We will back soon to this issue.