XSCT Use Cases

XSCT can be used in various scenarios in the development, debugging, verification, and deployment cycles. XSCT inherits high-level, interpreted, and dynamic programming features from Tcl, which makes the programming simple and powerful.

XSCT can inter-operate the workspace together with the Vitis™ IDE. When creating and managing projects, XSCT launches the Vitis IDE in the background. XSCT workspaces can be seamlessly used with the Vitis IDE and vice versa. When you are working in the Vitis IDE, equivalent XSCT commands will be printed in the console in most use cases. This can help you create scripts for batching and automation when actions need to be executed repeatedly.
Note: At any point in time, a workspace can either be used only from Vitis IDE or XSCT.

Common Use Cases

Checking the JTAG status of the board
In the new board bring-up phase, after verifying the power circuits, the first job for hardware verification is to test the JTAG status; checking whether the FPGA or SoC device can be scanned, and whether the processors can be found properly. XSCT can do this job with JTAG access and target connection management commands such as jtag targets, connect, and targets. If you suspect that the board is in an abnormal status and you need to check the basic hardware, it is also recommended to check the JTAG and processor status.
Initializing the board with a single script through JTAG
In some debugging cases (for example, debugging a PL module that needs a PS generated clock), the PS simply needs to be initialized into a certain status. Running customized initialization scripts can be faster and more lightweight than launching runs with the Vitis IDE. The Vitis IDE shows the equivalent XSCT debug commands in the console. To repeat an initialization cycle easily, copy these commands into a Tcl file and use XSCT to execute this Tcl script.
Loading U-Boot with a single script through JTAG
If you need to customize U-Boot, the easiest way to test and iterate is to use XSCT to initialize the board, load the U-Boot binary into DDR, and run it. This can be executed on the fly. Otherwise, you might have to package the boot.bin file and write it to an SD card or the flash memory every time you update the code.
Reading and writing registers with or without applications
When debugging peripherals or their drivers, the status of the peripheral registers is important. The status can be read from XSCT or it can be viewed in the Vitis IDE memory view. Using XSCT commands to read and write registers is quick and lightweight. The register read and write commands can be written into a script to automate repeated processes. You can also save the register values into a file for comparison.

Changing Compiler Options of an Application Project

An example XSCT session that demonstrates creating an empty application for Cortex®-A53 processor, by adding the compiler option -std=c99 is as follows.

setws /tmp/wrk/workspace
app create -name test_a53 -hw /tmp/wrk/system.xsa -os standalone -proc psu_cortexa53_0 -template {Empty Application}
importsources -name test_a53 -path /tmp/sources/
app config -name test_a53 -add compiler-misc {-std=c99}
app build -name test_a53

Creating an Application Project Using an Application Template (Zynq UltraScale+ MPSoC FSBL)

The following is an example XSCT session that demonstrates creating a FSBL project for a Cortex-A53 processor.

Note: Creating an application project creates a BSP project by adding the necessary libraries and setting compiler options automatically. FSBL_DEBUG_DETAILED symbol is added to FSBL for debug messages.
setws /tmp/wrk/workspace
app create -name a53_fsbl -hw /tmp/wrk/system.xsa -os standalone -proc psu_cortexa53_0 -template {Zynq MP FSBL}
app config -name a53_fsbl define-compiler-symbols {FSBL_DEBUG_INFO}
app build -name a53_fsbl

Creating an FSBL Application Project Using Manually Created Domain (Zynq UltraScale+ MPSoC FSBL)

The following is an example XSCT session that demonstrates creating a FSBL project for a Cortex-A53 processor by manually creating platform, domain and application. Configuration option zynqmp_fsbl_bsp is set for FSBL compiler optimization options.

setws /tmp/wrk/workspace
platform create -name HW1 -hw zcu102 -no-boot-bsp
domain create -name A53_Standalone -os standalone -proc psu_cortexa53_0
domain active A53_Standalone
bsp setlib -name xilffs
bsp setlib -name xilsecure
bsp setlib -name xilpm
bsp config zynqmp_fsbl_bsp true

