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.

long long comparison issue

Other Parts Discussed in Thread: AM3359

hello,

I use clpru compiler for am3359's PRU. Here is a code which seems to work in a wrong way:

volatile long long time=0, adcTime=0;	
while (1) { adcTime = time; time+=1000; if (time >= adcTime + (long long)(20000)) { msg(time, adcTime); break; } }

"if" fires when (adcTime + 20000) becomes greater when 2^32.

msg: 4294949000( 4294948000 )

here asm part:

;* --------------------------------------------------------------------------*
;*   BEGIN LOOP ||$C$L18||
;*
;*   Loop source line                : 136
;*   Loop closing brace source line  : 144
;*   Known Minimum Trip Count        : 1
;*   Known Maximum Trip Count        : 4294967295
;*   Known Max Trip Count Factor     : 1
;* --------------------------------------------------------------------------*
||$C$L18||:    
	.dwpsn	file "pru_main.c",line 137,column 3,is_stmt,isa 0
        LDI       r0, ||time||          ; [ALU_PRU] |137| time
        LBBO      &r0, r0, 0, 8         ; [ALU_PRU] |137| 
        SBBO      &r0, r2, 68, 8        ; [ALU_PRU] |137| adcTime
	.dwpsn	file "pru_main.c",line 139,column 3,is_stmt,isa 0
        LDI       r14, ||time||         ; [ALU_PRU] |139| time
        LDI       r16, 0x03e8           ; [ALU_PRU] |139| 
        ZERO      &r15, 4               ; [ALU_PRU] |139| 
        LBBO      &r0, r14, 0, 8        ; [ALU_PRU] |139| 
        ADD       r0, r16, r0           ; [ALU_PRU] |139| 
        ADC       r1, r15, r1           ; [ALU_PRU] |139| 
        SBBO      &r0, r14, 0, 8        ; [ALU_PRU] |139| 
	.dwpsn	file "pru_main.c",line 140,column 3,is_stmt,isa 0
        LDI       r15, 0x4e20           ; [ALU_PRU] |140| 
        ZERO      &r14, 4               ; [ALU_PRU] |140| 
        LBBO      &r0, r2, 68, 8        ; [ALU_PRU] |140| adcTime
        ADC       r14, r14, r1          ; [ALU_PRU] |140| 
        ADD       r15, r15, r0          ; [ALU_PRU] |140| 
        XOR       r14.b3, r14.b3, 0x80  ; [ALU_PRU] |140| 
        LDI       r0, ||time||          ; [ALU_PRU] |140| time
        LBBO      &r0, r0, 0, 8         ; [ALU_PRU] |140| 
        XOR       r1.b3, r1.b3, 0x80    ; [ALU_PRU] |140| 
        QBLT      ||$C$L18||, r14, r1   ; [ALU_PRU] |140| 
;* --------------------------------------------------------------------------*
        QBGT      ||$C$L19||, r14, r1   ; [ALU_PRU] |140| 
;* --------------------------------------------------------------------------*
        QBLT      ||$C$L18||, r15, r0   ; [ALU_PRU] |140| 
;* --------------------------------------------------------------------------*

