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.

CCS/TMS320F28379D: Profiling with GPIO and scope

Part Number: TMS320F28379D

Tool/software: Code Composer Studio

I'm trying to profile a time-critical section of code by inserting GPIO toggles throughout to see how long different chunks take to execute. For example:

var_Ref=u_ref_buff.data[u_ref_buff.readIndex];
var_FF=FF_Out_buff.data[FF_Out_buff.readIndex];
u_FF=uref_old; 

FF_Out_buff.data[FF_Out_buff.writeIndex]=FF_Out;
Ig_buff.data[Ig_buff.writeIndex]=var_Fdbk;

GpioDataRegs.GPBSET.all=GPIO_debug2_mask;

*FF_log_ptr++=var_FF;   //FF_log[fast_idx+1]=var_FF;
*Comp_log_ptr++=var_Out;   //Comp_log[fast_idx]=var_Out;
*Fdbk_log_ptr++=var_Fdbk;
*uref_log_ptr++=var_Ref;   

GpioDataRegs.GPBCLEAR.all=GPIO_debug2_mask;

u_ref_buff.writeIndex++;
u_ref_buff.writeIndex &= 0x003F;

GpioDataRegs.GPBSET.all=GPIO_debug2_mask;

FF_Out_buff.writeIndex++;
FF_Out_buff.writeIndex &= 0x003F;
u_ref_buff.readIndex++;
u_ref_buff.readIndex &= 0x003F;
FF_Out_buff.readIndex++;
FF_Out_buff.readIndex &= 0x003F;

Unsurprisingly, the compiler does not respect the order of execution, which means that I don't actually know what code is running in between subsequent GPIO edges. One solution I've tried is to put the GPIO manipulation into functions:

var_Ref=u_ref_buff.data[u_ref_buff.readIndex];
var_FF=FF_Out_buff.data[FF_Out_buff.readIndex];
u_FF=uref_old; 

FF_Out_buff.data[FF_Out_buff.writeIndex]=FF_Out;
Ig_buff.data[Ig_buff.writeIndex]=var_Fdbk;

cpudebug2_set(); //GpioDataRegs.GPBSET.all=GPIO_debug2_mask;

*FF_log_ptr++=var_FF;   //FF_log[fast_idx+1]=var_FF;
*Comp_log_ptr++=var_Out;   //Comp_log[fast_idx]=var_Out;
*Fdbk_log_ptr++=var_Fdbk;
*uref_log_ptr++=var_Ref;   

cpudebug2_clr(); 

u_ref_buff.writeIndex++;
u_ref_buff.writeIndex &= 0x003F;

cpudebug2_set();

FF_Out_buff.writeIndex++;
FF_Out_buff.writeIndex &= 0x003F;
u_ref_buff.readIndex++;
u_ref_buff.readIndex &= 0x003F;
FF_Out_buff.readIndex++;
FF_Out_buff.readIndex &= 0x003F;

void cpudebug2_set(void)
{
    GpioDataRegs.GPBSET.all=(GPIO_debug2_mask);
}

void cpudebug2_clr(void)
{
    GpioDataRegs.GPBCLEAR.all=(GPIO_debug2_mask);
}

The result is that the compiler now respects the ordering, but the function calls now slow it down greatly, which can cause erroneous operation. Setting the functions as inline gives similar results to the first example. Is there any way to get the compiler to respect order of execution without significant penalty to speed? I've also tried breakpoints and reading a timer, but the same problem comes up. Also as an aside, the profile clock does not function properly for me (usually stays at zero from breakpoint to breakpoint).

I'm aware that there's an inherent contradiction in what I'm trying to do; If I want code to be fast, I should allow the compiler to reorder things as it pleases, so long as I'm properly making use of volatiles and such. But if I let it mix everything together into assembly soup I won't be able to tell where to make improvements.

  • Mike Twieg said:
    Is there any way to get the compiler to respect order of execution without significant penalty to speed?

    Unfortunately, no.  You are referring to a compiler implementation technique called instruction scheduling.  There is no mechanism which disables instruction scheduling.  It always occurs.  At lower levels of optimization, it is less effective, and perhaps easier to debug.  But that is not helpful here.

    Mike Twieg said:
    the profile clock does not function properly for me (usually stays at zero from breakpoint to breakpoint).

    This is not within my expertise.  But it seems that this is worth understanding.  I don't know why you would not be able to see the number of cycles used between breakpoints.  I'll involve some other experts.

    Thanks and regards,

    -George