platform generate
app create -name a53_fsbl -platform HW1 -template "Zynq MP FSBL" -domain A53_Standalone -lang c
app build -name a53_fsbl

Creating a Bootable Image and Program the Flash

An example XSCT session that demonstrates creating two applications (FSBL and Hello World) is as follows. Further, create a bootable image using the applications along with bitstream and program the image on to the flash.

Note: Assuming the board to be zc702 -flash_type qspi_single is used as an option in program_flash.
setws /tmp/wrk/workspace
app create -name a9_hello -hw /tmp/wrk/system.xsa -os standalone -proc ps7_cortexa9_0 -template {Zynq FSBL}
app create -name a9_fsbl -hw /tmp/wrk/system.xsa -os standalone -proc ps7_cortexa9_0 -template {Hello World}
app build -name a9_hello
app build -name a9_fsbl
exec bootgen -arch zynq -image output.bif -w -o /tmp/wrk/BOOT.bin
exec program_flash -f /tmp/wrk/BOOT.bin -flash_type qspi_single -blank_check -verify -cable type xilinx_tcf url tcp:localhost:3121

Debugging a Program Already Running on the Target

Xilinx® System Debugger Command-line Interface (XSDB) can be used to debug a program which is already running on the target (for example, booting from flash). Connect to the target and set the symbol file for the program running on the target. This method can also be used to debug Linux kernel booting from flash. For best results, the code running on the target should be compiled with the debug information.

The following is an example of debugging a program already running on the target. For demo purpose, the program has been stopped at main(), before this example session.

# Connect to the hw_server

xsdb% conn -url TCP:xhdbfarmc7:3121
tcfchan#0
xsdb% Info: Arm Cortex-A9 MPCore #0 (target 2) Stopped at 0x1005a4 (Hardware Breakpoint)
xsdb% Info: Arm Cortex-A9 MPCore #1 (target 3) Stopped at 0xfffffe18 (Suspended)

# Select the target on which the program is running and specify the symbol file using the 
# memmap command

xsdb% targets 2
xsdb% memmap -file dhrystone/Debug/dhrystone.elf

# When the symbol file is specified, the debugger maps the code on the target to the symbol 
# file. bt command can be used to see the back trace. Further debug is possible, as shown in 
# the first example

xsdb% bt
    0  0x1005a4 main(): ../src/dhry_1.c, line 79
    1  0x1022d8 _start()+88
    2  unknown-pc

Debugging Applications on Zynq UltraScale+ MPSoC

Note: For simplicity, this help page assumes that Zynq® UltraScale+™ MPSoC boots up in JTAG bootmode. The flow described here can be applied to other boot modes too, with minor changes.

When Zynq UltraScale+ MPSoC boots up JTAG bootmode, all the Cortex®-A53 and Cortex®-R5F cores are held in reset. Users must clear resets on each core, before debugging on these cores. The rst command in XSCT can be used to clear the resets. rst -processor clears reset on an individual processor core. rst -cores clears resets on all the processor cores in the group (APU or RPU), of which the current target is a child. For example, when Cortex-A53 #0 is the current target, rst -cores clears resets on all the Cortex-A53 cores in APU.

Below is an example XSCT session that demonstrates standalone application debug on Cortex-A53 #0 core on Zynq UltraScale+ MPSoC.

Note: Similar steps can be used for debugging applications on Cortex-R5F cores and also on Cortex-A53 cores in 32 bit mode. However, the Cortex-A53 cores must be put in 32 bit mode, before debugging the applications. This should be done after POR and before the Cortex-A53 resets are cleared.
#connect to remote hw_server by specifying its url. 
If the hardware is connected to a local machine,-url option and the <url> 
are not needed. connect command returns the channel ID of the connection

xsdb% connect -url TCP:xhdbfarmc7:3121 -symbols
tcfchan#0

# List available targets and select a target through its id. 
The targets are assigned IDs as they are discovered on the Jtag chain, 
so the IDs can change from session to session. 
For non-interactive usage, -filter option can be used to select a target, 
instead of selecting the target through its ID

