Description of the program:
An LED toggles on and off from a set delay time in R2.
A separate C program loads the PRU program, starts the core and then
prompts the user for a Time to do a delay. Upon the user entering a time,
the c program writes that value to dataram and reads back the mapped memory
from the PRU to show.
The PRU loop does a SBBO each time as well as a LBBO for a single R2 . My
LBBO call however is not returning the proper value, I am likely using the
wrong pointer value.
*lbbo r2, r2, 0 ,4 // read 4 bytes from there and store it into r2*
*After I write from C into shared_int[2], I am not able to load that value
from the PRU. Since I stored SBBO from reference point of r0 =0 then I
would expect R2 to be starting on the 9th byte over. I tried that too - no
go. *
*PRU program.*
*#include "memparams.hp"#define CONST_PRUCFG 0xC4#define CPU_HZ (200 *
1000 * 1000)//lbco r3, CONST_PRUCFG, 4, 4 .text .section .init0, "x"
.global __start__start: /* Initialize stack pointer. */ ldi sp,
%lo(__stack_top) ldi sp.w2, %hi_rlz(__stack_top) r2 = 0x0BEBC200
// set r2 to a default of 200,000,000 jmp main .text .section .textmain:
// init ldi r0, 0 ldi r1, 0xffff ldi r3, 777 ldi r4,
777 ldi r8, 1000 ldi r5, 10000main_loop: //Load valeu of
PRU data memory in general register r2 //ldi r9, 9 // offset to the
start of the third lbbo r2, r2, 0 ,4 mov r6, r2 // to prove in the
c program that data arrived and is correct when displayed R2 should equal
R6- debug sbbo r0, r0, 0 , 48 // copy all 12 registers to memory
R0...R11 . // the goal is for R2 to get set in a C program outside
theis assembly. Thus changing the speed of the // blinking LED -
defualt is set to 1 second = 200,000,000 cycles in CPU delay. //
led on mov r30, r1 ldi r14, %lo( r2/4 ) ldi r14.w2, %hi_rlz(r2/4) call
delay_n2_cycles // led off mov r30, r0 ldi r14, %lo(r2/4) ldi r14.w2,
%hi_rlz(r2/4 ) call delay_n2_cycles jmp main_loopdelay_n2_cycles: sub r14,
r14, 1 qbne delay_n2_cycles, r14, 0 retmy_resource_table: .word 1, 0, 0, 0
/* struct resource_table base */ .word 0 /* uint32_t offset[1] */*
*C program*
*#include <stdio.h>#include <fcntl.h>#include <errno.h>#include
<unistd.h>#include <stdlib.h>#include <string.h>#include <stdint.h>#include
<err.h>#include <sys/mman.h>#include <libelf.h>#include
"prussdrv.h"#include "pruss_intc_mapping.h"#define AM33XX_PRUSS_IRAM_SIZE
8192#define AM33XX_PRUSS_DRAM_SIZE 8192#define
PRU_NUM 0#define ADDEND1 0x98765400u#define ADDEND2 0x12345678u#define
ADDEND3 0x10210210u#define LOOPS 30#define DDR_BASEADDR
0x80000000#define OFFSET_DDR 0x00001000#define OFFSET_SHAREDRAM
0x00000000 //equivalent with 0x00002000#define PRUSS0_SHARED_DATARAM
4static int LOCAL_exampleInit ( );static unsigned short
LOCAL_examplePassed ( unsigned short pruNum, unsigned int millis );static
int mem_fd;static void *ddrMem, *sharedMem;static unsigned int
*sharedMem_int;static int counter ;int main (int argc, char *argv[]){
counter = 0 ; tpruss_intc_initdata pruss_intc_initdata =
PRUSS_INTC_INITDATA; int ret; printf("Initializing the PRUs...\n");
prussdrv_init(); /* Open PRU Interrupt */ ret =
prussdrv_open(PRU_EVTOUT_0); if (ret) errx(EXIT_FAILURE, "prussdrv_open
open failed\n"); /* Get the interrupt initialized */
prussdrv_pruintc_init(&pruss_intc_initdata); printf("\tINFO: Initializing
example. - Writing Data to Local CPU DDR Ram \r\n");
LOCAL_exampleInit(PRU_NUM); printf("Starting ...\n");
prussdrv_pru_enable(0); prussdrv_pru_enable(1); unsigned int
blinkySpeed = 1000; while (counter < LOOPS){ printf("Please Enter a
blinky speed in milliseconds:"); scanf("%d" , &blinkySpeed );
LOCAL_examplePassed(PRU_NUM, blinkySpeed ); //usleep(5 * 1000 *
1000); counter = counter + 1; } fflush(stdout); /*
Disable PRU and close memory mapping*/ prussdrv_pru_disable(PRU_NUM);
//munmap(ddrMem, 0x0FFFFFFF); //close(mem_fd); prussdrv_exit();
printf("Program done.\n"); return EXIT_SUCCESS;}static int
LOCAL_exampleInit ( ){ void *DDR_regaddr1, *DDR_regaddr2,
*DDR_regaddr3; /* open the device */ mem_fd = open("/dev/mem",
O_RDWR); if (mem_fd < 0) { printf("Failed to open /dev/mem
(%s)\n", strerror(errno)); return -1; } /* map the DDR memory
*/ ddrMem = mmap(0, 0x0FFFFFFF, PROT_WRITE | PROT_READ, MAP_SHARED,
mem_fd, DDR_BASEADDR); if (ddrMem == NULL) { printf("Failed to
map the device (%s)\n", strerror(errno)); close(mem_fd);
return -1; } /* Store Addends in DDR memory location */
DDR_regaddr1 = ddrMem + OFFSET_DDR; DDR_regaddr2 = ddrMem + OFFSET_DDR +
0x00000004; DDR_regaddr3 = ddrMem + OFFSET_DDR + 0x00000008;
*(unsigned long*) DDR_regaddr1 = ADDEND1; *(unsigned long*) DDR_regaddr2
= ADDEND2; *(unsigned long*) DDR_regaddr3 = ADDEND3;
return(0);}static unsigned short LOCAL_examplePassed ( unsigned short
pruNum, unsigned int millis ){ unsigned int result_0, result_1,
result_2,
result_3,result_4,result_5,result_6,result_7,result_8,result_9,result_10,result_11;
/* Allocate PRU Dataram memory. */
prussdrv_map_prumem(PRUSS0_PRU0_DATARAM, &sharedMem); sharedMem_int =
(unsigned int*) sharedMem; // set R2 which hold our delay valy for the
blinky action in the pru sharedMem_int[2] = (millis * 1000 * 200); //
read all the current data ram fields in result_0 = sharedMem_int[ 0];
result_1 = sharedMem_int[ 1]; result_2 = sharedMem_int[ 2]; result_3
= sharedMem_int[ 3]; result_4 = sharedMem_int[ 4]; result_5 =
sharedMem_int[ 5]; result_6 = sharedMem_int[ 6]; result_7 =
sharedMem_int[ 7]; result_8 = sharedMem_int[ 8]; result_9 =
sharedMem_int[ 9]; result_10 = sharedMem_int[ 10]; result_11 =
sharedMem_int[ 11]; printf("-------------------------------------\n");
//printf("%p\n", (void *) &sharedMem_int[0]); printf("value R0 = %d\n
", result_0); printf("value R1 = %d\n", result_1); printf("value R2 =
%d\n", result_2); printf("value R3 = %d\n ", result_3); printf("value
R4 = %d\n", result_4); printf("value R5 = %d\n", result_5);
printf("value R6 = %d\n ", result_6); printf("value R7 = %d\n",
result_7); printf("value R8 = %d\n", result_8); printf("value R9 =
%d\n ", result_9); printf("value R10 = %d\n", result_10);
printf("value R11 = %d\n", result_11); //return ((result_0 == ADDEND1) &
(result_1 == ADDEND2) & (result_2 == ADDEND3)) ;return 1;}*
Here is the pru program
On Sunday, November 27, 2016 at 2:09:27 PM UTC-7, [email protected] wrote:
>
> Hi, check my comments inline.
>
> On Sunday, November 27, 2016 at 10:15:00 PM UTC+2, Neil Jubinville wrote:
>>
>> Thx Charles, that was it. I was treating the registers as application
>> of dataram memory.
>>
>> In the assembly loop: I did a : * sbbo r0, r0, 0 , 48*
>>
>> and like magic my c pru memap dumped out values I have stuffed in some of
>> the registers.
>>
>> see below
>>
>> -------------------------------------
>> value R0 = 0
>> value R1 = 65535
>> value R2 = 8192
>> value R3 = 16
>> value R4 = 777
>> value R5 = 25
>> value R6 = -136853601
>> value R7 = 2146680819
>> value R8 = 1
>> value R9 = -45491713
>> value R10 = -89
>> value R11 = -1345356802
>>
>> ------------------------------------
>>
>> I do have a more basic question though about the value in R2 = 8192. My
>> understanding is the general purpose registers are 32 bit.
>>
>> In my assembly I set
>>
>> *r2 = 0x0BEBC200 // *decimal 200,000,000 to reflect the core
>> frequency.
>>
>> however as you can see the R2 after the mem copy to dataram shows 8192.
>> Why is it not reading 200,000,000 in R2 after the transfer?
>>
>
> Could you share your full source code?
>
>>
>> ---------
>>
>> Also, another question. Syntax wise the first *r0 *in the statement
>> below 'should' have &r0 but I get unknown register error when compiling.
>> If I leave out the & it works and the transfer does occur. Is this a
>> nuance of the gcc-pru compiler vs a direct pasm compile?
>>
>> *sbbo r0, r0, 0 , 48*
>>
> Yes, the & is not needed for pru-gcc. But for the sake of compatibility
> I'll make it optional with the next release.
>
>
>
>>
>>
>> Yet another question: the second argument of *r0* reflects the starting
>> address point in dataram. I would have expected dataram as a free for all
>> address space that I managed. Is the reference of an Rn type syntax
>> simply a convenience for addressing in dataram and dataram has the notion
>> of its own register mapping?
>>
> Dataram has no register mapping. It is simply memory. Consider the
> following example:
> ldi r1, 101
> ldi r2, 64
> sbbo r1, r2, 0, 4
> Converted to C syntax, it would look like:
> unsigned int r1 = 101;
> unsigned int *r2 = (void *)64;
> r2[0] = r1;
>
>
>
>
>>
>>
>> <https://lh3.googleusercontent.com/-PR6M_jNKhu4/WDs-tnOriEI/AAAAAAAAASU/VTpqCAMst9wgqHo1G8r1mmuserz0ZOprwCLcB/s1600/Screen%2BShot%2B2016-11-27%2Bat%2B1.13.55%2BPM.png>
>>
>>
>>
>> *Thx! *
>>
>>
>>
>>
>>
>>
>> On Saturday, November 26, 2016 at 12:43:37 PM UTC-7, Charles Steinkuehler
>> wrote:
>>>
>>> On 11/26/2016 1:33 PM, Neil Jubinville wrote:
>>> >
>>> > Here is my basic understanding - Focusing on PRU0:
>>> >
>>> > Each PRU has 8K of 'dataram' - This is where I expect R1,R2,R3 ----
>>> R31 to be
>>> > stored. *Is this true? I see many people changing the reference at
>>> *0x0000_0n00,
>>> > n = c24_blk_index[3:0], do I need to set where the Rn's lay down in
>>> memory?
>>>
>>> NO
>>>
>>> The data ram is what it says...data ram. The registers are what they
>>> say...registers. Registers are *NOT* data ram. If you want the
>>> register values to appear in memory, you have to write them out using
>>> the SBBO instruction.
>>>
>>> > Docs also state that the PRU 0 Data ram starts at *0x4a300000*;
>>> >
>>> > int registerStart;
>>> > registerStart = *(int*)0x4a300000;
>>> > printf("--> R0 = %d" + registerStart);
>>> >
>>> > However I get a seg fault trying to print what is in R0 that way.
>>> That was more
>>> > to just do a direct look see if possible and go around all the
>>> interfaces.
>>>
>>> 0x4a300000 is a physical address. You can use that if you are
>>> directly accessing memory (via /dev/mem, bus-mastering DMA, or
>>> something that doesn't use an MMU like the PRU core). If you try to
>>> access a physical address from a standard application that has not
>>> been mapped into your process memory space, the MMU will forbid access
>>> and your program seg-faults.
>>>
>>> To access the PRU memory in your application, use the address provided
>>> to you by the prussdrv_map_prumem function.
>>>
>>> --
>>> Charles Steinkuehler
>>> [email protected]
>>>
>>
--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups
"BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/beagleboard/fb902d5c-6649-443a-8eb0-4aff19423d85%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.