I'm not so good at asm to understand is right or not. Or may be there is my misunderstanding?

  • Not an expert in PRU assembly, but the second 64-bit add looks wrong: it appears that the carry bit is used (in ADC) before it is produced (in ADD).

    Because the first addition looks different, you might want to avoid the explicit cast of 20000 to long long and maybe assign the result of adcTime + 20000 to a temporary instead of using that expression inside the if.

  • I use the next workaround : if (time - adcTime >= (long long)(20000))

    Now it works but I'd like to draw TI's employee attention to this issue. How to do it?
  • I cannot reproduce the exact same assembly output from the compiler.  I can get close.  But that's not good enough.

    Please preprocess the source file that has this problem.  Attach the resulting preprocessed source file to your next post.  Indicate the name of the function where the problem occurs.  What compiler version do you use?  Please show the compiler build options used. 

    Thanks and regards,

    -George

  • hereis shortened source file.

    the error occur in main() function.

    clpru version:

    v2.1.1
    Build Number 1PCGL-0QRTSXTX-UAYAS-TAQ-ZAFHK_S_R_R

    build command:

    /usr/bin/clpru \

    --silicon_version=2 \

    --hardware_mac=on \

    --keep_asm \

    -i$PRU_CGT_DIR/include \

    -i$PRU_CGT_DIR/lib \

    -O0 \

    -c \

    pru_main.c

    pru_main.asm

    pru_hal.c
    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    #include <stdint.h>
    //volatile register uint32_t __R30; // Output pins
    volatile register uint32_t __R31; // Input pins
    //#define CTRL 0x22000 //Start of control registers
    void adc_init_Uc(void)
    {
    __asm__ __volatile__
    (
    //Init ADC CLKDIV
    " LDI32 r8, 0x44E0D04C \n"
    " LDI32 r9, 0x00000000 \n"
    " SBBO &r9, r8, 0, 4 \n"
    );
    __asm__ __volatile__
    (
    //Init ADC CTRL register to enable step editing
    " LDI32 r8, 0x44E0D040 \n"
    " LDI32 r9, 0x00000004 \n"
    " SBBO &r9, r8, 0, 4 \n"
    );
    __asm__ __volatile__
    (
    //ts charge delay
    " LDI32 r8, 0x44E0D060 \n"
    " LDI32 r9, 0x00000001 \n"
    " SBBO &r9, r8, 0, 4 \n"
    );
    __asm__ __volatile__
    (
    //Init ADC STEPCONFIG 1
    " LDI32 r8, 0x44E0D064 \n"
    " LDI32 r9, 0x002A8010 \n"
    " SBBO &r9, r8, 0, 4 \n"
    );
    __asm__ __volatile__
    (
    //Init ADC STEPDELAY 1
    " LDI32 r8, 0x44E0D068 \n"
    " LDI32 r9, 0x00000008 \n"
    " SBBO &r9, r8, 0, 4 \n"
    );
    __asm__ __volatile__
    (
    //Enable ADC steps //STEPENEBLE mask
    " LDI32 r8, 0x44E0D054 \n"
    " LDI32 r9, 0x0000002 \n"////enable 5 channels
    " SBBO &r9, r8, 0, 4 \n"
    );
    __asm__ __volatile__
    (
    //disable step editing
    " LDI32 r8, 0x44E0D040 \n"
    " LDI32 r9, 0x00000000 \n"
    " SBBO &r9, r8, 0, 4 \n"
    );
    }
    void adc_init_I1(void)
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    pru_hal.h

    pru_main.c
    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    #include <stdint.h>
    #include "pru_hal.h"
    //#include "comm.h"
    #define G4 4294967295
    #define TICK_TIME 200//ticks per us
    #define PIN_HIGH(x) __R30 = __R30 | (1 << x);
    #define PIN_LOW(x) __R30 = __R30 & ~(1 << x);
    #define I_COEF 8.53
    #define IMAX 100
    #define IMIN 50
    #define U_TARG 90
    #define U_TARG_DELTA 1
    #define K 6
    #define PREADC 22 * TICK_TIME
    #define AVG_ARR_SIZE 100
    #define AI_CH_NUM 5
    #define L 56//uH
    #define E 14//V
    #define B1 9//V
    #define B2 15//V
    #define UC_DELAY 70
    #define TAU_RELAX_MAX 1000
    #define TAU_RELAX_MIN 10
    #define STEPS_TO_DO 100000
    #define DEBUG_STEPS 30
    #define K_UC (float)0.285
    volatile register uint32_t __R30; // Output pins
    volatile uint32_t last_cnt;
    volatile long long time;//, t1, t2, t3;
    volatile uint32_t cnt;
    volatile uint32_t vv;
    volatile uint32_t state, I1, Uc, alg;
    volatile uint32_t cfgU, cfgdU, cfgImax, cfgImin;
    void error(uint32_t err, uint32_t add)
    {
    shm_write_uint32((PRU_MEM_ERR) * 4, err);
    shm_write_uint32((PRU_MEM_ERR_ADD) * 4, add);
    state = PRU_STATE_ERROR;
    }
    void msg(uint32_t err, uint32_t add)
    {
    shm_write_uint32((PRU_MEM_MSG) * 4, err);
    shm_write_uint32((PRU_MEM_MSG_ADD) * 4, add);
    }
    int main(void)
    {
    volatile long long dt, charge1Time, charge2Time, UcTime, adcTime, p;
    volatile uint32_t cur_avg;
    ocp_init();
    shm_init();
    error(PRU_ERR_NONE, 0);
    msg(PRU_MSG_NONE, 0);
    cur_avg = time = charge1Time = charge2Time = 0;
    while (1) {
    adcTime = time;//время запуска АЦП
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • I have not found cl6x on my machine to preprocess sources.
  • Thank you for submitting a test case.  I can reproduce the same error.  I filed SDSCM00052375 in the SDOWP system to have this investigated.  You are welcome to track it with the SDOWP link below in my signature.

    Gigo Dret said:
    I have not found cl6x on my machine to preprocess sources

    You don't need to submit a preprocessed test case any longer.  But to answer your question ... cl6x is the compiler for the TI C6000 family of devices.  Substitute clpru instead.

    Thanks and regards,

    -George