xsdb% targets
  1  PS TAP
     2  PMU
        3  MicroBlaze PMU (Sleeping. No clock)
     4  PL
  5  PSU
     6  RPU (Reset)
        7  Cortex-R5 #0 (RPU Reset)
        8  Cortex-R5 #1 (RPU Reset)
     9  APU (L2 Cache Reset)
       10  Cortex-A53 #0 (APU Reset)
       11  Cortex-A53 #1 (APU Reset)
       12  Cortex-A53 #2 (APU Reset)
       13  Cortex-A53 #3 (APU Reset)
xsdb% targets 5

# Configure the FPGA. When the active target is not a FPGA device, 
the first FPGA device is configured

xsdb% fpga ZCU102_HwPlatform/design_1_wrapper.bit
100%    36MB   1.8MB/s  00:24

# Source the psu_init.tcl script and run psu_init command to initialize PS
xsdb% source ZCU102_HwPlatform/psu_init.tcl
xsdb% psu_init

# PS-PL power isolation must be removed and PL reset must be toggled, 
before the PL address space can be accessed

# Some delay is needed between these steps

xsdb% after 1000
xsdb% psu_ps_pl_isolation_removal
xsdb% after 1000
xsdb% psu_ps_pl_reset_config

# Select A53 #0 and clear its reset

# To debug 32 bit applications on A53, A53 core must be configured 
to boot in 32 bit mode, before the resets are cleared

# 32 bit mode can be enabled through CONFIG_0 register in APU module. 
See ZynqMP TRM for details about this register

xsdb% targets 10
xsdb% rst -processor

# Download the application program

xsdb% dow dhrystone/Debug/dhrystone.elf
Downloading Program -- dhrystone/Debug/dhrystone.elf
                section, .text: 0xfffc0000 - 0xfffd52c3
                section, .init: 0xfffd5300 - 0xfffd5333
                section, .fini: 0xfffd5340 - 0xfffd5373
                section, .note.gnu.build-id: 0xfffd5374 - 0xfffd5397
                section, .rodata: 0xfffd5398 - 0xfffd6007
                section, .rodata1: 0xfffd6008 - 0xfffd603f
                section, .data: 0xfffd6040 - 0xfffd71ff
                section, .eh_frame: 0xfffd7200 - 0xfffd7203
                section, .mmu_tbl0: 0xfffd8000 - 0xfffd800f
                section, .mmu_tbl1: 0xfffd9000 - 0xfffdafff
                section, .mmu_tbl2: 0xfffdb000 - 0xfffdefff
                section, .init_array: 0xfffdf000 - 0xfffdf007
                section, .fini_array: 0xfffdf008 - 0xfffdf047
                section, .sdata: 0xfffdf048 - 0xfffdf07f
                section, .bss: 0xfffdf080 - 0xfffe197f
                section, .heap: 0xfffe1980 - 0xfffe397f
                section, .stack: 0xfffe3980 - 0xfffe697f
100%    0MB   0.4MB/s  00:00   
Setting PC to Program Start Address 0xfffc0000
Successfully downloaded dhrystone/Debug/dhrystone.elf

# Set a breakpoint at main()
xsdb% bpadd -addr &main
0

# Resume the processor core
xsdb% con

# Info message is displayed when the core hits the breakpoint
Info: Cortex-A53 #0 (target 10) Running
xsdb% Info: Cortex-A53 #0 (target 10) Stopped at 0xfffc0d5c (Breakpoint)

