Supporting an device in the JTAG chain (e.g. JTAG UART) - Multiple Server Arbitration?

Open source ARM Debugger

Moderator: phalanx

Post Reply
TomV
Posts: 3
Joined: Mon Apr 16, 2018 4:01 pm

Supporting an device in the JTAG chain (e.g. JTAG UART) - Multiple Server Arbitration?

Post by TomV » Mon Apr 16, 2018 4:18 pm

Hello All,

I have a design with multiple CPU JTAG TAPs. OpenOCD supports them just fine and GDB can access the information it needs.

However, I would also like to add other JTAG TAPs on the same JTAG chain that support completely different functionality. Possible examples are: a TAP to scan out debug information, a JTAG UART to implement a console etc.

An external client such as a debug status windows or a console application would need to continuously monitor those additional TAPs, in addition to still being able to run GDB.

Since OpenOCD is the master JTAG server that drives the physical JTAG dongle, one way or the other, I will need to tell OpenOCD to issue the correct JTAG instructions to the correct TAP and fetch the information that I need.

Which leads to my question: how does OpenOCD arbitrate between multiple servers?

In the current implementation, OpenOCD already has 3 servers with TCP/IP endpoints: GDB server, telnet server, and tcl server.

When a program is up and running on GDB, GDB will continuously operate the JTAG interface to check the execution state. While this is happening, I can also still issue OpenOCD commands through telnet.

What does OpenOCD do to select between these two servers and how does it prevent the two servers from stepping on each other's toes?

Second question: how would you as an expert go about implementing the system that I need?

I'm currently thinking of writing a python script that ties in to the tcl server. Is that a workable approach?

Thanks!
Tom

TomV
Posts: 3
Joined: Mon Apr 16, 2018 4:01 pm

Re: Supporting an device in the JTAG chain (e.g. JTAG UART) - Multiple Server Arbitration?

Post by TomV » Tue Apr 24, 2018 10:31 am

For posterity, here's my current solution for this:

OpenOCD ultimately works with multiple targets on the same bus. It maintains a list with all known targets. Targets can be enabled or disabled (they enabled by default.)

After initialization, OpenOCD enters a loop (in server.c:server_loop()). In this loop, every 100ms, it will go through all the active targets and run the poll() function of the target. In this poll() function, a CPU target will typically issue JTAG instructions to check the state of the CPU. For example: has it triggered a breakpoint?

OpenOCD has an API to issue JTAG commands for a particular target. The cool thing is that it keeps track of all TAP in the JTAG chain. If one target wants to send something to a particular DR but another target was accessed previously, the JTAG api will first issue an IR to put all the other TAPs in bypass mode and select the right DR for that one target. If the previous target was already the same target, and the correct DR was already selected, the JTAG api will immediately access the DR without first issuing the IRs.

This all works great for CPUs, but there is no reason for it not to work for other kind of targets.

So that's what I did: I define a target called "jtag_uart" that implements a "poll" function which issues JTAG commands to fetch the status of the read FIFO or send commands to the write FIFO. In addition, my target opens a socket to interface with other programs.

Post Reply