Question

I have an embedded linux setup generated using buildroot. As part of my application I have a dedicated thread that opens the serial port (/dev/ttyS0) for the purposes of listening for and replying to modbus messages. It works fine, but when my target device is connected to my host development machine, whenever I shutdown my dev machine, something is being sent over the serial port that is killing my process on the target. In this case I believe that it is the SAK (secure attention key) being received which results in SAK kernel messages and process being killed. I posted this question on unix/linux stackexchange and the answer to it partially helps me. The problem is that when I disable the serial port SAK using

 setserial /dev/ttyS0 ^sak

at system startup, when I later open the port using userspace API C code the serial port is opened with the SAK option again (I have verified this by disabling SAK, starting up my application, checking setserial again only to find SAK set once more). Basically, I need to know what flags I need to set in my termios struct that I pass to tcsetattr() when I am configuring the serial port. Currently my code that opens the serial is as follows:

int current_fd = open(strfile.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
termios new_settings;
tcgetattr(current_fd, &old_options);
tcgetattr(current_fd, &new_settings);

new_settings.c_cflag = 0;
new_settings.c_cflag |= (CLOCAL | CREAD | CS8);
new_settings.c_lflag = 0;
new_settings.c_oflag = 0;
new_settings.c_oflag |= (ONOCR | ONLRET);  
new_settings.c_iflag = 0;
new_settings.c_iflag |= (IGNBRK | IGNPAR | IGNCR);    
tcsetattr(current_fd, TCSANOW, &new_settings);

I have read through all of the termios man pages and I cannot see anything that refers to the SAK - the only relevent thing is the IGNBRK setting which I have set. Is there anything I can do to disable the SAK setting on the serial port via the userspace API?

Was it helpful?

Solution

I have actually been able to do this using the serial_struct struct and ASYNC_SAK flag using ioctl() as follows

serial_struct s_serial;
memset(&s_serial,0,sizeof(s_serial));
ioctl(current_fd, TIOCGSERIAL, &s_serial);
s_serial.flags &= ~ASYNC_SAK;  
ioctl(current_fd, TIOCSSERIAL, &s_serial);

I am still at a loss as to why opening the serial port had overridden the sak flag that I had previously set using setserial() but adding the code above before I set the termios options has resolved the issue and the sak flag remains disabled.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top