I have written some C code for aarch64-based SoC (Rockchip RK3399) with Debian 9 LXDE, to receive data from a GPS module. The GPS module is connected to "ttyS4" port in my SoC. I have created a pthread to receive data from the GPS module. I'm using the termios library. So my flow goes as follows:
- Initialize the UART port (baud rate, parity, stop bits etc.).
- Create a thread to receive the data from the module.
Now I need to change the baud rate of the UART upon receiving the baud rate from a external source. I am able to receive the new baud rate which I need to set it to the port.
How do I set the new baud rate to the port? Should I pthread_exit()
the receiving thread, initialize the UART port and then start the thread again?
Or should I just close the fd and initialize the UART port with the new baud rate without exiting from the thread?
Or is there any other simple way or function to set the UART to the port ?
My Initialization code:
int Gpsfd;
struct termios Gps_termios, Gps_old;
void GpsPortInit(void)
{
char path[12] = "/dev/ttyS4";
//open GSM_termios for tx/rx
Gpsfd = open(path, O_RDWR | O_NOCTTY);
if (Gpsfd < 0)
printf("port failed to open\n");
//save current attributes
tcgetattr(Gpsfd, &Gps_old);
bzero(&Gps_termios, sizeof(Gps_termios));
Gps_termios.c_cflag = CLOCAL | CREAD | CS8;
if (!strcmp(g_sParameters.RS232BaudRate, "9600"))
{
Gps_termios.c_cflag |= B9600;
}
else if (!strcmp(g_sParameters.RS232BaudRate, "19200"))
{
Gps_termios.c_cflag |= B19200;
}
else if (!strcmp(g_sParameters.RS232BaudRate, "57600"))
{
Gps_termios.c_cflag |= B57600;
}
else if (!strcmp(g_sParameters.RS232BaudRate, "115200"))
{
Gps_termios.c_cflag |= B115200;
}
Gps_termios.c_iflag = IGNPAR;
Gps_termios.c_oflag = 0;
Gps_termios.c_lflag = 0;
Gps_termios.c_cc[VTIME] = 0;
Gps_termios.c_cc[VMIN] = 1;
//clean the line and set the attributes
tcflush(Gpsfd, TCIFLUSH);
tcsetattr(Gpsfd, TCSANOW, &Gps_termios);
}
This is the baudrate change function suggested below:
int set_baudrate(speed_t speed)
{
//struct termios tty;
if (tcgetattr(Gpsfd, &Gps_termios) < 0) {
printf("Error from tcgetattr1: %s\n", strerror(errno));
return -1;
}
cfsetospeed(&Gps_termios, speed);
cfsetispeed(&Gps_termios, speed);
if (tcsetattr(Gpsfd, TCSANOW, &Gps_termios) != 0) {
printf("Error from tcsetattr: %s\n", strerror(errno));
return -1;
}
tcflush(Gpsfd, TCIOFLUSH); /* discard buffers */
return 0;
}
I am Initializing the UART once with GpsPortInit
and after that if I get any request to change the baudrate I change it with set_baudrate
.