Posts by RobMeades

    Yes, that's correct. nrfjprog is started with the command line:

    nrfjprog -f nrf52 --program nrf52840_xxaa.hex --chiperase --verify -r -s <serial number here>

    The Python code that does this is

    Code
    subprocess.Popen(<the command line above>,
                     stdout=subprocess.PIPE,
                     stderr=subprocess.STDOUT)

    The download is allowed to complete successfully, the Python sub-process exits all by itself with return value 0.

    J-Link is then started to obtain RTT logging from the same board with the command line:

    jlink.exe -Device NRF52840_XXAA -If SWD -Speed 4000 -Autoconnect 1 -ExitOnError 1 -RTTTelnetPort <Telnet port> -USB <serial number here>

    The Python code that does this is:

    Code
    subprocess.Popen(<the command line above>,
                     stdout=subprocess.PIPE,
                     stderr=subprocess.STDOUT,
                     stdin=subprocess.PIPE)

    [The difference in this case being that, as you requested, we can use stdin to send the string "exit\n" to J-Link when we wish to stop it]

    In all cases the serial number is appropriate to one of the three NRF52 boards we have on this test system. The Telnet port numbering starts at 19021 and is unique to each board (so 19021, 19022 and 19023).

    This sequence of operations is started and allowed to run asynchronously and in parallel on the three boards; since there is no connection between them they should not affect each other.

    Thanks for your swift response.

    The port numbers we use are distinct for each parallel case, of course.

    No port number is specified at all to nrfjprog: the download process needs/takes no Telnet port, as far as I'm aware: please tell me if I'm wrong.

    Could you explain what the line "Process: xxx" printed by J-Link means? Why is any other process involved at all, all we have asked for is for the target serial number in question to have its RTT output sent to a Telnet port that we specify. The only thing involved with this, as far as we are aware, is J-Link itself as it's the only thing we've invoked to do it.

    Further to [SOLVED] J-Link freeze in multiply parallel environment, having resolved that problem in a multiply parallel environment we seem to be left with a residual issue, which is that on some occasions (around the 1 in 10 times mark again) a J-Link session opened for RTT logging fails to emit any logging whatsoever from the target.

    On these occasions it seems that J-Link, or whatever underlies it, is confused about the process it is serving.

    In detail: we run Nordic nrfjprog to download to the NRF52 platform (details of the command-line below). This is driven from a Python script as a sub-process, non-shell, as described in the post concerning the previous problem, and runs perfectly normally, exiting all by itself having completed the download, no forced exit or anything of that nature.

    We then start J-Link to do RTT logging and, in the fail case, rather than indicating that the process is jlink.exe, J-Link prints out that the process is nrfjprog.exe, which terminated a second or two earlier. Find below a success case and a fail case for comparison.

    Do you have any suggestions as to how we might prevent this confusion from occurring? It is worth remembering that, as indicated, we are running multiple of these in parallel, our assumption being that by including the debugger serial number in the command-line that the processes are utterly separate. Is that a safe assumption or might there be "danger times" when that is not true? If so, what such situations should we avoid?

    Here's a success case with timestamps shown on the left:

    ...and after that RTT logging flows from telnet port 19021.

    Here's a fail case, again with timestamps:

    ...and after that no RTT logging whatsoever is emitted from telnet port 19021.

    Confirmed: for the benefit of the forum, in case anyone else has this problem, if you are using J-Link for RTT logging (reading from its RTT-socket), driven from an [e.g. Python] script, there is only ONE way to reliably shut J-Link down again and that is to keep a stdin pipe open to it and send it the string "exit\n" before terminating it.

    If you send J-Link SIGTERM/CTRL-C/CTRL-BREAK signals, or if you just terminate it, some percentage of the time (with us it was anything from 10% to 40% of the time) J-Link will hang the next time you try to start it on that board and only power-cycling the board will fix the problem; we tried everything, including programmatically resetting the PC's USB port, and nothing helped. When this happens, if you take a J-Link log (command-line parameter -Log <Path>) the log will end with "Out of sync, resynchronizing..." and then nothing more.

    Having implemented this send-exit-over-stdin-and-then-terminate scheme we can now use J-Link for RTT logging and then for something else afterwards reliably.

    Thanks for the support @SEGGER - Alex.

    That's *better*! Some real information, thank you :-).

    FYI, I have since modified my Python script to send a Windows termination, CTRL-C, to the application, so it is not like the power is being pulled, it is being told to exit (5 times at 1 second intervals) before the task-manager-style termination of terminate() is invoked. I hoped that would be a sufficiently clear "tidy up now" signal but obviously not. I will try typing "exit\n" at it over stdin next.

    Thanks, again, for your support.

    I guess we'll have to agree to disagree: I find it difficult to believe that the amount of flash used in tracking how much heap is in use is large versus the negative impact of not knowing that you've lost the much scarcer resource that is RAM. And heap checking, in my view, should be done on the target, in real scenarios, at which point you wouldn't be using a "test" malloc()ater because then you're not testing the real thing; practically speaking you'd just end up having to entirely replace the malloc() function SES provides with ones own, again kind of taking away from the usefulness of SES.

    Don't get me wrong, I really like SES from a GUI perspective: neat and fast, beats Eclipse and the like hands down.

    Just think it's missing an essential feature for those making production code.

    Thanks: it is quite an important function to have. Not having it is like driving a car without a fuel gauge; a little worrying when one is, for instance, running on an NRF52 with a "tank" only 64 kbytes in size. And of course, as a matter of principle, one's unit tests should always check that the code they are testing has not leaked any memory, which is impossible without this function.

    Without this function I have to run all the same code on GCC also, which starts to make SES a bit irrelevant: not something you would like to encourage I'm sure!

    I would like to determine the current heap usage (in order to check for memory leaks).

    On platforms that use newlib I can do this by calling mallinfo() but of course SES uses its own C libraries so that is not available to me: what is the equivalent function in the SES world?

    Rob

    Thanks for your remarkably swift attention. Just getting logs for you now. On the other stuff:

    We use JLink for two things: RTT logging and downloading to a board. To do the RTT logging part we open a Python sub-process as follows:

    Code
    process = subprocess.Popen(["jlink.exe", "-Device", "NRF52840_XXAA", "-If", "SWD",
                                "-Speed", "4000", "-Autoconnect", "1", "-ExitOnError", "1",
                                "-RTTTelnetPort", "19021", "-USB", "683253856"],
                                stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
                                shell=False)

    We connect to the Telnet port and let it run, monitoring the trace output. When the trace output tells us that the target has finished doing what it should, we terminate J-Link as follows:

    Code
    return_value = process.poll()
    if not return_value:
        process.terminate()
        while process.poll() is None:
            pass

    After this has completed we wait 5 seconds, just for good luck, and then load up the next thing onto the board by calling:

    Code
    process = subprocess.Popen(["jlink", "-nogui", "1", "-commandfile", "jlink.txt",
                                "-USB", "683253856"],
                               stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
                               shell=False)

    ...where jlink.txt contains:

    Code
    si swd
    speed 4000
    device NRF52840_XXAA
    connect
    r
    h
    erase
    loadfile nrf52840_xxaa.hex
    r
    exit

    It is when doing this latter download of the next board firmware that the hang often occurs.

    Hi there. We are using JLink [V6.84a] to download code to our test boards and then do RTT logging in a multiply parallel environment, i.e. we have many boards (Nordic NRF52/53) connected to the [Windows 10] PC in question. All operation is controlled through Python [3.8.5] scripts. Each board serial number is specifically addressed with the -USB parameter in the call to J-Link. We have a lock in place so that JLink is never called to download to two boards at the same time.

    Our problem is that about 1 in 10 times J-Link freezes: does nothing whatsoever, no prints, nothing, just sits there. This occurs when a board has been running J-Link for RTT logging and that J-Link executable is terminated to do the next thing, which is a J-Link download of new SW to the same board: on launching J-Link to do that download it freezes. It doesn't happen all the time but it does happen frequently enough to flash red lights on our CI display much of the time, so we need to fix it, but we're all out of ideas.

    Every J-Link session is a Python subprocess. The RTT logging session is terminated using subprocess.terminate(). We retry after 60 seconds of "frozen" but that doesn't help. We've tried resetting the USB port in question, at Windows device level, after a failure but that doesn't help. The only thing that fixes it is physically powering down the board and powering it back on again.

    Has anyone any suggestion for any workarounds we might apply?

    The debugger FW versions on the boards in question are:

    • J-Link OB-SAM3U128-V2-NordicSemi compiled Mar 17 2020 14:43:00 V1.0
    • SEGGER J-Link ARM V10.1
    • J-Link OB-K22-NordicSemi compil V1.00

    FYI, I've found a workaround for this. In my common pre-processor definitions I have added 10 generic entries with dummy default values as follows:

    $(EXTRA0:__dummy0)
    $(EXTRA1:__dummy1)
    $(EXTRA2:__dummy2)
    ..
    .

    I can then launch SES from the command line and supply the actual values for each one as parameters, e.g.:

    "C:\Program Files\Segger\SEGGER Embedded Studio for ARM 4.50\bin\emstudio" -D EXTRA0="MY_CONDITIONAL=1"

    Not elegant but it works.

    Referring to this thread from Feb 2018:

    [SOLVED] EMBuild -D option

    ...can I ask if it is still the case that there is no way to pass in #defines from the outside world into Segger Embedded Studio? I don't mean change ones that SES knows about, I mean just pass in the random stuff I need to get into my code. Not being able to do this is a real barrier to automation and to writing/maintaining cross-platform code. I have to deal with building/testing my code under many different SDKs at the same time and the last thing I want to have to do is tell each IDE about ever little thing when it matters not a jot: my code deals with the consequences and only my code cares, it really should be transparent to the IDE.

    Please tell me there's a way to do this. Make can obviously do it and even CMake is able to do it with a little persuasion. If there's really no way to do this then, unfortunately, SES is not a viable option for me.

    Rob