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.

PRU DRAM0 conflict; relocate RPMSG vrings?



Hi,

We are trying to port some PRU code for BBB from Linux 3.8 to 4.4.  In the process, we want to use the new rpmsg framework.  The sample code in the PRU software support package (pru-software-support-package/examples/am335x/PRU_RPMsg_Echo_Interrupt0) works fine, but we can't merge it with our application because we use the ram at 0x0000 in DRAM0, and as soon as we rpmsg_send anything, our working RAM is corrupted.

We'd like change the location rpmsg uses for vrings.  We've tracked it down to resource_table_0.h, with the comment "will be populated by host", but we haven't a clue how to tell Linux how to populate the vring da values.

Can someone show us how to change the base address of the RAM that rpmsg uses for vrings, or how rpmsg is used with applications that use DRAM0 memory?

Robert

From resource_table_0.h:

struct my_resource_table resourceTable = {

1, /* Resource table version: only version 1 is supported by the current driver */
2, /* number of entries in the table */
0, 0, /* reserved, must be zero */
....
/* the two vrings */
{
0, //da, will be populated by host, can't pass it in
16, //align (bytes),
PRU_RPMSG_VQ0_SIZE, //num of descriptors
0, //notifyid, will be populated, can't pass right now
0 //reserved
},
{
0, //da, will be populated by host, can't pass it in
16, //align (bytes),
PRU_RPMSG_VQ1_SIZE, //num of descriptors
0, //notifyid, will be populated, can't pass right now
0 //reserved
},

  • The PRU experts have been notified. They will respond here.
  • Robert,

    The vrings are allocated by the Linux kernel and are placed in DDR memory so this is not your issue.

    Your issue is stemming from the fact that the linker is not aware of your usage of DRAM0 at address 0x0. So, it is placing the .bss section (which contains the payload array that rpmsg uses to copy the message from DDR to local memory) into the first 0x200 bytes of DRAM0. You can check where the linker places things by taking a look at the generated PRU_RPMsg_Echo_Interrupt0.map file (either in the gen, Debug, or Release folder depending on how you build). Scroll down to the 'SECTION ALLOCATION MAP' and look for the 'output section' being place at the 'origin' 00000000 for 'page' 1.

    The simplest way to fix this issue is to remove the section of DRAM0 that you are using from the memory map that the linker is allowed to use:

    • Open the AM335x_PRU.cmd file and change the 'org' (origin) and 'len' (length) values for the PRU_DMEM_0_1 row.
      • E.g. You want to use the first 0x200 bytes of DRAM0 and have the linker leave it alone
      • PRU_DMEM_0_1    :       org = 0x00000200              len = 0x00001E00                  CREGISTER=24

    Let me know if any of this doesn't make sense,

    Jason Reeder

  • Jason,

    Thanks for the prompt reply!  This is good information.

    Unfortunately, we have legacy code from 2013 where our Linux driver and our PRU code, which we don't want to change, are using DRAM0 (and DRAM1) for communication, so our memory addresses are fixed there.  We are using the LOCATION pragma on the PRU side, as such:

    #pragma LOCATION(PRU_FW_SAMPLE_CNT_REG,0x0024)

    uint32_t PRU_FW_SAMPLE_CNT_REG = 0;

    We have a few dozen variables mapped from 0x0000 to 0x0110 in both DRAM0 and DRAM1... both PRUs have their own shared variables with Linux.

    We are hoping instead to tell Linux that those addresses are reserved, and that the vrings should be placed outside those bounds.  Do you have any information on how to control that?

    Another question: Is the PRU stack placed by the linker in low DRAM0 too?  Maybe we need both solutions to protect those locations, although the legacy code works well in Linux 3.8.

    Robert

  • Robert,

    The vrings are placed in DDR (not PRU DRAM) by the Linux kernel. The placement of vrings does not seem to be your issue.

    The solution that I posted above should work for your use case. To protect your hard coded locations from the PRU you need to change your AM335x_PRU.cmd file as shown above and then rebuild your PRU firmware. To check where the linker is placing things (PRU stack included) you can check the generated .map file that was referenced above as well.

    Jason Reeder