Skip to main content
Harvey White
Senior III
March 21, 2023
Question

What is the best way to debug both ends of a communications link?

  • March 21, 2023
  • 5 replies
  • 2823 views

Windows 10, CubeMXIDE 1.12.0

Mixed C/C++, STM32L562 processor on custom board.

using STLINK V2 and V3 debugging.

Common software installed as links, configuration file and main.c are really the only unique files that I provide. Configuration file is a bunch of #defines to switch in hardware and software features. All other files that I provide are identical, working equally well on both ends of the system (Root and new node).

I'm debugging both ends of an NRF24L01 mesh network at the same time, watching how each module responds (SPI interface). It's done, the mesh works but needs some refinement, but the communications sequences and responses are working properly.

Hardware debuggers work well with each, but as far as debugging both ends of the link at the same time, I'm wondering if there is an easier way.

With both projects in the same workspace, there is a problem with each debugger pulling up a "copy" of the source (it's the same). There's no really obvious way to tell which is which for the linked files, and I end up with two files in the editor that are out of sync. Any suggestions about that?

When debugging, the breakpoints are not separated by processor (and could be, and perhaps should be). This makes life difficult as well. Common software is working differently depending on the function, but the main loops are still identical. Breakpoints do not readily identify which processor is what, even though they are detailed in the thread descriptions. I'm looking for more obvious.

Any suggestions on the programs in the same workspace method?

I've also got the system set up with two instances of the IDE, which is better when identifying which processor is which. Needs dual monitors, but that's less of a problem than otherwise.

breakpoints would and are separate, so that is less of a problem.

The difficulty I see is in file synchronization. Changing one instance of a file for one processor does not automatically change the instance in the other IDE. Granted, when the software is recompiled, the file on disk changes.

However, that is not necessarily picked up by the second IDE. Since the natural inclination is to debug programs for each processor in the separate window, there are file synchronization problems.

Any comments about this method?

I'm suspecting that I might be missing something, but normally, I do not have two simultaneous debug sections running (and I foresee lots of them when I get into board to board communications). Surely there are people who do this a lot, so what am I missing? I have no real desire to change operating systems, but I'm used to FreeRTOS, know where the bodies are buried, and AZURE does not like C++, and I don't like AZURE queues. A topic for another time.

What's the better method?

This topic has been closed for replies.

5 replies

Pavel A.
Super User
March 22, 2023

You can create a new eclipse workspace (temporary) and run two instances of CubeIDE debugger.

Of course, use two monitors if this is more convenient.

In every CubeIDE instance keep only one project open and close the other one to avoid confusion. If you think some file is out of sync, press F5 (refresh) or re-index. Use your version control software to detect unwanted changes.

> There's no really obvious way to tell which is which for the linked files

Open the properties of a file, go to the Resource tab, it shows the real (resolved) file path.

If you think this is too complicated, imagine that other folks have to debug dozens of CPUs at once - and be relieved ))

Harvey White
Senior III
March 22, 2023

I was hoping that someone, somewhere had come up with a plugin, or a more rewarding methodology. I hadn't considered the F5 key to refresh, being more concerned with actually getting the project to work (silly me......). The two instances of CubeIDE may become my preferred method, two monitors are available, one way or another.

Actually, some attention to each instance of the IDE will give a good idea of what is what, I was looking for the large print version. I'm not worried about the resolved path, it comes out to the same regardless of which instance is in focus. Other than the files generated by CubeMX, There is really only one file that is different between the two projects. Other files would be included or not in the build depending on conditionals. The .loc files are different because the hardware is different, but my "options.h" contain all the #ifdef and #define statements needed to rather completely define a project other than the main.h, main.c files. Any other variables are not a problem.

Ya think that CubeMX is going to be used on a dozens of processors project? Not even sure I could afford the ST Links for the project, let alone the processors and boards. I have a feeling that someone dealing with a project of that magnitude would have a company that would throw money at the development tools. Alas, I cannot.

Thanks

Pavel A.
Super User
March 25, 2023

@Harvey White​ ST-LINKs are very affordable (I even wonder are they subsidized?). If they look expensive for you then I dunno. Again, compare them to J-LINKs or IAR adapters and be relieved.

> I have a feeling that someone dealing with a project of that magnitude would have a company that would throw money at the development tools.

Of course. When you work for such company, you get some interesting stuff. But throw... they call it investment ))

Harvey White
Senior III
March 25, 2023

I was thinking 5 plus nodes all simultaneously being debugged, not that I see myself doing it, but it did hit a price point. The ST-Links are likely subsidized, The rather high cost of a J-Link is one reason I never (and may never) use that product. The smart idea for a processor manufacturer is to supply the tools at as low a cost as possible to capture as much market as possible.

Big companies call it investment, my wallet calls it expense...... <grin>

ETong.1
Associate
March 24, 2023

Hi,

I'm trying to do the same, debug two target boards at the same time when both are running. How to set the debug port number to make it connect to the different board?

0693W00000aJgBwQAK.pngWhen I change debugger configuration by using the port number from Port COM 10 or 11, I'm getting connection error

0693W00000aJgC1QAK.pngSo far, only use Autostart localhost, by connecting one board at a time works.

0693W00000aJgCLQA0.pngThanks

ETong.1
Associate
March 25, 2023

Select ST-LINK S/N with the scanned value can find the right board now.

ETong.1
Associate
March 25, 2023

If you want to keep both projects in the same IDE, you can use split window to have one project on the left and the other project on the right side. But it is not as clear as two IDE workspaces. Sometimes when you open the file by double click, they may not go to the right side.

Harvey White
Senior III
March 25, 2023

OK, there are two approaches,

