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—调试串口用于普通串口

RK3399驱动开发 | 03 - WK2124串口芯片驱动调试

RK3399驱动开发 | 03 - WK2124串口芯片驱动调试

rk3399修改调试串口

Rk3399—添加usb转串口驱动

RK3399平台开发系列讲解(USB转串口)5.49/dev/ttyUSB 修改串口名