SOM-RK3399串口配置
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SOM-RK3399串口配置相关的知识,希望对你有一定的参考价值。
参考技术A siom-RK3399是友善推出的一款rockchip rk3399的开发板。默认串口配置为:
在linux下使用minicom作为串口工具。
串口配置help.read()和write()返回-1,串口通讯停止。为啥?
【中文标题】串口配置help.read()和write()返回-1,串口通讯停止。为啥?【英文标题】:serial port configuration help.read() and write() return -1 and serial comunication stop.why?串口配置help.read()和write()返回-1,串口通讯停止。为什么? 【发布时间】:2013-07-07 11:18:25 【问题描述】:我必须用 C 创建一个程序,以便我可以通过串行端口与设备通信。端口的配置应为 9600BPS 起始位:1 数据位:8 奇偶校验位:偶数停止位:1。我正在向您发送我如何配置端口的副本,但我有一个问题,我可以解决它。
我每 100 到 200 毫秒向设备发送一个状态请求,设备应该响应,因为我有一个计时器。在上电序列中,我向设备发送命令,设备正在响应,但是在发送和接收一些命令后,发送停止,因此接收也停止,我注意到写命令和读命令发回-1,之后什么都没有发生。为什么会出现这种情况?
是因为我正在尝试阅读,而我没有什么可阅读的,所以在这种情况下我得到 -1,但如果是这样,为什么我在写入后得到 -1? 感谢您的所有帮助。
int main(int argc, char *argv[])
timer_t tid = 0;
struct itimerspec it;
fd = open("/dev/ttyUSB1", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
perror("open_port: Unable to open /dev/ttyS0\n");
exit(1);
satimer.sa_handler = signal_handler_TIMER;
satimer.sa_flags = 0;
satimer.sa_restorer = NULL;
sigaction(SIGALRM, &satimer, NULL);
it.it_value.tv_sec = 0;
it.it_value.tv_nsec = 10000000;
it.it_interval.tv_sec = 0;
it.it_interval.tv_nsec = 10000000;
if (timer_create(CLOCK_REALTIME, NULL, &tid) == -1)
fprintf(stderr, "error in timer_create \n");
// printf("timer ID is 0x%lx\n", (long) tid);
if (timer_settime(tid, 0, &it, NULL) == -1)
fprintf(stderr, "error in settime \n");
fcntl(fd, F_SETFL, FNDELAY);
fcntl(fd, F_SETOWN, getpid());
fcntl(fd, F_SETFL, O_SYNC);
tcgetattr(fd, &termAttr);
//baudRate = B115200; /* Not needed */
cfsetispeed(&termAttr, B9600);
cfsetospeed(&termAttr, B9600);
termAttr.c_cflag |= PARENB;
termAttr.c_cflag &= ~PARODD;
termAttr.c_cflag &= ~CSTOPB;
termAttr.c_cflag &= ~CSIZE;
termAttr.c_cflag |= CS8;
termAttr.c_cflag |= (CLOCAL | CREAD);
termAttr.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
termAttr.c_iflag &= ~(IXON | IXOFF | IXANY);
termAttr.c_oflag &= ~OPOST;
termAttr.c_cc[VMIN] = 5;
termAttr.c_cc[VTIME] = 5;
tcsetattr(fd, TCSANOW, &termAttr);
CleanRxBuffer();
PowerUp();
......
void PowerUp(void)
unsigned char *p_commands,ima,komanda = STATUS_REQUEST;
p_commands = &comandi[0];
unsigned char *p_tx_buffer_;
for (;;)
if ((milisekundi == 10) || (milisekundi == 30) || (milisekundi == 50)
|| (milisekundi == 70) || (milisekundi == 90))
makeTXpaket(0x00);
makeTXpaket(komanda);
p_tx_buffer_ = &tx_buffer[1];
nbytes = write(fd, tx_buffer, *p_tx_buffer_);
if (nbytes != sizeof(tx_buffer))
/* problem! */
printf("error writing on serial port!!!");
sleep(0.2);
bytes = read(fd, rx_buffer, sizeof(rx_buffer));
if (bytes != sizeof(rx_buffer))
/* problem! */
printf("error reading on serial port!!!\n");
printf("%X\n", rx_buffer);
ima = CheckRXbuffer();
if ((answer == 0x40) && (ima != 0x00))
p_commands++;
komanda = *p_commands;
if ((answer == 0x50) && (ima != 0x00))
p_commands++;
komanda = *p_commands;
if ((answer == 0x1B) && (ima != 0x00))
p_commands++;
komanda = *p_commands;
if ((answer == 0xC0) && (ima != 0x00))
p_commands++;
komanda = *p_commands;
if ((answer == 0xC4) && (ima != 0x00))
p_commands++;
komanda = *p_commands;
if ((answer == 0xC1) && (ima != 0x00))
p_commands++;
komanda = *p_commands;
if ((answer == 0xC2) && (ima != 0x00))
p_commands++;
komanda = *p_commands;
if ((answer == 0xC5) && (ima != 0x00))
p_commands++;
komanda = *p_commands;
if ((answer == 0xC6) && (ima != 0x00))
p_commands++;
komanda = *p_commands;
if ((answer == 0xC7) && (ima != 0x00))
p_commands++;
komanda = *p_commands;
if ((answer == 0xC3) && (ima != 0x00))
p_commands++;
komanda = *p_commands;
if ((answer == 0x11) && (ima != 0x00))
break;
if ((*p_commands) == 0xFF)
break;
CleanRxBuffer();
【问题讨论】:
写系统调用返回时能否检查错误号并发布错误号。 我的意思是有一个名为 'errno' 的全局变量,其中包含表示在您的 write 调用期间发生的错误的数字。一般当有任何错误时,系统调用返回 -1 并将相应的错误代码存储在 errno 变量中。更多信息请参考写系统调用手册页bytes = read(fd, rx_buffer, sizeof(rx_buffer)); if (bytes != sizeof(rx_buffer))
是错误的。 read() 可以返回 -1、零或任何值 write()
errno=4 on write 并且我的串行通信停止!
我发送命令我的设备响应 n 次然后串行通信停止我的程序正在运行但串口中没有写入任何内容
【参考方案1】:
您已将文件描述符配置为非阻塞模式。
这意味着当你 write() (和读取,就此而言)它不会阻塞等待写入完成,如果端口已经很忙。
相反,它将返回 -1 并将 errno 设置为 EAGAIN(或 EWOULDBLOCK)。
所以,要解决这个问题:
fd = open("/dev/ttyUSB1", O_RDWR | O_NOCTTY | O_NDELAY);
删除 O_NDELAY。 O_NDELAY 是 O_NONBLOCK 的别名,这就是使 read() 和 write() 的行为如您所见的原因。
fcntl(fd, F_SETFL, FNDELAY);
这和O_NDELAY是一回事(其实FNDELAY是O_NDELAY的兼容别名,O_NONBLOCK是O_NONBLOCK的别名),只是重新设置了flag而已。
fcntl(fd, F_SETFL, O_SYNC);
这是你不想要的。但我不认为这会严重伤害事情。这将导致写入不使用任何缓冲。
【讨论】:
以上是关于SOM-RK3399串口配置的主要内容,如果未能解决你的问题,请参考以下文章
RK3399驱动开发 | 03 - WK2124串口芯片驱动调试