# Registers can be viewed when the core is stopped
xsdb% rrd
  r0: 0000000000000000    r1: 0000000000000000    r2: 0000000000000000
  r3: 0000000000000004    r4: 000000000000000f    r5: 00000000ffffffff
  r6: 000000000000001c    r7: 0000000000000002    r8: 00000000ffffffff
  r9: 0000000000000000   r10: 0000000000000000   r11: 0000000000000000
 r12: 0000000000000000   r13: 0000000000000000   r14: 0000000000000000
 r15: 0000000000000000   r16: 0000000000000000   r17: 0000000000000000
 r18: 0000000000000000   r19: 0000000000000000   r20: 0000000000000000
 r21: 0000000000000000   r22: 0000000000000000   r23: 0000000000000000
 r24: 0000000000000000   r25: 0000000000000000   r26: 0000000000000000
 r27: 0000000000000000   r28: 0000000000000000   r29: 0000000000000000
 r30: 00000000fffc1f4c    sp: 00000000fffe5980    pc: 00000000fffc0d5c
cpsr:         600002cd   vfp                     sys                  

# Local variables can be viewed
xsdb% locals
Int_1_Loc       : 1113232
Int_2_Loc       : 30
Int_3_Loc       : 0
Ch_Index        : 0
Enum_Loc        : 0
Str_1_Loc       : char[31]
Str_2_Loc       : char[31]
Run_Index       : 1061232
Number_Of_Runs  : 2

# Local variable value can be modified
xsdb% locals Number_Of_Runs 100
xsdb% locals Number_Of_Runs
Number_Of_Runs  : 100

# Global variables and be displayed, and its value can be modified
xsdb% print Int_Glob
Int_Glob  : 0
xsdb% print -set Int_Glob 23
xsdb% print Int_Glob
Int_Glob  : 23

# Expressions can be evaluated and its value can be displayed
xsdb% print Int_Glob + 1 * 2
Int_Glob + 1 * 2  : 25

# Step over a line of source code
xsdb% nxt
Info: Cortex-A53 #0 (target 10) Stopped at 0xfffc0d64 (Step)

# View stack trace
xsdb% bt
    0  0xfffc0d64 main()+8: ../src/dhry_1.c, line 79
    1  0xfffc1f4c _startup()+84: xil-crt0.S, line 110
Note: If the .elf file is not accessible from the remote machine on which the server is running, the xsdb% connect -url TCP:xhdbfarmc7:3121 command should be appended with the -symbols option as shown in the above example.

Selecting Target Based on Target Properties

The following is an example XSCT session that demonstrates selecting a target based on target properties. It shows how to connect to the Cortex®-A9 processor of the second device when multiple devices are connected in a JTAG chain (xc7z020 and xc7z045).

# connect to hw_server
xsdb% conn -ho xhdbfarmrkh1
tcfchan#0
# check the jtag targets connected, the IDs listed with jtag targets are called node IDs
xsdb% jtag targets 
 1 Platform Cable USB II 0000153f74cd01
 2 arm_dap (idcode 4ba00477 irlen 4)
 3 xc7z020 (idcode 03727093 irlen 6 fpga)
 4 arm_dap (idcode 4ba00477 irlen 4)
 5 xc7z045 (idcode 03731093 irlen 6 fpga)
# check the targets connected, the IDs listed with targets are called target IDs
xsdb% targets 
 1 APU
 2 ARM Cortex-A9 MPCore #0 (Suspended)
 3 ARM Cortex-A9 MPCore #1 (Suspended)
 4 xc7z020
 5 APU
 6 ARM Cortex-A9 MPCore #0 (Running)
 7 ARM Cortex-A9 MPCore #1 (Running)
 8 xc7z045
# check jtag target properties of 2nd device (2nd ARM DAP). Note the target_ctx here.
xsdb% jtag targets -target-properties -filter {node_id == 4}
{target_ctx jsn-DLC10-0000153f74cd01-4ba00477-1 level 1 node_id 4 is_open 1 is_active 1 is_current 1 name arm_dap jtag_cable_name {Platform Cable USB II 0000153f74cd01} state {} jtag_cable_manufacturer Xilinx jtag_cable_product DLC10 jtag_cable_serial 0000153f74cd01 idcode 4ba00477 irlen 4}
# using the target context, select the targets associated with the JTAG target (2nd ARM DAP - node id = 4) 
xsdb% targets -filter {jtag_device_ctx == "jsn-DLC10-0000153f74cd01-4ba00477-1"}
 5 APU
 6 ARM Cortex-A9 MPCore #0 (Running)
 7 ARM Cortex-A9 MPCore #1 (Running)

