element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
BeagleBoard
  • Products
  • Dev Tools
  • Single-Board Computers
  • BeagleBoard
  • More
  • Cancel
BeagleBoard
Blog Debugging the BeagleBone PRU in CCS
  • Blog
  • Forum
  • Documents
  • Quiz
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
BeagleBoard requires membership for participation - click to join
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: Fred27
  • Date Created: 18 May 2019 8:33 PM Date Created
  • Views 7119 views
  • Likes 9 likes
  • Comments 14 comments
  • xds110
  • ccs
  • am335x sitara
  • pru
  • BeagleBone
  • sitara
Related
Recommended

Debugging the BeagleBone PRU in CCS

Fred27
Fred27
18 May 2019

Debugging your PRU C code

Recently I decided to turn my attention to the fairly unique Programmable Realtime Units on the BeagleBone's TI Sitara processor. My earlier blog post covered Coding for the BeagleBone PRU with C in 2019 and hopefully showed how it's become easier to work with the PRUs over the last few years. Whilst it's great to be able to write C code in a nice IDE before deploying, it's even better if you can debug your code and see what's happening when things don't quite go to plan (i.e. 90% of the time). If you're looking a working with the PRUs and you haven't read that post then I suggest you do, as I'll be starting where that blog post left off.

 

What you'll needimage

To follow along with this guide you'll need:

  • A BeagleBone. I've worked with the black and green but I'm pretty sure any one will do.
  • A debugger. I used a standalone XDS100. There are more expensive options like the XDS200, etc. but this will do. The XDS110 from a Launchpad might work. It failed when i tried before, but I know a bit more now!
  • A JTAG headerheader to solder to your beaglebone. There are a few options, I went with FTR-110-51-L-D-06, but the important bit is FTR-110-**-*-D-06

 

Get your code deploying manually

There's no point trying to get this setup unless you have some simple code that you know you can build, deploy and run on the PRU. I suggest something like blinky to start with. Follow my previous guide to get it running from a manual deployment. Use the same code for debugging and you can be sure that it's the process that you're tweaking and not your code.

 

Solder on your headerimage

I hope you're up for a little surface mount soldering. The header is 0.05" pitch with is small, but definitely manageable with a reasonable soldering iron. I considered using hot air, but decided just to go with an iron instead. The pads should be fairly obvious on the bottom of the BeagleBone. I found that they were pre-tinned on the green but left clear on the black (both the Element14 and BeagleBone.org versions). As I mentioned earlier there are a few different versions of the header. Provided it's a FTR-110-nn-p-D-x then you will have 0.05" pitch pins, and each rows will be 0.1" apart. The 110 stands for 10 pins per row and D for a double row header. I think the correct length is the nn=51 version but I know other people have used slightly different lengths without a problem. The p is for the plating - user preference on that one. The x should be 06 meaning that pin 6 is deliberately missing to match up with TI's cTI-20 IDC connector on the XDS110. If you're not using this programmer then I don't suppose it will matter. Otherwise, if you couldn't find the 06 version then yank out pin 6 now. Personally, I have almost connected this the wrong way round, so a polarised connector is probably worth the effort!

 

I also found that with the header in place you'll probably want some stand-offs on the board. Mine are just 20mm M3 nylon screws and they seem to work just fine.

 

Set up CCS

Setup target configuration

You will need to add a target configuration. This just tells CCS what debugger to use and what processor to expect it to be connected to. Go to the target configurations window, add a new one, select "BeagleBone_Black" and you're done. There is an advanced tab that I spent a while messing around with, but you don't need to. You can also click "Test Connection" to verify that everything is connected OK.

 

{gallery} Target configuration

image

Target Configuration for the BeagleBone: This is all you need to connect to your BeagleBone

image

Target Configuration (Advanced): Leaving everything here as default works fine.

image

Target Configuration (Test Connection): Check that your debugger is working and you can see the BB.

 

Setup debug configuration

Setting up the Target Configuration isn't too tricky. The bit that had me stumped for a while was the Debug Configuration. This tells CCS what to do when you want to debug your code. I was banging my head again the wall with errors like "Cannot access the DAP" and "Verification failed". TI's PRU training was fairly helpful but didn't mention these problems. "Just click debug" and everything should be fine.

 

However, if Linux has ever been running on your BeagleBone, you need to undo some of the things it has configured. There is a small snippet of JavaScript that you need to run as the debug configuration starts - the magical bbb_pru_startup,js which I stumbled across referenced here and available here. This is the missing link. It's too important to be hidden away and isn't mentioned at all in TI's PRU training. I can only assume that the training is done on a virgin Sitara processor. It's not included in the otherwise excellent PRU software support package. I have discovered that as long as you run this script once before debugging that is enough. Further debuggging session don't need it - until you boot to Linux again. It doesn't get in the way though, so I suggest you leave it as part of your debug configuration.imageimage

 

