Skip to content

stdio_semihosting: Initial include of Semihosting-based STDIO #13320

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 9, 2020

Conversation

bergzand
Copy link
Member

@bergzand bergzand commented Feb 9, 2020

Contribution description

This PR adds ARM Semihosting-based STDIO capabilities. It allows STDIO over SWD/JTAG, similar to the Segger RTT protocol, but without requiring the proprietary Jlink binaries or a Jlink programmer to function. Only ARM MCUs are supported (but I've heard rumors that RISC-V has something similar). The big downsides are that Semihosting is relative slow and that it requires an active debugging session (at all times) when it is enabled. This last bit because it throws breakpoint instructions for write and read requests from the host.

Currently the terminal used is OpenOCD in debugger mode. Maybe this can be refined at some point by not halting the CPU when starting the terminal, but that's for later.

Testing procedure

  • Use the provided test application to verify the functionality
  • Check the provided docs.

I haven't tested it with pyOCD. It is probably also possible to use pyOCD for this, but that can be included in a follow-up PR.

Issues/PRs references

None

@bergzand bergzand added the Type: new feature The issue requests / The PR implemements a new feature for RIOT label Feb 9, 2020
@bergzand bergzand force-pushed the pr/stdio/semihosting branch 2 times, most recently from 1e7dc10 to 26d1b97 Compare February 9, 2020 13:28
@bergzand bergzand requested a review from aabadie February 10, 2020 12:00
@benpicco
Copy link
Contributor

Hm, how does this work?
When I simply do a make flash term I end up in gdb but don't see any output from the terminal.

Segger J-Link

/home/benpicco/dev/RIOT/dist/tools/openocd/openocd.sh debug /home/benpicco/dev/RIOT/tests/sys_stdio_semihosting/bin/mlpa_tracker-v2/tests_sys_stdio_semihosting.elf
### Starting Debugging ###
Open On-Chip Debugger 0.10.0+dev-00955-gef23852f-dirty (2019-10-28-14:52)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
Reading symbols from /home/benpicco/dev/RIOT/tests/sys_stdio_semihosting/bin/mlpa_tracker-v2/tests_sys_stdio_semihosting.elf...
Remote debugging using :3333
0x00000986 in timer_init (tim=tim@entry=0, freq=freq@entry=1000000, cb=cb@entry=0xc05 <_periph_timer_callback>, 
    arg=arg@entry=0x0 <cortex_vector_base>) at /home/benpicco/dev/RIOT/cpu/sam0_common/periph/timer.c:101
101	    while (dev(tim)->CTRLA.bit.SWRST) {}
(gdb) c
Continuing.
ps
ps

edbg on samr21-xpro

/home/benpicco/dev/RIOT/dist/tools/openocd/openocd.sh debug /home/benpicco/dev/RIOT/tests/sys_stdio_semihosting/bin/samr21-xpro/tests_sys_stdio_semihosting.elf
### Starting Debugging ###
Open On-Chip Debugger 0.10.0+dev-00955-gef23852f-dirty (2019-10-28-14:52)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
Reading symbols from /home/benpicco/dev/RIOT/tests/sys_stdio_semihosting/bin/samr21-xpro/tests_sys_stdio_semihosting.elf...
Remote debugging using :3333
0xfffffffe in ?? ()
(gdb) c
Continuing.
at91samd.cpu -- clearing lockup after double fault

Program received signal SIGINT, Interrupt.
[Switching to Thread 1]
0xfffffffe in ?? ()
(gdb) c
Continuing.
at91samd.cpu -- clearing lockup after double fault

@bergzand
Copy link
Member Author

When I simply do a make flash term I end up in gdb but don't see any output from the terminal.

😢

I'll check if I forgot something

@bergzand
Copy link
Member Author

@benpicco on the samr21-xpro I can reproduce your issue. However if I restart the node from the OpenOCD session it somehow starts working. I'll see if I can make this work without having to restart the node.

/* Moves cmd and args to r0 and r1. Then triggers a breakpoint.
* Finally moves the results stored in r0 to result
*/
__asm(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
__asm(
__asm__(

@@ -0,0 +1,103 @@
/*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do these defines need to be exported? If not, it is fine to define them in stdio_semihosting.c.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

ssize_t stdio_read(void* buffer, size_t count)
{
if (STDIO_SEMIHOSTING_RX) {
ssize_t read = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please rename variable. Somehow my brain doesn't shadow read() as happily as the C compiler, especially in stdio context.

@kaspar030
Copy link
Contributor

Hm, this doesn't come with an automatic test, but I guess that's difficult? If so, we should at least blacklist it for all workers and add a comment.

@kaspar030 kaspar030 added Area: sys Area: System Platform: ARM Platform: This PR/issue effects ARM-based platforms labels Apr 14, 2020
@kaspar030
Copy link
Contributor

Hm, this doesn't come with an automatic test, but I guess that's difficult? If so, we should at least blacklist it for all workers and add a comment.

offline discussion, result: please add README.md.

@kaspar030 kaspar030 self-assigned this Apr 14, 2020
@bergzand
Copy link
Member Author

offline discussion, result: please add README.md.

Added a very concise readme

@fjmolinas
Copy link
Contributor

@bergzand can you rebase this one?

@bergzand bergzand force-pushed the pr/stdio/semihosting branch from 3b66345 to 75e378f Compare June 2, 2020 11:11
@bergzand
Copy link
Member Author

bergzand commented Jun 2, 2020

Rebased!

@fjmolinas
Copy link
Contributor

Rebased!

You also seemed to have addressed a couple of the commetns I was going to make hahaha :D

Copy link
Contributor

@fjmolinas fjmolinas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments, I'll test asap.

* `RIOT_TERMINAL` variable has to be set to `semihosting`:
*
* ```
* make term RIOT_TERMINAL=semihosting
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You didn't add this to Makefile.include because of inclusion order right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean to automatically setting the RIOT_TERMINAL based on whether stdio_semihosting is enabled? I honestly haven't tried it :D

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would work if USEMODULE is passe by the user or in the APPLICATION but not in a BOARD configuration, which kind of sucks.

@fjmolinas
Copy link
Contributor

It is indeed slow but works like a charm.

### Starting Debugging ###
Open On-Chip Debugger 0.10.0+dev-01100-g51dd4ce6-dirty (2020-03-03-15:33)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
Reading symbols from /home/francisco/workspace/RIOT/tests/sys_stdio_semihosting/bin/iotlab-m3/tests_sys_stdio_semihosting.elf...
Remote debugging using :3333
0x080008ba in _semihosting_raw (args=0x2000090c <main_stack+1180>, cmd=5)
    at /home/francisco/workspace/RIOT/sys/stdio_semihosting/stdio_semihosting.c:89
89	    return _semihosting_raw(0x05, args);
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/francisco/workspace/RIOT/tests/sys_stdio_semihosting/bin/iotlab-m3/tests_sys_stdio_semihosting.elf 
main(): This is RIOT! (Version: 2020.07-devel-872-g75e378-pr-13320)
STDIO semihosting test application
> help
keep_alive() was not invoked in the 1000ms timelimit. GDB alive packet not sent! (1646). Workaround: increase "set remotetimeout" in GDB
help
Command              Description
---------------------------------------
reboot               Reboot the node
version              Prints current RIOT_VERSION
pm                   interact with layered PM subsystem
ps                   Prints information about running threads.
> 

@fjmolinas fjmolinas added the Reviewed: 3-testing The PR was tested according to the maintainer guidelines label Jun 2, 2020
@fjmolinas
Copy link
Contributor

Hmm I checked the output with more details and there is:

keep_alive() was not invoked in the 1000ms timelimit. GDB alive packet not sent! (5570). Workaround: increase "set remotetimeout" in GDB
ps

@fjmolinas fjmolinas self-assigned this Jun 2, 2020
@fjmolinas
Copy link
Contributor

fjmolinas commented Jun 2, 2020

I do not get the timeout on a samr21-xpro, usb-kw41z or nucleo-f103rb so it seems like its something related with the iotlab-m3 debugger.

@fjmolinas
Copy link
Contributor

I do not have anymore comments here you can squash if @kaspar030 feels like his comments have been addressed as well!

@bergzand bergzand force-pushed the pr/stdio/semihosting branch from 0c0f593 to 11ee5ff Compare June 9, 2020 08:16
@bergzand
Copy link
Member Author

bergzand commented Jun 9, 2020

Squashed

Copy link
Contributor

@fjmolinas fjmolinas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK on my side.

Copy link
Contributor

@kaspar030 kaspar030 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK from me, too.

@kaspar030 kaspar030 added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Jun 9, 2020
@kaspar030 kaspar030 merged commit 1ed0d65 into RIOT-OS:master Jun 9, 2020
@bergzand bergzand deleted the pr/stdio/semihosting branch June 9, 2020 14:54
@bergzand
Copy link
Member Author

bergzand commented Jun 9, 2020

Thanks!

@miri64 miri64 added this to the Release 2020.07 milestone Jun 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: sys Area: System CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Platform: ARM Platform: This PR/issue effects ARM-based platforms Reviewed: 3-testing The PR was tested according to the maintainer guidelines Type: new feature The issue requests / The PR implemements a new feature for RIOT
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants