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.

TMS320F280039C: Stuck in fd_add28.asm when migrating from F280049

Part Number: TMS320F280039C
Other Parts Discussed in Thread: C2000WARE

Dear Champs,

I am asking this for our customer.

The user is migrating codes from F280049C onto F280039C.

It weird that after ISRs are running (right after EINT;), the code is stuck in fd_add28.asm/fd_sub28.asm/fd_mpy28.asm..., which are all part of RTS library (rts2800_fpu32_eabi.lib).

Like below. Code is running and stuck in these files.

F280049 uses COFF but F280039C uses EABI in our migration. 

Note that when I use stuck, it does not mean the code is in ESTOP.

Instead, I mean that the code is running in these files and could not go back to main().

But on F280049, it can run normally.

When we used only one ISR (ADCA1 ISR or Timer0 ISR) and traced them step-by-step, it seemed to work. But when we ran them both (ADCA1 ISR and Timer0 ISR), then this issue happened.

Would you please help us debug this?

Questions:

1. Why does the user's ISR code can go into these RTS library codes during runtime (after user's initialization and EINT;)?

2. Are these codes related to double type, which is viewed as 64-bit in EABI rather than 32-bit in COFF? We tried to check the user's code, there were a few long-double variables. But these should be done by compiler. It's very hard to imagine the code can be stuck there?

