{"id":620,"date":"2020-02-04T15:59:47","date_gmt":"2020-02-04T21:59:47","guid":{"rendered":"https:\/\/jacobncalvert.com\/?p=620"},"modified":"2020-02-04T15:59:49","modified_gmt":"2020-02-04T21:59:49","slug":"jtag-on-the-cheap-with-the-ftdi-ft232r","status":"publish","type":"post","link":"https:\/\/jacobncalvert.com\/blog-archive\/2020\/02\/04\/jtag-on-the-cheap-with-the-ftdi-ft232r\/","title":{"rendered":"JTAG On the Cheap with the FTDI FT232R"},"content":{"rendered":"\n<h2>JTAG 101<\/h2>\n\n\n\n<h3>What is it?<\/h3>\n\n\n\n<p>JTAG stands for the Joint Test Action Group, and the TAP or Test Access Port this group defined is one of the most (if not <strong><em>the<\/em><\/strong> most) common way to program and debug embedded devices and computers of all flavors. For the professional, JTAG devices are bountiful and usually not too much of a strain on the commercial budget. But for the hobbyist, things aren&#8217;t so peachy. A <a href=\"https:\/\/www.segger.com\/products\/debug-probes\/j-link\/models\/j-link-edu\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">Segger J-Link EDU can be had for ~$70 USD<\/a> shipped, but the full featured J-Link is still ~$400, which is more than I want to pay as a hobbyist.<\/p>\n\n\n\n<h3>What does it do?<\/h3>\n\n\n\n<p>The JTAG TAP port consists of a few standard signals which essentially give you complete control over the systems in the JTAG <em>chain<\/em>. The chain is exactly what it sounds like: multiple devices which support JTAG chaining can be chained up and accessed from a single JTAG port. Need that flash programmed? JTAG can do that. Need to debug that microcontroller? JTAG can do that too. Want to do both without switching out tools? Yep, JTAG can do it. See <a href=\"https:\/\/en.wikipedia.org\/wiki\/JTAG#\/media\/File:Jtag_chain.svg\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">this helpful diagram at Wikipedia<\/a> for a visual representation.<\/p>\n\n\n\n<h2>JTAG for the Hobbyist<\/h2>\n\n\n\n<p>Chances are that you&#8217;ve got an USB -> Serial cable or breakout board lying around somewhere in your hoard. Chances are also, that it&#8217;s based on the wildly popular FTDI FT232R or a similar FT232-esque chip which converts USB to RS232. If you&#8217;re lucky enough to have this essential piece of hobbyist equipment, you&#8217;ve got a USB->JTAG adapter waiting to be unlocked!<\/p>\n\n\n\n<h3>Enter OpenOCD<\/h3>\n\n\n\n<p>OpenOCD (Open On-chip Debugger) is a fantastic project which aims to create an open and extensible OCD solution for all, and lucky for us, this includes the hobbyist! The <a rel=\"noreferrer noopener\" aria-label=\"OpenOCD project (opens in a new tab)\" href=\"http:\/\/openocd.org\/\" target=\"_blank\">OpenOCD project<\/a> defines interfaces between the common parts of the OCD process, such as the target board or device, the OCD device used, etc., and using these well-defined interfaces is able to create a modular system which can support many different targets and debuggers with only a configuration change. This is a simplification of how this works, but it is sufficient to understand what we want to do with it. <\/p>\n\n\n\n<p>So back to the FT232R. This little chip can be re-configured to use the RS232 signals as bit-banged JTAG signals, and OpenOCD can drive it. Even better, once the OpenOCD agent is up and running, we can then use GDB to connect to and drive our debug efforts. This mode of operation is detailed over <a rel=\"noreferrer noopener\" aria-label=\"at their documentation site. (opens in a new tab)\" href=\"http:\/\/www.openocd.org\/doc\/html\/Debug-Adapter-Configuration.html\" target=\"_blank\">at their documentation site (hint: search for ft232r).<\/a> <\/p>\n\n\n\n<p>The OpenOCD tool can usually be installed with your package manager on Linux. I&#8217;m running Linux Mint, so I apt install&#8217;d openocd. When I ran the tool pointing to the ft232r config file, it complained that it was not a supported interface&#8230; so I guess we&#8217;ll build from source!<\/p>\n\n\n\n<h3>Building OpenOCD with the Right Interfaces<\/h3>\n\n\n\n<p>All we need to do is build OpenOCD from source with the right interfaces enabled and we can make it work. What follows next is my step-by-step on doing this. I&#8217;m doing this in \/tmp just so I can recreate the steps I did earlier in my apps directory. <\/p>\n\n\n\n<h4>Grab the Source<\/h4>\n\n\n\n<p>Go get the source from the <a rel=\"noreferrer noopener\" aria-label=\"GitHub mirror here (opens in a new tab)\" href=\"https:\/\/github.com\/ntfreak\/openocd.git\" target=\"_blank\">GitHub mirror here<\/a> and drop it in a working directory. I would also read the README for any dependencies you didn&#8217;t have already on your machine.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\njacob@jacob-aspire-mint:\/tmp$ git clone https:\/\/github.com\/ntfreak\/openocd.git\nCloning into 'openocd'...\nremote: Enumerating objects: 74, done.\nremote: Counting objects: 100% (74\/74), done.\nremote: Compressing objects: 100% (53\/53), done.\nremote: Total 62845 (delta 36), reused 50 (delta 21), pack-reused 62771\nReceiving objects: 100% (62845\/62845), 24.17 MiB | 24.90 MiB\/s, done.\nResolving deltas: 100% (51571\/51571), done.\njacob@jacob-aspire-mint:\/tmp$ \n\n<\/pre><\/div>\n\n\n<h4>Run the bootstrapper<\/h4>\n\n\n\n<p>This little piece of code essentially checks that your build environment is sane and you have all the tools needed to build OpenOCD. Output is  below,  you should come away with no errors. <\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\njacob@jacob-aspire-mint:\/tmp\/openocd$ .\/bootstrap \n+ aclocal\n+ libtoolize --automake --copy\n+ autoconf\n+ autoheader\n+ automake --gnu --add-missing --copy\nconfigure.ac:26: installing '.\/compile'\nconfigure.ac:37: installing '.\/config.guess'\nconfigure.ac:37: installing '.\/config.sub'\nconfigure.ac:16: installing '.\/install-sh'\nconfigure.ac:16: installing '.\/missing'\nMakefile.am:46: warning: wildcard $(srcdir: non-POSIX variable name\nMakefile.am:46: (probably a GNU make extension)\nMakefile.am: installing '.\/INSTALL'\nMakefile.am: installing '.\/depcomp'\nMakefile.am:23: installing '.\/mdate-sh'\nMakefile.am:23: installing '.\/texinfo.tex'\nSetting up submodules\nSubmodule 'jimtcl' (http:\/\/repo.or.cz\/r\/jimtcl.git) registered for path 'jimtcl'\nSubmodule 'src\/jtag\/drivers\/libjaylink' (http:\/\/repo.or.cz\/r\/libjaylink.git) registered for path 'src\/jtag\/drivers\/libjaylink'\nSubmodule 'tools\/git2cl' (http:\/\/repo.or.cz\/r\/git2cl.git) registered for path 'tools\/git2cl'\nCloning into '\/tmp\/openocd\/jimtcl'...\nwarning: redirecting to https:\/\/repo.or.cz\/r\/jimtcl.git\/\nCloning into '\/tmp\/openocd\/src\/jtag\/drivers\/libjaylink'...\nwarning: redirecting to https:\/\/repo.or.cz\/r\/libjaylink.git\/\nCloning into '\/tmp\/openocd\/tools\/git2cl'...\nwarning: redirecting to https:\/\/repo.or.cz\/r\/git2cl.git\/\nSubmodule path 'jimtcl': checked out 'a9bf5975fd0f89974d689a2d9ebd0873c8d64787'\nSubmodule path 'src\/jtag\/drivers\/libjaylink': checked out 'f73ad5e667ae8b26a52b847c603fdadaabf302a6'\nSubmodule path 'tools\/git2cl': checked out '8373c9f74993e218a08819cbcdbab3f3564bbeba'\nGenerating build system...\nlibtoolize: putting auxiliary files in AC_CONFIG_AUX_DIR, 'build-aux'.\nlibtoolize: copying file 'build-aux\/config.guess'\nlibtoolize: copying file 'build-aux\/config.sub'\nlibtoolize: copying file 'build-aux\/install-sh'\nlibtoolize: copying file 'build-aux\/ltmain.sh'\nlibtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'm4'.\nlibtoolize: copying file 'm4\/libtool.m4'\nlibtoolize: copying file 'm4\/ltoptions.m4'\nlibtoolize: copying file 'm4\/ltsugar.m4'\nlibtoolize: copying file 'm4\/ltversion.m4'\nlibtoolize: copying file 'm4\/lt~obsolete.m4'\nconfigure.ac:42: installing 'build-aux\/ar-lib'\nconfigure.ac:37: installing 'build-aux\/compile'\nconfigure.ac:30: installing 'build-aux\/missing'\nMakefile.am: installing '.\/INSTALL'\nlibjaylink\/Makefile.am: installing 'build-aux\/depcomp'\nBootstrap complete. Quick build instructions:\n.\/configure ....\njacob@jacob-aspire-mint:\/tmp\/openocd$ \n<\/pre><\/div>\n\n\n<h4>Run the configure script<\/h4>\n\n\n\n<p>This is where we determine that we want the FTDI FT232R to be supported. We do this by adding a flag to the configure line. Output is cut short in the middle because it&#8217;s quite long, but the important part is at the end.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\njacob@jacob-aspire-mint:\/tmp\/openocd$ .\/configure --enable-ft232r \nchecking for makeinfo... no\nconfigure: WARNING: Info documentation will not be built.\nchecking for a BSD-compatible install... \/usr\/bin\/install -c\nchecking whether build environment is sane... yes\nchecking for a thread-safe mkdir -p... \/bin\/mkdir -p\nchecking for gawk... gawk\n\n&#91; ... snip ... ]\n\nlibjaylink configuration summary:\n - Package version ................ 0.2.0-git-f73ad5e\n - Library version ................ 0:0:0\n - Installation prefix ............ \/usr\/local\n - Building on .................... x86_64-pc-linux-gnu\n - Building for ................... x86_64-pc-linux-gnu\n\nEnabled transports:\n - USB ............................ yes\n - TCP ............................ yes\n\n\n\nOpenOCD configuration summary\n--------------------------------------------------\nMPSSE mode of FTDI based devices        yes (auto)\nST-Link Programmer                      yes (auto)\nTI ICDI JTAG Programmer                 yes (auto)\nKeil ULINK JTAG Programmer              yes (auto)\nAltera USB-Blaster II Compatible        yes (auto)\nBitbang mode of FT232R based devices    yes\nVersaloon-Link JTAG Programmer          yes (auto)\nTI XDS110 Debug Probe                   yes (auto)\nOSBDM (JTAG only) Programmer            yes (auto)\neStick\/opendous JTAG Programmer         yes (auto)\nAndes JTAG Programmer                   yes (auto)\nUSBProg JTAG Programmer                 no\nRaisonance RLink JTAG Programmer        no\nOlimex ARM-JTAG-EW Programmer           no\nCMSIS-DAP Compliant Debugger            no\nCypress KitProg Programmer              no\nAltera USB-Blaster Compatible           no\nASIX Presto Adapter                     no\nOpenJTAG Adapter                        no\nSEGGER J-Link Programmer                yes (auto)\n\n<\/pre><\/div>\n\n\n<h4>Build it<\/h4>\n\n\n\n<p>Finally, we build it. Again, I&#8217;m snipping the output down to size, but you should end up with an executable binary in src\/ called openocd. This final step doesn&#8217;t take long (on my machine only about 45s). <\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\njacob@jacob-aspire-mint:\/tmp\/openocd$ make\nMakefile:4634: warning: overriding recipe for target 'check-recursive'\nMakefile:4045: warning: ignoring old recipe for target 'check-recursive'\ncat src\/helper\/startup.tcl src\/jtag\/startup.tcl src\/target\/startup.tcl src\/server\/startup.tcl src\/flash\/startup.tcl | .\/src\/helper\/bin2char.sh &gt; src\/startup_tcl.inc || { rm -f src\/startup_tcl.inc; false; }\ncp src\/jtag\/drivers\/minidriver_imp.h src\/jtag\/minidriver_imp.h\nmake  all-recursive\nmake&#91;1]: Entering directory '\/tmp\/openocd'\nMakefile:4634: warning: overriding recipe for target 'check-recursive'\nMakefile:4045: warning: ignoring old recipe for target 'check-recursive'\nMaking all in jimtcl\nmake&#91;2]: Entering directory '\/tmp\/openocd\/jimtcl'\n\n\n&#91; ... snip ... ]\n\nlibtool: link: ranlib src\/.libs\/libopenocd.a\nlibtool: link: rm -fr src\/.libs\/libopenocd.lax src\/.libs\/libopenocd.lax\nlibtool: link: ( cd &quot;src\/.libs&quot; &amp;&amp; rm -f &quot;libopenocd.la&quot; &amp;&amp; ln -s &quot;..\/libopenocd.la&quot; &quot;libopenocd.la&quot; )\ndepbase=`echo src\/main.o | sed 's|&#91;^\/]*$|.deps\/&amp;|;s|\\.o$||'`;\\\ngcc -DHAVE_CONFIG_H -I.   -I.\/src -I.\/src -I.\/src\/helper -DPKGDATADIR=\\&quot;\/usr\/local\/share\/openocd\\&quot; -DBINDIR=\\&quot;\/usr\/local\/bin\\&quot; -I.\/jimtcl -I.\/jimtcl  -Wall -Wstrict-prototypes -Wformat-security -Wshadow -Wextra -Wno-unused-parameter -Wbad-function-cast -Wcast-align -Wredundant-decls -Werror -g -O2 -MT src\/main.o -MD -MP -MF $depbase.Tpo -c -o src\/main.o src\/main.c &amp;&amp;\\\nmv -f $depbase.Tpo $depbase.Po\n\/bin\/bash .\/libtool  --tag=CC   --mode=link gcc -Wall -Wstrict-prototypes -Wformat-security -Wshadow -Wextra -Wno-unused-parameter -Wbad-function-cast -Wcast-align -Wredundant-decls -Werror -g -O2   -o src\/openocd src\/main.o src\/libopenocd.la  .\/jimtcl\/libjim.a  -ldl \nlibtool: link: gcc -Wall -Wstrict-prototypes -Wformat-security -Wshadow -Wextra -Wno-unused-parameter -Wbad-function-cast -Wcast-align -Wredundant-decls -Werror -g -O2 -o src\/openocd src\/main.o  src\/.libs\/libopenocd.a -lusb-1.0 -lm .\/jimtcl\/libjim.a -ldl\nmake&#91;2]: Leaving directory '\/tmp\/openocd'\nmake&#91;1]: Leaving directory '\/tmp\/openocd'\n<\/pre><\/div>\n\n\n<h3>Testing OpenOCD<\/h3>\n\n\n\n<p>Now that we have a binary, we need to test it out and see if it works. My target for today is a Raspberry Pi 3 B. We first need to gather some info about our <em>target<\/em>, i.e., the Raspberry Pi 3. We need to know which pins on the GPIO header correspond to which JTAG signals. <\/p>\n\n\n\n<p>First let&#8217;s grab the BCM2835 pinout reference. (<em>Side note: we use the BCM2835 reference because there is no BCM2837 reference, and it seems the pinouts are roughly the same.<\/em>) This will tell us what each GPIO pin does. Some of the GPIOs are only designated for one singular function, whereas many other GPIOs are multi-function, and their function is software programmable. These alternate functions are designated ALT on the reference material. I used the <a rel=\"noreferrer noopener\" aria-label=\"reference over at e-Linux  (opens in a new tab)\" href=\"https:\/\/elinux.org\/RPi_BCM2835_GPIOs\" target=\"_blank\">reference over at e-Linux <\/a>because I find the table easy to read. Searching the table, we find the JTAG signals we&#8217;re interested in (TRST, TCK, TMS, TDI, TDO) are assigned in the range of GPIOs 22-27 for the ALT4 function. Next we want to pull up <a rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\" href=\"https:\/\/www.raspberrypi.org\/documentation\/hardware\/raspberrypi\/schematics\/rpi_SCH_3b_1p2_reduced.pdf\" target=\"_blank\">the schematic of our Raspberry Pi 3 B<\/a>, and see what each of those map to on the GPIO header. I&#8217;ve created the table below to keep things straight.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"\"><tbody><tr><td><strong>JTAG Signal<\/strong><\/td><td><strong>BCM283x GPIO #<\/strong><\/td><td><strong>Raspberry Pi 3B J8 Pin #<\/strong><\/td><\/tr><tr><td>TRST<\/td><td>GPIO22<\/td><td>P15<\/td><\/tr><tr><td>TCK<\/td><td>GPIO25<\/td><td>P22<\/td><\/tr><tr><td>TMS<\/td><td>GPIO27<\/td><td>P13<\/td><\/tr><tr><td>TDI<\/td><td>GPIO26<\/td><td>P37<\/td><\/tr><tr><td>TDO<\/td><td>GPIO24<\/td><td>P18<\/td><\/tr><tr><td>GND<\/td><td>many<\/td><td>P6<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Once we&#8217;ve got these figured out we&#8217;ve got to prep the Pi for JTAG usage. This is the simplest part in the whole setup. On the Pi&#8217;s SD card, add the following line to the config.txt. <\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nenable_jtag_gpio=1\n<\/pre><\/div>\n\n\n<p>Finally, we&#8217;re ready to hook up our JTAG debugger. Looking in the documentation for the OpenOCD FT232R configuration, we find the following table which shows us which RS232 signals correspond to which JTAG signals. We need to (powered down of course!) hook up our FT232R module\/cable and Pi accordingly, and don&#8217;t forget the ground wire!<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\n    - RXD(5) - TDI\n    - TXD(1) - TCK\n    - RTS(3) - TDO\n    - CTS(11) - TMS\n    - DTR(2) - TRST\n    - DCD(10) - SRST \n<\/pre><\/div>\n\n\n<p>Once things are hooked up, we need to setup our configuration for the OpenOCD tool. The default config from the ft232r.cfg is sufficient for the interface, but I wanted to add one item and to get us debugging we need to tell OpenOCD how to connect to the Pi and its four cores. I&#8217;ve based my rpi3b.cfg config off of a fellow <a rel=\"noreferrer noopener\" aria-label=\"GitHub contributor's config (opens in a new tab)\" href=\"https:\/\/github.com\/metebalci\/baremetal-rpi\/blob\/master\/rpi3.cfg\" target=\"_blank\">GitHub contributor&#8217;s config<\/a> but made some modifications. <\/p>\n\n\n\n<h4>ft232r.cfg<\/h4>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nadapter driver ft232r\nadapter speed 3000\nft232r_restore_serial 0x15\n\n<\/pre><\/div>\n\n\n<p>I modified the ft232r.cfg to increase the adapter speed to 3M (3000 kHz) and to restore the port config when OpenOCD is done so the adapter can be used as a serial device again. <\/p>\n\n\n\n<h4>rpi3b.cfg<\/h4>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ntransport select jtag\n\nadapter speed 3000\n\nreset_config trst_and_srst\n\njtag_ntrst_delay 500\n\nif { &#91;info exists CHIPNAME] } {\n  set _CHIPNAME $CHIPNAME\n} else {\n  set _CHIPNAME rpi3\n}\n\nif { &#91;info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME tap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -enable\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.tap\n\nset _TARGETNAME $_CHIPNAME.a53\nset _CTINAME $_CHIPNAME.cti\n\nset DBGBASE {0x80010000 0x80012000 0x80014000 0x80016000}\nset CTIBASE {0x80018000 0x80019000 0x8001a000 0x8001b000}\nset _cores 4\n\nfor { set _core 0 } { $_core &lt; $_cores } { incr _core } {\n\n    cti create $_CTINAME.$_core -dap $_CHIPNAME.dap -ap-num 0 \\\n        -ctibase &#91;lindex $CTIBASE $_core]\n\n    target create $_TARGETNAME.$_core aarch64 \\\n        -dap $_CHIPNAME.dap -coreid $_core \\\n        -dbgbase &#91;lindex $DBGBASE $_core] -cti $_CTINAME.$_core\n\n    $_TARGETNAME.$_core configure -event reset-assert-post &quot;aarch64 dbginit&quot;\n}\n\n<\/pre><\/div>\n\n\n<h2>Putting it All Together<\/h2>\n\n\n\n<p>Now we have all the pieces we need to debug using our JTAG adapter. Let&#8217;s begin!<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\njacob@jacob-aspire-mint:\/opt\/apps\/openocd$ sudo .\/src\/openocd -f .\/ft232r.cfg -f .\/rpi3b.cfg \nOpen On-Chip Debugger 0.10.0+dev-01047-g09ac9ab1 (2020-02-04-09:11)\nLicensed under GNU GPL v2\nFor bug reports, read\n\thttp:\/\/openocd.org\/doc\/doxygen\/bugs.html\nInfo : only one transport option; autoselect 'jtag'\nFT232R restore serial: 0x0015 (enabled)\n\nWarn : Transport &quot;jtag&quot; was already selected\nInfo : Listening on port 6666 for tcl connections\nInfo : Listening on port 4444 for telnet connections\nInfo : clock speed 3000 kHz\nInfo : JTAG tap: rpi3.tap tap\/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd.), part: 0xba00, ver: 0x4)\nInfo : rpi3.a53.0: hardware has 6 breakpoints, 4 watchpoints\nInfo : rpi3.a53.1: hardware has 6 breakpoints, 4 watchpoints\nInfo : rpi3.a53.2: hardware has 6 breakpoints, 4 watchpoints\nInfo : rpi3.a53.3: hardware has 6 breakpoints, 4 watchpoints\nInfo : Listening on port 3333 for gdb connections\nInfo : Listening on port 3334 for gdb connections\nInfo : Listening on port 3335 for gdb connections\nInfo : Listening on port 3336 for gdb connections\n\n<\/pre><\/div>\n\n\n<p>Now we&#8217;re cooking! You can connect GDB up to each core, debug that way, or use the OpenOCD interface, see below:<\/p>\n\n\n\n<h3>OpenOCD Interface<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\nacob@jacob-aspire-mint:\/tmp\/openocd$ telnet localhost 4444\nTrying 127.0.0.1...\nConnected to localhost.\nEscape character is '^]'.\nOpen On-Chip Debugger\n&gt; halt\nrpi3.a53.3 cluster 0 core 3 multi core\ntarget halted in AArch64 state due to debug-request, current mode: EL3H\ncpsr: 0x000003cd pc: 0x20001c\nMMU: disabled, D-Cache: disabled, I-Cache: disabled\n&gt; targets\n    TargetName         Type       Endian TapName            State       \n--  ------------------ ---------- ------ ------------------ ------------\n 0  rpi3.a53.0         aarch64    little rpi3.tap           running\n 1  rpi3.a53.1         aarch64    little rpi3.tap           running\n 2  rpi3.a53.2         aarch64    little rpi3.tap           running\n 3* rpi3.a53.3         aarch64    little rpi3.tap           halted\n\n&gt; reg\n===== Aarch64 registers\n(0) x0 (\/64): 0x0000000000000003 (dirty)\n(1) x1 (\/64): 0x00000000C1000000\n(2) x2 (\/64)\n(3) x3 (\/64)\n(4) x4 (\/64)\n(5) x5 (\/64)\n(6) x6 (\/64)\n(7) x7 (\/64)\n(8) x8 (\/64)\n\n&#91; ... snip ... ]\n\n<\/pre><\/div>\n\n\n<h3>GDB Interface<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\njacob@jacob-aspire-mint:\/tmp\/openocd$ aarch64-none-elf-gdb\nGNU gdb (GNU Toolchain for the A-profile Architecture 9.2-2019.12 (arm-9.10)) 8.3.0.20190709-git\nCopyright (C) 2019 Free Software Foundation, Inc.\nLicense GPLv3+: GNU GPL version 3 or later &lt;http:\/\/gnu.org\/licenses\/gpl.html&gt;\nThis is free software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permitted by law.\nType &quot;show copying&quot; and &quot;show warranty&quot; for details.\nThis GDB was configured as &quot;--host=x86_64-pc-linux-gnu --target=aarch64-none-elf&quot;.\nType &quot;show configuration&quot; for configuration details.\nFor bug reporting instructions, please see:\n&lt;https:\/\/bugs.linaro.org\/&gt;.\nFind the GDB manual and other documentation resources online at:\n    &lt;http:\/\/www.gnu.org\/software\/gdb\/documentation\/&gt;.\n\nFor help, type &quot;help&quot;.\nType &quot;apropos word&quot; to search for commands related to &quot;word&quot;.\n(gdb) target remote :3333\nRemote debugging using :3333\nwarning: No executable has been specified and target does not support\ndetermining executable automatically.  Try using the &quot;file&quot; command.\n0x0000000000200028 in ?? ()\n(gdb) si\n0x000000000020002c in ?? ()\n(gdb) si\n0x0000000000200074 in ?? ()\n(gdb) si\n0x0000000000200078 in ?? ()\n(gdb) \n\n<\/pre><\/div>\n\n\n<h2>Wrapping Up<\/h2>\n\n\n\n<p>Now we have a JTAG solution that can debug many, many flavors of processors and microcontrollers given the right configuration. It becomes even more useful if your FT232R module supports selecting the logic level voltage like mine does. See below for some pros and cons of this approach. <\/p>\n\n\n\n<h3>Pros<\/h3>\n\n\n\n<p>This is a quick and dirty way to get a JTAG adapter at no cost if you&#8217;ve already got these FTDI chips laying around. It&#8217;s quick and fully configurable (check out the OpenOCD config pages for all it can do) and makes a great debugger. <\/p>\n\n\n\n<h3>Cons<\/h3>\n\n\n\n<p>Since we are bit-banging our way to success here, it is a bit on the slow side. It&#8217;s not unusable, but it is slower than a native interface. If you don&#8217;t have one of these chips already at your disposal, I&#8217;d opt for one of the FT232H or better yet the FT2232H, both of which have an MPSSE engine which greatly improves emulation. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>JTAG 101 What is it? JTAG stands for the Joint Test Action Group, and the TAP or Test Access Port this group defined is one of the most (if not the most) common way to program and debug embedded devices and computers of all flavors. For the professional, JTAG devices are bountiful and usually not too much of a strain on the commercial budget. But for the hobbyist, things aren&#8217;t so peachy. A Segger J-Link EDU can be had for&hellip;<\/p>\n","protected":false},"author":1,"featured_media":622,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[85,72,73,76],"tags":[114,115,111,112,48],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v16.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>JTAG On the Cheap with the FTDI FT232R - Jacob N Calvert<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/jacobncalvert.com\/blog-archive\/2020\/02\/04\/jtag-on-the-cheap-with-the-ftdi-ft232r\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"JTAG On the Cheap with the FTDI FT232R - Jacob N Calvert\" \/>\n<meta property=\"og:description\" content=\"JTAG 101 What is it? JTAG stands for the Joint Test Action Group, and the TAP or Test Access Port this group defined is one of the most (if not the most) common way to program and debug embedded devices and computers of all flavors. For the professional, JTAG devices are bountiful and usually not too much of a strain on the commercial budget. But for the hobbyist, things aren&#8217;t so peachy. A Segger J-Link EDU can be had for&hellip;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/jacobncalvert.com\/blog-archive\/2020\/02\/04\/jtag-on-the-cheap-with-the-ftdi-ft232r\/\" \/>\n<meta property=\"og:site_name\" content=\"Jacob N Calvert\" \/>\n<meta property=\"article:published_time\" content=\"2020-02-04T21:59:47+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-02-04T21:59:49+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/jacobncalvert.com\/wp-content\/uploads\/2020\/02\/rpi.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1500\" \/>\n\t<meta property=\"og:image:height\" content=\"1000\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"14 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https:\/\/jacobncalvert.com\/blog-archive\/#website\",\"url\":\"https:\/\/jacobncalvert.com\/blog-archive\/\",\"name\":\"Jacob N Calvert\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https:\/\/jacobncalvert.com\/blog-archive\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/jacobncalvert.com\/blog-archive\/2020\/02\/04\/jtag-on-the-cheap-with-the-ftdi-ft232r\/#primaryimage\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/jacobncalvert.com\/blog-archive\/wp-content\/uploads\/2020\/02\/rpi.jpg\",\"contentUrl\":\"https:\/\/jacobncalvert.com\/blog-archive\/wp-content\/uploads\/2020\/02\/rpi.jpg\",\"width\":1500,\"height\":1000,\"caption\":\"Raspberry Pi\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/jacobncalvert.com\/blog-archive\/2020\/02\/04\/jtag-on-the-cheap-with-the-ftdi-ft232r\/#webpage\",\"url\":\"https:\/\/jacobncalvert.com\/blog-archive\/2020\/02\/04\/jtag-on-the-cheap-with-the-ftdi-ft232r\/\",\"name\":\"JTAG On the Cheap with the FTDI FT232R - Jacob N Calvert\",\"isPartOf\":{\"@id\":\"https:\/\/jacobncalvert.com\/blog-archive\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/jacobncalvert.com\/blog-archive\/2020\/02\/04\/jtag-on-the-cheap-with-the-ftdi-ft232r\/#primaryimage\"},\"datePublished\":\"2020-02-04T21:59:47+00:00\",\"dateModified\":\"2020-02-04T21:59:49+00:00\",\"author\":{\"@id\":\"https:\/\/jacobncalvert.com\/blog-archive\/#\/schema\/person\/f4b22a996d41bf09ed2bbe22912a8c8a\"},\"breadcrumb\":{\"@id\":\"https:\/\/jacobncalvert.com\/blog-archive\/2020\/02\/04\/jtag-on-the-cheap-with-the-ftdi-ft232r\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/jacobncalvert.com\/blog-archive\/2020\/02\/04\/jtag-on-the-cheap-with-the-ftdi-ft232r\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/jacobncalvert.com\/blog-archive\/2020\/02\/04\/jtag-on-the-cheap-with-the-ftdi-ft232r\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"item\":{\"@type\":\"WebPage\",\"@id\":\"https:\/\/jacobncalvert.com\/blog-archive\/\",\"url\":\"https:\/\/jacobncalvert.com\/blog-archive\/\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"position\":2,\"item\":{\"@id\":\"https:\/\/jacobncalvert.com\/blog-archive\/2020\/02\/04\/jtag-on-the-cheap-with-the-ftdi-ft232r\/#webpage\"}}]},{\"@type\":\"Person\",\"@id\":\"https:\/\/jacobncalvert.com\/blog-archive\/#\/schema\/person\/f4b22a996d41bf09ed2bbe22912a8c8a\",\"name\":\"Jacob\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/jacobncalvert.com\/blog-archive\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/64a2dd1c00cb39dfc19bb1204c87efbc?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/64a2dd1c00cb39dfc19bb1204c87efbc?s=96&d=mm&r=g\",\"caption\":\"Jacob\"},\"sameAs\":[\"https:\/\/jacobncalvert.com\"],\"url\":\"https:\/\/jacobncalvert.com\/blog-archive\/author\/jcalvert\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","_links":{"self":[{"href":"https:\/\/jacobncalvert.com\/blog-archive\/wp-json\/wp\/v2\/posts\/620"}],"collection":[{"href":"https:\/\/jacobncalvert.com\/blog-archive\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jacobncalvert.com\/blog-archive\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jacobncalvert.com\/blog-archive\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jacobncalvert.com\/blog-archive\/wp-json\/wp\/v2\/comments?post=620"}],"version-history":[{"count":23,"href":"https:\/\/jacobncalvert.com\/blog-archive\/wp-json\/wp\/v2\/posts\/620\/revisions"}],"predecessor-version":[{"id":644,"href":"https:\/\/jacobncalvert.com\/blog-archive\/wp-json\/wp\/v2\/posts\/620\/revisions\/644"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/jacobncalvert.com\/blog-archive\/wp-json\/wp\/v2\/media\/622"}],"wp:attachment":[{"href":"https:\/\/jacobncalvert.com\/blog-archive\/wp-json\/wp\/v2\/media?parent=620"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jacobncalvert.com\/blog-archive\/wp-json\/wp\/v2\/categories?post=620"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jacobncalvert.com\/blog-archive\/wp-json\/wp\/v2\/tags?post=620"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}