Modifying BSP Settings

Below is an example XSCT session that demonstrates building a HelloWorld application to target the MicroBlaze™ processor. The STDIN and STDOUT OS parameters are changed to use the MDM_0.

Note: When the BSP settings are changed, it is necessary to update the mss and regenerate the BSP sources to reflect the changes in the source file before compiling.
setws /tmp/wrk/workspace
app create -name mb_app -hw /tmp/wrk/kc705_system.xsa -proc microblaze_0 -os standalone -template {Hello World}
bsp config stdin mdm_0
bsp config stdout mdm_0
platform generate
app build -name mb_app

Performing Standalone Application Debug

Xilinx® System Command-line Tool (XSCT) can be used to debug standalone applications on one or more processor cores simultaneously. The first step involved in debugging is to connect to hw_server and select a debug target. You can now reset the system/processor core, initialize the PS if needed, program the FPGA, download an elf, set breakpoints, run the program, examine the stack trace, view local/global variables.

An example XSCT session that demonstrates standalone application debug on Zynq®-7000 SoC is as follows. Comments begin with #.

#connect to remote hw_server by specifying its url. 
#If the hardware is connected to a local machine,-url option and the <url> 
#are not needed. connect command returns the channel ID of the connection

xsct% connect -url TCP:xhdbfarmc7:3121 tcfchan#0

# List available targets and select a target through its id. 
#The targets are assigned IDs as they are discovered on the Jtag chain, 
#so the IDs can change from session to session. 
#For non-interactive usage, -filter option can be used to select a target, 
#instead of selecting the target through its ID

xsct% targets
  1  APU
     2  Arm Cortex-A9 MPCore #0 (Running)
     3  Arm Cortex-A9 MPCore #1 (Running)
  4  xc7z020
xsct% targets 2
# Reset the system before initializing the PS and configuring the FPGA

xsct% rst
# Info messages are displayed when the status of a core changes
Info: Arm Cortex-A9 MPCore #0 (target 2) Stopped at 0xfffffe1c (Suspended)
Info: Arm Cortex-A9 MPCore #1 (target 3) Stopped at 0xfffffe18 (Suspended)

# Configure the FPGA. When the active target is not a FPGA device, 
#the first FPGA device is configured

xsct% fpga ZC702_HwPlatform/design_1_wrapper.bit
100%    3MB   1.8MB/s  00:02

# Run loadhw command to make the debugger aware of the processor cores’ memory map   
xsct% loadhw ZC702_HwPlatform/system.xsa
design_1_wrapper

# Source the ps7_init.tcl script and run ps7_init and ps7_post_config commands
xsct% source ZC702_HwPlatform/ps7_init.tcl
xsct% ps7_init
xsct% ps7_post_config

# Download the application program
xsct% dow dhrystone/Debug/dhrystone.elf
Downloading Program -- dhrystone/Debug/dhrystone.elf
     section, .text: 0x00100000 - 0x001037f3
     section, .init: 0x001037f4 - 0x0010380b
     section, .fini: 0x0010380c - 0x00103823
     section, .rodata: 0x00103824 - 0x00103e67
     section, .data: 0x00103e68 - 0x001042db
     section, .eh_frame: 0x001042dc - 0x0010434f
     section, .mmu_tbl: 0x00108000 - 0x0010bfff
     section, .init_array: 0x0010c000 - 0x0010c007
     section, .fini_array: 0x0010c008 - 0x0010c00b
     section, .bss: 0x0010c00c - 0x0010e897
     section, .heap: 0x0010e898 - 0x0010ec9f
     section, .stack: 0x0010eca0 - 0x0011149f
100%    0MB   0.3MB/s  00:00   

Setting PC to Program Start Address 0x00100000

Successfully downloaded dhrystone/Debug/dhrystone.elf