Update: As the link to bbb_pru_startup.js appear to have vanished, here's the file contents:

//****************************************************************************
// BBB_PRU_STARTUP.JS 
// Version 0.20.00 
// Released subject to the license at the end of this file
//****************************************************************************  

//---------------------------------------------------------------------------- 
// Purpose: Prepare the AM355x SOC so CCS can connect to the PRU as if it were 
// any other standalone CPU.   
// 
// This script is only intended to be used as described in  
// http://processors.wiki.ti.com/index.php/Debug_Configuration_Initialization_Scripts // In particular, it does NOT WORK as a standalone script. 
// 
// Presumptions: 
// - Target system is BeagleBone Black or BeagleBone White 
// - The target configuration has launched 
// - PRU connection occurs after this script runs
//----------------------------------------------------------------------------  

//---------------------------------------------------------------------------- 
// Constants 
//---------------------------------------------------------------------------- 
var AM335X_INPUT_EN   = 1 << 5; 
var AM335X_PULL_DISA  = 1 << 3; 
var AM335X_PIN_OUTPUT = 0; 
var AM335X_PIN_INPUT  = AM335X_INPUT_EN | AM335X_PULL_DISA; 

//---------------------------------------------------------------------------- 
// Invoke the main function in this file 
//----------------------------------------------------------------------------
startup_pru(); 

//**************************************************************************** 
// STARTUP_PRU 
//**************************************************************************** 
function startup_pru()
{
    var errCode = 0;
    //-------------------------------------------------------------------------
    // Import the DSS packages into our namespace to save on typing
    //-------------------------------------------------------------------------
    importPackage(Packages.com.ti.debug.engine.scripting);
    importPackage(Packages.com.ti.ccstudio.scripting.environment);
    importPackage(Packages.java.lang);
    //-------------------------------------------------------------------------

    // Create our scripting environment object - which is the main entry
    // point into any script and the factory for creating other Scriptable
    // servers and Sessions
    //-------------------------------------------------------------------------
    script = ScriptingEnvironment.instance();

    //-------------------------------------------------------------------------
    // Get the Debug Server and start a Debug Session
    //-------------------------------------------------------------------------
    debugServer = script.getServer("DebugServer.1");

    //-------------------------------------------------------------------------
    // Open a session on the Debug Access Port (DAP)
    //-------------------------------------------------------------------------
    var debugSessionDAP = debugServer.openSession("*", "CS_DAP_DebugSS");

    //-------------------------------------------------------------------------
    // Connect to the DAP.  Error check.
    //-------------------------------------------------------------------------
    print("Connecting to DAP");
    try
    {
       debugSessionDAP.target.connect();
    }
    catch (ex)
    {
       errCode = getErrorCode(ex);
       print("Error code #" + errCode + ", could not connect to DAP!");
       print("Aborting!");
       java.lang.System.exit(errCode != 0 ? errCode : 1);
    }

    //-------------------------------------------------------------------------
    // Init steps for PRU carried out by the DAP
    //-------------------------------------------------------------------------
    print("Configuring PRU pins");
    PRU_PINMUX_Config(debugSessionDAP.memory);

    print("Enabling ICSS clock");
    debugSessionDAP.expression.evaluate(
       "*((unsigned int*) 0x44E000E8 ) |= 0x02;");

    print("Resetting ICSS");
    debugSessionDAP.expression.evaluate(
       "*((unsigned int*) 0x44E00C00 ) |= 0x2;");
    debugSessionDAP.expression.evaluate(
       "*((unsigned int*) 0x44E00C00 ) &= 0xFFFFFFFD;");

    print("Done");
}

