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.

Does SYS/BIOS really work with FPU on Cortex M4F?

I am running into a very strange problem while working on StellarisLM4F120H5QR Launch Pad based prototype.

The basic structure of my firmware is: a HWI collects data from SSI port and save it in Ping-Pong buffer, when the Ping buffer is full, a Semaphore is posted to notify the number crunching Task for processing, as the same time, HWI is still working in the background collecting data to Pong buffer. The number crunching Task uses CMSIS DSP lib and it uses floating point data. The HWI doesn’t use float point data, hence no FPU registers are accessed in HWI.

The problem is: I randomly get incorrect floating point results. If I do fake calculation using only fixed points, everything works great. If I disable the interrupt all together during calculation, the problem is gone, but that defeat the whole purpose of using RTOS, Ping-Pong buffer etc.

The pseudo code look likes this, I reduced the code, but the problem can be illustrated (and reproduced!) :

/////////////////////////////////////////

Int sampleCount = 0;

Semaphore_Handle sem;

static const float testData[32] =

{

               0.0,  1.0,  2.0,  3.0,  4.0,  5.0,  6.0,  7.0,

               8.0,  9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0,

              14.0, 13.0, 12.0, 11.0, 10.0,  9.0,  8.0,  7.0,

               6.0,  5.0,  4.0,  3.0,  2.0,  1.0,  0.0, -1.0

};

/* Using int type, the problem will not show

static const long testData[32] =

{

               0, 1, 2, 3, 4, 5, 6, 7,

               8, 9, 10, 11, 12, 13, 14, 15,

               14, 13, 12, 11, 10, 9, 8, 7,

               6, 5, 4, 3, 2, 1, -1

};

*/

void SomeHWI(UArg arg)

{

       sampleCount++;

 

       if(sampleCount == 1024)

       {

              Semaphore_post(sem);

       }

}

Void ProcessTask(UArg arg0, UArg arg1)

{

    UInt32 ii;

 

    while(1)

    {

        Semaphore_pend(sem, BIOS_WAIT_FOREVER);

 

        //IntMasterDisable();//<-- This will correct the problem

        for(ii = 0; ii < 512; ii++)

        {

            float testMax = -10.0;

            //long testMax = -10; // Using int type, the problem will not show

            long testMaxIndex = 0;

 

            for (uint16_t testIndex = 0; testIndex < 32; testIndex++)

            {

                 if (testData[testIndex] > testMax)

                 {

                     testMax = testData[testIndex];

                     testMaxIndex = testIndex;

                 }

              }

 

              if(testMaxIndex != 15)

              {

                  // Error! Turn on Red LED

                  GPIO_write(LM4F120H5QR_LED_RED, Board_LED_ON);

             }

        }

        //IntMasterEnable();//<-- This will correct the problem

    }

}

The problem seems to be related to FPU and stacking, so these are the actions I took:

  1. Add FPUStackingEnable()/FPULazyStackingEnable() to the start of the main(), and combination with or without these two function calls, it made absolutely no difference.
  2. Increase the size of HWI stack and Task stack to ridiculous level, 8192 bytes, by disabling all other functions of the application, it made absolutely no difference.
  3. Changing all local variables to static or global, it made absolutely no difference.
  4. I enabled/disabled M3 HWI support, made absolutely no difference.
  5. I enabled/disabled zero latency HWI somewhere else in this firmware, made absolutely no difference.

I hope it was something stupid I did, but just like the test code above, something as simple as that will reproduce the error (try it!).

I am using SYS/BIOS 6.34 (come with TI-RTOS 1.01/StellarisWare9453, because of CMSIS-DSP lib reason, http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/261081.aspx?pi239031349=2); tried Arm complier version 4.97, 4.98, 5.06, make no difference; I have “PART_LM4F120H5QR, ARM_MATH_CM4, __FPU_PRESENT=1, ccs” symbol predefine for the compiler, and other compiler setting necessary for CMSIS-DSP lib.

I vaguely that SYS/BIOS manages stacking on its own, so I suspect FPUStackingEnable()/FPULazyStackingEnable() will not make any difference; and as of SYS/BIOS v6.34, FPU registers are not saved to stack, BUT I didn’t touch those FPU registers in the HWIs (unless the compiler is doing something behind my back), did I miss anything?

Thanks in advance!