# Set a breakpoint at main()
xsct% bpadd -addr &main
0

# Resume the processor core
xsct% con

# Info message is displayed when the core hits the breakpoint
xsct% Info: Arm Cortex-A9 MPCore #0 (target 2) Stopped at 0x1005a4 (Breakpoint)

# Registers can be viewed when the core is stopped
xsct% rrd
     r0: 00000000       r1: 00000000       r2: 0010e898       r3: 001042dc
     r4: 00000003       r5: 0000001e       r6: 0000ffff       r7: f8f00000
     r8: 00000000       r9: ffffffff      r10: 00000000      r11: 00000000
    r12: 0010fc90       sp: 0010fca0       lr: 001022d8       pc: 001005a4
   cpsr: 600000df      usr                fiq                irq         
    abt                und                svc                mon         
    vfp               cp15            Jazelle

# Memory contents can be displayed
xsct% mrd 0xe000d000
E000D000:   800A0000

# Local variables can be viewed
xsct% locals
Int_1_Loc       : 1113232
Int_2_Loc       : 30
Int_3_Loc       : 0
Ch_Index        : 0
Enum_Loc        : 0
Str_1_Loc       : char[31]
Str_2_Loc       : char[31]
Run_Index       : 1061232
Number_Of_Runs  : 2

# Local variable value can be modified
xsct% locals Number_Of_Runs 100
xsct% locals Number_Of_Runs
Number_Of_Runs  : 100

# Global variables and be displayed, and its value can be modified
xsct% print Int_Glob
Int_Glob  : 0
xsct% print -set Int_Glob 23
xsct% print Int_Glob
Int_Glob  : 23

# Expressions can be evaluated and its value can be displayed
xsct% print Int_Glob + 1 * 2
Int_Glob + 1 * 2  : 25

# Step over a line of source code
xsct% nxt
Info: Arm Cortex-A9 MPCore #0 (target 2) Stopped at 0x1005b0 (Step)

# View stack trace
xsct% bt
    0  0x1005b0 main()+12: ../src/dhry_1.c, line 91
    1  0x1022d8 _start()+88
    2  unknown-pc

# Set a breakpoint at exit and resume execution
xsct% bpadd -addr &exit
1
xsct% con
Info: Arm Cortex-A9 MPCore #0 (target 2) Running
xsct% Info: Arm Cortex-A9 MPCore #0 (target 2) Stopped at 0x103094 (Breakpoint)
xsct% bt
    0  0x103094 exit()
    1  0x1022e0 _start()+96
    2  unknown-pc

While a program is running on A9 #0, you can download another elf onto A9 #1 and debug it, using similar steps. It is not necessary to re-connect to the hw_server, initialize the PS or configure the FPGA in such cases. You can select A9 #1 target and download the elf and continue with further debug.

Generating SVF Files

SVF (Serial Vector Format) is an industry standard file format that is used to describe JTAG chain operations in a compact, portable fashion. An example XSCT script to generate an SVF file is as follows:

# Reset values of respective cores
set core 0
set apu_reset_a53 {0x380e 0x340d 0x2c0b 0x1c07}
# Generate SVF file for linking DAP to the JTAG chain
# Next 2 steps are required only for Rev2.0 silicon and above.
svf config -scan-chain {0x14738093 12 0x5ba00477 4
} -device-index 1 -linkdap -out "dapcon.svf"
svf generate
# Configure the SVF generation
svf config -scan-chain {0x14738093 12 0x5ba00477 4
} -device-index 1 -cpu-index $core -delay 10 -out "fsbl_hello.svf"
# Record writing of bootloop and release of A53 core from reset
svf mwr 0xffff0000 0x14000000
svf mwr 0xfd1a0104 [lindex $apu_reset_a53 $core]
# Record stopping the core
svf stop
# Record downloading FSBL
svf dow "fsbl.elf"
# Record executing FSBL
svf con
svf delay 100000
# Record some delay and then stopping the core
svf stop
# Record downloading the application
svf dow "hello.elf"
# Record executing application
svf con
# Generate SVF
svf generate
Note: SVF files can only be recorded using XSCT. You can use any standard SVF player to play the SVF file.

