Communications
Ordered Halting Unordered Halting Software Breakpoints Hardware Breakpoints Application IO Restarting Sessions Swappable Partitions Multi-core devicesCommunications with Debugger
Communications with the debugger use command queue. There are functions to issue commands, the functions to check if the response is available, and the functions to fetch the results of the command execution.
Command Queue
The command queue is maintained by NSDSP Interface Library. All the commands are stored in the output buffer. Once the buffer is full, the commands get sent to NSDSP for execution. Or, you can force the execution of the queue by calling the flush function which sends the queue to NSDSP immediately.
Many commands will produce a response. Responses are sent back in the same order as the commands were issued, and you must retrieve and process them in the exact same order.
Data Reading Commands
The majority of commands used during the debugging are read commands. They may read memory, registers, state of breakpoints etc. Each successful read command returns the number of bytes in the expected response. You can use this number to determine if the response is fully received before calling a fetch function. For example:
responseSize = debugSession.readRegister(RegisterId)
debugSession.flush
while responseSize < debugSession.availableData do {
// Doing something else
}
// Now fetch will execute without delays
R = debugSession.fetchWord
Alternatively, you can simply call a fetch function and let it wait for data (subject to timeout):
debugSession.readRegister(RegisterId)
debugSession.flush
// Fetch will block until data arrive
R = debugSession.fetchWord
Code Execution Commands
The code execution commands - running, single stepping, and multi-stepping - are also a part of the same command queue. However, their behavior depends on whether the target device uses ordered halting or unordered halting.
If the target device implements ordered halting the code execution commands stop the command queue, and the queue does not move until the target device halts. After the halt (which may be a long time since the code execution command was issued), NSDSP sends back a response containing the information about the halt containing the address where the target halted. Once the halt information is sent, the command queue resumes.
You retrieve the halt information when you call a check or wait function. For example:
debugSession.run
debugSession.flush
while not debugSession.checkForHalt do {
// Doing something else
}
// The target is halted
Or if you prefer to wait for the halt (without timeouts):
debugSession.run
debugSession.flush
debugSession.waitForHalt
// The target is halted
Ordered halting requires strict ordering. The checks for the halt and fetch commands must be in the same order as the code execution and data fetching commands. This pseudo-code shows an example of correct ordering:
debugSession.readRegister(RegisterId)
debugSession.singleStep
debugSession.readRegister(RegisterId)
debugSession.flush
regBeforeStep = debugSession.fetchWord
debugSession.waitForHalt
regAfterStep = debugSession.fetchWord
In contrast, the code below will not work because fetching order does not match the order of requests in the command queue:
debugSession.readRegister(RegisterId)
debugSession.singleStep
debugSession.readRegister(RegisterId)
debugSession.flush
debugSession.waitForHalt // Wrong!!! Must fetch regBeforeStep first
regBeforeStep = debugSession.fetchWord
regAfterStep = debugSession.fetchWord
In contrast, if your chip uses unordered halting then the code execution commands produce no response. When the target device starts running, the command queue doesn't stop and subsequent commands continue to execute while the device runs. The command sent while the device runs may execute while it is still running, or, if the device halts, they may execute after the halt. The halt checking does not need to be ordered relative to other commands. For example, both of the following two examples are correct:
debugSession.run
debugSession.readRAM(Address,wordSize)
debugSession.flush
debugSession.waitForHalt
regAfterStep = debugSession.fetchWord
and
debugSession.run
debugSession.readRAM(Address,wordSize)
debugSession.flush
regAfterStep = debugSession.fetchWord
debugSession.waitForHalt
Both of these sequences will produce the same result
Not all of the commands can execute at run-time. The majority of commands can only execute when the device is halted.
Out of Bounds Halt
When the target is running, you can halt it manually. If the command queue is blocked waiting for halt, the halt command is executed out of bounds. From the viewpoint of communication sequences, the manual halt is not different from a halt on breakpoint.
© 2007-2025 Northern Software Inc. All Rights Reserved.