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.

Compiler/OMAP-L138: Migration from pasm to PRU C Compiler

Part Number: OMAP-L138

Tool/software: TI C/C++ Compiler

Hi there,

TI Support told me to ask my question here, for there are more technical experts available. At the moment, I develop on a device using OMAP-L138. It is based on an actual product, where the colleagues used TI pasm tool to create a C Array out of the code written in assembly language. This array was loaded to PRU Instruction RAM before PRU was started. Now we want to switch over to program the PRU in C and use TI PRU C Compiler. Now I wonder how I have to edit lnk.cmd that I get the same situation like using pasm. I tried with the settings provided here: e2e.ti.com/.../571029

But the problem is that I don't want to get two Arrays for loading one to PRU instruction ram and the other to PRU data ram. I would like to get a single Array (just like pasm generates) that I can load to PRU instruction ram. The Reason is that our PRU Data Ram is full with a data structure ARM provides for the PRU before PRU is started. How do I have to change the linker cmd File that i get a setting like described above? Unfortunately, I am not very firm to Compiler & Linker structure and work, I am very new to these topics.

I hope you can understand my problem, any hints are appreciated.

Another question: In Technical Reference manual spruh77c it says that PRU Cycle Counter (In the registers on address 0x780c) can only be cleared to 0 if PRU is disabled. In my old Assembler Program, this cycle Counter is cleared right in the assembly code. How can this work?

Best regards,

Chris

  • Hi Chris,

    We're looking into this...

    Regards,
    Sahin

  • Hi Sahin,

    thank you for your quick reply. I'm looking forward to hearing from you.

    Regarding my question concerning the PRU cycle counter I think I found the solution already:
    It is only impossible to write / clear the PRU cycle counter from the Host while PRU is running. PRU itself can reset its cycle counter while running.
    I've tested this yesterday, I wrote a little Assembler routine which clears the PRU cycle counter in an endless loop, assembled it using pasm and loaded it into the PRU. That worked fine.

    So my other question regarding PRU C Code Generation is the only one left.

    Best Regards,

    Chris

  • Thanks for the update. Glad to hear you found a solution.

    Our PRU expertise on this device is limited so I apologize in advance for that, but hopefully we can find you a solution. 

    >>  I would like to get a single Array (just like pasm generates) that I can load to PRU instruction ram.

    Do you know the name of this array? Is it .init_array in the linker command file linked above? (I'm not familiar with the pasm tool)

    If so, I believe you can do something like below to place it in instruction ram:

    MEMORY
    {
          PRUIMEM:   o = 0x00000000  l = 0x00001000  /* 4kB PRU0 Instruction RAM */
          PRUDMEM:   o = 0x00001000  l = 0x00000200  /* 512B PRU Data RAM 0 */
    }
    
    SECTIONS
    {
        .text:_c_int00* >  0x0
        .text          >  PRUIMEM
        .bss           >  PRUIMEM
        .data          >  PRUIMEM
        .rodata        >  PRUIMEM
        .farbss        >  PRUIMEM
        .fardata       >  PRUIMEM
        .rofardata     >  PRUIMEM
        .sysmem        >  PRUIMEM
        .stack         >  PRUIMEM
        .init_array    >  PRUIMEM
        .cinit         >  PRUIMEM
        .args          >  PRUIMEM
    }
    

    This places all sections in instruction RAM (PRUIMEM), which is what I believe you wanted since the data ram is full in your application. 

    Let me know if this works for you or not.

    Regards,
    Sahin

  • Hi Sahin,

    thank you for your suggestions. Based on your explanations I tried the following setup:

    -cr /* LINK USING C CONVENTIONS */
    -stack 0x040 /* SOFTWARE STACK SIZE */
    -heap 0x100 /* HEAP AREA SIZE */
    /*--args 0x100 */
    
    /* SPECIFY THE SYSTEM MEMORY MAP */
    
    MEMORY
    {
    PAGE 0:
    PRUIMEM: org = 0x00000000 len = 0x00001000 /* 4kB PRU0 Instruction RAM */
    
    PAGE 1:
    PRUDMEM: org = 0x00000000 len = 0x00000200 /* 512B PRU Data RAM 0 */
    
    }
    
    /* SPECIFY THE SECTIONS ALLOCATION INTO MEMORY */
    
    SECTIONS
    {
    .text:_c_int00* > 0x0
    .text > PRUIMEM, PAGE 0
    .bss > PRUIMEM, PAGE 0
    .data > PRUIMEM, PAGE 0
    .rodata > PRUIMEM, PAGE 0
    .farbss > PRUIMEM, PAGE 0
    .fardata > PRUIMEM, PAGE 0
    .rofardata > PRUIMEM, PAGE 0
    .sysmem > PRUIMEM, PAGE 0
    .stack > PRUDMEM, PAGE 1
    .init_array > PRUIMEM, PAGE 0
    .cinit > PRUIMEM, PAGE 0
    
    .args > PRUIMEM, PAGE 0
    
    }

    I left the Stack section in Data Ram, that works for me. Important is, that both, the Data RAM and the Instruction RAM start with the Address 0x00000000!

    When I tried first, it didn't work, but now I found out with another post in this forum that Compiler Option --silicon_version has to be set to 1 for OMAP-L138!
    Now it works perfectly and I can go on working!

    Thank you for your kind assistance!

    Best Regards,

    Chris

  • ########################### IMPORTANT UPDATE!!! #####################################

    Hi OMAP-Programmers,

    i have to correct my above statement!

    First, i thought, that Sahin's hint would work. On first sight, it worked perfect, but then strange effects occured, for example the code execution was stopped while PRU cycle Counter was still incrementing. Errors occured at several points in the code.

    I found out, that .bss and .stack section MUST NOT be located in Instruction  RAM!

    The Following mem map does now work for me:

    -cr /* LINK USING C CONVENTIONS */
    -stack 0x040 /* SOFTWARE STACK SIZE */
    -heap 0x100 /* HEAP AREA SIZE */
    /*--args 0x100 */
    
    /* SPECIFY THE SYSTEM MEMORY MAP */
    
    MEMORY
    {
    PAGE 0:
    PRUIMEM: org = 0x00000000 len = 0x00001000 /* 4kB PRU0 Instruction RAM */
    
    PAGE 1:
    PRUDMEM: org = 0x00000000 len = 0x00000200 /* 512B PRU Data RAM 0 */
    
    }
    
    /* SPECIFY THE SECTIONS ALLOCATION INTO MEMORY */
    
    SECTIONS
    {
    .text:_c_int00* > 0x0
    .text > PRUIMEM, PAGE 0
    .bss > PRUDMEM, PAGE 1
    .data > PRUIMEM, PAGE 0
    .rodata > PRUIMEM, PAGE 0
    .farbss > PRUIMEM, PAGE 0
    .fardata > PRUIMEM, PAGE 0
    .rofardata > PRUIMEM, PAGE 0
    .sysmem > PRUIMEM, PAGE 0
    .stack > PRUDMEM, PAGE 1
    .init_array > PRUIMEM, PAGE 0
    .cinit > PRUIMEM, PAGE 0
    
    .args > PRUIMEM, PAGE 0
    
    }

    But please pay attention! All the other sections which are still moved into I-RAM, are empty in my example program. I do not know, if the above problems occur again if these sections are used! If you only put .text section in I-RAM it is certainly correct. If you have space problems in D-RAM like me, and use more sections than me, you will have to give a try, which sections can be placed in IRAM without errors.