cancel
Showing results for 
Search instead for 
Did you mean: 

Erroneous result in arithmetic operations

Guillermo Corrales
Associate II
Posted on March 08, 2018 at 16:29

Hi all,

I'm developing an application (PROJECT) for a STM8S208RB (128k flash) t

hat was using around 100kB of flash and I

 have added recently a new library (LIBRARY) that has increased memory usage up yo 120kB

of flash

.

I had an issue because of this event that has been solved. More info in here: 

https://community.st.com/message/188751

  

In the new library I have a function that reads a frequency in Hz (

IE: 208064

) and 

then print it in MHz (IE: 208.064 Hz):

void disp_freq_mhz(void)

{

   uint32_t frequency;

   uint16_t mhz_num, khz_num;

   frequency = frequency_hz;                                                            // frequency_hz 

is a global variable (uint32_t)

   mhz_num = (uint16_t)(frequency/1000);                                      

   khz_num = (uint16_t)(frequency%1000);

   printf (' %03d.%03d MHz', mhz_num, khz_num);

}

The problem is sometimes 

the division and/or modulus operations returns an erroneous value.

I have been debugging this error with STVD in the following way:

  • Known that frequency_hz == 208064, I have added the following code after khz_num assignation:

mhz_num = (uint16_t)(frequency/1000);

khz_num = (uint16_t)(frequency%1000);

if(khz_num != 64 || mhz

_num != 208

)

   return;
  • I have placed a breakpoint in the  return; , so the execution stops when I get a bad division or modulus.
  • This is one reading of the variables involved in the function during one stop (the erroneous values are not always the same):

frequency_hz = 208064

frequency = 208064

mhz_num = 208              

khz_num = 872                          // sometimes it is 640, but most of the time the erroneous value is 872

Result of printf -> ' 208.872 MHz '

Has anybody any idea of why is failing this arithmetic operations?

Thanks all of you in advance,

Guillermo,

#uint16_t #uint32_t #basic-arithmetic
13 REPLIES 13
Posted on March 10, 2018 at 01:01

That suggests a situational component, but the snippet lacks the larger context, and supporting detail.

The OP will need to debug and refine the problem further.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on March 12, 2018 at 10:20

Once again, thank you all!

As Luca and dhenry have proved, I also think is difficult to figure that compiler is doing the division/rest wrong and to be honest I don't think my issue is compiler related.

Responding to all of your suggestions:

  1. luca wrote:

    .......

    the problem is probably due to some runtime issue, like stack overflow or interrupts corrupting something.

    I've been looking the stack while the code is running and I haven't found any kind of stack overflow, at least looking in the memory. 

    What is the best way to debug the issues you mentioned?

  2. Clive One wrote:

    ......

    Try with optimization on/off

    .......

    I'd printf(''%ld %ld\n'',  frequency, frequency_hz);  in the error case to confirm the input conditions, especially for the potential of the global variable being modified.

    This is the first thing I thought, that the global variable was being modified somewhere (IE: by an interrupt), but this is not the case, look at the image below:
0690X00000609yyQAA.png
  • dab_ens_freq is the global variable (frequency_hz in the first example)
  • frequency (local var) == dab_ens_frequency == 208064
  • frequency/1000 == 208
  • frequency%1000 == 64
  • mhz_num != 208

  • khz_num == 64

I can't compile the project with no-optimizations (because I get a ''not enough memory'' error), but with ''maximice execution speed'' (+speed) and ''minimze code size''(+compact) I get the same issue.

I've tried to disable and re-enable interrupts during the division and rest operations and it seems to fix the issue (or at least it reduces a lot the

repeatability

of the issue) but I don't understand why. So while I keep debugging the code I will use a workaround to at least avoid printing bad results.

As far I get some news about this issue, I will post a new comment.

Best regards,

Guillermo.

Posted on March 12, 2018 at 10:27

Guillermo Corrales wrote:

I've tried to disable and re-enable interrupts during the division and rest operations and it seems to fix the issue ..

Best regards,

Guillermo.

make sure all your interrupt routines have the @svlreg keyword

@svlreg @interrupt myIntRoutine() ..

and see if that fixes the problem.

Posted on March 14, 2018 at 15:35

Wow, your suggestion fixed my problem!

I've taken a look to 

@svlreg in the COSMIC user guide and I have found that it should be used when inside the IT floats or longs vars are used. This is my case since I added the new library, so now it makes sense with ITs disabled I didn't get the 'arithmetic' error.

Thank you so much Luca!!

Best regards,

Guillermo.