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.

Issue with accessing shared memory on PRU



Hello,

Right now I am preparing an example code for PRU to do some POC. I am trying to put some buffer in shared mem, but when I load the code through CCS, it does not allow me to write anything into shared memory. So anyone please let me know how can I access the shared memory region to load the code?

My gel file is as below:

menuitem "PRU_CAPE"

/* AM335x specific mux bit defines */

#define AM572X_SLEWCTRL_FAST            (0 << 19)
#define AM572X_SLEWCTRL_SLOW            (1 << 19)
#define AM572X_INPUT_EN                 (1 << 18)
#define AM572X_PULL_UP                  (1 << 17)
/* bit 3: 0 - enable, 1 - disable for pull enable */
#define AM572X_PULL_DISA                (1 << 16)

#define AM572X_PIN_OUTPUT               (0)
#define AM572X_PIN_OUTPUT_PULLUP        (AM335X_PULL_UP)
#define AM572X_PIN_INPUT                (AM335X_INPUT_EN | AM335X_PULL_DISA)
#define AM572X_PIN_INPUT_PULLUP         (AM335X_INPUT_EN | AM335X_PULL_UP)
#define AM572X_PIN_INPUT_PULLDOWN       (AM335X_INPUT_EN)

hotmenu PRU_Cape_Init()
{
    PRU_PINMUX_Config();
    PRU_PRCM_Enable();
    PRU_ICSS_Reset();
}

hotmenu PRU_PINMUX_Config()
{
    
    GEL_TextOut("****** PRU Cape PINMUX is being configured  ***** \n","Output",1,1,1);

//**********************************************************
//                     DAC
//**********************************************************
    //Data Out    gpio6_10 - Mode 13
    *((unsigned int*) 0x4A003774) = AM572X_PIN_OUTPUT | 13;
    
    //Clock out
    *((unsigned int*) 0x4A003778) = AM572X_PIN_OUTPUT | 13;
    
    //Sync
    *((unsigned int*) 0x4A00377C) = AM572X_PIN_OUTPUT | AM572X_PULL_DISA | 13;
}

hotmenu PRU_ICSS_Reset()
{
    
    GEL_TextOut("*\t***** Reseting the PRU-ICSS   ******\n","Output",1,1,1);

//    *((unsigned int*) 0x44E00C00 ) |= 0x2;
//    *((unsigned int*) 0x44E00C00 ) &= 0xFFFFFFFD;

}

