PRU compiler Optimization Issue

124 views
Skip to first unread message

Bill Bitner

unread,
Dec 1, 2018, 3:33:25 PM12/1/18
to BeagleBoard
Hi!

First, a *big* thanks to Mark Yoder, who kindly put a whole lot of information together to help me figure this out.

I'm attempting to using the BBB to make a simple motor controller and will use the PRU's to do the critical timing
events.    To demonstrate a baby step, I decided to play around with an ultrasonic detector to prove I could generate
timed pulses, and also time an incoming pulse.   I started using Mark's PruCookbook set up.   I found that using
the -O 2 flag for clpru, the compiler would *delete* certain looping code.   Removing the flag would run the code
properly.   It took a while to figure out what was happening since I'm not an expert in assembly, but looking at
the .lst file and using prudebug and single stepping showed me what the problem was.

Details:

while (1)
        {

            runState = pru0Dram[0]; 
            if (runState == 0)
            {
                __R30 &= ~gpio;         // Set the GPIO pin to 0, this should be a 10 us pulse
                continue;
            }

            onTime  = pru0Dram[1]; 

            __R30 |= gpio;
 >>>           while(1)
            {
                if (counter > onTime)
                {
                    __R30 &= ~gpio;         // Set the GPIO pin to 0, this should be a 10 us pulse
                    break;
                }
                counter += 1;
            }

            inputState = 0;


without the -O 2 flag, the compiler generates the following assembly code.


    259;----------------------------------------------------------------------
     260;  54 | __R30 |= gpio;                                                         
     261;----------------------------------------------------------------------
     262 0000007c 000000F1002281          LBBO      &r1, r2, 0, 4         ; [ALU_PRU] |54| gpio
     263 00000080 00000012E1FEFE          OR        r30, r30, r1          ; [ALU_PRU] |54| 
     264        .dwpsn  file "pruUltraSonic2.c",line 55,column 19,is_stmt,isa 0
     265;----------------------------------------------------------------------
     266;  55 | while(1)                                                               
     267;----------------------------------------------------------------------
     268;* --------------------------------------------------------------------------*
     269;*   BEGIN LOOP ||$C$L3||
     270;*
     271;*   Loop source line                : 55
     272;*   Loop closing brace source line  : 63
     273;*   Known Minimum Trip Count        : 1
     274;*   Known Maximum Trip Count        : 4294967295
     275;*   Known Max Trip Count Factor     : 1
PRU Assembler Unix v2.3.1 Sat Dec  1 17:26:17 2018

Tools Copyright (c) 2012-2017 Texas Instruments Incorporated
/tmp/pru0-gen/pruUltraSonic2.asm                                     PAGE    6

     276;* --------------------------------------------------------------------------*
     277 00000084                 ||$C$L3||:    
     278        .dwpsn  file "pruUltraSonic2.c",line 57,column 17,is_stmt,isa 0
     279;----------------------------------------------------------------------
     280;  57 | if (counter > onTime)                                                  
     281;----------------------------------------------------------------------
     282 00000084 000000F1142280          LBBO      &r0, r2, 20, 4        ; [ALU_PRU] |57| counter
     283 00000088 00000058E0EE04          QBLE      ||$C$L4||, r14, r0    ; [ALU_PRU] |57| 
     284;* --------------------------------------------------------------------------*
     285        .dwpsn  file "pruUltraSonic2.c",line 59,column 21,is_stmt,isa 0
     286;----------------------------------------------------------------------
     287;  59 | __R30 &= ~gpio;         // Set the GPIO pin to 0, this should be a 10 u
     288;     | s pulse                                                                
     289;----------------------------------------------------------------------
     290 0000008c 0000001600E1E0          NOT       r0, r1                ; [ALU_PRU] |59| 
     291 00000090 00000010E0FEFE          AND       r30, r30, r0          ; [ALU_PRU] |59| 
     292        .dwpsn  file "pruUltraSonic2.c",line 60,column 21,is_stmt,isa 0
     293;----------------------------------------------------------------------
     294;  60 | break;                                                                 
     295;----------------------------------------------------------------------
     296 00000094 00000021000000!         JMP       ||$C$L5||             ; [ALU_PRU] |60| 
     297;* --------------------------------------------------------------------------*
     298 00000098                 ||$C$L4||:    
     299        .dwpsn  file "pruUltraSonic2.c",line 62,column 17,is_stmt,isa 0
     300;----------------------------------------------------------------------
     301;  62 | counter += 1;                                                          
     302;----------------------------------------------------------------------
     303 00000098 0000000101E0E0          ADD       r0, r0, 0x01          ; [ALU_PRU] |62| 
     304 0000009c 000000E1142280          SBBO      &r0, r2, 20, 4        ; [ALU_PRU] |62| counter
     305        .dwpsn  file "pruUltraSonic2.c",line 55,column 19,is_stmt,isa 0
     306 000000a0 00000021000000!         JMP       ||$C$L3||             ; [ALU_PRU] |55| 

With the -O2 flag present, the compiler generates
  187;  54 | __R30 |= gpio;                                                         
     188;  55 | while(1)                                                               
     189;  57 |     if (counter > onTime)                                              
     190;----------------------------------------------------------------------
     191 00000020 0000001F00FEFE          SET       r30, r30, 0x00000000  ; [ALU_PRU] |54| 
     192        .dwpsn  file "pruUltraSonic2.c",line 59,column 21,is_stmt,isa 0
     193;----------------------------------------------------------------------
     194;  59 | __R30 &= ~gpio;         // Set the GPIO pin to 0, this should be a 10 u
     195;     | s pulse                                                                
     196;  60 | break;                                                                 
     197;  62 | counter += 1;                                                          
     198;  65 | inputState = 0;                                                        
     199;  66 | didSeeHigh = 0;                                                        
     200;  67 | timerWhenHigh = 0;                                                     
     201;  68 | counter = 0;                                                           
     202;----------------------------------------------------------------------
     203 00000024 0000001D00FEFE          CLR       r30, r30, 0x00000000  ; [ALU_PRU] |59| 
     204        .dwpsn  file "pruUltraSonic2.c",line 69,column 13,is_stmt,isa 0
     205;----------------------------------------------------------------------


Notice that there is No looping code.    It sets the R30 (gpio) and then imediately clears CLR R30.
This really took a while to figure out what was happening.     I downloaded the newest compiler version from TI and
the issue remains...     I haven't tried other levels of optimization to find out if the issue still exists.

Bill Bitner

Dennis Lee Bieber

unread,
Dec 1, 2018, 7:21:46 PM12/1/18
to beagl...@googlegroups.com
On Sat, 1 Dec 2018 12:33:25 -0800 (PST), Bill Bitner
<wjbi...@gmail.com> declaimed the following:

>PruCookbook set up. I found that using
>the -O 2 flag for clpru, the compiler would *delete* certain looping code.
> Removing the flag would run the code
>properly. It took a while to figure out what was happening since I'm not

Try declaring some of the loop controlling variables "volatile" -- that
should tell the compiler that they can change state /external/ to the
actions of the loop itself.

>
>while (1)
> {
>
> runState = pru0Dram[0];

for example, pru0Dram

> if (runState == 0)
> {
> __R30 &= ~gpio; // Set the GPIO pin to 0, this
>should be a 10 us pulse
> continue;

just as a style -- I'd probably drop the "continue" and code the rest as an
"else" block
> }
>
> onTime = pru0Dram[1];
>
> __R30 |= gpio;
> >>> while(1)
> {
> if (counter > onTime)

I don't see any code initializing "counter" -- did you snip some
intervening code? And again, if not volatile, the compiler may be assuming
pru0Dram initializes as 0, and also assumes it never changes, so any
non-zero value of counter will set R30 and exit the loop -- that comes down
to one loop pass doing nothing but incrementing counter, and the second
loop pass sets R30/exits.


> {
> __R30 &= ~gpio; // Set the GPIO pin to 0, this
>should be a 10 us pulse
> break;
> }
> counter += 1;
> }
>


--
Wulfraed Dennis Lee Bieber AF6VN
wlf...@ix.netcom.com HTTP://wlfraed.home.netcom.com/

Bill Bitner

unread,
Dec 2, 2018, 8:12:33 PM12/2/18
to beagl...@googlegroups.com
Hi Dennis!

Thank you very  much!   Your comments are spot on and tell me where to look!
I hadn't used 'volatile' and that certainly messed things up :)   Thank you again for
your quick response and great help.. 
Have a great week.

Bill

--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/beagleboard/fd860e1a5r49nvengb6gbbv2b3d88vlhlb%404ax.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages