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.

AM2634: PRU C compiler: unable to access a const table

Part Number: AM2634

Dear TI support service,

I am using your PRU C compiler to implement a simple xy2 100 stream generator, and I noticed that defining a const table like:

__far static const uint32_t table_yx_clock_hi_const[4] =
{
        def_xy2_100_clock_hi | def_xy2_100_sync_hi | 0,
        def_xy2_100_clock_hi | def_xy2_100_sync_hi | (1 << def_xy2_100_x_shift),
        def_xy2_100_clock_hi | def_xy2_100_sync_hi | (1 << def_xy2_100_y_shift),
        def_xy2_100_clock_hi | def_xy2_100_sync_hi | (1 << def_xy2_100_y_shift) | (1 << def_xy2_100_x_shift),
};
The table is place din IMEM (page 0), so far so good.
 
But when trying to access the table, the compiler generates an LBBO instruction that access the table as if it was in DMEM, while the table has been placed in IMEM.
It seems that the compiler tries to access the table at an address in DMEM that has the same numeric value as the table address in IMEM, but this is wrong because the table as stated is in IMEM.
I wonder if:
  • is there a way to access data stored in IMEM
  • is there any other way to access the const table?

 

Best regards and many thanks for your help

  • Hi,

    Please note that due to the holiday season, there may be some delay in responses. 

    Best Regards,
    Aishwarya

  • Hi
    Isn't it better to put data in DMEM? IMEM is instruction memory.

    Regards

    Dhaval

  • Hello,

    It is possible to define a section of memory in IMEM at a specific address, and then use the assembly JMP command to jump to that address. (I have seen this used in very timing constrained usecases to save a couple of clock cycles when the code needs to jump to one of a large number of functions, but if you are programming in C I assume that you do not have such tight constraints). However, as far as I am aware there is not a good way to use IMEM for data storage. As you noted, the PRU cores are designed to use DMEM0, DMEM1, and SMEM for local data storage.

    For a general overview of read/write latencies, please refer to this FAQ. AM26x will behave similarly to AM62x:
    [FAQ] PRU: How do I calculate read and write latencies?

    Regards,

    Nick

  • s there a way to access data stored in IMEM

    No, IMEM is exclusive for instructions and not data !!!

    is there any other way to access the const table?

    Yes, keep the const table in DMEM or SMEM. (+) LP-AM261: Problems when loading C application on the PRU programmatically (stuck in __TI_decompress_lzss) - Arm-based microcontrollers forum - Arm-based microcontrollers - TI E2E support forums has example of loading .data section during init

  • OK the problem IMHO is that using a legit C construct, an incorrect assembly code is generated.

    Can you confirm that using the const reserved word generates a bug where the table is placed in IMEM but the code accesses it as if it was in DMEM?

    Thanks

  • Hello Michele,

    Please share your linker.cmd file so we can see how you are instructing the linker to place the data.

    Regards,

    Nick

  • Hi, Mr Saulnier!

    Many thanks for your reply and sorry for the delay!

    Attached you can find my linker.cmd file.

    I have defined the array parity8_const

    static const uint8_t parity8_const[256] = {
      0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
      1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
      1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
      0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
      1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
      0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
      0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
      1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
      1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
      0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
      0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
      1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
      0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
      1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
      1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
      0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0
    };

    and it is accessed on the main() function so that it is not discarded

    I attach the generated map file too.

    As you can see in the attached map file, the array parity8_const is placed on page 0, this way it can't be accessed:

    .rodata    0    00000d10    00000100     
                      00000d10    00000100     main.obj (.rodata:.string:parity8_const)

    Many thanks again for your help

    Michele

  • Hi

    I am unable to see the attached linker file. Can you please paste relevant lines or attach the file again?

    Regards

    Dhaval

  • Hi, dear TI support service!

    It seems that the attachments got lost..

    Please see in the following my linker.cmd file:

    /* Specify the System Memory Map */
    MEMORY
    {
        PRU0_CTRL: origin=0x22000 length=1024 CREGISTER=4

        PAGE 0:
          /* 12 KB PRU Instruction RAM */
          PRU_IMEM          : org = 0x00000000 len = 0x00003000

        PAGE 1:
          /* Data RAMs */
          /* 8 KB PRU Data RAM 0 */
          PRU0_DMEM_0       : org = 0x00000000 len = 0x00002000 CREGISTER=24
          /* 8 KB PRU Data RAM 1 */
          PRU0_DMEM_1       : org = 0x00002000 len = 0x00002000 CREGISTER=25

        PAGE 2:
          /* C28 needs to be programmed to point to SHAREDMEM, default is 0 */
          /* 32 KB Shared general purpose memory RAM with ECC, shared between PRU0 and PRU1 */
          PRU_SHAREDMEM     : org = 0x00010000 len = 0x00008000 CREGISTER=28

        // IMPORTANT
        // the value 11 for CREGISTER is found in the AM263P_tech_ref_spruj55d.pdf file
        // chapter 7.3.5.2.1 PRU Constant Table
        // EntryNo. Region Pointed To             Value [31:0]
        // 11       PRU-ICSS PRU0 Control (local) 0002_2000h PRU0
        //
        // or, just check the file: C:\ti\pru_support_package\labs\Getting_Started_Labs\assembly_code\solution\am62x\AM62x_PRU0.cmd
        // where all the settings are explicited
        //
          PRU0_CTRL: origin=0x00022000 length=0x30 CREGISTER=11

    }

    /* Specify the sections allocation into memory */
    SECTIONS {

        .text:_c_int00* >  0x0, PAGE 0
        .text           >  PRU_IMEM,    PAGE 0
        .data_RAM : ALIGN(4)
        {
          *(PRU_sync)
        } > PRU0_DMEM_0, PAGE 1
        .bss            >  PRU0_DMEM_0, PAGE 1
        .stack          >  PRU0_DMEM_0, PAGE 1
        .shared_RAM : ALIGN(4)
        {
          *(shared_PRUs)
        }> PRU_SHAREDMEM, PAGE 2
    }
  • Hi

    We need to put .rodata section in DMEM/SMEM in linker file. 

    Please check following linker file for reference: open-pru/source/linker_cmd/c_code/am263x/AM263x_PRU0.cmd at main · TexasInstruments/open-pru · GitHub

    Regards

    Dhaval