Adjusting serial buffer size

Discussion to talk about software related topics only.
Lachlanp
Posts: 91
Joined: Tue Jan 29, 2013 4:44 am

Adjusting serial buffer size

Post by Lachlanp »

I am trying to talk with a serial device through UART 1 that sends me packet lengths of 365 characters. However, I only consistently only receive about 148 - 166 of them at 115k baud. It could it be that the serial buffer size if too small?

How do i determine what the serial buffer size is, and how can I adjust it?

Regards
Lachlan
seulater
Posts: 445
Joined: Fri Apr 25, 2008 5:26 am

Re: Adjusting serial buffer size

Post by seulater »

I dont think the buffer is your problem. What methodology are you using to read the serial data.
We need some of your code for that area to help.
ecasey
Posts: 164
Joined: Sat Mar 26, 2011 9:34 pm

Re: Adjusting serial buffer size

Post by ecasey »

Perhaps you need a delay between when the data is available and when you read it. If you read data as soon as "dataavail( fd )" becomes true, then you will probably only pull that part of the data that arrives before the read is completed.
User avatar
dciliske
Posts: 624
Joined: Mon Feb 06, 2012 9:37 am
Location: San Diego, CA
Contact:

Re: Adjusting serial buffer size

Post by dciliske »

You can also do an incremental read in a while loop like this:

Code: Select all

BytesRead = 0;
while ( pktLen - BytesRead)
{
    BytesRead += ReadWithTimeout( fdSerial, (char*)rxBuf+BytesRead, pktLen-BytesRead, 0 );
}
The issue you have is that for larger packets, this can burn a fair bit of CPU time, but for simply getting something working, it's often the right way to go (something, something, premature optimization...).
Dan Ciliske
Project Engineer
Netburner, Inc
Lachlanp
Posts: 91
Joined: Tue Jan 29, 2013 4:44 am

Re: Adjusting serial buffer size

Post by Lachlanp »

I have tried
read_nbr = ReadWithTimeout(U1_FD, message, 361, 10);
This returns 140 - 160 bytes.

I have tried
read_nbr = 0;
to_read = 361;
while (read_number < to_read)
read_nbr += ReadWithTimeout(U1_FD, &message[read_nbr], (to_read - read_nbr), 10);
This retunrs 140 - 160 bytes on the first pass, and no bytes on the second pass.

I have tried
read_nbr = 0;
to_read = 361;
while (read_number < to_read)
read_nbr += read(U1_FD, &message[read_nbr], (to_read - read_nbr);
This returns 140 - 160 bytes on the first pass and never retruns form the second pass

Lachlan
User avatar
dciliske
Posts: 624
Joined: Mon Feb 06, 2012 9:37 am
Location: San Diego, CA
Contact:

Re: Adjusting serial buffer size

Post by dciliske »

Hmm... Something is wrong here. Are you certain that you're actually sending all the data? Is it physically going out on the wire? I ask, because the serial fd's can buffer 2 ethernet packets worth (~3kB)...

Also, I assume that the difference between 'read_nbr' and 'read_number' you posted is only for the post, and wasn't actually the code you used...
Dan Ciliske
Project Engineer
Netburner, Inc
Lachlanp
Posts: 91
Joined: Tue Jan 29, 2013 4:44 am

Re: Adjusting serial buffer size

Post by Lachlanp »

The code works OK on the PC using Serial ports and C# and I get all 361 bytes of video. I have just changed the structure slightly to fit the netburner. I will try the code later this week on an 8 bit processor where I can see all the code coming in to check that it is arriving from the video processor OK.

If I use OpenSerial (1
I am using Interrupt driven serial mode, arent I?

Thanks
Lachlan
seulater
Posts: 445
Joined: Fri Apr 25, 2008 5:26 am

Re: Adjusting serial buffer size

Post by seulater »

read_nbr = ReadWithTimeout(U1_FD, message, 361, 10);
This does not work as one thinks it would. placing 361 in there does not mean that it will hang here until it gets 361 or 10 ticks expire. As soon as one char comes in it returns. Another way to do this is is this way.

int num;
unsigned int total=0;

// This may be optional. Depending on how you are doing things.
// Wait here until time expires, or we get the first char in.
// you can remove z so it will sit here and loop forever until something comes in
// your choice.
int z=0;
do
{
OSTimeDly( 1 );

}while( (dataavail(U1_FD) == 0) && (z++ < 20) );




do
{
num = ReadWithTimeout(U1_FD, (char *)& &message[total], 361 ,TICKS_PER_SECOND);

total += num;

}while( num > 0 );


when all data has been sent, and the buffer has been read this will return 0 after one second. When its returns 0 then you know all the data has been received. Providing of course that your data gets belched out from the transmitter in one second. Otherwise just increase TICKS_PER_SECOND to give you assurance.
User avatar
tod
Posts: 587
Joined: Sat Apr 26, 2008 8:27 am
Location: Southern California
Contact:

Re: Adjusting serial buffer size

Post by tod »

Post the actual code.
Lachlanp
Posts: 91
Joined: Tue Jan 29, 2013 4:44 am

Re: Adjusting serial buffer size

Post by Lachlanp »

Thanks guys, you have solved my problem. I did not realise the ReadWithTimeout function worked that way. The solutiuon was simply to add OSTimeDly(2) prior to the read and everything works. However, to make it robust I have used a differnt version of the ReadWithTimeout that waits till either the number of bytes have been received, or the timeout has occured, whichever comes first.

int ReadTimeout(inf fd, char * buf, int nbytes, int ticks){
int read_nbr = 0;

do {
if (dataavail(fd))
read_nbr += read(fd, &buf[read_nbr], (nbytes - read_nbr));
else {
if (ticks == 0)
return read_nbr;
else {
OSTimeDly(1);
ticks--;
}
}
} while (read_nbr < nbytes);
return read_nbr;
}

does that look correct?

Thanks
Lachlan
Post Reply