I have written the C program that should read UART's RxD port and display the results as soon as there is any information. To achieve this I'm using signal_handler SIGIO signal
Read program c code
#include <iostream>
#include <termios.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/signal.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <poll.h>
#include <time.h>
#include <string.h>
#define BAUDRATE B19200
#define PORT "/dev/ttyO4"
#define _POSIX_SOURCE 1
int fd;
void signal_handler_IO(int status);
void set_port_settings();
char buff[255];
sig_atomic_t flag=0;
using namespace std;
int main ()
{
set_port_settings();
for(;;){
if(flag !=0)
{
//printf( "sync : 0x%X\n", buff[1]);
//printf ( "PID: 0x%X\n", buff[2]);
printf ( "D0: 0x%X\n", buff[4]);
printf ( "D1: 0x%X\n", buff[5]);
printf ( "D2: 0x%X\n", buff[6]);
printf ( "D3: 0x%X\n", buff[7]);
printf ( "D4: 0x%X\n", buff[8]);
printf ( "D5: 0x%X\n", buff[9]);
printf ( "D6: 0x%X\n", buff[10]);
printf ( "D7: 0x%X\n", buff[11]);
printf ( "CHK: 0x%X\n", buff[12]);
flag = 0;
}
}
}
void signal_handler_IO(int status)
{
if(flag !=1)
{
read(fd, &buff, sizeof(buff));
flag = 1;
}
}
void set_port_settings()
{
struct termios oldtio, newtio;
struct sigaction saio;
fd = open(PORT, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd<0) {perror(PORT); exit(-1);}
saio.sa_handler=signal_handler_IO;
sigemptyset(&saio.sa_mask);
saio.sa_flags=SA_RESTART;
sigaction(SIGIO, &saio,NULL);
fcntl (fd, F_SETOWN, getgid());
fcntl(fd, F_SETFL, FASYNC);
tcgetattr(fd, &oldtio); perror("tsgetattr");
newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD ; perror("c_cflag");
newtio.c_iflag = IGNPAR | IXON ; perror("c_iflag");
newtio.c_oflag = 0; perror("c_oflag");
newtio.c_lflag = ICANON | ISIG ; perror("c_lflag");
newtio.c_cc[VMIN]=8;perror("c_cc[VMIN]");
newtio.c_cc[VTIME]=1; perror("c_cc[VTIME]");
newtio.c_cc[VSTART]=0x55;
tcflush(fd, TCIFLUSH); perror("TCFLUSH");
tcsetattr(fd, TCSANOW, &newtio); perror("tcsetattr");
}
Problem that I have, is that when the program reads data and starts printing out the results, the information printed out is somehow correct just printed (or read in) in a wrong place.
I'm writing to the port using another C program. I've tried to do it from the same C program but was unsuccessful to write and read from the same C program. So I keep 2 shells open: on one shell I'm running write program, on another shell I'm running read program to display what it was able to read in.
Write program C code
#include <iostream> #include <termios.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/signal.h> #include <stdlib.h> #include <sys/ioctl.h> #define BAUDRATE9600 B19200 #define PORT "/dev/ttyO4" #define _POSIX_SOURCE 1 using namespace std; int main() { int fd; char buffer[255]; struct termios oldtio, newtio; struct sigaction saio; fd = open(PORT, O_RDWR | O_NOCTTY | O_NONBLOCK); if (fd<0) {perror(PORT); exit(-1);} tcgetattr(fd, &oldtio); newtio.c_cflag = BAUDRATE9600 | CS8 | CLOCAL | CREAD; newtio.c_iflag = IGNPAR; newtio.c_oflag = 0; newtio.c_lflag = 0; tcflush(fd, TCIFLUSH); tcsetattr(fd, TCSANOW, &newtio); char SYNC [] = {0x55}; char PID [] = {0x97}; char data0 [] = {0x25}; char data1 [] = {0xFF}; char data2 [] = {0x00}; char data3 [] = {0x64}; char data4 [] = {0x01}; char data5 [] = {0xFF}; char data6 [] = {0xFF}; char data7 [] = {0xFC}; char checksum [] ={0xE0};
for (;;) {
ioctl(fd, TIOCSBRK); usleep(676); // 13 bits, 1 bit = 52us ioctl(fd,TIOCCBRK); usleep(260); // 5 bits write(fd, SYNC, sizeof(SYNC)); write(fd, PID, sizeof(PID)); write(fd, data0, sizeof(data0)); write(fd, data1, sizeof(data1)); write(fd, data2, sizeof(data2)); write(fd, data3, sizeof(data3)); write(fd, data4, sizeof(data4)); write(fd, data5, sizeof(data5)); write(fd, data6, sizeof(data6)); write(fd, data7, sizeof(data7)); write(fd, checksum, sizeof(checksum)); usleep(10000); close (fd); }
When I run both programs to check if the READ programs is working as it should, I can see that the data is read in, but is not exactly as it it's written to the port.
example of the data read in
d0: 0x7C
d1: 0x66
d2: 0x1
d3: 0xE0
d4: 0x4C
d5: 0x7C
d6: 0x8
d7: 0x60
CHK: 0x60
d0: 0x1
d1: 0xE0
d2: 0x4C
d3: 0x7C
d4: 0x8
d5: 0x60
d6: 0xFC
d7: 0x60
CHK: 060
I hope that somebody will be able to point where I have made a mistake and what should I do to be able to read from the UART port without the problem.