|
|
View previous topic :: View next topic |
Author |
Message |
zilog
Joined: 17 Aug 2007 Posts: 19
|
sprintf questions |
Posted: Mon Aug 20, 2007 4:23 am |
|
|
My question is how many locations of tempmsg the code below occupies worst case, my assumption has always been 15, but now I have gotten indications on things being different. I assume the first sprintf to use 3 bytes, and the second to use 5/6 bytes, am I right or wrong?
/Daniel
Code: |
#define MAX_SELECT_LENGTH 16
|
Code: |
void send_CommandToFU( unsigned int16 code, signed int32 value )
{
char tempmsg[MAX_SELECT_LENGTH];
char BCC = 0;
int pos = 0;
int i;
tempmsg[pos++] = EOT;
tempmsg[pos++] = FU_ADDRESS;
tempmsg[pos++] = STX;
sprintf(&tempmsg[pos], "%03Lu", code); pos +=3;
tempmsg[pos++] = '=';
if (value >= 0) {
sprintf(&tempmsg[pos], "%05Ld", value); pos+= 5;
} else {
sprintf(&tempmsg[pos], "%06Ld", value); pos+= 6;
}
tempmsg[pos++] = ETX;
for (i = 3; i < pos; i++)
BCC ^= tempmsg[i];
tempmsg[pos++] = BCC;
FUCode = 0xFFFF;
rs485_AddQueue(tempmsg, pos);
return;
}
|
|
|
|
zilog
Joined: 17 Aug 2007 Posts: 19
|
|
Posted: Mon Aug 20, 2007 4:44 am |
|
|
Running this modified code on a Linux/64-bit/gcc PC gives the execution trace below:
Code: |
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAX_SELECT_LENGTH 16
#define EOT 1
#define FU_ADDRESS 32
#define STX 2
#define ETX 3
int FUCode;
void send_CommandToFU(long long int code, long long int value )
{
char tempmsg[MAX_SELECT_LENGTH];
char BCC = 0;
int pos = 0;
int i;
tempmsg[pos++] = EOT;
tempmsg[pos++] = FU_ADDRESS;
tempmsg[pos++] = STX;
sprintf(&tempmsg[pos], "%03Lu", code); pos +=3;
tempmsg[pos++] = '=';
if (value >= 0) {
sprintf(&tempmsg[pos], "%05Ld", value); pos+= 5;
} else {
sprintf(&tempmsg[pos], "%06Ld", value); pos+= 6;
}
tempmsg[pos++] = ETX;
for (i = 3; i < pos; i++)
BCC ^= tempmsg[i];
tempmsg[pos++] = BCC;
FUCode = 0xFFFF;
// rs485_AddQueue(tempmsg, pos);
printf("msg: %s, len: %d\n", tempmsg, pos);
//printf("code: %Ld, value: %Ld", code, value);
return;
}
int main(void)
{
while (1) {
send_CommandToFU(999, 123456);
}
return;
}
|
Code: |
msg: 999=1234566, len: 14
|
While modifying for send_CommandToFU(999, 123456); gives
Code: |
msg: 999=-12345en: 15
|
And yes, I do know that I dont check for the end of the string here, this is just for testing ;) |
|
|
zilog
Joined: 17 Aug 2007 Posts: 19
|
|
Posted: Mon Aug 20, 2007 5:28 am |
|
|
I now see that I made an erroneous assumption, sprintf CAN fill more than 5/6 spaces here. The solution is to limit "value" to only fill 5 digit places. |
|
|
Ttelmah Guest
|
|
Posted: Mon Aug 20, 2007 7:19 am |
|
|
Remember that a 'string', always has a terminating '0'. The sprintf, adding three characters, adds three characters, and then a terminating '0'. This shouldn't matter (since you then start again 'over' this zero in each case). However, then remember that 'pos', is incremented after adding the last checksum byte, so could reach 16. If the RS485 function, uses this as a length indicator, it'll be one larger than the length of the actual data stored. I'd suspect this is your problem.
Best Wishes |
|
|
zilog
Joined: 17 Aug 2007 Posts: 19
|
|
Posted: Mon Aug 20, 2007 7:25 am |
|
|
Ttelmah wrote: | Remember that a 'string', always has a terminating '0'. The sprintf, adding three characters, adds three characters, and then a terminating '0'. This shouldn't matter (since you then start again 'over' this zero in each case). However, then remember that 'pos', is incremented after adding the last checksum byte, so could reach 16. If the RS485 function, uses this as a length indicator, it'll be one larger than the length of the actual data stored. I'd suspect this is your problem.
Best Wishes |
I only count pos increasing to the value of 14 at the end of the function, it is used as a"number of characters"-indicator for the add-function. You can find all of the abovementioned functions in http://wintermute.csbnet.se/~zilog/kod/styrkort_riktiga/DriveLPI.c |
|
|
Ttelmah Guest
|
|
Posted: Mon Aug 20, 2007 8:00 am |
|
|
Er. Pos will always be larger than you expect then...
Remember '++', means 'increment after using the value', so 'pos' will always be one _more_ than the number of characters.
Best Wishes |
|
|
zilog
Joined: 17 Aug 2007 Posts: 19
|
|
Posted: Mon Aug 20, 2007 8:18 am |
|
|
Ttelmah wrote: | Er. Pos will always be larger than you expect then...
Remember '++', means 'increment after using the value', so 'pos' will always be one _more_ than the number of characters.
Best Wishes |
pos begins at zero and is incremented after each use -> should contain the number of characters at the end. During a run with a negative number not exceeding 5 digits in magnitude, I place the following in the buffer:
[EOT, ADDRESS, STX, 3 digits code, '=', 6 digits value where the first is '-', ETX, BCC] which adds up to 15 characters in the buffer, and leaves pos == 15, being the number of elements in the buffer. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|