To play a SVF file in the Vivado hardware manager, connect to a target and use the following Tcl command to play the file on the selected target.

execute_hw_svf <*.svf file>

Running an Application in Non-Interactive Mode

Xilinx® System Debugger Command-line Interface (XSDB) provides a scriptable interface to run applications in non-interactive mode. To run the program in previous example using a script, create a Tcl script (and name it as, for example, test.tcl) with the following commands. The script can be run by passing it as a launch argument to XSDB.

connect -url TCP:xhdbfarmc7:3121

# Select the target whose name starts with Arm and ends with #0. 
# On Zynq, this selects “Arm Cortex-A9 MPCore #0”

targets -set -filter {name =~ "Arm* #0"}
rst
fpga ZC702_HwPlatform/design_1_wrapper.bit
loadhw ZC702_HwPlatform/system.xsa
source ZC702_HwPlatform/ps7_init.tcl
ps7_init
ps7_post_config
dow dhrystone/Debug/dhrystone.elf

# Set a breakpoint at exit

bpadd -addr &exit

# Resume execution and block until the core stops (due to breakpoint) 
# or a timeout of 5 sec is reached

con -block -timeout 5

Running Tcl Scripts

You can create Tcl scripts with XSCT commands and run them in an interactive or non-interactive mode. In the interactive mode, you can source the script at XSCT prompt. For example:

xsct% source xsct_script.tcl 

In the non-interactive mode, you can run the script by specifying the script as a launch argument. Arguments to the script can follow the script name. For example:

$ xsct xsct_script.tcl [args]

The script below provides a usage example of XSCT. This script creates and builds an application, connects to a remote hw_server, initializes the Zynq PS connected to remote host, downloads and executes the application on the target. These commands can be either scripted or run interactively.

