Skip to content
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

[tools] Refactor tooling and add JLink support #965

Merged
merged 3 commits into from
Mar 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions examples/nucleo_l476rg/itm/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright (c) 2019, Niklas Hauser
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// ----------------------------------------------------------------------------

#include <modm/board.hpp>
#include <modm/processing.hpp>

using namespace Board;

modm::IODeviceWrapper<Itm, modm::IOBuffer::DiscardIfFull> itm_device;
modm::IOStream stream(itm_device);

int
main()
{
Board::initialize();
Itm::initialize();

stream << "Hello from the SWO." << modm::endl;
stream << "debug" << modm::endl;
stream << "info" << modm::endl;
stream << "warning" << modm::endl;
stream << "error" << modm::endl;


while (true)
{
static modm::PeriodicTimer tmr{500ms};
if (tmr.execute())
{
tmr.restart(Button::read() ? 100ms : 500ms);
LedGreen::toggle();

static uint32_t counter{0};
stream << "loop: " << counter++ << modm::endl;
}
Itm::update();
}

return 0;
}
13 changes: 13 additions & 0 deletions examples/nucleo_l476rg/itm/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<library>
<extends>modm:nucleo-l476rg</extends>
<options>
<option name="modm:build:build.path">../../../build/nucleo_l476rg/itm</option>
<option name="modm:platform:itm:buffer.tx">250</option>
</options>
<modules>
<module>modm:build:scons</module>
<module>modm:build:make</module>
<module>modm:platform:itm</module>
<module>modm:processing:timer</module>
</modules>
</library>
86 changes: 86 additions & 0 deletions examples/nucleo_l476rg/rtt/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright (c) 2021, Niklas Hauser
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// ----------------------------------------------------------------------------

#include <modm/board.hpp>
#include <modm/processing.hpp>
#include <modm/debug.hpp>

using namespace Board;

Rtt rtt(0);
modm::IODeviceObjectWrapper< Rtt, modm::IOBuffer::DiscardIfFull > rtt_device(rtt);
modm::IOStream rtt_stream(rtt_device);

#undef MODM_LOG_LEVEL
#define MODM_LOG_LEVEL modm::log::INFO

/*

$ scons rtt
╭───OpenOCD───> Real Time Transfer
╰─────RTT────── stm32f303vct6
Info : STLINK V2J16S0 (API v2) VID:PID 0483:3748
Info : stm32f3x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : rtt: Searching for control block 'SEGGER RTT'
Info : rtt: Control block found at 0x20000c04
Info : Listening on port 9090 for rtt connections
Info
Warning
Error
loop: 0
loop: 1
loop: 2
loop: 3
loop: 4
loop: 5


Type number 0-9, then press enter to send.
The LED should blink slower or faster.

Ctrl+D to exit

*/

// ----------------------------------------------------------------------------
int
main()
{
Board::initialize();

rtt_stream << "RTT Demo on Nucleo-64" << modm::endl;

uint32_t counter(0);
modm::PeriodicTimer tmr(100ms);

char data;
while (true)
{
rtt_stream.get(data);
switch(data)
{
case '0':
tmr.restart(1s);
break;
case '1'...'9':
tmr.restart(std::chrono::milliseconds((data - '0') * 100));
break;
}
if (tmr.execute())
{
LedGreen::toggle();

rtt_stream << "loop: " << counter++ << modm::endl;
}
}

return 0;
}
13 changes: 13 additions & 0 deletions examples/nucleo_l476rg/rtt/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<library>
<extends>modm:nucleo-l476rg</extends>
<options>
<option name="modm:build:build.path">../../../build/nucleo_l476rg/rtt</option>
<option name="modm:platform:rtt:buffer.rx">16</option>
</options>
<modules>
<module>modm:platform:rtt</module>
<module>modm:processing:timer</module>
<module>modm:build:scons</module>
<module>modm:debug</module>
</modules>
</library>
2 changes: 1 addition & 1 deletion examples/stm32f3_discovery/gdb/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Then you can start GDB in TUI mode by default:

Alternatively if you installed gdbgui you can use:

scons debug profile=debug ui=web
scons debug profile=debug ui=gdbgui


Useful GDB Commands:
Expand Down
4 changes: 2 additions & 2 deletions ext/adamgreen/catcher.lb
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ def init(module):
CrashCatcher hooks into the ARM Cortex-M HardFault handler and generates a coredump
that can be used with CrashDebug for post-mortem debugging.
You must place the `CrashDebug` binary in your path or alternatively set the
environment variable `MODM_CRASHDEBUG_PATH` to point to the enclosing folder:
environment variable `MODM_CRASHDEBUG_BINARY` to point to the enclosing folder:

```sh
export MODM_CRASHDEBUG_PATH=/path/to/crashdebug/bin
export MODM_CRASHDEBUG_BINARY=/path/to/crashdebug/bin/CrashDebug
```

- https://github.com/adamgreen/CrashCatcher
Expand Down
29 changes: 26 additions & 3 deletions src/modm/platform/uart/cortex/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ for an advanced use-case (like de-multiplexing data streams).
You must provide the CPU/HCLK frequency of your target, so that
OpenOCD can correctly set the prescaler for the asynchronous SWO output.

When using the `modm:build:scons` module, you can also use the convenience
wrapper, which logs to a temporary file and displays it's contents on the
terminal
When using the `modm:build:scons` or `modm:build:make` modules, you can also use
the convenience wrapper, which logs to a temporary file and displays its
contents on the terminal:

