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.
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 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
#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) { __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, 0x00198010 \n" //AVG16 " LDI32 r9, 0x00198008 \n" //AVG4 " 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(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, 0x00000010 \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__ ( //Init ADC STEPCONFIG 2 " LDI32 r8, 0x44E0D06C \n" " LDI32 r9, 0x00110010 \n" " SBBO &r9, r8, 0, 4 \n" ); __asm__ __volatile__ ( //Init ADC STEPDELAY 2 " LDI32 r8, 0x44E0D070 \n" " LDI32 r9, 0x00000008 \n" " SBBO &r9, r8, 0, 4 \n" ); __asm__ __volatile__ ( //Init ADC STEPCONFIG 3 " LDI32 r8, 0x44E0D074 \n" " LDI32 r9, 0x00198010 \n" " SBBO &r9, r8, 0, 4 \n" ); __asm__ __volatile__ ( //Init ADC STEPDELAY 3 " LDI32 r8, 0x44E0D078 \n" " LDI32 r9, 0x00000008 \n" " SBBO &r9, r8, 0, 4 \n" ); __asm__ __volatile__ ( //Init ADC STEPCONFIG 4 " LDI32 r8, 0x44E0D07C \n" " LDI32 r9, 0x002A8010 \n" " SBBO &r9, r8, 0, 4 \n" ); __asm__ __volatile__ ( //Init ADC STEPDELAY 4 " LDI32 r8, 0x44E0D080 \n" " LDI32 r9, 0x00000008 \n" " SBBO &r9, r8, 0, 4 \n" ); __asm__ __volatile__ ( //Init ADC STEPCONFIG 5 " LDI32 r8, 0x44E0D084 \n" " LDI32 r9, 0x00330010 \n" " SBBO &r9, r8, 0, 4 \n" ); __asm__ __volatile__ ( //Init ADC STEPDELAY 5 " LDI32 r8, 0x44E0D088 \n" " LDI32 r9, 0x00000008 \n" " SBBO &r9, r8, 0, 4 \n" ); __asm__ __volatile__ ( //Enable ADC steps //STEPENEBLE mask " LDI32 r8, 0x44E0D054 \n" " LDI32 r9, 0x0000003E \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_start(void) { __asm__ __volatile__ ( //Enable ADC steps //STEPENEBLE mask " LDI32 r8, 0x44E0D054 \n" // " LDI32 r9, 0x0000003E \n"////enable 5 channels " LDI32 r9, 0x00000002 \n"////enable steps mask " SBBO &r9, r8, 0, 4 \n" ); __asm__ __volatile__ ( //enables ADC " LDI32 r0, 0x44E0D040 \n" " LDI32 r1, 0x00000001 \n" " SBBO &r1, r0, 0, 4 \n" ); } uint16_t adc_read(register uint32_t x) { /* must be compiled without optimizations */ /* r2 used for the stack pointer, do not modify */ /* r3 used for return address, do not modify */ /* x=r14, y=r15, z=r16 registers used */ /* r14 used for return values */ __asm__ __volatile__ ( /* read fifo */ " LDI32 r1, 0x44e0d100 \n" //ADC_MIO_ADDR + ADC_REG_FIFO0DATA \n" " LBBO &r14, r1, 0, 4 \n" " LDI32 r1, 0x0000ffff \n" " AND r14, r14, r1 \n" " JMP R3.w2 \n" ); return 0; } uint16_t adc_fifo_stat(register uint32_t x) { /* must be compiled without optimizations */ /* r2 used for the stack pointer, do not modify */ /* r3 used for return address, do not modify */ /* x=r14, y=r15, z=r16 registers used */ /* r14 used for return values */ __asm__ __volatile__ ( /* read fifo */ " LDI32 r1, 0x44e0d0e4 \n" //ADC_MIO_ADDR + ADC_REG_FIFO0DATA \n" " LBBO &r14, r1, 0, 4 \n" " LDI32 r1, 0x0000007f \n" " AND r14, r14, r1 \n" " JMP R3.w2 \n" ); return 0; } void cnt_start(void) { __asm__ __volatile__ ( " LDI32 r8, 0x22000 \n" //set r8 for the lbbo " LBBO &r9, r8, 0, 4 \n" // Get the control register ); __asm__ __volatile__ ( " SET r9, r9, 3 \n" // Set the cycle counter enable " SBBO &r9, r8, 0, 4 \n" // Put back to the register to start ); } void cnt_stop(void) { __asm__ __volatile__ ( " LDI32 r8, 0x22000 \n" //set r8 for the lbbo " LBBO &r9, r8, 0, 4 \n" // Get the control register ); __asm__ __volatile__ ( " CLR r9, r9, 3 \n" // Set the cycle counter enable " SBBO &r9, r8, 0, 4 \n" // Put back to the register to start ); } void cnt_clear(void) { __asm__ __volatile__ ( " LDI32 r8, 0x22000 \n" //set r8 for the lbbo " LDI32 r9, 0 \n" //set r8 for the lbbo " SBBO &r9, r8, 12, 4 \n" // Put back to the register to start ); } uint32_t cnt_get(register uint32_t x) { __asm__ __volatile__ ( " LDI32 r8, 0x22000 \n" //set r8 for the lbbo " LBBO &r14, r8, 0xC, 4 \n" // return value " JMP R3.w2 \n" ); //unreachable return 0; } void mem_write_uint32(register uint32_t x, register uint32_t y) { /* i is the absolute offset relative from shared memory start */ /* write x at shm + i */ __asm__ __volatile__ ( " SBBO &r15, r14, 0, 4 \n" ); } void ocp_init(void) { /* enable ocp wide access */ __asm__ __volatile__ ( " LBCO &r0, C4, 4, 4 \n" " CLR r0, r0, 4 \n" " SBCO &r0, C4, 4, 4 \n" ); } void shm_init(void) { /* configure the programmable pointer register for */ /* PRU0 by setting c28_pointer[15:0] field to 0x0120 */ /* this will make C28 point to 0x00012000 (PRU shared RAM). */ /* save r4, r5 */ __asm__ __volatile__ ( " SUB r2, r2, 8 \n" " SBBO &r4, r2, 0, 8 \n" ); __asm__ __volatile__ ( " LDI32 r4, 0x0120 \n" " LDI32 r5, 0x22028 \n" " SBBO &r4, r5, 0x00, 4 \n" ); /* restore r4, r5 */ __asm__ __volatile__ ( " LBBO &r4, r2, 0, 8 \n" " ADD r2, r2, 8 \n" ); } void shm_write_uint32(register uint32_t i, register uint32_t x) { /* i is the absolute offset relative from shared memory start */ /* write x at shm + i */ __asm__ __volatile__ ( " SBCO &r15, C28, r14.w0, 4 \n" ); } void shm_write_float(register uint32_t i, register float x) { __asm__ __volatile__ ( " SBCO &r15, C28, r14.w0, 4 \n" ); } uint32_t shm_read(register uint32_t i, register uint32_t b) { /* b is the absolute offset relative from shared memory start */ /* read x at shm + b */ //r14 used for returning value __asm__ __volatile__ ( " LDI32 r0, 0x000000120 \n" " LDI32 r1, 0x22028 \n" " SBBO &r0, r1, 0, 4 \n" " LDI32 r0, 0x00100000 \n" " LDI32 r1, 0x2202c \n" " SBBO &r0, r1, 0, 4 \n" // " LBCO &r14, C31, 0, 4 \n"//third operand is the offset " LBCO &r14, C31, r15, 4 \n"//third operand is the offset " JMP R3.w2 \n" ); /* unreached */ return 0; } /* void pwm(void) { __asm__ __volatile__ ( //EPWM_TBCTL " LDI32 r8, 0x48300000 \n" " LDI32 r9, 0x00000503 \n" " SBBO &r9, r8, 0, 4 \n" ); __asm__ __volatile__ ( //EPWM_CMPB " LDI32 r8, 0x48300014 \n" " LDI32 r9, 0x00001388 \n" " SBBO &r9, r8, 0, 4 \n" ); __asm__ __volatile__ ( //EPWM_CMPA " LDI32 r8, 0x48300012 \n" " LDI32 r9, 0x00001388 \n" " SBBO &r9, r8, 0, 4 \n" ); __asm__ __volatile__ ( //EPWM_TBPRD " LDI32 r8, 0x4830000A \n" " LDI32 r9, 0x0000C350 \n" " SBBO &r9, r8, 0, 4 \n" ); __asm__ __volatile__ ( //EPWM_TBCNT " LDI32 r8, 0x48300008 \n" " LDI32 r9, 0x00000000 \n" " SBBO &r9, r8, 0, 4 \n" ); __asm__ __volatile__ ( //EPWM_AQCTLA " LDI32 r8, 0x48300016 \n" " LDI32 r9, 0x00000032 \n" " SBBO &r9, r8, 0, 4 \n" ); __asm__ __volatile__ ( //EPWM_AQCTLB " LDI32 r8, 0x48300018 \n" " LDI32 r9, 0x00000302 \n" " SBBO &r9, r8, 0, 4 \n" ); __asm__ __volatile__ ( //EPWM_TBCNT " LDI32 r8, 0x48300008 \n" " LDI32 r9, 0x00000000 \n" " SBBO &r9, r8, 0, 4 \n" ); __asm__ __volatile__ ( //EPWM_TBCTL " LDI32 r8, 0x48300000 \n" " LDI32 r9, 0x00000500 \n" " SBBO &r9, r8, 0, 4 \n" ); }*/ uint32_t di(void) { return __R31; } void delay(register uint32_t x) { __asm__ __volatile__ ( " LDI32 r8, 1000 \n" //" SUB r8, r14, 0 \n" "WAIT: \n" " SUB r8, r8, 1 \n" " QBNE WAIT, r8, 0 \n" ); }
#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;//время запуска АЦП time+=1000; if (time >= adcTime + (long long)(20000)) {//контролируем что мы не вышли за пределы времени ожидания АЦП msg(time, adcTime); break; } } while(1) { cur_avg++; shm_write_uint32((PRU_AI_DATA_OFFSET + 4) * 4, (uint32_t)cur_avg); } __halt(); return 0; }
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