# Set Vitis workspace
setws /tmp/workspace
# Create application project
app create -name hello -hw /tmp/wrk/system.xsa -proc ps7_cortexa9_0 -os standalone -lang C -template {Hello World}
app build -name hello hw_server
connect -host raptor-host
# Select a target
targets -set -nocase -filter {name =~ “Arm* #0}
# System Reset
rst -system
# PS7 initialization
namespace eval xsdb {source /tmp/workspace/hw1/ps7_init.tcl; ps7_init}
# Download the elf
dow /tmp/workspace/hello/Debug/hello.elf
# Insert a breakpoint @ main
bpadd -addr &main
# Continue execution until the target is suspended
con -block -timeout 500
# Print the target registers
puts [rrd]
# Resume the target
con

Switching Between XSCT and Vitis Integrated Development Environment

Below is an example XSCT session that demonstrates creating and building an application using XSCT. After execution, launch the Vitis development environment and select the workspace created using XSCT to view the updates.

Note: The workspace created in XSCT can be used from Vitis IDE. However, at a time, only one instance of the tool can use the workspace.
# Set Vitis workspace
setws /tmp/workspace
# Create application project
app create -name hello -hw /tmp/wrk/system.xsa -proc ps7_cortexa9_0 -os standalone -lang C -template {Hello World}
app build -name hello
 

Using JTAG UART

XSDB supports virtual UART through JTAG, which is useful when the physical UART does not exist or is non-functional. To use JTAG UART, the software application should be modified to redirect STDIO to the JTAG UART. Vitis IDE provides a CoreSight™ driver to support redirecting of STDIO to virtual UART on Arm based designs. For MB designs, the uartlite driver can be used. To use the virtual UART driver, open board support settings in Vitis IDE and can change STDIN / STDOUT to coresight/mdm.

XSDB supports virtual UART through two commands.

  • jtagterminal - Start/Stop JTAG based hyper-terminal. This command opens a new terminal window for STDIO. The text input from this terminal will be sent to STDIN and any output from STDOUT will be displayed on this terminal.
  • readjtaguart - Start/Stop reading from JTAG UART. This command starts polling STDOUT for output and displays in on XSDB terminal or redirects it to a file.

An example XSCT session that demonstrates how to use a JTAG terminal for STDIO is as follows:

connect
source ps7_init.tcl
targets -set -filter {name =~"APU"}
loadhw system.xsa
stop
ps7_init
targets -set -nocase -filter {name =~ "Arm*#0"}
rst –processor
dow <app>.elf
jtagterminal
con
jtagterminal -stop #after you are done  

An example XSCT session that demonstrates how to use the XSCT console as STDOUT for JTAG UART is as follows:

connect
source ps7_init.tcl
targets -set -filter {name =~"APU"}
loadhw system.xsa
stop
ps7_init
targets -set -nocase -filter {name =~ "Arm*#0"}
rst –processor
dow <app>.elf
readjtaguart
con
readjtaguart -stop #after you are done

An example XSCT session that demonstrates how to redirect the STDOUT from JTAG UART to a file is as follows:

connect
source ps7_init.tcl
targets -set -filter {name =~"APU"}
loadhw system.xsa
stop
ps7_init
targets -set -nocase -filter {name =~ "Arm*#0"}
rst –processor
dow <app>.elf
set fp [open uart.log w]
readjtaguart -handle $fp
con
readjtaguart -stop #after you are done

Working with Libraries

An example XSCT session that demonstrates creating a default domain and adding XILFFS and XILRSA libraries to the BSP is as follows. Create a FSBL application thereafter.

Note: A normal domain/BSP does not contain any libraries.
setws /tmp/wrk/workspace
app create -name hello -hw /tmp/wrk/system.xsa -proc ps7_cortexa9_0 -os standalone -lang C -template {Hello World}
bsp setlib -name xilffs
bsp setlib -name xilrsa
platform generate
app build -name hello 

Changing the OS version.

bsp setosversion -ver 6.6

Assigning a driver to an IP.

bsp setdriver -ip ps7_uart_1 -driver generic -ver 2.0

Removing a library (removes xilrsa library from the domain/BSP).

bsp removelib -name xilrsa

Editing FSBL/PMUFW Source File

The following example shows you how to edit FSBL/PMUFW source files.

setws workspace
app create -name a53_app -hw zcu102 -os standalone -proc psu_cortexa53_0
#Go to “workspace/zcu102/zynqmp_fsbl” or “workspace/zcu102/zynqmp_pmufw”  and modify the source files using any editor like gedit or gvim for boot domains zynqmp_fsbl and zynqmp_pmufw.
platform generate

Editing FSBL/PMUFW Settings

The following example shows you how to edit FSBL/PMUFW settings.

setws workspace
app create -name a53_app -hw zcu102 -os standalone -proc psu_cortexa53_0
#If you want to modify anything in zynqmp_fsbl domain use below command to active that domain
domain active zynqmp_fsbl
#If you want to modify anything in zynqmp_pmufw domain use below command to active that domain
domain active zynqmp_pmufw
#configure the BSP settings for boot domain like FSBL or PMUFW
bsp config -append compiler_flags -DFSBL_DEBUG_INFO
platform generate

Exchanging Files between Host Machine and Linux running on QEMU

XSCT tfile can be used to communicate with the tcf-agent running in Linux to transfer files. To exchange file between host machine and Linux in QEMU, follow these steps:
  1. Launch QEMU from Vitis GUI by selecting Xilinx > Start/Stop Emulator. QEMU is launched to boot Linux. The tcf-agent runs in the backend when Linux finishes booting. It is required to include the tcf-agent in the Linux root file system configuration in PetaLinux.
  2. Launch XSCT and use the following commands to exchange file:
    1. Connect to the tcf-agent using XSCT:
      connect -host 127.0.0.1 -port 1440
      Note: 1440 is port forwarded by QEMU.
    2. Copy file from host to target:
      tfile copy -from-host <host_path> <target_path>
    3. Copy file from target to host:
      tfile copy -to-host <target_path> <host_path>