04-04-2020 04:20 PM
I started debugging a program which is running on a Zynq with the SDK debugger. The program runs a main loop (doing a communication interface via UART) and an ISR which is periodically triggered by a custom IP core (a PWM unit). The ISR time was measured by setting a GPIO pin at the beginning of ISR execution and clearing the pin after before the ISR is finished. I figured out that every time I read or change a global variable in the "Expressions" window in SDK, the ISR is not executed over a longer time period (milliseconds!). This brings up some questions:
- I thought that the logic which communicates via JTAG with the debugger is completely independent of the CPU and behaves like some "background god" which does not interfere with the CPU executing the program. This is obviously not the case. How is this working exactly. Is the CPU halted every time I change a variable? Does the CPU get the value communicated via JTAG and has to write it to the memory by itself? I thought that the debug instance has it's own memory interface and some "magic background access" to basically everything (e.g. CPU registers).
- Why is this taking milliseconds? The whole process of updating a single integer variable is interfering with my program over a period of 150 ms. Within these 150 ms, the ISR is stopped 7 times with each of these "pauses" exhibiting a duration between 5 ms and 30 ms. It is enough to scroll through the Expressions window (which apparently updates the presented values there) to see the ISR not working anymore for similar intervals. The observed aren't identical each time.
- How can I avoid this behavior? This is absolutely catastrophic. I build power converters where my ISR executes current controllers. If my control stops working for several milliseconds my converter blows up into pieces.
04-14-2020 03:26 AM
Still struggling with this one...does anybody have some hints regarding how this communication via JTAG works? I really have to avoid that the debugger interferes with the ISR execution. Is there anything I can do against this?
05-05-2020 05:30 AM
ARM debug interface has 2 paths which are used by the debugger to access memory, registers, etc. based on what the user is doing
1. AXI port for accessing physical memory. Debugger uses this path when users select non-processor type targets (ex. APU, RPU, PSU, etc.). This port can access only physical memory, and not CPU registers, caches, etc.
2. APB port for accessing CPU debug registers. This port can be used to inject instructions into CPU core to access memory, registers, etc. Since CPU is executing the instructions injected by debugger, it can access virtual memory, caches, etc. However, CPU cores need to be in suspended state to do this
Since the global variables are CPU specific, they can be part of virtual memory/caches, so debugger always uses CPU cores to evaluate global variables in expressions window. If you need to access the global variables when the core is running, you can use non-cpu core targets from XSCT console (memory window in the GUI will access a minimum of 100 bytes at a time). However, you need to know the address of the global variable to do this. This also requires that the global variable is not stored in cache, or the cache is flushed immediately after the variable is updated
05-19-2020 12:37 AM
Thanks for your response, this at least explains what I observed. I guess I will stop to use the variables/expressions window then when running the system with power...although this definitely leaves behind a bad feeling. Can I rely on my CPU not being interrupted by JTAG if I don't use the memory observation? Or is there other communication running via JTAG in the background that could stall my ISR execution?