//****************************************************************************
// PRU_PINMUX_Config 
//**************************************************************************** 
function PRU_PINMUX_Config(dsDAP_mem) [
    // GEL_TextOut("****** PRU Cape GPI/O PINMUX is being configured  ***** \n","Output",1,1,1);

    //-------------------------------------------------------------------------
    // LEDS
    //-------------------------------------------------------------------------
    //red led  = pru0 r30_3  ARM pin c12    
    dsDAP_mem.writeData(0, 0x44e1099c, AM335X_PIN_OUTPUT | 5, 32); //mode 5

    //green led = pru0 r30_2 arm pin d12
    dsDAP_mem.writeData(0, 0x44e10998, AM335X_PIN_OUTPUT | 5, 32); //mode 5

    //blue led  = pru0 r30_0 arm pin a13
    dsDAP_mem.writeData(0, 0x44e10990, AM335X_PIN_OUTPUT | 5, 32); //mode 5

    //orange led = pru0 r30_1 arm pin b13
    dsDAP_mem.writeData(0, 0x44e10994, AM335X_PIN_OUTPUT | 5, 32); //mode 5

    //RGB_0 led = pru1 r30_2 arm pin r3
    dsDAP_mem.writeData(0, 0x44e108AC, AM335X_PIN_OUTPUT | 5, 32); //mode 5

    //RGB_1 led = pru1 r30_3 arm pin r4
    dsDAP_mem.writeData(0, 0x44e108B0, AM335X_PIN_OUTPUT | 5, 32); //mode 5

    //RGB_2 led = pru0 r30_4 arm pin t1
    dsDAP_mem.writeData(0, 0x44e108B4, AM335X_PIN_OUTPUT | 5, 32); //mode 5

    //-------------------------------------------------------------------------
    // Switches
    //-------------------------------------------------------------------------
    //switch 1 = pru0 r31_5 c13
    dsDAP_mem.writeData(0, 0x44e109a4, AM335X_PIN_INPUT  | 6, 32); //mode 6

    //switch 2 = pru0 r31_7 a14
    dsDAP_mem.writeData(0, 0x44e109ac, AM335X_PIN_INPUT  | 6, 32); //mode 6

    //-------------------------------------------------------------------------
    // Audio
    //-------------------------------------------------------------------------
    //audio data pr1 r30_0 r1
    dsDAP_mem.writeData(0, 0x44e108a0, AM335X_PIN_OUTPUT | 5, 32); //mode 5

    //audio clk pr1 r30_1 r2
    dsDAP_mem.writeData(0, 0x44e108a4, AM335X_PIN_OUTPUT | 5, 32); //mode 5

    //audio sync pr1 r30_2 r3
    dsDAP_mem.writeData(0, 0x44e108a8, AM335X_PIN_OUTPUT | 5, 32); //mode 5

    //-------------------------------------------------------------------------
    // UART
    //-------------------------------------------------------------------------
    //Uart txd d15
    dsDAP_mem.writeData(0, 0x44e10984, AM335X_PIN_OUTPUT | 5, 32); //mode 5

    //UART rxd d16
    dsDAP_mem.writeData(0, 0x44e10980, AM335X_PIN_INPUT  | 5, 32); //mode 5

    //UART rts b17
    dsDAP_mem.writeData(0, 0x44e1097C, AM335X_PIN_OUTPUT | 5, 32); //mode 5

    //UART cts a17
    dsDAP_mem.writeData(0, 0x44e10978, AM335X_PIN_INPUT  | 5, 32); //mode 5

    //------------
------------------------------------------------------------
    // LCD
    //-------------------------------------------------------------------------
    //lcd rs t3
     dsDAP_mem.writeData(0, 0x44e108B8, AM335X_PIN_OUTPUT | 4, 32); //mode 4
     //lcd r/w t4
    dsDAP_mem.writeData(0, 0x44e108BC, AM335X_PIN_OUTPUT | 4, 32); //mode 4
     //lcd e v5
     dsDAP_mem.writeData(0, 0x44e108E8, AM335X_PIN_OUTPUT | 4, 32); //mode 4
     //lcd data4 b16
     dsDAP_mem.writeData(0, 0x44e10958, AM335X_PIN_OUTPUT | 6, 32); //mode 6
     //lcd data5 a16
    dsDAP_mem.writeData(0, 0x44e1095C, AM335X_PIN_OUTPUT | 6, 32); //mode 6
     //lcd data6 u5
     dsDAP_mem.writeData(0, 0x44e108e0, AM335X_PIN_OUTPUT | 4, 32); //mode 4
     //lcd data7 r5
     dsDAP_mem.writeData(0, 0x44e108e4, AM335X_PIN_OUTPUT | 4, 32); //mode 4

    //------------------------------------------------------------------------- 
    // TEMP SENSOR
    //-------------------------------------------------------------------------
    //gpmc ad14 - input (GPI direct)
    dsDAP_mem.writeData(0, 0x44E10838, AM335X_PIN_INPUT  | 6, 32); //mode 6
    
    //lcd data7 - output (DIGIO)
    dsDAP_mem.writeData(0, 0x44E108BC, AM335X_PIN_OUTPUT | 4, 32); //mode 4
}

//****************************************************************************
// getErrorCode
//****************************************************************************
function getErrorCode(exception)
{
    var ex2 = exception.javaException;
    if (ex2 instanceof Packages.com.ti.ccstudio.scripting.environment.ScriptingException)
    {
       return ex2.getErrorID();
    }
    return 0;
}