hotmenu PRU_PRCM_Enable()
{
    
    GEL_TextOut("\t****** Enabling PRU-ICSS clock ****** \n","Output",1,1,1);

//    *((unsigned int*) 0x44E000E8 ) |= 0x02;    // enabling the pru-icss module taking it out of idle    //Rakesh Commented
    *((unsigned int*) 0x4A009718 ) |= 0x02;    // enabling the pru-icss module taking it out of idle    //Rakesh Added
    *((unsigned int*) 0x4A009720 ) |= 0x02;    // enabling the pru-icss module taking it out of idle    //Rakesh Added

    //CSS_Reset();
    
}

  • Hi,

    I will ask the PRU experts to look at this.
  • Hi Rakesh,

    Are you trying access the PRU shared memory or SoC level shared memory (i.e. OCMC RAM)?  Also, can you explain how you are trying to write to the shared memory?

    Regards,
    Melissa

  • Hello Melissa,

    I am trying to access PRU shared memory. I have write an example code in which one of the buffer I have mapped to store in shared memory using pragma as shown below.

    #pragma DATA_SECTION(sequencer, ".sequencer")
    volatile far struct sequ sequencer[1024]

    But while I load this code, it gives me error. So I have tried to write random value in shared memory through CCS on memory window. This way also I was not able to write anything in shared memory region.

    Please let me know if you require more information.
  • Rakesh,

    Can you post the contents of your linker file (.cmd) as well?

    Jason Reeder

  • Hello Jason,


    Please see here attached linker file.

    /****************************************************************************/
    /*  AM57xx_PRU.cmd                                                          */
    /*  Copyright (c) 2015  Texas Instruments Incorporated                      */
    /*                                                                          */
    /*    Description: This file is a linker command file that can be used for  */
    /*                 linking PRU programs built with the C compiler and       */
    /*                 the resulting .out file on an AM57xx device.             */
    /****************************************************************************/
    
    -cr								/* Link using C conventions */
    
    /* Specify the System Memory Map */
    MEMORY
    {
          PAGE 0:
    	PRU_IMEM		: org = 0x00000000 len = 0x00003000  /* 12kB PRU-ICSS1 Instruction RAM */
    
          PAGE 1:
    
    	/* RAM */
    
    	PRU_DMEM_0_1	: org = 0x00000000 len = 0x00002000 CREGISTER=24 /* 8kB PRU Data RAM 0_1 */
    	PRU_DMEM_1_0	: org = 0x00002000 len = 0x00002000	CREGISTER=25 /* 8kB PRU Data RAM 1_0 */
    	PRU_SHAREDMEM	: org = 0x00010000 len = 0x00008000 CREGISTER=28 /* 32kB Shared RAM */
    
    	DDR			    : org = 0x80000000 len = 0x00000100	CREGISTER=31
    	L3OCMC			: org = 0x40000000 len = 0x00010000	CREGISTER=30
    
    
    	/* Peripherals */
    
    	PRU_CFG			: org = 0x00026000 len = 0x00000120	CREGISTER=4
    	PRU_ECAP		: org = 0x00030000 len = 0x00000060	CREGISTER=3
    	PRU_IEP			: org = 0x0002E000 len = 0x0000031C	CREGISTER=26
    	PRU_INTC		: org = 0x00020000 len = 0x00001504	CREGISTER=0
    	PRU_UART		: org = 0x00028000 len = 0x00000038	CREGISTER=7	
    	
    	MCASP3_DMA		: org = 0x46000000 len = 0x00000100	CREGISTER=8
    	I2C3			: org = 0x48060000 len = 0x00000300	CREGISTER=5
    	
    	RSVD1			: org = 0x48040000 len = 0x0000005C	CREGISTER=1
    	RSVD2			: org = 0x4802A000 len = 0x000000D8	CREGISTER=2
    	RSVD6			: org = 0x48030000 len = 0x000001A4	CREGISTER=6
    	RSVD9			: org = 0x4A100000 len = 0x0000128C	CREGISTER=9
    	RSVD10			: org = 0x48318000 len = 0x00000100	CREGISTER=10
    	RSVD11			: org = 0x48022000 len = 0x00000088	CREGISTER=11
    	RSVD12			: org = 0x48024000 len = 0x00000088	CREGISTER=12
    	RSVD13			: org = 0x48310000 len = 0x00000100	CREGISTER=13
    	RSVD14			: org = 0x481CC000 len = 0x000001E8	CREGISTER=14
    	RSVD15			: org = 0x481D0000 len = 0x000001E8	CREGISTER=15
    	RSVD16			: org = 0x481A0000 len = 0x000001A4	CREGISTER=16
    	RSVD17			: org = 0x4819C000 len = 0x000000D8	CREGISTER=17
    	RSVD18			: org = 0x48300000 len = 0x000002C4	CREGISTER=18
    	RSVD19			: org = 0x48302000 len = 0x000002C4	CREGISTER=19
    	RSVD20			: org = 0x48304000 len = 0x000002C4	CREGISTER=20
    	RSVD21			: org = 0x00032400 len = 0x00000100	CREGISTER=21
    	RSVD22			: org = 0x480C8000 len = 0x00000140	CREGISTER=22
    	RSVD23			: org = 0x480CA000 len = 0x00000880	CREGISTER=23
    	RSVD27			: org = 0x00032000 len = 0x00000100	CREGISTER=27
    	RSVD29			: org = 0x49000000 len = 0x00001098	CREGISTER=29
    }
    
    /* Specify the sections allocation into memory */
    SECTIONS {
    	/* Forces _c_int00 to the start of PRU IRAM. Not necessary when loading
    	   an ELF file, but useful when loading a binary */
    	.text:_c_int00*	>  0x0, PAGE 0
    
    	.text		>  PRU_IMEM, PAGE 0
    	.stack		>  PRU_DMEM_0_1, PAGE 1
    	.bss		>  PRU_DMEM_0_1, PAGE 1
    	.cio		>  PRU_DMEM_0_1, PAGE 1
    	.data		>  PRU_DMEM_0_1, PAGE 1
    	.switch		>  PRU_DMEM_0_1, PAGE 1
    	.sysmem		>  PRU_DMEM_0_1, PAGE 1
    	.cinit		>  PRU_DMEM_0_1, PAGE 1
    	.rodata		>  PRU_DMEM_0_1, PAGE 1
    	.rofardata	>  PRU_DMEM_0_1, PAGE 1
    	.farbss		>  PRU_DMEM_0_1, PAGE 1
    	.fardata	>  PRU_DMEM_0_1, PAGE 1
    
    	.resource_table > PRU_DMEM_0_1, PAGE 1
    	.sequencer > PRU_SHAREDMEM, PAGE 1
    }
    

  • The #pragma and linker file both look correct.

    Two more questions quick questions:

    Can you remove the 'far' keyword in your sequencer declaration and see if that changes anything?

    Do you see any linker warnings (or errors) during your build process?

    Judging by the fact that you can't even access the shared memory in the CCS memory window I doubt the above two questions will shed any light on the root cause but I'd like to know.

    Jason Reeder
  • Can you remove the 'far' keyword in your sequencer declaration and see if that changes anything?
    After removing 'far' keyword, there is no change in behaviour.

    Do you see any linker warnings (or errors) during your build process?
    I do not see any compiler warnings while I compile the source code.
  • Hi Rakesh,

    A few quick tests in CCS...

    Can you write to the PRU Shared RAM from the ARM's Memory Browser in CCS? (i.e. address 0x4B210000 for AM57x PRU-ICSS1 Shared RAM and 0x4B290000 for AM57x PRU-ICSS2 Shared RAM)

    Also, try writing to the PRU Shared RAM from the PRU's Memory Browser again. Make sure to select "PRU_Device_Memory" (not "Data_Memory") from the Memory Browser's drop down menu and enter the address as 0x10000.

    Regards,
    Melissa
  • Hello Melissa,
    I am able to access shared memory through CCS. May be I was trying to access "Data_Memory" instead of "PRU_DEVICE_MEM" in CCS.

    Also Please not that I got below warning while compiling the code, if I remove "far" keyword.

    ""../main.c", line 273: warning #17003-D: relocation from function "main" to symbol "sequencer" overflowed; the 17-bit relocated address 0x10002 is too large to encode in the 16-bit unsigned field (type = 'R_PRU_FRDO_U16_C32_So8s16_P1' (9), file = "./main.obj", offset = 0x00000098, section = ".text:main")
    warning #10015-D: output file "Test_Sequencer.out" cannot be loaded and run on a target system"
  • Rakesh,

    Yes, you are right about the 'far' keyword. It's also a good sign that we can see the relocated address is where we expect it to be (0x10002).

    Since you can now access the memory through CCS does this mean that your issue is fixed? Or can you still not load the code?

    Jason Reeder

  • Jason,

    I am still not able to load the code. Looks like we may have to remove the compilation, then may be I will able to load the code. I got below error, while I am trying to load the code:

    "PRU_0_ICSS2: File Loader: Verification failed: Values at address 0x0000000000010000 do not match Please verify target memory and memory map.
    PRU_0_ICSS2: GEL: File: /home/zeiss/workspace_v6_1/Test_Sequencer/Debug/Test_Sequencer.out: a data verification error occurred, file load failed."

  • Is there any update on this issue? Could you guys please help me resolve it asap?
  • Rakesh,

    I cannot replicate your issue on my AM335x board with a structure array loaded into PRU shared memory. I am trying to get my hands on an AM572x EVM to test that as well.

    To make sure we are on the same page once I find one, what version of CCS are you using and can you shared your entire project?

    Jason Reeder

  • Hello Jason,

    Thanks for your reply. Please find here attached source code.

    PRU_RPMsg_Echo_Interrupt2_0.zip

  • Rakesh,

    This project does not compile. It doesn't seem to be the same project posted above: /home/zeiss/workspace_v6_1/Test_Sequencer/Debug/Test_Sequencer.out

    Also, if you are testing an RPMsg project you will need to use the pruss_remoteproc Linux module to load the code and not CCS over JTAG.

    Jason Reeder
  • Hello Jason,

    It does not depend on the project type. If you compile this project you will get a warning, which I have posted earlier. I am using linux module to load the RPMsg project. Also I have attached here the Test_sequencer project which can be load through CCS.

    Test_Sequencer.zip

  • Rakesh,

    I can finally see the same verification issue that you see. It appears that we are running into an issue where CCS can't verify the data it is trying to load in the shared memory. It seems to be related to the issue we ran into where we couldn't see/change the data in the shared ram using the Data_Memory drop down in the memory browser window.

    Right now the only data being loaded into the shared memory are your default/initialized values for the sequencer array. While I chase down this issue on my end, can you move forward with your development by leaving the sequencer array uninitialized (or initialize it once at the beginning of your program)? I've tested and seen that leaving the array uninitialized allows CCS to load and verify the program.

    Jason Reeder
  • Hello Jason,

    I have tried to implement your suggestion and I was able to store data in shared memory, but when I pass sequencer[] as an argument, it does not work properly. It looks like there is some problem in address conversion. So, some how we need to remove the warning and pass the proper address to the function. I am here attaching my entire updated source code. Please let me know if you have any idea to remove the warning.

    Test_Sequencer1.zip

  • Hi Jason,
    I am able to successfully access the shared memory. I need to use "far" keyword when I declare the structure. Thanks for all your support. Please mark this question answered. :) Thanks you once again.
  • Rakesh,

    That's great news!

    I looked into this further and I think I have a more concrete solution for you than just simply not initializing your shared variables. You need to move the PRU_SHAREDMEM memory to PAGE 2 instead of PAGE 1 in your command linker file. Check out this file as an example of what I mean: git.ti.com/.../AM335x_PRU.cmd

    You'll need to add a PAGE 2 line in the MEMORY section of the file as well as update to PAGE 2 at the bottom in the SECTIONS portion of the file.

    This is due to the fact that CCS can only modify the PRU shared memory through PAGE 2. This is why we were getting data verification errors when CCS loaded your program, because CCS couldn't write your initialization values to the shared memory through PAGE 1.

    This was a bug that was found due to this e2e thread. I've updated all of the command linker files in the PRU Software Support Package git repository as a result (git.ti.com/.../5a6db4835093061762b74eaad081ab913be66728).


    Jason Reeder

  • Jason,

    Thanks for pointing to the updated AM335x_PRU.cmd file. The PAGE 2 notation for the PRU Device Memory sections has solved a lot of problems for me, and will be vital to many other users who are finding the PRU very useful.

    In my case, I tried putting an initialized array in the PRU_SHAREDMEM area so I could keep it initialized for re-use when I Restart the program during debug. The loader would not initialize it until I switched to your new linker .cmd file. I had also tried using the -c ROM model which generates a .cinit section, but that was too big to fit into the DMEM area so I tried moving that to shared memory, with the same problem as with my own initialized array in the -cr RAM model (in which the CCS or other loader initializes all initialized memory, saving a lot of space in the PRU SRAM but losing the ability to restart the program - have to reload instead).

    Thank you for this very helpful information, and I hope it will find its way into all of the SDKs and PRU support packages. It seems to be in some of them but not all.

    Regards,
    RandyP