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.

[SOLVED] PRU C compiler failed math? No, the programmer failed pointers.



Hi,

I have the following function in the PRU to initialize a two-dimensional array (pointers into that array get passed back to a Linux program). The function was purposely made verbose to avoid confusion, yet the compiler seems confused anyway. All optimizations are turned off.

/* Clear all position arrays to zero */
void	clearBuffer()
{
	int	i, j, k=50;

	for ( i=0 ; i<RING_SIZ ; i++ )
	{
		for ( j=0 ; j<MAX_NODES ; j++ )
		{
			positions[i][j] = k*10;
			k = k+1;
		}
	}
}

Now you would expect this code to generate the sequence 500, 510, 520, 530, 540,  . . . 950, 960, 970

But instead, it generates the following sequence:

 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547,

It appears to me that the compiler is doing the multiply k*10 only once, and then incrementing from there, rather than multiplying after each increment. This is a serious issue for me, as I need to do a lot of scaling in the PRU.


Thanks for any help.

Mark

  • I am unable to reproduce this result.  Please submit an example I can compile.  What compiler version?  Please show exactly which compiler options you use.

    Thanks and regards,

    -George

  • Hi George,

    Thanks for the reply.

    I compile using a batch file and two command files (one for the compiler/assembler and one for the linker). Here is the batch file, compile.bat:

    clpru -@=C-options louma2pru.c -@=Link-options -o=louma2pru.out -m=louma2pru.map link.cmd louma2pru.obj
    hexpru "C:\Program Files\TI_PRU_2.0.0B2\bin.cmd" louma2pru.out
    del louma2pru.obj louma2pru.out louma2pru.bin data.bin
    rename text.bin louma2pru.bin
    copy louma2pru.bin \\Beaglebone\louma2\
    pause

    Here is the compiler and assembler's command file, C-options:

    --opt_level=off
    #--opt_level=5
    #--opt_for_speed=4
    --include_path=include
    #--asm_listing
    #--absolute_listing  ##NOTE: This causes the object file to not be generated
    #--c_src_interlist
    #--keep_asm
    --abs_directory=.
    --list_directory=.

    And here is the linker's command file, Link-options:

     --run_linker
     --ram_model
     --search_path="C:\Program Files\TI_PRU_2.0.0B2\lib"

    The compiler version is  v2.0.0B2

    The source code is rather large right now - it has a lot of UART, eCAP and interrupt code included. Give me some time to pair it down, and I will post the result.

    Thanks,

    Mark

  • Hi again, George:

    After 10 days of no replies to another thread (I know, the holidays), Melissa just informed me that there is a newer version. (v2.1.0)?

    So don't waste any time with this until I try the latest compiler. I will report back soon.

    mark
  • Well, that was disappointing . . .

    I upgraded to the latest compiler/assembler version, but still the same problem.

    I will now pare-down the code to a reasonable size that can be posted.
  • Hi George,

    I added in the .h file and then chopped out everything except the failing math (in the clearBuffer() function) and the parts of main() that allow me to access the results (I assume you have better methods of examining the results). This code can be built using the batch and command files attached in my previous post. Let me know if you need anything else.

    /*
     * Failing Math test.
     */
    
    #include <stdint.h>
    //#include "../louma2pru.h"
    //
    // DEBUG: The following is from "louma2pru.h".
    //
    /*
    	Constant definitions:
    */
    #define	PRUtoARM_event0 0x23
    
    #define MAX_NODES	12
    #define RING_SIZ	4
    
    /*
    	Structure declarations:
    */
    typedef struct {
        int UpdateRate;
        int BufferIndex;
        int NodeStatus[MAX_NODES];
    } pruCtrl;
    
    /*
    	Global variables:
    */
    extern void*	pruDataMem;								// The pointer into PRU data memory
    extern int		positions[RING_SIZ][MAX_NODES];	// array of buffers for all axis positions
    //
    // End of necessary peices of "louma2pru.h".
    //
    
    volatile register uint32_t __R31;
    
    /* This hostBuffer structure allows the PRU to know the number of Louma2
     * network periods per OSC update. It also lets the host know the array-index
     * of the most recent position data and also the network status of each node.
     * This structure is in the PRU-0 data memory starting at address 0
     */
    #pragma LOCATION(PruControl, 0)
    volatile pruCtrl PruControl;				// control structure shared with the host
    
    /* This positions array is used to pass the received position data to the host */
    #pragma LOCATION(positions, sizeof(pruCtrl))
    int	positions[RING_SIZ][MAX_NODES];	// array of buffers for all axis positions
    
    
    // MATH PROBLEM
    // This should initialize the array to:	100, 110, 120, 130 . . . 
    //  But instead, the array is built as:	100, 101, 102, 103 . . .
    //
    void	clearBuffer()
    {
    	int	i, k=10;
    
    	for ( i=0 ; i<RING_SIZ*MAX_NODES ; i++ )
    	{
    			positions[0][i] = k*10;
    			k += 1;
    	}
    }
    
    
    void main()
    {
    	int i, j;
    	volatile int zzz;
    
    	clearBuffer();
    
    	/*		MAIN LOOP	*/
    	for ( i=0 ;; i=++i%RING_SIZ ) {						// Loop here for each OSC update. forever.
    		for ( j=PruControl.UpdateRate ; j ; j-- )		// Loop for each pile of "UpdateRate" packets
    			for ( zzz=60000 ; zzz ; zzz-- );				// DEBUG: spin, trying to delay for 3 milliseconds
    
    		// Issue an interrupt to the linux software.
    		PruControl.BufferIndex = i;		// bump the index to the most recent array
    		__R31 = PRUtoARM_event0;			// tell the linux program we have new position data
    	}
    }
    

    Sorry if the formatting looks bad in this post - it was good in my editor, but I don't know how to set the tab spacing to 3 in this window.

  • Hi George,

    OK, false alarm, my fault . . .

    The PRU is correctly calculating the array, but the Linux routine was incorrectly displaying it. Due to missing parentheses,  for each array member it was supposed to display, the host side was taking the value of the first array member, and then adding the index to it to display, rather than displaying the value of each array member.

    We have sent that programmer back to "C pointer" school.


    Sorry for the bum steer.

    mark