This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

c6CCS v6 PRU C-Compiler

Other Parts Discussed in Thread: AM3359

Hello,

I am trying to build a project that uses the pru of the AM335x on the Beaglebone Black. This is one of my first embedded project, but by far not my first programming try, I have done many ANSI-C-based Windows programms.

I am running Windows 7 64 bit SP1 and CCS Version: 6.1.0.00104 and I get some realy strange behavior of the compiled code on the Beagelbone. I guess I miss some little thing in the settings, as this is the first project of that kind in this company, to make it work just fine.

Now to the problem:

I wrote this programm to run on the pru, it should Light and clear a LED0 (witch works fine) and put out some chars on the UART0 ( in a subrutine as i want to use this to debug because i have no JTAG debugger). So first things first, here is the code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

#define PRU0_ARM_INTERRUPT 	19
#define GPIO1 			0x4804c000
#define GPIO_CLEARDATAOUT 	0x190
#define GPIO_SETDATAOUT 	0x194
#define SYSCFG                  (*(&C4+0x01))
int C4 __attribute__((cregister("MEM",near),peripheral));							

volatile register unsigned int __R31;

int DebugLogOut( void )
{
	char  cTest[5];
	uint8_t iCounter;

	cTest[0] = 'q';
	cTest[1] = 'w';
	cTest[2] = 'e';
	cTest[3] = 'r';
	cTest[4] = '\0';

	// Register (LineControlRegister) : 0x0000_000C
	//            (Transsmit Buffer THR): 0x0
	//  	    UART Base adress: 0x44E0_9000
	// 	    Address LCR--> 0x44E0_900C
	//          Address THR--> 0x44E0_9000

	(*(volatile unsigned long *)(0x44E0900C)) &= ~(1 << 7); // Clear bit to enable THR register

	iCounter = 0;

	while (iCounter < 5)
	{
		(*(volatile unsigned long *)(0x44E09000)) =cTest[iCounter]; // current char in the cTest char array to the uart
		__delay_cycles(1000000);
		iCounter++;
	}
	(*(volatile unsigned long *)(0x44E09000)) = 'E'; // char E to the uart
	(*(volatile unsigned long *)(0x44E09000)) = 13; // CR
	(*(volatile unsigned long *)(0x44E09000)) = 10; // LF

	return 0;
}

void main()
{

	/*Intialise OCP Master port for accessing external memories*/
       SYSCFG&=0xFFFFFFEF;       // Clear SYSCFG[STANDBY_INIT] to enable OCP master port

       /*Start Main Code*/

		(*(volatile unsigned long *)(GPIO1 | GPIO_SETDATAOUT)) = 1<<21; // Set LED0 on
		__delay_cycles(100000000);

		(*(volatile unsigned long *)(GPIO1 | GPIO_CLEARDATAOUT)) = 1<<21; // Set LED0 off

		DebugLogOut();
		__delay_cycles(50000);
		__delay_cycles(50000);

		(*(volatile unsigned long *)(0x44E09000)) = '1'; // put out a 1 as char on the uart

        /*Exiting procedure*/
	__R31 = 35;			// Send notification to Host for program completion
	__halt();

}


in the int DebugLogOut( void ) it should put out the 5 chars out of the cTest variable and then print an 'E' together with CR and LF. After that exit the subprogramm and finish the mainprogramm.

What it actualy does on my board it puts out endles 'E'+CRLF over the UART and i can't explain that at all.

And now the Strange thing, if i change the line

(*(volatile unsigned long *)(0x44E09000)) =cTest[iCounter]; // current char in the cTest char array to the uart

to

(*(volatile unsigned long *)(0x44E09000)) =cTest[1]; // char 1 in the cTest char array to the uart

it should just put out 5 times 'w' and this works perfectly it results in 'wwwwwE'+CRLF+'1' on the UART port and than halts the PRU.

Now to the compilersettings where i guess there might be something wrong:


PRU Compiler:

-v3 -O2 --opt_for_speed=5 --include_path="C:/ti/ccsv6/tools/compiler/ti-cgt-pru_2.1.1/include" --c99 --define=am3359 --define=pru0 --diag_warning=225 --display_error_number --diag_wrap=off --endian=little --hardware_mac=on -k

PRU Linker:

-v3 -O2 --opt_for_speed=5 --c99 --define=am3359 --define=pru0 --diag_warning=225 --display_error_number --diag_wrap=off --endian=little --hardware_mac=on -k -z -m"PRU_Test.map" --heap_size=0x9FF --stack_size=0x9FF -i"C:/ti/ccsv6/tools/compiler/ti-cgt-pru_2.1.1/lib" -i"C:/ti/ccsv6/tools/compiler/ti-cgt-pru_2.1.1/include" --reread_libs --define=PRU_CORE=1 --warn_sections --display_error_number --diag_wrap=off --xml_link_info="PRU_Test_linkInfo.xml" --rom_model

