Open perlindgren opened 4 years ago
sudo lsof -i | grep 50001 JLinkGDBS 72740 pln 3u IPv4 705474 0t0 TCP *:50001 (LISTEN)
So it seems that jlink uses a tcp connection. Well still using gives me a zero sized file:
nc -l 50001 > /tmp/log
I finally got it working. The problem was my misunderstanding on the port
abstraction. Here is a working solution for tracing ITM from the terminal using JLinkGDBServer. The tool itmdump
is found at https://crates.io/crates/itm.
> mkfifo /tmp/itm.fifo
> itmdump -f /tmp/itm.fifo
> nc localhost 50001 > /tmp/itm.fifo
I had an -l
(as in listen) there before. It's the gdb server that is listening. So I had two listeners to the port but no one connecting. My bad!
In any case, I still have a few questions. 1) Why does the repo say 0.2.7 while the Market Place lists is as 3.4. 2) What's happening at startup causing the Adapter log to show the data exchange (is that just some verbose option enabled somewhere from within Cortex Debug, or is actually Cortex Debug doing something "extra/special"
By the way thanks to everybody contributing to the Cortex Debug, I use it a lot myself, and also use it teaching embedded Rust and Rust RTFM.
Whew, log message. I will answer the best I can. Just ping me if I missed answering something
0
with label Output
. Cortex-Debug creates a window in the Output tab where you should see the output. For mine, I get something like this (my label was 'hdm', my initials)
Cortex-Debug adds the time-stamp, btw. This way, your output is not mixed up with other junk on that ITM port. Did you look for such a window and found that there was nothing?I am still learning how all the ITM stuff works myself (from the chip point of view). I only made any headway with JLink. OpenOCD and STLink were not working for me (yet).
Hi Haneefdm Thanks for the input:
* Cortex-Debug has a bunch of gdb utility functions it creates and uses to enable SWO/ITM. They can be found [here](https://github.com/Marus/cortex-debug/blob/3e3e2cf92408a91e56f06054f5c3e211211b17ed/support/gdbsupport.init#L2)
Great info. That explains the log (that Cortex Debug was actually doing stuff on its own..)
* For each gdb-server, it uses a combination of command-line options, monitor commands or gdb utility functions mentioned above to setup the ITM/SWO registers. Since you are using JLink refer to [this set of commands](https://github.com/Marus/cortex-debug/blob/3e3e2cf92408a91e56f06054f5c3e211211b17ed/src/jlink.ts#L81)
Good to know, if I run into other related problems.
* In your example, you set up you use port `0` with label `Output`. Cortex-Debug creates a window in the Output tab where you _should_ see the output. For mine, I get something like this (my label was 'hdm', my initials) ![image](https://user-images.githubusercontent.com/41269583/68815401-2a886480-0630-11ea-9bbd-fb3d84452d54.png) Cortex-Debug adds the time-stamp, btw. This way, your output is not mixed up with other junk on that ITM port. Did you look for such a window and found that there was nothing?
I got it working with Jlink but not openocd.
* You said _'repo says 0.2.7`_. May I ask where it says that? I can correct it perhaps.
I think this was my bad, or that it has been fixed. It was the Changelog.md. (When I checked that was referring to 0.2.7 as the latest, it could have been that my cloned version was not up to date.)
* The Adapter Output window contains all the stdout/stderr from the gdb-server. You can see how the gdb-server was launched in the Debug Console JLink also echoes the same) and everything else I mentioned above. Nothing special is going on here.
Yepp, thats very helpful.
I am still learning how all the ITM stuff works myself (from the chip point of view). I only made any headway with JLink. OpenOCD and STLink were not working for me (yet).
I think the openocd problem is somehow related to the NRF onboard programmer (as openocd works well with STM chips and ITM.)
We can either close this thread and open a new one for ITM tracing with openocd for the NRF, or keep this one open. What do you say?
...hmmm, now I see why I was confused regarding the versioning of Cortex Debug.
I would suggest making a tag and Release info at least for 0.3.4 so bug reports can be associated a release (and not just a rolling repo). Looking over the tags, there seems to be quite a lot missing up to 0.3.4, so I figure its hard to re-produce proper/accurate tags for intermediate releases, but its not so important as getting a release tag for the latest, and for each new update and release to the vscode store, make a proper tag with release info.
Also it would be great to have example launch/debug configurations in the repository somewhere and at least some documentation for the configuration keywords. As of now, information is a bit spread out and not entirely clear/complete.
@haneefdm - the tag on release info on GitHub is probably a good idea - not something that I was always keeping up with for earlier releases - which is why there are quite a number of them missing, in particular with older versions. But as @perlindgren suggested - would be good for tying issues to releases in GitHub.
As for ITM on OpenOCD - there are some fairly significant differences in how it works compared to J-Link implementation.
First major difference is that with OpenOCD we configure the ITM peripheral using a number of macros from the gdbsupport.init
file that @haneefdm mentioned; while with J-Link a large portion of the initial ITM setup is handled by a J-Link monitor
command (we do still use some of the macros; but mostly just for selecting which ITM ports are enabled and a couple of minor settings changes).
Second major difference is how we get the output into the extension. As you noted for J-Link it opens a listening socket which the plugin connects to; receiving the ITM output from there. With OpenOCD it generally sends the ITM output to a file - on Linux and macOS we create a named pipe/fifo (yay for everything being "files") which it uses to get the output; on Windows (since we don't have a named pipe implementation we can use from the extension) it is actually written to a file which we read back (this tends to make it a bit slower and less reliable on Windows with OpenOCD).
If you are able to get ITM working with the OpenOCD/STM pair - that suggests that the FIFOs are working without issues for you; so the issue is almost certainly with the manipulation that is done in the macros that @haneefdm had pointed out in the gdbsupport.init
file (and likely the ones that take the place of the J-Link monitor command; so EnableITMAccess
, BaseSWOSetup ${ratio}
, SetITMId 1
, and ITMDWTTransferEnable
). While the ITM should in theory be largely the same across different chips that implement it, those macros were written and tested against STM32 devices (since I primarily work with STM32F1 and F4 devices) - so there very-well could be differences between targets that are not accounted for in those GDB macros.
I'm currently doing some work on the ITM/SWO system in the extension (adding logging to files; as well as getting the serial port collection working again with newer versions of the VSCode runtime) - so I will try to take a quick look through the NRF52 documentation to see if I can spot anything that needs to be done that wouldn't currently be hit, or may be done incorrectly, in those macros. Unfortunately I don't have any NRF52 boards to actually test against - but if I can find anything that may help I'll let you know.
@Marus, yes, I saw that not every release had a tag so, I did not do it either. One thing though, that we have duplication of information between the tags and the ChangeLog.md. If we were to put tags again, we could just point people to the ChangeLog. As extension users within VSCode, it is the ChangeLog that is more visible.
While, J-Link was fine, I wasn't able to use OpenOCD for ITM with my boards, but that is because of a hardware bug(s) I found. Now that I have an STM F4 board, I can try again with OpenOCD and STLink. I tried briefly with stlink and it failed to program the device (target load failed). So, I have to program using another method and they try stlink.
Btw, J-Link + the STM F4 board works for ITM_SendChar() and I did nothing special to make it happen.
I am trying to do PC sampling (profiling) and this not quite working for me with the STM F4 board. Trying to figure out why, but I am also not sure what I am expected to see. I see a mostly graph and time seems to be moving. I see packets coming in furiously with valid PC though. That's another topic though. I am probably doing something wrong.
On another note, I had some trouble with SWO frequencies until I made sure I would get a nice integer divisor. May not be a real issue but, I was playing it safe. In the example shown here CPU is 64MHz and SWO is set to 6MHz. Perhaps 4 or 8MHz for SWO is a better option.
Something I saw was in a PSoC5 device, nothing came out on the SWO pin because the input clock to the TPIU was turned off. I had to enable it in some obscure/magic register in FW and I also had to select a clock that feeds the TPIU. The NRF52 may also have such a register. Look for TRACECLKIN
in their docs/TRM or the block diagram for TPIU. In STM, I did not have to do anything because TRACECLKIN
was hard-wired to their CPU/BUS clock. In PSoC5, I had to make a connection and enable the clock.
Hi @Marus and @haneefdm. Just to clarify, there is a big difference between tags/releases and just CHANGELOG.md updates. The thing with a tag, is that it amounts to a specific commit (as a hash) allowing you to checkout that specific version, which is useful to associate bug reports to specific releases/tags, and find where regressions occur, etc.
Regarding documentation, as mentioned one can refer to the CHANGELOG.md from the tag/release to avoid duplication (but it does not hurt to have the info at both places).
I think both the GitHub tags and the Changelog are useful - in different ways. Changelog gives good visibility in VSCode marketplace - but as @perlindgren mentions tags are useful for tying releases back to particular code and associating bug reports. Definitely something that we should try to be more consistent with in the future.
And yes, with SWO you will have to pick an integer divisor; as it does scale from the core clock (at least typically; wondering if it is the core clock in 100% of devices or if it could be off of one of the other clocks) with an integer divisor.
I fully expect that the issue with the NRF52 device is that there are clocks that need to be enabled that don't have the same/an equivalent on STM devices, sort of like you had on the PSoC5 devices. Works with J-Link, as they have this knowledge built into the debug server.
I'm thinking this may be a good thing for me to expand into the device support packs, similar to the SVD files that used to be bundled. That way separate devices/device families can provide additional/replacement GDB macros. Will look into that idea a bit.
Yes, I totally understand the usefulness of tags & releases from a git perspective. I never made a release in my personal projects without tagging. The duplication of release notes was the thing I was trying to highlight. I prefer not to have two versions of the truth and some of our release notes are large. Adding the change log during tagging is a manual method (cmd-line for me). I don't use the web interface, but I can.
The integer divisor has to fit in a 13-bit unsigned int. Not a problem here.
Actually, for PSoC5, it did NOT work even with J-Link. I had to hunt that magic register (was not where the rest of the clock setting registers were) and set two magic bits before anything came out of the SWO and when it did it was not the frequency that J-Link was expecting so I had to lie accordingly to J-Link. Then the stars aligned. This is the first time I had to buy a cheapo logic analyzer to debug a problem at home :-)
Just to mention the obvious, with any device, you have to reserve/enable the SWO pin. Both STM and PSoCs offered this option in their IDEs and set appropriate registers and drive modes, etc. This aspect is totally vendor-specific and may require setting more than one register.
If there is nothing coming out for SWO in Cortex-Debug or the SWO viewer, chances are there is nothing on the pin. Or the sampling frequencies are not matching with the probe/gdb-server being used. This was my learning, that I wanted to pass on. I needed a logic analyzer to find both issues. And stay within the limits of your IOs and the probes advertised speed for SWO -- assuming the probe has to 2-4x oversample the async. SWO input.
@Marus, so far I have not found anything wrong or needing to be device-specific in the gdbsupport.init
file. Perhaps an assumption was made for PC sampling as to how fast to sample but this is for all devices and can be worked around.
Well regarding the SWO, there are essentially two ways to go by. 1) doing all setup from the debugger (under control of the Cortex Debug plugin) 2) doing the target part from application code running on the target, with only a minimal setup from the Cortex Debug plugin (setting up the receiving part)
Alternative 2) leaves the Cortex Debug target agnostic, but requires some attention by the programmer.
We develop exclusively in and for Rust RTFM. I could have a go at a SWO trait (interface of 2) and implement that for the platform at hand. Not sure exactly how it would look, though as there is some trickery regarding generics over hardware abstractions, but presumably it could be made. Regarding C,C++, there is in general nothing like platform independent hardware abstractions, so I'm not sure it could be done.
In any case from Cortex Debug point of view, it could make sense to have the option of selecting either 1) or 2). (Now its something like 1.4, meaning that it attempts 1, but cannot guarantee success for all targets...)
@perlindgren You can already kind of do (2) today. Override everything the gdbserver, probe and/or the Cortex-Debug did in FW.
Even if (2) can be done, there are things that are out of Cortex-Debug's control. Example: Just to request the SWO capture from the gdb-server/probe, JLink will end up setting up a bunch of registers. All of them are device-agnostic registers so far; ie. registers supported by ARM and CoreSight. I bet they do that to reduce their support calls. J-Link no longer recommends that you even mess with or override it in FW. They expect UART encoding and if you program it as 'manchester' it will not work. OpenOCD and PyOCD are also doing some of this type of configuration. Cortex-Debug is doing the rest. Looking into OpenOCD source code, they have sooo much code to setup registers that is probe specific and generic stuff as well.
Overall though, it is neither (1) or (2) that is happening today. What I see is:
A. Cortex-Debug + gdb-server does all the setup necessary in a generic way to get SWO up and running. B. Users' FW or launch.json or gdb-commands has to do whatever device-specific is needed to get SWO enabled/functioning.
I like this division of labor. It is even documented as such in the readme for the repo (see below)
- SWO Decoding - "console" text output and binary data (signed and unsigned 32-bit integers, Q16.16 fixed point integers, single percision floating point values)
- The registers that are part of the DWT, TPIU, and ITM debug components will automatically be configured and do not need to be set in firmware.
- Firmware may still need to enable the SWO output pin - as this part of the setup is microcontroller dependant.
Once we start becoming device-dependent, then I am afraid it will become a maintenance headache as we won't be able to fix bugs, add features because none of us have all the HW+setup needed.
+1 to have releases in GitHub. I got confused in the same way as @perlindgren Thanks!
passing by, I wanted to highlight that I have worked out a patch into OpenOCD to stream the captured trace over TCP as multi-OS solution since the pipe is for UNIX based systems. the patch is under: http://openocd.zylin.com/#/c/5345/ I hope it will merged soon.
I'm convinced it's always better to have in the IDE a dedicated consoles for ITM and semihosting.
Another patch serving the same purpose for semihosting is under development: http://openocd.zylin.com/#/c/5562/
Yes - a TCP option would be much appreciated for our stuff - currently on Windows in particular the OpenOCD ITM output is a big of an ugly hack as it writes it to a file and polls that file for changes (as we can't even do a named pipe). Hopefully that comes to be and we can update that (although getting it into peoples OpenOCD release that they're using will be difficult)
On Sat, Apr 4, 2020 at 8:45 AM Tarek BOCHKATI notifications@github.com wrote:
passing by, I wanted to highlight that I have worked out a patch into OpenOCD to stream the captured trace over TCP as multi-OS solution since the pipe is for UNIX based systems. the patch is under: http://openocd.zylin.com/#/c/5345/ I hope it will merged soon.
I'm convinced it's always better to have in the IDE a dedicated consoles for ITM and semihosting.
Another patch serving the same purpose for semihosting is under development: http://openocd.zylin.com/#/c/5562/
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Marus/cortex-debug/issues/220#issuecomment-609016197, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAD2FLKBYL6Y7JFSD222NSTRK4MUZANCNFSM4JNCPUJQ .
-- Marcel Ball maball@gmail.com
The purpose of writing is to inflate weak ideas, obscure pure reasoning, and inhibit clarity. With a little practice, writing can be an intimidating and impenetrable fog!
I have got a NRF52840-dk devkit and got the ITM tracing to work using JLinkGDBServer. I tried to get it working using OpenOCD but yet to no avail.
I'm on arch linux with the latest of everything JLinkGDBServer SEGGER J-Link GDB Server V6.54c Command Line Version JLinkARM.dll V6.54c (DLL compiled Nov 7 2019 17:05:41)
OpenOCD Open On-Chip Debugger 0.10.0+dev-00957-g9de7d9c81 (2019-11-13-15:32)
vscode 1.40
Cortex-Debug (3.4), This it what it lists in vscode, but the repo seems to have 2.7 as the latest release, how is that????
I'd like to understand exactly what is going on, why it works with JLink but not OpenOCD, and also how i can pipe the ITM to a file (I saw that one can have "external" servers now, but unsure how to set that up correctly, so that might be an option once I figure out what happens here).
My launch
I get the desired output in the SWO: Output window.
In the Adapter output I get.
So here is my wild guessing, please correct me where I'm wrong.
Here we first see that Cortex Debug sends an EnableTarget command (or rather that JLINK successfully received it). But what happens next? Is it that Cortex Debug actively runs some internal script for setting up the NRF ITM tracing, or? The 0xE0000E00 is ITM_TER (one of the ITM registers). Then for some reason the content of the PC where the MCU was halted is read as well. Then it seems that Cortex Debugs writes a word to 0xE0000E00 (likely a zero). then it reads
Read 4 bytes @ address 0xE0000E00 (Data = 0x00000000)
, to confirm that the write was successful (perhaps, guessing here). ... and so forth.So my question here is, where is this "script", and who is running it (is it Cortex Debug that invokes its own script, or is it a "high level command" sent by Cortex Debug to do this magic)?
I need to know since I want to run ITM tracing in a background process (either using JLink, OpenOCD, or PyOCD), so that I can rout that to an external viewer, and also NOT need to restart the gdb server on each debug run, unless there is some way of pinning adapter output/SWO output to different windows, but that seems like a long shot....
I assume what the Data exchange amounts to in the end is programming the ITM HW on the NRF52 to the correct clock divider, etc.
Attempting to replicate the behavior from terminal(s). .gdbinit
When I try running JLinkGDBServer with the same invocation parameters as listed in the output log:
I get the following output:
So far so good. But listening on the port (assuming udp).
one can see that nothing happens.
the
/tmp/log
never changes. So I'm not sure what happens here. What I can see is that there is no visible reading/writing of the ITM registers. I'm not sure exactly what SWO EnableTarget is doing under the hood (the JLink doc is not clear about this, but I would expect it to program ITM registers of the target, and perhaps validate that the clock divider was correct). I tried to force some problems by setting an illegal SWO frequency, and indeed it reported an error. Even if I don't do anything with the trace data I would expect the size of the/tmp/log
to change.I tried doing a similar setup for OpenOCD both in vscode and from terminal. There the behavior was slightly different. In vscode, I could not get any trace data. From terminal, I could see that data was written by openocd to the file alotted, but it was garbage, at least I was not able to decode it correctly using the
itmdump
tool. Looking at the data in an hex editor gave me the impression that the data was garbage. I tried a few different SWO speed settings and the data changed but still looked like garbage (itmdump
failed to decode it at least). So regarding OpenOCD, there might be some bug in the itm setup management for the NRF52).Sorry for the lengthy post, but if you got this far, please shed some light on this if you have any idea on what could be going on?
Thanks in advance, Per