The goal is to combine the benefits of a virtual prototype with a software debugger.
By Achim Nohl
In my last post I introduced the debugging challenges during porting, or developing native code, for Android. This time I would like to outline how virtual prototypes can enable software debugging and perform in an even better way. Before I describe what “better” refers to exactly, I want to shed some light on some prominent myths around the value of VPs for debugging.
Whenever VPs are mentioned in the context of debugging, it’s claimed that they offer many debugging advantages over real hardware. It is said that VPs have better controllability, visibility and provide determinism. But is this really true? And what does this really mean for a software developer?
For many people, a VP is nothing more than a piece of software simulating a HW/SW system. This software (the VP) can be debugged on the host PC of the user. Using the host’s software debugging tools, or VP vendor-specific tools, the user is able to inspect all aspects of the platform such as memories, registers and signals. Also, he/she can suspend the simulation in the host debugger, and above all has full control over the VP. The next time anyone executes the VP it is likely that it will perform the same functions in the same order as before, and that its behavior will be fully deterministic (as long as there is no interaction with non-deterministic external components such as the user). This all sounds great, but it does not consider the real needs of a software developer.
“Run-mode” software debugging using a VP
While a software developer is definitely thankful for inspecting the hardware beyond what is possible with a software debugger, in the first place he/she will still need to debug software. This is of course also possible with a VP. Most VPs do contain virtualized interfaces such as USB, Ethernet or UART. Those interfaces allow a software debugger to connect to an embedded software agent. This agent establishes the connection between the debug target and the debugger. Now a VP can be easily combined with arbitrary software debug tools and even integrated into SDKs. As an example, the Google Android SDK connects to the debug target through Ethernet. This works perfectly with a VP.
Interestingly, this is not any different from the way it is done with real hardware. But unfortunately, also no real advantages exist. The praised controllability, visibility and determinism has to be re-evaluated. The control is now with the software debugger. When you suspend using the SW debugger, the VP will keep running. Timers, watchdogs and other SW processes continue to work (so called “run mode” debugging). In order to inspect the HW and correlate the platform state with the software state, you would need to suspend the VP. But, if you suspend the VP, then the debugger communication will likely time out. Remember, the embedded software agent is also halted. Also, the agent itself influences the execution of the overall system and has side effects. Now, the determinism is also gone. But, there is a solution to combine the best of both worlds.
Virtual prototypes as debug servers
To marry the advantages of VPs and software debuggers, the VP simulation framework needs to take over the task of the software agent and act as a debug server. The debug server establishes the link between the software debugger and the VP simulation. Now we can take advantage of the VP’s “view from the top” and serve even multiple software debuggers with information from all over the platform. The debug server also orchestrates the control and makes sure all debug views are synchronized. The debug server itself does not interfere with the execution of the platform. Neither the hardware models, nor the software, can tell whether they are debugged or not. Now the VP can really play its hand and deliver all the advantages to the software engineers. Summarizing, it is important to recognize that a VP is more than a model. A VP requires tooling to make it useful beyond simulation.
Coming back to Android and my previous post: The 21 steps to set up a debugger to debug native code can now be reduced to two. Using a VP with a debug server, you set a breakpoint at the address and process that you are interested in; afterward you simply connect the software debugger. No more worries about when and how to launch the gdb-server agent. But VPs even help in the context of using run-mode debugging of Android native code libraries. The user of the VP can easily inject an endless loop within the start-up code of an embedded software process just by writing the instructions into the VP memories. No change and recompilation of the embedded software is needed, as required in the best practice.
Leave a Reply