3. Do you have any suggestion for us to debug?

  • Hello Wayne,

    1. Why does the user's ISR code can go into these RTS library codes during runtime (after user's initialization and EINT;)?

    It's difficult for me to tell based on the screenshot, can you look in the Disassembly window to verify where the program counter is currently pointing to at this point where the code is 'stuck'? From the screenshot I can't tell whether that blue dot on the left is a breakpoint or the PC arrow.

    2. Are these codes related to double type, which is viewed as 64-bit in EABI rather than 32-bit in COFF? We tried to check the user's code, there were a few long-double variables. But these should be done by compiler. It's very hard to imagine the code can be stuck there?

    I see no 64-bit floating-point assembly code in the screenshot you provided, and nothing about the filenames indicates to me that they would be viewed as 64-bit floating-point. If the user was attempting to use FPU64 when it's not available to the device, the code would not be stuck, it would instead result in a compiler warning/error.

    3. Do you have any suggestion for us to debug?

    Try to view the Disassembly window during the debug session and see what is causing the PC to be where it is; based on the screenshot you provided, I don't see why it would be stuck at an instruction which is just a MOV instruction.

  • Dear Omer,

    Now, we found the problem is related to Timer0ISR on F280039.

    Timer0 ISR is running every 50 KHz.

    On F280049 (using TI F280049 Launchpad), the user uses Timer0 PRD = 2000 (@100MHz), and the Timer0 ISR uses around 1000 counts (using CCS Debug->Run->Clock to measure).

    On F280039 (using TI F280039 CC), the user uses Timer0 PRD = 2400 (@120MHz), but the Timer0 ISR uses around 7000 counts (using CCS Debug->Run->Clock to measure). It is obvious Timer0 ISR has something wrong.

    On F280049, it uses external crystal, but on F280039, it uses INTOSC2.

    We only changed the device.c and device.h and use INTOSC2 instead when we migrated.

    Timer0ISR is running on RAM and we confirm the codes are on RAM using CCS. But it may jump to fd_add28.asm/fd_sub28.asm/fd_mpy28.asm, which are on flash. But from step-by-step trace, the behaviors look same between F280049 and F280039.

    We are still confused.

    The user uses bit-field codes.

    Our migration methods:

    1. Upgrade C2000ware and replace with its related bit-field codes/driverlib/flash API/DCL

    2. Change device.c/device.h from F28004x onto F28003x

    3. Change F280049 .cmd to F280039 .cmd accordingly from COFF to EABI

    Quesitons:

    Is there anything related to clocking we need to note when migrating from 100-MHz F280049 onto 120-MHz F280039?

  • Wayne,

                F280049 LaunchPad uses a 20 MHz crystal. F280039 INTOSC2 is 10 MHz. First you need to ensure both devices are running at their respective (rated) frequencies. Once this is confirmed, you can move to the next question. What is important is the frequency of the timer interrupt. Is it still occurring every 20 us? If the interrupt frequency is correct, the timer itself is not the source of the issue.

    What exactly happens inside the ISR? Is the ISR code exactly identical between the two devices?

    Have you verified that the desired values are written in the Timer registers? You need to confirm this in the Registers window.

  • Dear Omer, Hareesh,

    Both codes are same and we confirmed F280039 clocking (120-MHz) was correct and flash initialization (waitstate = 5 etc) was same as the default by TI's f28003x_sysctrl.c.

    They both use the same compiler with the sample optimization -O2 --opt_for_speed=5.

    After tracing and analyzing the code, we managed to run F280039 as fast as F280049.

    Our workarounds:

    1. We found there is a bottleneck code for cosine, which calls math.h using "double". On F280039 in EABI, it should be viewed as 64-bit with cosine, so it's incredibly slow. After forcing it to use TMU operation by intrinsic "__cos()", we find it has been speeded up significantly.

    2. We move many codes in RTS including fd_add28.asm/fd_sub28.asm/fd_mpy28.asm from flash to RAM. On F280049, they do run on flash, but on F280039, we moved them from flash onto RAM, which can accelerate further.

    By the above two methods, now F280039 Timer ISR runs around ~1400 cycle (moving some of RTS to RAM) out of 2400 PRD and F280049 ~1200 (RTS are all on flash) cycles out of 2000 PRD.

    We can explain 1 above.

    But we still can not comprehend why the same code with the same compiler and optimization setting, F280049 could run with fewer cycles of the same ISR.

    If you have any further comment, please let us know.

  • Hi Wayne,

    What sort of binary format COFF or EABI is being generated for F28003x and F28004x projects? Are they both the same?

    For EABI any float constant without an f at the end is a double by default, for COFF it is float.

    example:

    #define PI 3.14     // double in EABI, float in COFF

    @define 3.14f      // float in COFF and EABI

    Since you mentioned that double is being invoked for F28003x I wonder if it is being compiled for EABI and F28004x was compiled for COFF and did not show the same behavior.

    Here is some additional info for your reference in case this is the situation.

    https://software-dl.ti.com/ccs/esd/documents/C2000_c28x_migration_from_coff_to_eabi.html

    Thanks,

    Ashwini

  • Dear Ashwini,

    Yes, F280049 uses COFF and F280039 uses EABI, and we are aware double is one of the reasons that incredibly slowed down when using cosine. We tried to search "double" in their code, but we could not find other "double" variables explicitly.

    Let me confirm again, you meant even such simple define

    #define PI 3.14     // double in EABI, float in COFF

    It's viewed as double in EABI rather than float in COFF.

    Therefore, the user has to add "f" explicitly in this kind of define every time.

    #define PI 3.14

    Is our understanding correct?

  • Hello Wayne,

    You are correct.

    See the app note here for recommendations and suggestion on handling double types. There is a compiler option for compiler to generate error if 64-bit floating operation is being used to help identify which parts of code where 64-bit float is being used.

    https://software-dl.ti.com/ccs/esd/documents/C2000_c28x_migration_from_coff_to_eabi.html

    Thanks,

    Ashwini

  • Dear Ashwini,

    Based on the link you sent, can the user "just" add this on their compiler setting by forcing all float operation to 32-bit float only without explicitly modifying every of these codes including the define we mentioned in the last post?

    --float_operations_allowed=32

  • Dear Ashwini,

    I tested "--float_operations_allowed=32" and found this could be only used to know where 64-bit floating was used for debugging.

    There were not a few statements using 64-bit in the user's code after using "--float_operations_allowed=32" for debugging and we also found in the advisory of compiler console, there were also similar suggestions for performance improvement because of 64-bit double usage in EABI.

    Questions:

    1. Do we have any compiler setting to force all constants to use 32-bit float rather than 64-bit double by default without explicitly using "f"? Otherwise, it's very troublesome for the user to change all the constants they use.

    2. The user uses many "double fabs(double)", which is from standard math.h. I do not see a float corresponding one. How do we change it to use float rather than use double?

    3. The user does use a few "long double". But in theory, even in COFF, it's also viewed as 64-bit rather than 32-bit. So, because of precision concern, we don't need to change it from COFF F280049 to EABI F280039. Do you think it makes sense?

     

  • Dear Ashwini,

    Update. Tested with the user.

    We replaced the double fabs(double) in math.h by own float fabs_float(float) and then modified every float constant with "f". But we kept "long double" usage in the code because we are afraid it's application dependent.

    Now, the total cycle used of Timer0ISR on F280039 EABI is even somewhat better than that on F280049 COFF, which is as expected because we have moved some RTS library from flash to RAM.

    Therefore, the question now is only below. 

    1. Do we have any compiler setting to force all constants to use 32-bit float rather than 64-bit double by default without explicitly using "f"? Otherwise, it's very troublesome for the user to change all the constants they use.

  • Hi Wayne, I am finding out from compiler expert, will let you know soon.

  • Hi Wayne,

    C2000 compiler version 22.6.0.LTS introduces the option --fp_single_precision_constant.  For details, see this readme entry https://software-dl.ti.com/codegen/esd/cgt_public_sw/C2000/22.6.0.LTS/README.html#new-option---fp_single_precision_constant-treats-unsuffixed-floating-point-constants-as-32-bit .