sprintf saves garbage values into character array

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

sprintf saves garbage values into character array

3,993 Views
swapnilv
Contributor III

Hi,

I have mqx 4.0.1 installled on my device. I am using its web server.

When sending the data from device to web browser I am using sprintf at several places in device side C code.

I am using sprintf to copy float values into a character array as below:

CHAR MyArray[50]={0};

FLOAT f_Value=0.0;

sprintf(MyArray, "%5.3f", f_Value);

The float value is first read into variable "f_Value" and then I am using sprintf() as mentioned above to copy the float value into buffer "MyArray".

The value that is read into variable "f_Value" is correct.

But when I use sprintf() to copy it to "MyArray" then sometimes a garbage value(18434449246735240000000.000) gets stored in "MyArray".

Sometimes if  variable "f_Value" is having value say 100.000 into it; then after copying it to "MyArray" using sprintf() shows value 0.000 into " MyArray".

Or sometimes a random character like "/" appears in "MyArray".

I tried using snprintf as below but still same issue is observed.

snprintf(MyArray, sizeof(MyArray), "%5.3f", f_Value);

Please let me know if you have any solution to fix this problem.

Thanks,

Swapnil

Tags (2)
10 Replies

3,006 Views
DavidS
NXP Employee
NXP Employee

Hi Swapnil,

Have you defined the following in your user_config.h?

MQX_INCLUDE_FLOATING_POINT_IO

Default is zero.

One: ioprintf() and ioscanf() include floating point I/O code.

MQX_INCLUDE_FLOATING_POINT_IO

The default value is 0.

Enables floating point types, such as printf and scanf, in the MQX I/O function and

enables float point conversion API.

This information is in the MQX_User_Guide.pdf in the MQX4.0/doc/mqx folder.

Regards,

David

0 Kudos
Reply

3,006 Views
swapnilv
Contributor III

One more observation:

When I send the data directly as mentioned below, I do not get garbage values.

CHAR MyArray[50]={0};

for(i=0;i<1400;i++)

{

   sprintf(MyArray, "%s", "20.000" );

   httpd_sendstr(session->sock, MyArray);

}

But when using  sprintf along with float as below then garbage values are getting stored in "MyArray".

CHAR MyArray[50]={0};

FLOAT f_Value=20.000;

for(i=0;i<1400;i++)

{

   sprintf(MyArray, "%5.3f", f_Value);

   httpd_sendstr(session->sock, MyArray);

}

Thanks,

Swapnil

0 Kudos
Reply

3,006 Views
DavidS
NXP Employee
NXP Employee

Hi Swapnil,

I've tested your code using MQX4.0.2.2 (I do not have MQX4.0.1 installed any longer....current MQX version is 4.1.1 with MQX4.1.2 coming out mid-December...can you update?), CW10.6, TWR-K60D1200M, and ARM GCC compiler, and your code.

I am getting proper results for contents of MyArray for all use cases you have described.  I am simply inspecting the MyArray variable in the debugger Variable window and also printf'ing the variable.

The release notes for MQX4.0.2 have following:

Fixed printf, sscanf and scanf functions not working when using floats (%f) on Kinetis.

Not a far stretch to say sprintf affected too.

So it is possible the newer MQX version will resolve your issue.

Regards,

David

0 Kudos
Reply

3,006 Views
swapnilv
Contributor III

Hi David,

Any other reason do you see that could cause  such problem ?

I am reading more than 1000 float values and converting those to string using sprintf in a for() loop.

If I reduce this number to around 700 and add a time dalay of about  5 msec after float to string conversion; then I see the frequency of garbage values appearing in read data is reduced to great extent.

Please let me know if you have any suggestion regarding this.

Thanks,

Swapnil

0 Kudos
Reply

3,006 Views
matthewkendall
Contributor V

Any task that uses floating point math must be marked with the attribute MQX_FLOATING_POINT_TASK in the template list. It is possible that you have another task that is using floats but has not been so marked. This can cause corruption of the floating point math registers. Check that all tasks that use floats have the correct attribute.

0 Kudos
Reply

3,006 Views
swapnilv
Contributor III

Hi Matthew,

I have set this MQX_FLOATING_POINT_TASK  attribute in the template list for RTOS related tasks.

How can we ensure to have the MQX_FLOATING_POINT_TASK attribute set if starting any kind of RTCS related
tasks (e.g. http server, session tasks etc..) ?

Thanks,

Swapnil

0 Kudos
Reply

3,006 Views
matthewkendall
Contributor V

In a task where you do not have control of the startup attributes (e.g. in a function called from the shell, started by RTCS) you can turn the floating point attribute on and off with:

_task_enable_fp();

/* do floating point stuff here*/

_task_disable_fp();

3,006 Views
swapnilv
Contributor III

Hi Matthew,

Thanks for your reply.

Initially I was using below API for RTCS tasks to create "httpd server" and "httpd session" tasks.

RTCS_task_create(name, priority, stacksize, start, arg);

There exists one more API to which we can pass the attribute(4th parameter) as MQX_FLOATING_POINT_TASK

RTCS_task_create_att(name, priority, stacksize, attribute, start, arg) ;

But when I use this new API; and try to acees html pages on the device; then the web server hangs (no response is received from server; even I dont get any response when I ping the server IP).

I tried the approach suggested by you by calling  "_task_enable_fp()" and "_task_disable_fp()"  when reading data from server through "asp" .

In this case also sometimes the server sends response; but after refreshing html page ; the web server hangs and does not send any response( here also  I dont get any response when I ping the server IP).

Do you see any reason for such behaviour?

Do we have any limitaions on how many number of times I can call  _task_enable_fp() and _task_disable_fp() from functions such as "asp" functions which read data from server?

Please let me know if you have any suggestions.

Thanks,

Swapnil

0 Kudos
Reply

3,006 Views
matthewkendall
Contributor V

I don't think there is any need to start RTCS with the floating point attribute. Doing so will just slow down context switches needlessly.

The ability to turn the flag on and off at run time is useful if you have some user functions that are called by (and thus executed in the context of) a task you don't start yourself and thus have no control over the attributes of. I came across this when I wrote some functions to be called by the shell. I start RTCS and TELNET, then TELNET spawns shell tasks. Those spawned shell tasks do not have the floating point attribute set. So if I need to do floating point stuff in my functions I enable the attribute before doing it (and disable it again afterwards).

Enabling and disabling the attribute is cheap (it just sets a flag). The cost comes whenever there is a context switch to or from a task with the flag set; the context switch stacks the floating point registers in addition to the regular ones.

The enable/disable functions are not nestable (they don't keep track of how many times you have called them), so there is no harm in calling enable twice but the first time you call disable the attribute will be cleared. The functions are described in the MQX Reference Manual (MQXRM Rev 17, Section 2.1.260, p. 354).

I don't know what is going on with your web server. I sounds like you have other problems.

0 Kudos
Reply

3,006 Views
swapnilv
Contributor III

Hi David,

Thanks for your reply.

Yes, I have already defined MQX_INCLUDE_FLOATING_POINT_IO equal to 1 in user_config.h.

Still I am getting those garbage values.

Thanks,

Swapnil

0 Kudos
Reply