Catch BREAK signal on UART bus.

Hello,

I’m have connected some device on one of the UART peripherals of the BeagleBone Black, and now I would like to be able to somehow detect if there’s a “BREAK” sequence present (with some kind of Linux signaling method).

I have tried with this code:

`
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>

#define error_message printf

int set_interface_attribs (int fd, int speed, int parity) {
struct termios tty;

memset (&tty, 0, sizeof tty);

if (tcgetattr (fd, &tty) != 0) {
error_message (“error %d from tcgetattr”, errno);
return -1;
}

cfsetospeed (&tty, speed);
cfsetispeed (&tty, speed);

tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars
tty.c_iflag &= IGNBRK; // disable break processing
tty.c_lflag = 0; // no signaling chars, no echo,
// no canonical processing
tty.c_oflag = 0; // no remapping, no delays
tty.c_cc[VMIN] = 0; // read doesn’t block
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout

tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl

tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
// enable reading
tty.c_cflag &= ~(PARENB | PARODD); // shut off parity
tty.c_cflag |= parity;
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CRTSCTS;
//tty.c_iflag = ~BRKINT | ~INPCK;

if (tcsetattr (fd, TCSANOW, &tty) != 0) {
error_message (“error %d from tcsetattr”, errno);
return -1;
}
return 0;
}

void breakHandler(int signo) {
printf("\n\nCATCHED!!!\n\n");
}

int main() {

char *portname = “/dev/ttyO5”;

int fd = open (portname, O_NOCTTY);

if (fd < 0) {
error_message (“error %d opening %s: %s”, errno, portname, strerror (errno));
return;
}

set_interface_attribs (fd, B19200, 0); // set speed to 192,000 bps, 8n1 (no parity)

char buf [100];

if (signal(SIGINT, breakHandler) == SIG_ERR) {
printf("\n\nCan’t catch SIGINT!\n\n");
}

fcntl(fd, F_SETOWN, getpid());

struct sigaction saio; /* definition of signal action */

saio.sa_handler = breakHandler;
saio.sa_flags = 0;
saio.sa_restorer = NULL;

sigaction(SIGINT, &saio, NULL);

while(1) {
int n = read (fd, buf, sizeof buf); // read up to 100 characters if ready to read
usleep ((95 + 25) * 100);
printf("\n I read:\n");

int i;

for(i = 0; i < n; i++) {
printf("%#08x ", buf[i]);
}

printf("\nError: %s\n", strerror(errno));
}

return 0;
}
`

But it seems that it’s not working, the signal is only triggered when I press CTRL+C on my keyboard.

What should be the problem?

Thanks.

Are you running this code as root, or a regular user ?

as root