```
$ scons log-itm fcpu=64000000
Expand All @@ -79,4 +79,27 @@ loop 4
loop 5
```

Alternatively you can also use a JLink debug probe which auto-detects the CPU
frequency:

```
$ scons log-itm-jlink
╭────JLink────> Single Wire Viewer
╰─────SWO────── stm32l476rgt6

Target CPU (stm32l476rg) is running @ 48251 kHz.
Receiving SWO data @ 4500 kHz.
Showing data from stimulus port(s): 0
-----------------------------------------------
Hello from the SWO.
debug
info
warning
error
loop 0
loop 1
loop 2
loop 3
loop 4
loop 5
```
22 changes: 21 additions & 1 deletion src/modm/platform/uart/rtt/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ You can also call this from inside GDB via the `monitor` command:
rtt: Searching for control block 'SEGGER RTT'
rtt: Control block found at 0x20001024
Listening on port 9090 for rtt connections
(gdb)
(gdb) continue&
```

You can then use for example `telnet 127.0.0.1 9090` to connect to the stream.
Expand Down Expand Up @@ -92,5 +92,25 @@ loop 61
If you want to use this as a proper communication channel with a custom protocol
you should implement the OpenOCD config yourself (with different ports).

You can also use JLink to access the RTT data, which may be significantly faster
than OpenOCD if the debug probe has hardware support for the protocol.

```
$ scons log-rtt-jlink
╭────JLink────> Real Time Transfer
╰─────RTT────── stm32l476rgt6

SEGGER J-Link V7.84f - Real time terminal output
RTT Demo on Nucleo-64
loop: 0
loop: 1
loop: 2
loop: 3
loop: 4
loop: 5
loop: 6
loop: 7
```


[rtt]: http://openocd.org/doc/html/General-Commands.html#Real-Time-Transfer-_0028RTT_0029
82 changes: 80 additions & 2 deletions tools/build_script_generator/cmake/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,15 @@ Writes the executable onto your target via Black Magic Probe.
(\* *only ARM Cortex-M targets*)


#### program-jlink

Writes the executable onto your target via JLink.
(\* *only ARM Cortex-M targets*)


#### debug

- option `MODM_DBG_UI`=tui in {`tui`, `gdbgui`}.
- option `MODM_DBG_UI=tui` in {`tui`, `gdbgui`}.

Launches OpenOCD in the background, then launches GDB in foreground with the
correct executable with text-based or [web-based gdbgui][gdbgui] UI. When GDB
Expand All @@ -61,6 +67,20 @@ To use gdbgui you must have it installed via `pip install gdbgui`.
**We recommend using the IDE provided debug interface instead of this!**


#### debug-bmp

- option `MODM_BMP_PORT=auto` as string.

Launches GDB via Black Magic Probe.
(\* *only ARM Cortex-M targets*)


#### debug-jlink

Launches GDB via JLink.
(\* *only ARM Cortex-M targets*)


#### debug-coredump

- option `MODM_DBG_UI=tui` in {`tui`, `gdbgui`}.
Expand All @@ -69,7 +89,48 @@ Launches GDB for post-mortem debugging with the using the data in the
`coredump.txt` argument.
(\* *only ARM Cortex-M targets*)

See the `:platform:fault` module for details how to receive the coredump data.
Use the `coredump` method to generate a coredump with a debugger attached,
otherwise see the `modm:platform:fault` module for details how to generate and
receive the coredump data from the device itself.


#### coredump

Launches GDB via OpenOCD and creates a `coredump.txt` file containing all
volatile memories and prints the GNU build ID of the firmware under debug.
Note that this command does not require an ELF file, so it can be used to
coredump any firmware whose ELF file is currently unavailable.
(\* *only ARM Cortex-M targets*)


#### coredump-bmp

Creates a coredump via Black Magic Probe.
(\* *only ARM Cortex-M targets*)


#### coredump-jlink

Creates a coredump via JLink.
(\* *only ARM Cortex-M targets*)


#### reset

Resets the executable via OpenOCD.
(\* *only ARM Cortex-M targets*)


#### reset-bmp

Resets the executable via Black Magic Probe.
(\* *only ARM Cortex-M targets*)


#### reset-jlink

Resets the executable via JLink.
(\* *only ARM Cortex-M targets*)


#### log-itm
Expand All @@ -78,11 +139,20 @@ See the `:platform:fault` module for details how to receive the coredump data.

Configures OpenOCD in tracing mode to output ITM channel 0 on SWO pin and
displays the serial output stream.
(\* *only ARM Cortex-M targets*)

See the `modm:platform:itm` module for details how to use the ITM as a logging
output.


#### log-itm-jlink

- option `MODM_ITM_FCPU` in Hz

Outputs ITM channel 0 via JLinkSWOViewer.
(\* *only ARM Cortex-M targets*)


#### log-rtt

- option `MODM_RTT_CHANNEL=0` as integer.
Expand All @@ -94,5 +164,13 @@ simple telnet client. Disconnect with Ctrl+D.
See the `modm:platform:rtt` module for details how to use RTT for data transfer.


#### log-rtt-jlink

- option `MODM_RTT_CHANNEL=0` as integer.

Configures JLink in RTT mode to output the chosen channel (default 0) via a
simple telnet client. Disconnect with Ctrl+D.
(\* *only ARM Cortex-M targets*)

[cmake]: http://cmake.org
[gdbgui]: https://www.gdbgui.com
Loading