mirror of
https://git.rtems.org/rtems-docs/
synced 2025-05-31 07:51:24 +08:00
user: Add xilinx-zynq BSP details
This commit is contained in:
parent
ba9dfcf92c
commit
75f51d67e0
@ -1,8 +1,118 @@
|
||||
.. SPDX-License-Identifier: CC-BY-SA-4.0
|
||||
|
||||
.. Copyright (C) 2019 TBD
|
||||
.. Copyright (C) 2020 Chris Johns (chrisj@rtems.org)
|
||||
|
||||
xilinx-zynq
|
||||
===========
|
||||
|
||||
TODO.
|
||||
This BSP supports the Xilinx Zynq range of devices. This family of
|
||||
devices contain the same ARM hard IP and the different parts have
|
||||
different sizes of programable logic.
|
||||
|
||||
The BSP defaults may need to be adjusted using ``configure`` BSP
|
||||
options to match the size of memory your board may have.
|
||||
|
||||
Bootloader
|
||||
----------
|
||||
|
||||
The bootloader initialises the Zynq device. The Xilinx tool provide an
|
||||
interface to configure the hardware. This is includes the buses,
|
||||
clocks, memory and UART board rate. The output of this is called
|
||||
``ps7_init`` and it a C file. The Xilinx SDK builds a first stage boot
|
||||
loader (FSBL) using this file.
|
||||
|
||||
The U-Boot boot loader has it's own FSBL called ``MLO`` to initialise
|
||||
the hardware.
|
||||
|
||||
Clocks
|
||||
------
|
||||
|
||||
An application can provide a function called:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
uint32_t a9mpcore_clock_periphclk(void);
|
||||
|
||||
to return the peripheral clock. Normally this is half the CPU
|
||||
clock. This function is declared ``weak`` so you can override the
|
||||
default behaviour by providing it in your application.
|
||||
|
||||
Debugging with xilinx_zynq_a9_qemu
|
||||
----------------------------------
|
||||
|
||||
To debug an application add the QEMU options ``-s``. If you need to
|
||||
debug an initialisation issue also add ``-S``. For example to debug a
|
||||
networking application you could use:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
qemu-system-arm -M xilinx-zynq-a9 -m 256M -no-reboot -serial \
|
||||
null -serial mon:stdio -nographic \
|
||||
-net nic,model=cadence_gem -net vde,id=vde0,sock=/tmp/vde1 \
|
||||
-kernel myapp.exe \
|
||||
-s -S
|
||||
|
||||
Start GDB with the same executable QEMU is running and connect to the
|
||||
QEMU GDB server:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
(gdb) target remote :1234
|
||||
|
||||
If your application is crashing set a breakpoint on the fatal error
|
||||
handler:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
(gdb) b bsp_fatal_extension
|
||||
|
||||
Enter continue to run the application. Running QEMU loads the
|
||||
executable and initialises the CPU. If the ``-S`` option is provided
|
||||
the CPU is held in reset. Without the option the CPU runs starting
|
||||
RTEMS. Either way you are connecting to set up target and all you need
|
||||
to do is continue:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
(gdb) c
|
||||
|
||||
If you have a crash and the breakpoint on ``bsp_fatal_extension`` is
|
||||
hit, load the following a GDB script:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
define arm-crash
|
||||
set $code = $arg0
|
||||
set $r0 = ((const rtems_exception_frame *) $code)->register_r0
|
||||
set $r1 = ((const rtems_exception_frame *) $code)->register_r1
|
||||
set $r2 = ((const rtems_exception_frame *) $code)->register_r2
|
||||
set $r3 = ((const rtems_exception_frame *) $code)->register_r3
|
||||
set $r4 = ((const rtems_exception_frame *) $code)->register_r4
|
||||
set $r5 = ((const rtems_exception_frame *) $code)->register_r5
|
||||
set $r6 = ((const rtems_exception_frame *) $code)->register_r6
|
||||
set $r7 = ((const rtems_exception_frame *) $code)->register_r7
|
||||
set $r8 = ((const rtems_exception_frame *) $code)->register_r8
|
||||
set $r9 = ((const rtems_exception_frame *) $code)->register_r9
|
||||
set $r10 = ((const rtems_exception_frame *) $code)->register_r10
|
||||
set $r11 = ((const rtems_exception_frame *) $code)->register_r11
|
||||
set $r12 = ((const rtems_exception_frame *) $code)->register_r12
|
||||
set $sp = ((const rtems_exception_frame *) $code)->register_sp
|
||||
set $lr = ((const rtems_exception_frame *) $code)->register_lr
|
||||
set $pc = ((const rtems_exception_frame *) $code)->register_pc
|
||||
set $cpsr = ((const rtems_exception_frame *) $code)->register_cpsr
|
||||
end
|
||||
|
||||
Enter the command:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
(gdb) arm-crash code
|
||||
|
||||
|
||||
Enter ``bt`` to see the stack back trace.
|
||||
|
||||
The script moves the context back to the crash location. You should be
|
||||
able to view variables and inspect the stack.
|
||||
|
||||
The fatal error handler runs inside an exception context that is not
|
||||
the one than generated the exception.
|
||||
|
Loading…
x
Reference in New Issue
Block a user