/*
 *
 * Copyright (C) 2015 Texas Instruments Incorporated - 
 *
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *    Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 *    Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the
 *    distribution.
 *
 *    Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

 

To get this set up, click the down arrow next to the green bug and select "Debug Configurations...". Click the button to create a new Launch Configuration (different name, same thing). Select the Target Configuration from the next step. Were you to go ahead and try to debug now, you'd get the "Cannot access the DAP" error that plagued me for ages. Just to the right of the empty initialization script box you can click "File System..." or "Workspace..." and reference bbb_pru_startup.js from wherever you saved it. I put it in the workspace but it doesn't matter where it is.

 

You don't need to poke around in the JavaScript, but of course I did. It sets up a few pins related to the PRU Cape which is great if you have one. The interesting thing though seem to be this:

print("Enabling ICSS clock");

debugSessionDAP.expression.evaluate("*((unsigned int*) 0x44E000E8 ) |= 0x02;");

 

 

print("Resetting ICSS");

debugSessionDAP.expression.evaluate("*((unsigned int*) 0x44E00C00 ) |= 0x2;");

debugSessionDAP.expression.evaluate("*((unsigned int*) 0x44E00C00 ) &= 0xFFFFFFFD;");

This is documented on the PRU_ICSS Debug page as follows:

Because the PRU-ICSS cores are deeply embedded inside the AM335x, there are multiple registers that need to be configured in order to perform JTAG debug. This includes:

  • ICSS clocks
  • ICSS reset
  • Pin muxing for PRU-ICSS signals
  • And in some cases even enabling various JTAG clocks so you can connect. (Linux turns many clocks off.)

A script was developed in large part from the work in Debug Configuration Initialization Scripts to handle this automatically.

.

Let's debug!

Prevent Linux from booting

You need to make sure the Linux isn't currently running on the BeagleBone. Unfortunately I don't think you can debug the PRU whilst the Sitara's A8 core is busy running Linux. Obviously this means you can't debug any interaction between your Linux code and the PRU. Maybe it's possible, but I've not heard of it. (Jan Cumps has an excellent post on using CCS to debug just the Linux bit by the way.)

 

The easiest way is to make sure you have no micro SD card inserted and hold down the "Boot" button (S2) whilst powering on. I read other guides that suggested formatting the eMMC but you don't have to go this far.

 

Debug your code

With Linux temporarily disabled, and the startup script in your debug configuration, all is right with the world. Debug your PRU project and you should see it fire up in CCS, deploy and stop at a breakpoint in the first line of your PRU code. We've cracked it! Happy PRU debugging.

image

  • Sign in to reply

Top Comments

  • shabaz
    shabaz over 6 years ago +1
    Another awesome post, this is very helpful! I think I have that connector so I will be soldering it onto my BBB soon too. As I understand, there is some stuff possible from Linux, in terms of stopping…
  • Jan Cumps
    Jan Cumps over 5 years ago +1
    I just bought the same debug probe as you - it arrived today. I'm going to try this. I know that the probe is OK - it works on a TI CC1310, TMS570LS04 (both tested on LaunchPads) and a CC2650 (the SensorTag…
  • Jan Cumps
    Jan Cumps over 5 years ago in reply to Jan Cumps +1
    The connector is on ... I'll now try the first debug steps ...
  • Fred27
    Fred27 over 3 years ago

    I added bb_pru_startup.js to the body of this post so it win't get lost again. (Why is pasting in code always to difficult!)

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps over 3 years ago in reply to cstanton

    Yes, the wiki they had for the controllers and processors has been decommissioned. This was announced several years ago, with a plan to migrate that info.

    The shutdown was done. The replacement didn't (reliably) happen. The Hercules and BB devices had essential info that was only available there.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • cstanton
    cstanton over 3 years ago in reply to joshua1609

    Looks like Texas Instruments has pulled almost everything and/or moved them. One of the first links goes to a discussion where you can download a zip archive of the wiki.

     

    If you google for the file you can find it elsewhere, such as https://github.com/vittali/vittali.ch-1-bbb-jtag

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • joshua1609
    joshua1609 over 3 years ago

    Could you share a copy of the startup file bbb_pru_startup.js.  Ive tried both links but in 2021 they are both dead.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps over 5 years ago in reply to Fred27

    Thanks. Yes I noticed and I haven't vaporised anything image.

    I have unsoldered that header in he mean time, because the height of connector + plugin flat cable interferes with an active project I'm doing.

    I may order another BB just for debug reasons.

    Or if there is someone here that wants to trade an unused BB black or green for "something else", I'm open for that too.

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
>
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube