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.
Part Number: LAUNCHXL-F28377S
Tool/software: TI C/C++ Compiler
Hi,
I am trying to use CLA to offload some math calculations away from CPU using CLAmath library. I am using compiler version ti-cgt-c2000_18.1.3.LTS.
I have defined a global structure in a header file task1.h. This structure is then declared in task1.c file on CPU side. CLA uses the same header file and is able to access the structure.
Problem is that microcontroller will not start or it goes to reset loop if I try pass the members of that structure to CLAmath functions. CLAmath functions work okay if I use any global or local non-struct variables as arguments instead.
For example,
task1.h:
typedef struct cla_task1_variables_s
{
float x;
float y;
float Angle;
} CLA_Task1Variables;
task1.c
#include "task1.h"
#pragma SET_DATA_SECTION( "CLADataMemory" )
CLA_Task1Variables T1;
float fTempGlobal;
#pragma SET_DATA_SECTION()
void task1_init()
{
//possible initialisations
}
task1.cla:
#include "task1.h"
extern CLA_Task1Variables T1;
extern float fTempGlobal;
float fTempLocal;
void task1()
{
T1.x = read_value_from_ADC(0);
T1.y = read_value_from_ADC(1);
//Raw angle, atan2(y,x)
T1.Angle = CLAatan2PU( 1.0f, 2.0f ); //[-0.5 0.5] WORKS FINE.
T1.Angle = CLAatan2PU( 1.0f, fTempGlobal ); //[-0.5 0.5] WORKS FINE.
T1.Angle = CLAatan2PU( 1.0f, fTempLocal ); //[-0.5 0.5] WORKS FINE.
T1.Angle = CLAatan2PU( 1.0f, T1.x ); //[-0.5 0.5] WORKS FINE.
T1.Angle = CLAatan2PU( T1.y, 2.0f ); //[-0.5 0.5] WORKS FINE.
T1.Angle = CLAatan2PU( T1.y, T1.x ); //[-0.5 0.5] THIS WILL CAUSE WATCHDOG RESET or COMPLETE HANG or THAT CPU WILL NOT EVEN START! Why?
}
Any help is appreciated.
JM
Repost code part.
task1.h:
typedef struct cla_task1_variables_s
{
float x;
float y;
float Angle;
} CLA_Task1Variables;
task1.c
#include "task1.h"
#pragma SET_DATA_SECTION( "CLADataMemory" )
CLA_Task1Variables T1;
float fTempGlobal;
#pragma SET_DATA_SECTION()
void task1_init()
{
//possible initialisations
}
task1.cla:
#include "task1.h"
extern CLA_Task1Variables T1;
extern float fTempGlobal;
float fTempLocal;
void task1()
{
T1.x = read_value_from_ADC(0);
T1.y = read_value_from_ADC(1);
//Raw angle, atan2(y,x)
T1.Angle = CLAatan2PU( 1.0f, 2.0f ); //[-0.5 0.5] WORKS FINE.
T1.Angle = CLAatan2PU( 1.0f, fTempGlobal ); //[-0.5 0.5] WORKS FINE.
T1.Angle = CLAatan2PU( 1.0f, fTempLocal ); //[-0.5 0.5] WORKS FINE.
T1.Angle = CLAatan2PU( 1.0f, T1.x ); //[-0.5 0.5] WORKS FINE.
T1.Angle = CLAatan2PU( T1.y, 2.0f ); //[-0.5 0.5] WORKS FINE.
T1.Angle = CLAatan2PU( T1.y, T1.x ); //[-0.5 0.5] THIS WILL CAUSE WATCHDOG RESET or COMPLETE HANG or THAT CPU WILL NOT EVEN START! Why?
}
Hi Juhamatti,
Try halting the CLA before the function call and single step through the code. This will provide some information to help pin-point where things go wrong.
It sounds like everything is setup, however it is worth checking these two faqs:
When you write back with your findings, please let me know which version of the CLAmath library you are using or the C2000Ware version.
More CLA faqs here: https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/786227
Regards
Lori
Problem solved.
This was a bit tricky issue after all. The problem was that the microcontroller did not start after software was updated or it crashed due to watchdog during run after CLA was started. I figured it out by not starting CLA during system boot but later manually.
It seems that CLAmath library does not handle any mathematical exceptions or undefined operations that may occur normally during operation.
For example:
I think I got division by zero in CLAatan2PU function during boot up because ADC converters had not yet sampled any non-zero values. The problem was quite difficult to find out as I thought there might problem with 1) boot ROM symbols, 2) CLA math library, 3) compiler flags, 4) linker file, 5) you name it....
I guess, I will have to write my own wrapper library around CLAmath library to handle undefined operations.
NOTE 1. atan2(y,x) "should" give undefined value only when both y = x = 0. In a real-time system, probably better way would be to return 0 in this case as well as watchdog reset is not desired.
NOTE 2. I was using the latest CLAmath library v4_02_00_00. It caused also some confusion that devices symbol file had different size in CLAmath library and in the controlSuite util folder for the same micrcontroller.
C:\ti\controlSUITE\libs\math\CLAmath\v4_02_00_00\lib\2837x_c1bootROM_CLADataROMSymbols_fpu32.lib is 27,842 bytes.
C:\ti\controlSUITE\libs\utilities\boot_rom\F2837x_revb\revb_rom_symbol_libs\c1rom_CLA_Data_ROM\F2837xRevB_c1bootROM_CLADataROMSymbols_fpu32.lib is 30,216 bytes.
NOTE 3. Is there any way to protect main CPU from crashing if CLA crashes? I am assuming that what happens in those undefined cases is some sort of CLA-scratchpad stack overflow-issue which eventually causes CPU watchdog to kick.
NOTE 4. It seems also that CLA crashes if there is a call to CLAsqrt(0) because zero case is not handled due inverse calculation in asm file. Should be sqrt(0) = 0.
BR,
Juhamatti
Hi Juhamatti,
I suggest moving to C2000Ware instead of using the content in controlSuite.controlSuite updates have been frozen and any updates for these libraries will be found in C2000Ware.
Juhamatti Nikander said:NOTE 3. Is there any way to protect main CPU from crashing if CLA crashes? I am assuming that what happens in those undefined cases is some sort of CLA-scratchpad stack overflow-issue which eventually causes CPU watchdog to kick.
I'm working to better understand what happened. I'm hoping you can help me understand where it went wrong.
Looking at the division routine, for example, C2000Ware version 2.00.00.02. I don't see any way the CLA would cause the C28x to reset.
The input isn't checked against 0, but the 1/x estimate instruction (MEINVF32) instruction should calculate 1/0 as infinity and set the overflow flag. The overflow flag is tied to an interrupt in the C28x PIE and, if enabled, be serviced there. Do you have this interrupt enabled and is it just looping? Could that be the cause of the WD interrupt?
Juhamatti Nikander said:NOTE 4. It seems also that CLA crashes if there is a call to CLAsqrt(0) because zero case is not handled due inverse calculation in asm file. Should be sqrt(0) = 0.
When you say "crashes" can you describe what happens? The sqrt function, like the division, shouldn't stall or halt or reset anything. Looking at the assembly there are some checks for x = 0. I think that something else is going on perhaps related to the C28x interrupts tied to CLA overflow/underflow.
I do notice that the library documentation doesn't mention what happens with x/0. I will file a ticket asking that the exceptions for each routine be documented.
Hi,
Thanks for pointing out about the CLA overflow / undeflow interrupts. I had enabled those earlier as an attempt to debug CLA but forgot to map any interrupt routines to those interrupts which, then, caused function calls to null pointer functions which, eventually, caused CPU to starve + watchdog reset / crash.
Now system is able to boot up and run normally even when CLAmath functions behave badly. I have to probably add some wrapper library around CLAmath as I don't want any floating-point INFs or NANs to propagate.
Thanks a lot.
Best regards,
Juhamatti Nikander