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/AM3358: Porting pasm to c code struct definition

Part Number: AM3358

Tool/software: TI C/C++ Compiler

Hi, 

I am currently porting a functional pasm program to a c code wrapper (thus keeping as much of the assembler code as possible)

In the original program a struct is defined as following:

.struct AppParams
.u32 RunFlag
.u32 DDRBaseAddress
.u32 DDRBytesAvailable
.u32 delayCycles
.u32 numChannels
.ends

I would like to port this into an __asm__ __volatile(...) format, however I haven't succeeded yet.

I tried the format written in the spruhv6 manual, as well as some minor changes.

What is the right format for defining an asm struct that can be compiled by clpru 2.1.5?

Kind regards,
Rens

  • Rens Baeyens said:
    however I haven't succeeded yet.

    Please elaborate.  What goes wrong?  What you do look at?  How do you know that it is wrong?

    Thanks and regards,

    -George

  • Hi George, 

    Thanks for the quick reply! 

    I have made some progress since posting the item.

    Currently I define the asm struct in my c wrapper program as following:

    _asm__ __volatile__(
    " .struct AppParams   \n"
    " .int RunFlag \n"
    " .int DDRBaseAddress \n"
    " .int	DDRBytesAvailable \n"
    " .int	delayCycles \n"
    " .int	numChannels \n"
    " .endstruct \n"
    );

    This seems to give no errors.

    Can you confirm that this syntax is correct?

    ---------------------

    A further question:

    In the original program, the following is defined:

    LBBO      RUN_FLAG, ADDR_PRURAM, OFFSET(AppParams.RunFlag), 4

    I already ported this to:

    LBBO      &RUN_FLAG, ADDR_PRURAM, OFFSET(AppParams.RunFlag), 4

    How do I replace the OFFSET command?

    Currently the following errors are generated by this line:

    ERROR! at line 73: [E0009] Missing struct/union member or
    tag
    LBBO &RUN_FLAG, ADDR_PRURAM, OFFSET(AppParams.RunFlag), 4

    REMARK at line 73: [R0001] After symbol substitution the
    line became:
    LBBO &R6, R16, OFFSET(AppParams.RunFlag), 4

    ERROR! at line 73: [E0003] Invalid instruction
    LBBO &RUN_FLAG, ADDR_PRURAM, OFFSET(AppParams.RunFlag), 4

    REMARK at line 73: [R0001] After symbol substitution the
    line became:
    LBBO &R6, R16, OFFSET(AppParams.RunFlag), 4

    Thanks in advance,

    Rens

  • Hi,

    In attachment I placed the wrapper program.

    I forgot to mention this concerning the struct definition. 

    At the end of the clpru output:

    ERROR! at EOF: [E0300] The following symbols are
    undefined:
    delayCycles
    RunFlag
    numChannels
    DDRBaseAddress
    AppParams
    OFFSET
    DDRBytesAvailable

    However, these symbols are defined in the struct at the beginning of my file.

    /*AUTO GENERATED PRU PROGRAM*/
    
    #include "Beaglebone_Black.h"
    
    int main (void)
    {
    	doread(0);
    	dowrite(1);
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	doread(1);
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	dowrite(0);
    /*match sample frequency with NOPS*/
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    	nop();
    }
    

  • While I'm not certain, I think you are trying to share a structure definition between C code and assembly code.

    The best way to do that is to define the structure in C, then in assembly code, automatically inherit that structure definition by using the .cdecls directive.  Please search the PRU assembly tools manual for the chapter titled Sharing C/C++ Header Files With Assembly Source.  I recommend you learn it by writing a very small example program.  Then slowly scale it up to how it works in the final program.

    As for your question about the OFFSET command ... Just write AppParams.RunFlag.  The assembler replaces that with offset of that field in the structure.

    Please let me know if these suggestions resolve the problem.

    Thanks and regards,

    -George

  • Hi George,

    Thanks again for the elaborate answer.

    I should have clarified my purpose a bit further. 

    In the original program the struct is initiated and set by a separate c program on the main core using the shared memory.

    So in the wrapper program, I would only like to be able to use it in the assembler code, so it is not necessary to be able to use it both in c and asm in the wrapper program.

    Is it possible to provide me a small example of defining a struct in the __asm__ (..) function?

    Kind regards,

    And thanks for the great support!

    Rens

  • The more I see, the more I think you should not write this PRU code in C.  Write it in assembly instead.

    For instance ... The asm function supported by the compiler should be used very little.  Please search the PRU compiler manual for the sub-chapter titled Use Caution With asm Statements in Optimized Code.  That being the case, it does not make sense to use asm to define the layout of a structure.

    Please let me know if this suggestion resolves the problem.

    Thanks and regards,

    -George

  • Hi George,

    Thanks again for the quick reply!

    I am writing the C code asm wrapper because I am developing a generic model based code generator for control systems.

    Thus the generator develops C code based on the desired platform specifications. Currently the generator produces a c program which is basically an initialisation, followed by a series of reads and writes according to a model-defined timing diagram.

    As far as I can see, for this platform the easiest solution to implement predictable hard real time behavior is by means of wrapping the already existing asm code (which was proven functional) If I were to rewrite the existing program I would have to reevaluate the timing behavior and reliability.

    So in essence, as input for my model I provide some platform specifications (e.g. read time: 5ns). These specifications are then combined with a specified model of the desired timing diagram to generate a c program which complies with both the platform specs and the timing diagram. In this c-program the generator defines the appropriate header-file to use according to the platform. (in this case, the file I shared above) Once everything is generated it is compiled using the appropriate compiler for the platform (in this case clpru)

    Is there a cleaner way to use the asm code in a C header file?

    If not, currently the remaining compile errors are the ones related to defining the struct.

    Thanks already for the help!

    Rens

  • Rens Baeyens said:
    Is there a cleaner way to use the asm code in a C header file?

    Unfortunately, no.  

    The solutions provided by the TI PRU compiler tools support a development flow which presumes C code as the starting point, and then assembly code inherits from the C code.  It doesn't support working the other way around, where assembly code is the starting point.  

    Thanks and regards,

    -George