You can certainly read multiple bytes using read
.
The comments about FIFO are misleading, even though they are important to ensure high speed troughput, are inaccessable.
The kernel drivers almost certainly provide buffering, but again this is inaccessable. (In the 1970s I wrote my own drivers which used a 256 character circular buffer.)
The following code fragment is an example of how you could write such a buffered interface (into a user supplied buffer).
This ia actually an add-on to a wiringPi
library routine (AFAIK installed by default on the Raspbian) which I use to provide an equivalent to fgets
. Similar code could be used with any library.
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <wiringPi.h>
#include <wiringSerial.h>
#define MAXLINE 20
/*
* serialOpenB:
* Open and initialise the serial port,
* setting canonical mode, ignore CR on input, no timeout
*********************************************************************************
*/
int serialOpenB (const char *device, const int baud, const int max)
{
struct termios options ;
int fd = serialOpen(device, baud);
// Get and modify current options:
tcgetattr (fd, &options) ;
options.c_lflag |= ICANON; // set canonical mode (line by line)
options.c_iflag |= IGNCR; // ignore CR on input
options.c_cc [VMIN] = max-1; // return if max-1 bytes received
options.c_cc [VTIME] = 0; // no timeout
tcsetattr (fd, TCSANOW | TCSAFLUSH, &options) ;
usleep (10000) ; // 10mS
return fd ;
}
/* Get a newline-terminated string of finite length.
*********************************************************************************
*/
char * serialGets (char *buf, const int n, const int fd)
{
int m;
m = read (fd, buf, n);
*(buf+m) = '\0';
return (buf) ;
}
The following is a test program
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <wiringPi.h>
#include <wiringSerial.h>
#define MAXLINE 120
extern int serialOpenB (const char *device, const int baud, const int n);
extern char * serialGets (char *buf, const int n, const int fd);
char * rstrip(char *s) {
char *p = s + strlen(s)-1;
while((*p == '\n')||(*p == '\n')) {
p--;
}
*p = '\0';
return s;
}
int main ()
{
char tbuf[20];
time_t ctm;
struct tm *ltime;
char line[MAXLINE];
puts("SerialTest\n");
// Always initialise wiringPi. Use wiringPiSys() if you don't need
// (or want) to run as root
wiringPiSetupSys () ;
int fd = serialOpenB("/dev/ttyAMA0", 9600, MAXLINE);
for(;;) {
serialGets(line, MAXLINE, fd);
ctm = time(NULL); // log time
ltime = localtime (&ctm);
strftime (tbuf, 20, "%F %T", ltime);
printf("%s %s\n", rstrip(line), tbuf);
fflush(stdout);
}
return 0 ;
}
open()
syscall with/dev/ttyUSBx
. Moreover, you are definitely right about that I actually read through kernel, not directly SoC's buffer. I missed it. Since for the different SoC's, there will be different buffer size, i just curious about does linux kernel optimize this? Another question, is 16x12 FIFO memory means 16 UART packet (Start bit, 8 data bits, 1 parity bit and 2 stop bits)? What will happen if I configure 7N1? Will SoC's buffer still store 16 packet (last bit space become useless) ? – Black Glix Dec 27 '17 at 19:59