LinuxQuestions.org
Did you know LQ has a Linux Hardware Compatibility List?
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 01-17-2005, 07:07 PM   #1
pwlodarczyk
LQ Newbie
 
Registered: Apr 2003
Posts: 4

Rep: Reputation: 0
How to increase the serial transmit buffer size in the Kernel.


I am writing an application in C++ that sends large packets out the /dev/ttyS0 serial port of a PC using the write function.

The problem is for writing packets larger than 4096 bytes.

I would like my program to be able to transmit packets larger than 4096 bytes without being blocked.

I've looked in the kernel code (linux\drivers\char\serial.c) and there is a #define called SERIAL_XMIT_SIZE. At first I tought maybe I could change that but it seems that the trasmit buffer is actially fixed to be a memory page (4k).

Any ideas on how I can change this?

I could create a seperate serial transmit thread or create a secondary buffer that gets polled but this seems like a lot of bother when the kernel already provides the mechanism.

Thanks

Last edited by pwlodarczyk; 01-17-2005 at 07:16 PM.
 
Old 01-18-2005, 11:04 AM   #2
jtshaw
Senior Member
 
Registered: Nov 2000
Location: Seattle, WA USA
Distribution: Ubuntu @ Home, RHEL @ Work
Posts: 3,892
Blog Entries: 1

Rep: Reputation: 66
I suppose you could change the size to two pages by editing include/kernel/serial.h and setting SERIAL_XMIT_SIZE to page*2. You'd certainly have to go through and see where it is used and make sure they don't do anything that depends on the size being exactly one page. Is there a particular reason why blocking is hurting you?
 
Old 01-19-2005, 06:14 PM   #3
pwlodarczyk
LQ Newbie
 
Registered: Apr 2003
Posts: 4

Original Poster
Rep: Reputation: 0
Quote:
Is there a particular reason why blocking is hurting you?
I writing out the serial port in a real time application. I can't tolerate being blocked.

I didn't want to have to modify the Kernel just as I don'y what to have to add handling of large blocks into the code that transmits the data.

The Kernel seems to handle serial comms very simply. It would just have been nice if it was possible to configure the size of the transmit buffer.
 
Old 01-19-2005, 09:03 PM   #4
randyding
Member
 
Registered: May 2004
Posts: 552

Rep: Reputation: 31
I always open the serial port like this
Code:
open(serial->port, O_RDWR | O_NOCTTY | O_NONBLOCK)
then its impossible to block. You see no matter what buffer size the kernel has, it won't be big enough for someone somewhere in their application... so the answer is you just accept the fact that the write() function may returns with less bytes written than you requested.
This is the normal behavior and the way you deal with it is you call select() and wait for write access to be available again, just like any other fd.
 
Old 01-19-2005, 09:22 PM   #5
pwlodarczyk
LQ Newbie
 
Registered: Apr 2003
Posts: 4

Original Poster
Rep: Reputation: 0
Quote:
I always open the serial port like this: open(serial->port, O_RDWR | O_NOCTTY | O_NONBLOCK)
I realise that this won't block.

If want to transmit a 3k block of data, I can open the port as you suggest, and just write it out using write().
It will add the data to the kernel serial transmit buffer, return straight away so I can continue to do important things.

The problem is if I want to write a block greater than 4k. If I want to return stright away, I need to have a secondary buffer that other transmitters also access.
I then need to make sure that something somewhere in the code (a thread or polled task) checks my secondary buffer to see if more data should be written.

This isn't that hard to do but I didn't want to bother with it. I guess I will have to.
 
Old 02-14-2005, 11:14 PM   #6
HZC
LQ Newbie
 
Registered: Feb 2005
Posts: 7

Rep: Reputation: 0
how to increase serial read buffer size from 4096 bytes?

hello everyone!!!

i have a similar kind of problem.
i am writing an application in C that receives large packets from the /dev/ttyS0 serial port of a PC using the read function.

The problem is for reading packets larger than 4096 bytes.

i have created a buffer in which i save the incoming packets but i cant seem to increase its size more than 4096 bytes.

please help me in this regard, i would really appreciate an urgent reply
thanks in advance.

regards
 
Old 02-16-2005, 12:49 AM   #7
randyding
Member
 
Registered: May 2004
Posts: 552

Rep: Reputation: 31
I think its better not to think of the data coming from a serial port as packets. Its really not packets, but a byte stream. You application layer software decides where a boundary exist if there are any, but its purely arbitrary.
I'm not exactly sure what problem you're describing, but if you're trying to call read() with a buffer size larger than 4096 and you're never receiving more than 4096, then that is normal behavior for a serial port. Keep calling read() until you receive all the data you expect, it may take several calls.
 
Old 02-17-2005, 12:36 AM   #8
HZC
LQ Newbie
 
Registered: Feb 2005
Posts: 7

Rep: Reputation: 0
here is my part of the code where m reading data from serial port into a buffer n thn from buffer m writing the data into a file.
this pgm is workin fine, it reads data from serial port, n creates and writes that data in to a file also, but the problem is jus that i want to recieve files greater than 4096bytes, even if i increase the BUFFSIZE, and sends a file greater than 4096bytes from the other pc , it does not receive more than 4096bytes.
please help me that where i am going wrong, n how can i do this.
thanks

