DEV Community

nima
nima

Posted on

Serial port communication in C

github link for this project:
https://github.com/atrotech/comtest
How to build

git clone https://github.com/atrotech/comtest.git

cd comtest

gcc -o comtest comtest.c

Usage
./comtest -d /dev/ttyAMA3 -s 38400
Parameters

./comtest --help

comtest - interactive program of comm port
press [ESC] 3 times to quit
Usage: comtest [-d device] [-t tty] [-s speed] [-7] [-c] [-x] [-o] [-h]
-7 7 bit
-x hex mode
-o output to stdout too
-c stdout output use color
-h print this help
comtest.c :

include

include

include

include

include

include

include

include

include

static int SerialSpeed(const char *SpeedString)
{
int SpeedNumber = atoi(SpeedString);

define TestSpeed(Speed) if (SpeedNumber == Speed) return B##Speed

TestSpeed(1200);
TestSpeed(2400);
TestSpeed(4800);
TestSpeed(9600);
TestSpeed(19200);
TestSpeed(38400);
TestSpeed(57600);
TestSpeed(115200);
TestSpeed(230400);
return -1;
Enter fullscreen mode Exit fullscreen mode

}
static inline void WaitFdWriteable(int Fd)
{
fd_set WriteSetFD;
FD_ZERO(&WriteSetFD);
FD_SET(Fd, &WriteSetFD);
if (select(Fd + 1, NULL, &WriteSetFD, NULL, NULL) < 0) {
printf("%s",strerror(errno));

}
Enter fullscreen mode Exit fullscreen mode

}
int main(int argc, char **argv)
{
int CommFd, TtyFd;
struct termios TtyAttr;
struct termios BackupTtyAttr;
int DeviceSpeed = B38400;
int TtySpeed = B38400;
int ByteBits = CS8;
const char *DeviceName = "/dev/ttyAMA3";
const char *TtyName = "/dev/tty";
int OutputHex = 0;
int OutputToStdout = 0;
int UseColor = 0;

CommFd = open(DeviceName, O_RDWR, 0);

if (fcntl(CommFd, F_SETFL, O_NONBLOCK) < 0)
  printf("Unable set to NONBLOCK mode");
Enter fullscreen mode Exit fullscreen mode

memset(&TtyAttr, 0, sizeof(struct termios));
TtyAttr.c_iflag = IGNPAR;
TtyAttr.c_cflag = DeviceSpeed | HUPCL | ByteBits | CREAD | CLOCAL;
TtyAttr.c_cc[VMIN] = 1;
if (tcsetattr(CommFd, TCSANOW, &TtyAttr) < 0)
printf("Unable to set comm port");
TtyFd = open(TtyName, O_RDWR | O_NDELAY, 0);
TtyAttr.c_cflag = TtySpeed | HUPCL | ByteBits | CREAD | CLOCAL;
if (tcgetattr(TtyFd, &BackupTtyAttr) < 0)
printf("Unable to get tty");
if (tcsetattr(TtyFd, TCSANOW, &TtyAttr) < 0)
printf("Unable to set tty");
for (;;) {
unsigned char Char = 0;
fd_set ReadSetFD;
void OutputStdChar(FILE *File) {
char Buffer[10];
int Len = sprintf(Buffer, OutputHex ? "%.2X " : "%c", Char);
fwrite(Buffer, 1, Len, File);
}
FD_ZERO(&ReadSetFD);
FD_SET(CommFd, &ReadSetFD);
FD_SET( TtyFd, &ReadSetFD);

define max(x,y) ( ((x) >= (y)) ? (x) : (y) )

if (select(max(CommFd, TtyFd) + 1, &ReadSetFD, NULL, NULL, NULL) < 0) {
printf("%s",strerror(errno));
}

undef max

if (FD_ISSET(CommFd, &ReadSetFD)) {
while (read(CommFd, &Char, 1) == 1) {
WaitFdWriteable(TtyFd);
if (write(TtyFd, &Char, 1) < 0) {
printf("%s",strerror(errno));
}
if (OutputToStdout) {
if (UseColor)
fwrite("\x1b[01;34m", 1, 8, stdout);
OutputStdChar(stdout);
if (UseColor)
fwrite("\x1b[00m", 1, 8, stdout);
fflush(stdout);
}
}
}
if (FD_ISSET(TtyFd, &ReadSetFD)) {
while (read(TtyFd, &Char, 1) == 1) {
static int EscKeyCount = 0;
WaitFdWriteable(CommFd);
if (write(CommFd, &Char, 1) < 0) {
printf("%s",strerror(errno));
}
if (OutputToStdout) {
if (UseColor)
fwrite("\x1b[01;31m", 1, 8, stderr);
OutputStdChar(stderr);
if (UseColor)
fwrite("\x1b[00m", 1, 8, stderr);
fflush(stderr);
}
if (Char == '\x1b') {
EscKeyCount ++;
if (EscKeyCount >= 3)
goto ExitLabel;
} else
EscKeyCount = 0;
}
}
}
ExitLabel:
if (tcsetattr(TtyFd, TCSANOW, &BackupTtyAttr) < 0)
printf("Unable to set tty");
return 0;
}
Makefile
CROSS=arm-linux-
all: armcomtest x86comtest
armcomtest: comtest.c
$(CROSS)gcc -Wall -O3 -o armcomtest comtest.c
x86comtest: comtest.c
gcc -o x86comtest comtest.c
clean:
@rm -vf armcomtest x86comtest *.o *~

Speedy emails, satisfied customers

Postmark Image

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (1)

Collapse
 
muhyilmaz profile image
MUHAMMED YILMAZ

bad writing

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay