EmbeddedRelated.com
Forums

Serial/sprintf crashing RCM3700

Started by lingerfelt30016 July 16, 2007
I have a project that requires Serial communications to multiple
devices. Each device has a seperate sensor number and send all data
in HEX format. The program works fine in debug mode but when I
deploy it starts rebooting my RCM3700 over and over. It seems to be
failing when I call sprintf. Can anyone point me in the right
direction?

I am using Dynamic C version 9.50

Here is some of the code:

char val[14][8];
char data[16];
if ((D = serDgetc()) == 0x7E){
printf("%x",D);
for (i=0;i<15;i++){
data[i] = serDgetc();
printf("%x",data[i]);
}

sensor = data[4];
// number of the sensor 1-XX
sprintf(val[sensor],"%x%x",data[12],data[13]);
// Data[12], data[13] = Sensor analog reading
printf("\nValue%d: %s\n",sensor+1,val[sensor]);
}

serDrdFlush();

Thanks in advance,

Scott
Scott,

One thing that stands out is that you are not checking the return value
of serDgetc() before writing it into data[i]. Your application will run
faster when not connected to Dynamic C so there's a good chance
serDgetc() will be returning -1. Also note that it returns an integer
not a char.

These may go a long way to explaining your problem...

Nathan

-----Original Message-----
From: r... [mailto:r...]
On Behalf Of lingerfelt30016
Sent: Tuesday, 17 July 2007 10:26 AM
To: r...
Subject: [rabbit-semi] Serial/sprintf crashing RCM3700

I have a project that requires Serial communications to multiple
devices. Each device has a seperate sensor number and send all data
in HEX format. The program works fine in debug mode but when I
deploy it starts rebooting my RCM3700 over and over. It seems to be
failing when I call sprintf. Can anyone point me in the right
direction?

I am using Dynamic C version 9.50

Here is some of the code:

char val[14][8];
char data[16];

if ((D = serDgetc()) == 0x7E){
printf("%x",D);
for (i=0;i<15;i++){
data[i] = serDgetc();
printf("%x",data[i]);
}

sensor = data[4];
// number of the sensor 1-XX
sprintf(val[sensor],"%x%x",data[12],data[13]);
// Data[12], data[13] = Sensor analog reading
printf("\nValue%d: %s\n",sensor+1,val[sensor]);
}

serDrdFlush();

Thanks in advance,

Scott
Hi Nathan,

The simple things will stop you in your tracks! Here is the changed
code and it works well!

char val[14][8];
int data[16];

if ((D = serDgetc()) == 0x7E){
printf("%x",D);
for (i=0;i<15;i++){
data[i] = serDgetc();
if (data[i] != -1){
printf("%x",data[i]);
}else{
serDrdFlush();
break;
}
}

sensor = data[4]-1;
sprintf(val[sensor],"%x%x",data[12],data[13]);
printf("\nValue%d: %s\n",sensor+1,val[sensor]);
}

serDrdFlush();

Thanks for your help Nathan!

Scott
I'm not so sure that's the best approach either. From the look of things
you've got data of fixed string length (start character 0x7E) that is
continuously coming out of the sensor. There is no need to flush the
read buffer (it's empty already!) but you are breaking out of the for
loop if you received -1. This means you are giving up on that string and
then searching for the next one. Your data is also invalid for you to be
operating on given that you've already written to your data array. You
could either wait for the data to be received or fill another buffer as
the data comes in and only process it once it's full or use serDread as
it has a timeout between bytes.

I previously worked on a system that had 5 sensors connected outputting
fixed length strings at high speed (16per/sec) and needed to be
realtime. I ended up coming up with a system that used serXpeek and
serXgetc to make sure the start of the string was present, and then
check the size of the read buffer serXrdUsed() to check that it
contained at least the number of bytes of the message then read it. This
worked really well.

Regards,

Nathan

-----Original Message-----
From: r... [mailto:r...]
On Behalf Of lingerfelt30016
Sent: Tuesday, 17 July 2007 11:21 AM
To: r...
Subject: [rabbit-semi] Re: Serial/sprintf crashing RCM3700

Hi Nathan,

The simple things will stop you in your tracks! Here is the changed
code and it works well!

char val[14][8];
int data[16];

if ((D = serDgetc()) == 0x7E){
printf("%x",D);
for (i=0;i<15;i++){
data[i] = serDgetc();
if (data[i] != -1){
printf("%x",data[i]);
}else{
serDrdFlush();
break;
}
}

sensor = data[4]-1;
sprintf(val[sensor],"%x%x",data[12],data[13]);
printf("\nValue%d: %s\n",sensor+1,val[sensor]);
}

serDrdFlush();

Thanks for your help Nathan!

Scott
Nathan,

I have added the following to my code. I check to see if data is
present then I want to check the length of the buffer. The code
executes way to fast to get the entire length and I never process the
data. I have added a waitfor but do not like this because I may never
get the rest of the first packet. This will cause issues with parts
of multiple packets in the buffer. Is this correct?

if (serDpeek() != -1)
{
length = serDrdUsed();
if (length >= 15){
Do this;

Scott
It depends if you absolutely need to have the most recent packet if
there are multiple packets in the buffer. In my case it was so if there
were more than 1 complete packets in the buffer I'd remove the first one
(just by just calling serXgetc()).

If it's not so important you can make sure that your data in the buffer
is synchronized (i.e. first character expected matches first character
in buffer) and do a serXread(), then working backwards from the end of
the data read, find the most recent packet. This approach can mean there
is potential to miss packets though because you could read half of
packet (if timeout set too low or serial buffer full) meaning you will
get the remaining half next read.

As you can see it can become rather complex so it really depends on the
requirements of your application.

Regards,

Nathan

-----Original Message-----
From: r... [mailto:r...]
On Behalf Of lingerfelt30016
Sent: Tuesday, 17 July 2007 12:23 PM
To: r...
Subject: [rabbit-semi] Re: Serial/sprintf crashing RCM3700

Nathan,

I have added the following to my code. I check to see if data is
present then I want to check the length of the buffer. The code
executes way to fast to get the entire length and I never process the
data. I have added a waitfor but do not like this because I may never
get the rest of the first packet. This will cause issues with parts
of multiple packets in the buffer. Is this correct?

if (serDpeek() != -1)
{
length = serDrdUsed();
if (length >= 15){
Do this;

Scott