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