1) both projects in the workspace: cons: the processors are hard to tell apart.

2) each project in a separate instance of the IDE.

I've been quite successful with #2, and #1 is awkward.

Open one end in an instance of the IDE. Under Debugging, select a specific serial number for the STLink you're using, easiest to do is to configure the system with only one connected, but do not choose "auto". You need to have a specific serial number matching the STLink you have connected to the current project. You don't care about which serial port is emulated.

Open the other end in another instance. Select the other STLink by its serial number/ Things related to one end will be in the appropriate instance. .

You must, however, realize that when you make a change to one instance of a common file, while you automatically save the file when you, you do not update the editor's view in the other instance. You must remember to hit F5 to refresh the file.

Otherwise, you'll get the "file has been changed and is not the same as the file in the editor....." etc.

We need a mechanism to handle this, but debugging two instances (or more) has never been a priority, judging simply by probability.

Harvey White
Senior III
March 26, 2023

I've noticed that with two instances of the IDE, making a change in one will be reflected in the other, without having to it F5. The changes do have to be saved, of course. Makes life more convenient.

In this instance, I'm debugging the actual communications logic, the mesh networking handshaking. I'm doing a similar thing with some direct wired connections when boards are in a common stack.

Timing assures that the master processor can become a root node in the mesh network if no other processor is available, else it becomes another node. The remaining processors in a board stack do not boot until a master processor is assigned (if any). They can become a node, but not a root node (already picked if a master processor exists).

Slave processors may either be standalone, or linked to the master processor by I2C links. Makes sense if you have board stacks and a separate mesh environment.

Harvey White
Senior III
March 28, 2023

I've had some problems with how CubeMX finds files, so I've had to resort to absolute paths. Because of this, I've tried things and the existing structure of my project reflects the experiments (that didn't work). I've tried relative paths, and the like, and I found that project properties/paths entries don't work well for me. I've resorted to absolute paths. Because the project structure is similar for many projects of this type, the absolute paths work from project to project.

The basic project structure (modified from the default) is to add SUBSYSTEMS, which is a file structure that has all of the common files. It does not include any unique files per project. Each file in SUBSYSTEMS is common to all projects.

0693W00000aJo7EQAS.pngNow the overall directory structure is

0693W00000aJo8vQAC.pngand the project directory is

0693W00000aJo9PQAS.pngand just for fun, the common files are:

0693W00000aJo9eQAC.pngNow, there's no reason that you have to follow this setup, but it does work for me.

In each file, as needed, insert the following which (as you see, has multiple projects under the same overall umbrella, using the same common files

#if (defined _PCA9634) && (defined _I2C) && (defined _PACKET)
#include "D:\Documents\Projects\ARM projects\PROJECT 42\SUBSYSTEMS\SYSTEM_CPP\SYSTEM_LED.hpp"
	extern SYSTEM_LED* pca9634;
#endif
 
// *********************************************************************** end revised *
	#include "D:\Documents\Projects\ARM projects\PROJECT 42\SUBSYSTEMS\HAL_CPP\HAL_I2C.hpp"
 
	#include "SYSTEM_I2C.hpp"
 

when I created links by importing the files, I did not copy the files, I simply allowed it to link to existing files. (A little iffy on that, mostly because I've never seen a good explanation of what CubeIDE really does here. Major thing is not to copy files at all. Using the absolute paths gets rid of a lot of "I can't find it".

So for your specific questions or comments:

I use autostart GDB. I don't seem to have a problem there.

I just bypassed the relative path by using absolute paths. Because the major directory structure is independent of the project (see the project folder), for a particular incarnation of "I'm doing it this way", all of this is under Project 42, a number which may indicate the answer to everything <obscure reference>, the paths from part to part in the SUBSYSTEM files do not vary per project. Figure it out once, and it works.

Now, all this is under CubeIDE, so it produces a main.c file. The main.c file links to a C++ file "CPP_LINK", which sets up certain subsystems, mostly displays, I2C, and SPI. At this point, the overall system boot sequence can use an existing OLED display (small: 128 x 64).

CPP_LINK then calls a create routine which sets up the main project .cpp file. That conditionally sets up (using an included options.h with a lot of #define declarations) the subsystems: Networking, packets, mesh networking, display templates, various I2C hardware and the like.

Once this is done, there is a loop updating the status (OLED) display every five seconds or so.

The entire system runs on FreeRTOS, is written in C++, and is an event driven system (mostly). Touches on a display generally cause things to happen. External messages from other processors or processors in the mesh network cause things to happen.

It's a lot easier now, once I figured out this project structure. Is it perfect? no. Is it the only way to do things? no. Does it work? yes.

Hope that this helps and answers your questions.

Hope that this also helps others who stumble on this thread with much the same problems.

ETong.1
Associate
March 28, 2023

Thanks for your reply and showing the detailed folder structure. I see how you are doing it. I think if you setup the include file path under each project, you don't need to add the absolute path inside the source code file. I'll try to setup it up later when I'm ready, now I need to debug some functionality first.

Thanks

Harvey White
Senior III
March 28, 2023

I did this, this way, specifically for the following reasons:

1) I could not get the include path in the project to work properly.

2) I had to set up each project (I've got a lot of them) individually, so a bother

3) I got really tired with messing around with this. Eclipse (the basis of CubeMX) has (I heard) some long standing issues with relative path resolution.

4) it works. Seems to be reliable, so that's good.

5) if I change paths, for whatever reason, a good blanket compilation will point out the unresolved paths, Somewhat tedious, but those changes do the entire project.

If the relative paths work for you, then that's good, and I'd like to hear of it.

Hope it all turns out well, glad to be of help.