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
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
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
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
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
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.
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
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();
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
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.
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