PRU Hex Utility, Command-line pattern:  ${command} ${flags} ${output_flag} ${output} ${inputs}${PROJECT_LOC}/bin.cmd as explaind in this post: e2e.ti.com/.../1430541

so I generate exectuable files for the PRU.

And I made 1 change to the AM335x.cmd as it is written in the example I used to start of, I added "MEM : o = 0x00026000 l = 0x00002000 CREGISTER=4" to the Page 2 in the Memory section so it looks like that:

#ifdef PRU_CORE    /* PRU memory map */
MEMORY
{
    PAGE 0:
      PRUIMEM:   o = 0x00000000  l = 0x00001000  /* 8kB PRU0 Instruction RAM */
    PAGE 1:
      PRUDMEM:   o = 0x00000000  l = 0x00001000  /* 8kB PRU Data RAM 0 */
	PAGE 2:
      SHAREDMEM: o = 0x00010000  l = 0x00003000  /* 12kB Shared RAM */
      MEM : o = 0x00026000 l = 0x00002000 CREGISTER=4
}


Then i just move the generatet data.bin and text.bin with WinSCP to the Beaglebone and execute them with a little executable that calls the pru loader api. I looked around and no one seems to have that kind of problem, i tried different optimisation levels and speed vs size trade of but that didn't do a thing.

I hope some of you can help me with this strange thing as I realy like the pru for its speed.

If you need any additional information pleas just let me know.

Greetings from Germany

Stefan

  • I apologize for the delay.

    I am unable to reproduce your results.  I do not see the LED blink or any UART output at all.  I'm pretty sure I'm doing something wrong.  Please send the entire project, including the target configuration file.  Also show, in detail, the steps you take to load the code, get it running, and see the results.  If your code is based on a published example, please send the link to that example.

    Thanks and regards,

    -George

  • Hello George,

    no problem for the delay.

    I thought you had some experience with the Beaglebone Black PRU and so i didnt include the full Project, i am sorry for that.

    I am using the default debug UART (UART0) witch is available on the J1 pins (see Pic:  ) and an FTDI-USB-Cable

    First you have to enable the PRU and disable the Heartbeat-LED this is done by connecting to the Board via SSH and send the commands:

    echo BB-BONE-PRU-01 > /sys/devices/bone_capemgr.9/slots
    echo none > /sys/class/leds/beaglebone\:green\:usr0/trigger
    


    Then you have to cpoy the createt text.bin and data.bin to a dir on the Board (i used WinSCP), its important to use Release mode in CCS for the correct file Size. I have attatched the complett project for you.

    As a last step you need a main-programm that runs on the Linux. That just simply calls the PRU Apploader API as is written in your wiki 


    I attatched this as well (the files: example, example.c and Makefile). You can build this just normal on the board (so i dont have to crosscompile this as well) using the command "make" this will create the example out of the example.c.

    In the end your Beaglebone Black diretory should look like this

    +-(user home e.g.: root)/
       |
       +-code/
       | | example
       | | example.c 
       | | Makefile
       | | data.bin
       | | text.bin 

    now you can run the code with "./example" in the SSH and you should see the led go on and off one time and then the UART output. I havent found a way to do this directly from the CCS, i think that is because i have no JTAG-Debugger.

    As i said above this way will not work

    (*(volatile unsigned long *)(0x44E09000)) =cTest[iCounter]; // current char in the cTest char array to the uart

    and this will

    (*(volatile unsigned long *)(0x44E09000)) =cTest[1]; // the char number 1 in the cTest char array to the uart

    it is in line 42 / 45 of the CCS-Project.


    I hope you can reproduce the error and mabey tell me how to fix it. I added the files so it will work out of the box and to the reproduce the error you have to enable line 42 and disable line 45. Your UART0 sould get you this output:

    blubb
    wwwwwE
    1

    Stefan

    2543.files.zip

  • Hi Stephen,

    Unfortunately, I have not able to reproduce the error you described.  What Linux kernel are you using?  Here, however, are a few initial suggestions:

    1.  The PRU software package includes two examples that use the PRU to control the PRU-ICSS UART (which is very similar to the debug UART).  These might be helpful references.  Here are direct links to the examples:

    Example 1 

    Example 2

    2.  The uio_pruss driver currently being used is a legacy driver.  The latest driver is based on remoteproc (more details under the "Software Information" section of the PRU-ICSS wiki).  The remoteproc driver enables some basic PRU debug capabilities from the command line and does not require a JTAG debugger.  Additional details are available in this forum post: https://e2e.ti.com/support/arm/sitara_arm/f/791/p/401694/1425395#1425395  .  

    Regards,

    Melissa

  • Hey Melissa,

    thank you for your reply, i am running Debian 7 on my Beaglebone Black Image 2014-04-23, what version where you using while testing?

    Mabey you can send me a link to your image so i can try it with the version of you.

    Stefan