[[TOC(Debugging/OpenOCD/BeagleBoneBlack, depth=3)]] = OpenOCD Support for !BeagleBone Black = OpenOCD supports the [http://beagleboard.org/black BeagleBone Black] board that use the [https://www.ti.com/product/am3358 TI AM3358] SOC. The support is in the OpenOCD source and you can you can create a suitable environment. At the time of writing this page I am using the latest GIT version of OpenOCD. The !BeagleBone Black board as shipped has pad on the underside for JTAG. You need to solder a header on to the board so a suitable JTAG cable can be connected. It does require a small level of soldering skill but do not be put off by this. The main OpenOCD page details [wiki:Debugging/OpenOCD how to build OpenOCD from GIT]. == Flyswatter2 for the !BeagleBone Black == Tincan Tools provides a [http://www.tincantools.com/JTAG/BeagleBone-Black-JTAG-Adapter-Kit.html BeagleBone Black JTAG Adapter Kit] and detailed instructions on their wiki describing [https://www.tincantools.com/wiki/Flyswatter2_BeagleBone_Black_How_To how to install the JTAG Adapter Kit]. The kit and the Flyswatter2 pod provide an accessible way to get JTAG debugging. = !BeagleBone Initialization = An RTEMS application runs in the DDR memory and in production the uBoot bootloader initializes the AM3358 SOC device and the connected hardware before loading the executable from local storage or over the network into the DDR memory and passing control to RTEMS entry point. JTAG needs to emulate the bootloader process and there are a number of ways this can be done. 1. Directly access the SOC registers to initialize the hardware 2. Use uBoot to perform initialize the hardware Directly accessing the SOC is fast and direct however it requires you detail all the set up required. This can often be more than writing the DDR controller registers to enable the DDR memory, it can also require the configuration of clocks and bus configuration hardware. Getting this right can be time consuming and complex. uBoot contains all the required SOC set up however uBoot is designed to boot the processor so while loading and executing uBoot is easy, it can often be tricky stopping after the hardware is initialized to regain control. There are couple of methods that can be used, the first is to make sure uBoot cannot load any executable so it runs and stops. You can load the first stage of uBoot and start it executing, wait a while then halt the target. The second method is to have a look into uBoot and find a suitable place to stop it and to set a breakpoint. This requires a little investigation because the location can be different for each uBoot. There is another small complication with the AM3358 SOC. The hardware watchdog is enabled after reset and this means resetting the SOC via JTAG will result in the SOC resetting after approximately 6 seconds. The watchdog device needs to be disabled and this can be done 2 ways, the first is in the OpenOCD BBB support where the watchdog registers are updated to disable the watchdog or you can let the SOC ROM based initialization code run which also disables the watchdog. Once the watchdog reset has been disabled and the DDR memory is initialized you can load the RTEMS ELF executable using GDB and start it executing. = OpenOCD Configuration = Tincan tools provides a TCL configuration file to use with OpenOCD. Download [https://www.tincantools.com/wiki/Flyswatter2_BeagleBone_Black_How_To#The_BeagleBone_Black_Config_File !BeagleBone Black Config File] from Tincan Tool's wiki and save. Create a configuration file with an editor containing: {{{ source [find interface/ftdi/flyswatter2.cfg] source [find ti_beaglebone_with_fs2.cfg] telnet_port 4445 tcl_port 6667 gdb_port 3334 proc bbb_restart { } { reset halt bp 0x402f0400 4 hw reset run sleep 300 rbp 0x402f0400 } init }}} The script defines `bbb_restart` which executes the SOC's ROM code disabling the watchdog. The address `0x402f0400` is the entry the ROM code calls once it has finished it's initialization and it has loaded uBoot's MLO first stage loader. Start OpenOCD with: {{{ # sudo openocd -f bbb-fs.cfg }}} == Initializing with uBoot == The following details how to initialize the SOC using uBoot. For this you need to get uBoot from git and to build it for the !BeagleBone Black. The initialization is done by GDB calling OpenOCD's monitor interface. This approach lets you provide a personal specific initialization which is useful if you are sharing hardware on a network with a team. In your home directory create or edit your `.gdbinit` file adding: {{{ def target-connect-fs echo JTAG FS\n set $TARGET_JTAG = 1 set $TARGET_REMOTE = "kaka:3333" end def target-connect target remote $TARGET_REMOTE end def bbb-restart if $TARGET_JTAG mon echo "] BBB Restart..." mon cortex_a dacrfixup on mon cortex_a maskisr on mon reset halt mon bp 0x402f0400 4 hw mon reset run mon sleep 1000 mon rbp 0x402f0400 mon echo "] Loading MLO" # EDIT to a path for your uBoot MLO loader mon load_image /opt/src/rtems/beagle/black/u-boot-spl-nodtb.bin 0x402f0400 bin mon bp 0x402f1424 4 hw mon resume 0x402f0400 mon sleep 1000 # EDIT to match your uBoot mon rbp 0x402f1424 end end }}} The first GDB script function added is `target-connect-fs`. This is called by your application's generic `.gdbinit` script. It is a simple way to manage team access to shared debugging resources without polluting your application's repository with network specific debugging configurations. The remote target in my configuration is `kaka:3333`, this is the server on my networking the Flyswatter2 pod is connected to and is running OpenOCD. The port is the OpenOCD default GDB server port of `3333` and that matches the OpenOCD configuration above. The second GDB script function restarts the BBB. GDB passes `mon` commands to the target monitor. The first two monitor commands are important when debugging RTEMS. The first command is `mon cortex_a dacrfixup on` and it tells OpenOCD to enable all domains in the Domain Access Control registers. Without this OpenOCD will get data aborts when writing to the DDR after RTEMS has enabled the MMU. The second command `mon cortex_a maskisr on` tells OpenOCD that RTEMS can vector to an interrupt handler when a step is taken. Without this command a step will result in you stepping into highest priority interrupt and that gets a little boring when the timer interrupt is enabled. The following monitor commands: 1. Reset and halt the SOC 2. Run the SOC's ROM code to disable the watchdog and perform any other low level initialization 3. Load uBoot's MLO first stage loader, which is called SPL in uBoot source and build 4. Set a break to the instruction after the function `TODO find function name`. 5. Run uBoot's MLO until the breakpoint 6. Remove the breakpoint Once this has run the hardware is ready to load an RTEMS application. = GDB Configuration = GDB is initialized with the following script: {{{ target-connect-fs target-connect bbb-restart echo ] Loading RTEMS exe ...\n load # Catch any exit paths b exit b _exit b bsp_reset b bsp_fatal_extension # Uncomment if Init is the entry point tb Init # Uncomment if main is the entry point #tb main c }}}