Normally we would like to use the termios API to initialize the serial device.
I think you didn’t try the
stty -F /dev/ttyUSB2 115200 cs8 -parenb -cstopb -echo -icanon raw
Or you can the example
gcc test_AT.c -o test_AT -lpthread
// test_AT.c
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/select.h>
#include <termios.h>
#include <string.h>
#include <semaphore.h>
static int timeoutVal = 10;
static int waitsecond = 1;
static char Version[100] = "Q-v0.1";
sem_t my_semaphore; // 定义一个信号量
int xget1(int fd, struct termios *tio, struct termios *tiosfd) {
if (tcgetattr(fd, tio) < 0) {
perror("tcgetattr failed");
return -1;
}
*tiosfd = *tio; // Save the current settings
return 0;
}
int xset1(int fd, struct termios *tio, const char *dev) {
if (tcsetattr(fd, TCSANOW, tio) < 0) {
perror("tcsetattr failed");
return -1;
}
return 0;
}
int main(int argc, char **argv)
{
int i;
int fd;
int ret;
char buffer[409600] = {0};
int rate;
char* sendbuffer;
int totallen = 0;
fd_set readfds;
struct timeval timeout;
struct termios tio0, tiosfd, tio;
(void)tio0;
for (i = 1; i < argc; i++) {
printf("argv[%d]: %s\n",i, argv[i]);
}
for (i = 1; i < argc; i++)
{
if (argc > 2 && !strcmp(argv[i], "-version"))
{
printf("%s Version is %s\n", argv[0], Version);
printf("Usage: %s <dev> <baudrate> [timeout [waitsecond]] <atcmd>\n", argv[0]);
printf("For example:\n (1)%s /dev/ttyUSB2 115200 \"ATI\"\n (2)%s -version\n", argv[0], argv[0]);
exit(0);
}
}
if (argc == 2 && !strcmp(argv[1], "-version"))
{
printf("%s Version is %s\n", argv[0], Version);
exit(0);
}
if (argc != 4 && argc != 5 && argc != 6)
{
printf("Usage: %s <dev> <boundrate> [timeout [waitsecond]] <atcmd>\n", argv[0]);
printf("For example:\n (1)%s /dev/ttyUSB2 115200 \"ATI\"\n (2)%s -version\n", argv[0], argv[0]);
exit(1);
}
char *dev = argv[1];
rate = atoi(argv[2]);
if (argc == 4)
sendbuffer = argv[3];
else if (argc == 5)
{
timeoutVal = atoi(argv[3]);
sendbuffer = argv[4];
}
else
{
timeoutVal = atoi(argv[3]);
waitsecond = atoi(argv[4]);
sendbuffer = argv[5];
}
// 初始化信号量(如果未初始化)
if (sem_init(&my_semaphore, 0, 1) != 0)
{
perror("sem_init failed");
exit(1);
}
// 等待信号量
if (sem_wait(&my_semaphore) != 0)
{
perror("sem_wait failed");
exit(1);
}
printf("%d %d\n", timeoutVal, waitsecond);
fd = open(dev, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd < 0)
goto ERR;
fcntl(fd, F_SETFL, O_RDWR);
// put device to "raw mode"
xget1(fd, &tio, &tiosfd);
cfsetspeed(&tio, 115200);
if (xset1(fd, &tio, dev))
goto ERR;
tcflush(fd, TCIOFLUSH);
// printf("### %d waitseconnd : %d###\n",__LINE__, waitsecond);
if (waitsecond > 0)
sleep(waitsecond);
sprintf(buffer, "%s\r", sendbuffer);
ret = write(fd, buffer, strlen(buffer));
if (ret < 0)
{
printf("write failed\n");
goto ERR;
}
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
while (1)
{
timeout.tv_sec = timeoutVal;
timeout.tv_usec = 0;
ret = select(fd + 1, &readfds, NULL, NULL, &timeout);
if (ret > 0)
{
ret = read(fd, buffer + totallen, sizeof(buffer) - totallen - 1);
if (ret < 0)
{
printf("read failed\n");
goto ERR;
}
if (ret == 0)
{
goto ERR;
}
totallen += ret;
buffer[totallen] = '\0';
if (strstr(buffer, "\nOK") || strstr(buffer, "\nERROR") || strstr(buffer, "\n+CME ERROR:") || strstr(buffer, "\n+CMS ERROR:"))
{
break;
}
}
else
{
printf("select timeout\n");
goto ERR;
}
}
tcsetattr(fd, TCSAFLUSH, &tiosfd);
printf("%s\n", buffer);
// 释放信号量
if (sem_post(&my_semaphore) != 0)
{
perror("sem_post failed");
exit(1);
}
close(fd);
exit(0);
ERR:
if (fd > 0)
close(fd);
// 释放信号量
if (sem_post(&my_semaphore) != 0)
{
perror("sem_post failed");
exit(1);
}
exit(1);
}