# define BUFFSIZE 4096
char buf[BUFFSIZE];
char *bufptr;
bufptr=buf;
//fp is a pointer to a file
while( (nbytes = read(fd,bufptr,512)) > 0 )
{

while( (*bufptr!='\0') && fputc( *(bufptr++), fp) !=EOF );


tbytes+=nbytes; // ttbytes keeps track of the totel bytes read
if(tbytes > 0)
{
if(tbytes % BUFFSIZE == 0)
bufptr=buf;
}


} //while ends
 
Old 02-18-2005, 12:16 AM   #9
randyding
Member
 
Registered: May 2004
Posts: 552

Rep: Reputation: 31
I'm still not understanding your code, so here is my example
for reading forever, or at least until the buffer is completely full.
You can add your own test in the loop to break out when the
entire file has been transferred, however big that may be.
Code:
char *buf;
int n, used, bufsize;
bufsize=1000000;
buf=malloc(bufsize);
used=0;
while (used<bufsize) {
    n=read(fd,buf+used,bufsize-used);
    if (0==n) break;  //unknown serial port error
    used+=n;
}
 
Old 02-18-2005, 12:22 AM   #10
pwlodarczyk
LQ Newbie
 
Registered: Apr 2003
Posts: 4

Original Poster
Rep: Reputation: 0
Does anyone know the answer to my original question?

I want a non-blocking serial transmit that can take more that 4k without having to create a secondary buffer or a seperate transmitter thread?
 
Old 02-28-2005, 01:42 AM   #11
HZC
LQ Newbie
 
Registered: Feb 2005
Posts: 7

Rep: Reputation: 0
hello!!

thnx for ur reply !!
well yah now my program is working fine, and the serial port is able to recieve a file greater than 4K.
but i have observed another problem that the serial port is not reading the complete file being sent to it. that is if a file of size 22K is sent to it ,thn it only reieves till 20K. n the size of the datanot being read is not constant, it varies.
am not being able to figure out that what isthe problem, maybe it hasto do with flushing.
here is my code...

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <stdlib.h>
#define bufsize 1000000

int main(void)
{
int n,i;
int fd;
struct termios options;
int used;
int nbytes;
char *buf;
int offsetvar;
int count;
FILE *fp;

//opening the file

fp=fopen("/rcvdfile.txt", "w");
if(fp==NULL)
{
printf("cant open rcvdfile.txt");
}


//openingthe serial port AM2

fd=open("/dev/ttyAM2", O_RDWR | O_NOCTTY | O_NDELAY);

if(fd== -1)
{
perror("open_port:unable toopen /dev/ttyAM2");
}
else
fcntl(fd, F_SETFL, 0);

//setting baud rate

tcgetattr(fd, &options);
cfsetispeed(&options, B19200);
cfsetospeed(&options, B19200);

options.c_cflag |= (CLOCAL | CREAD);
tcsetattr(fd, TCSANOW, &options);

//reading from the port

buf=malloc(bufsize);
offsetvar=0;
used=0;

while( used<bufsize)
{
nbytes=read ( fd, buf, bufsize-used ); //data being read into a buffer 'buf' from serial port
while( (*buf!='\0') && fputc( *(buf++),fp ) !=EOF); // this saves data being read from the buffer into a file.
used+=nbytes;

}

//closin the port and files

fclose(fp);
close(fd);

} // main ends


please reply soon.
thnx in advance
cheers...
 
Old 02-28-2005, 11:56 PM   #12
randyding
Member
 
Registered: May 2004
Posts: 552

Rep: Reputation: 31
I'm thinking this is not quite right.
Code:
while( (*buf!='\0') && fputc( *(buf++),fp ) !=EOF);
*buf!='\0' can't be used because your data is not null terminated.
I'd use write(fileno(stdout),buf,used) instead of that loop.
 
Old 03-15-2005, 12:36 AM   #13
HZC
LQ Newbie
 
Registered: Feb 2005
Posts: 7

Rep: Reputation: 0
hello!!!
am having the same problem, even after makin an amendment tht u suggested.
there's no problem of the file size anymore, but last 1 to 2 Kbytes are not saved.
pls reply soon
thanks in advance
 
Old 01-21-2009, 05:39 PM   #14
sean04
LQ Newbie
 
Registered: Oct 2007
Posts: 8

Rep: Reputation: 0
Has anyone found a solution to this?
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Increase the command line buffer size Akiles Linux - General 3 04-19-2005 12:17 PM
how to increase serial receive email buffer size? HZC Programming 0 02-14-2005 11:32 PM
How do you increase a kernel stack size? ginda Linux - Newbie 4 01-24-2005 07:52 PM
No of bytes in the serial drivers transmit buffer igjesdal Programming 0 10-13-2004 11:58 AM
How do i increase the size of the linux fifo's currently set to 4K in 2.6 kernel ? ayb Programming 2 06-25-2004 08:55 AM


All times are GMT -5. The time now is 05:01 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration