RT-Thread / rt-thread

RT-Thread is an open source IoT Real-Time Operating System (RTOS).
https://www.rt-thread.io
Apache License 2.0
10.47k stars 5.01k forks source link

关于串口运行时修改参数无效的疑问 【RT_DEVICE_FLAG_ACTIVATED】 #4222

Open novrain opened 3 years ago

novrain commented 3 years ago

例如:

        rt_device_t dev = rt_device_find(RS485_NAME);
        struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
        config.baud_rate = 1200;
        config.data_bits = DATA_BITS_7;
        config.stop_bits = STOP_BITS_1;
        config.parity = PARITY_EVEN;
        rt_device_control(dev, RT_DEVICE_CTRL_CONFIG, &config);
        rt_device_open(dev, RT_DEVICE_FLAG_INT_RX | RT_DEVICE_OFLAG_RDWR);
        //  操作....
        rt_device_close(dev);

        // 更改串口参数,与其他设备通信
        config.baud_rate = 9600;
        config.data_bits = DATA_BITS_8;
        config.stop_bits = STOP_BITS_1;
        config.parity = PARITY_NONE;
        // 设置无效
        rt_device_control(dev, RT_DEVICE_CTRL_CONFIG, &config);
        //  必须手工去除 RT_DEVICE_FLAG_ACTIVATED
        // dev->flag &= ~RT_DEVICE_FLAG_ACTIVATED;
        rt_device_open(dev, RT_DEVICE_FLAG_INT_RX | RT_DEVICE_OFLAG_RDWR);

设备在首次打开的时候RT_DEVICE_FLAG_ACTIVATED会被设置, 但是串口关闭的时候,RT_DEVICE_FLAG_ACTIVATED并未去除,同时具体实现rt_serial_control(serial.c)中的逻辑,会导致设备被打开前,不会执行设置。

 case RT_DEVICE_CTRL_CONFIG:
            if (args)
            {
                struct serial_configure *pconfig = (struct serial_configure *) args;
                if (pconfig->bufsz != serial->config.bufsz && serial->parent.ref_count)
                {
                    /*can not change buffer size*/
                    return RT_EBUSY;
                }
                /* set serial configure */
                serial->config = *pconfig;
                if (serial->parent.ref_count)  // 这里导致在打开前不会被执行
                {
                    /* serial device has been opened, to configure it */
                    serial->ops->configure(serial, (struct serial_configure *) args);
                }
            }

            break;

这样会导致rt_device_control无效(修改波特率等)。

BernardXiong commented 3 years ago

谢谢反馈,这个问题会被收集到《RTT串口框架建议收集》

mysterywolf commented 2 years ago

我也遇到这个问题了,Arduino设置波特率的时候,没有反应。。


更新 该问题已解决

armink commented 2 years ago

我也遇到这个问题了,Arduino设置波特率的时候,没有反应。。

串口V2 框架 + POSIX API 亲测没问题

static int btstack_uart_posix_set_baudrate(uint32_t baudrate){

    int fd = transport_data_source.source.fd;

    log_info("h4_set_baudrate %u", baudrate);
    struct termios toptions;

    if (tcgetattr(fd, &toptions) < 0) {
        log_error("btstack_uart_posix_set_baudrate: Couldn't get term attributes");
        return -1;
    }

    speed_t brate = baudrate; // let you override switch below if needed
    switch(baudrate) {
        case    9600: brate=B9600;    break;
        case   19200: brate=B19200;   break;
        case   38400: brate=B38400;   break;
        case   57600: brate=B57600;   break;
        case  115200: brate=B115200;  break;
#ifdef B230400
        case  230400: brate=B230400;  break;
#endif
#ifdef B460800
        case  460800: brate=B460800;  break;
#endif
#ifdef B500000
        case  500000: brate=B500000;  break;
#endif
#ifdef B576000
        case  576000: brate=B576000;  break;
#endif
#ifdef B921600
        case  921600: brate=B921600;  break;
#endif
#ifdef B1000000
        case 1000000: brate=B1000000; break;
#endif
#ifdef B1152000
        case 1152000: brate=B1152000; break;
#endif
#ifdef B1500000
        case 1500000: brate=B1500000; break;
#endif
#ifdef B2000000
        case 2000000: brate=B2000000; break;
#endif
#ifdef B2500000
        case 2500000: brate=B2500000; break;
#endif
#ifdef B3000000
        case 3000000: brate=B3000000; break;
#endif
#ifdef B3500000
        case 3500000: brate=B3500000; break;
#endif
#ifdef B4000000
        case 4000000: brate=B4000000; break;
#endif
        default:
            log_error("can't set baudrate %dn", baudrate );
            return -1;
    }
    cfsetospeed(&toptions, brate);
    cfsetispeed(&toptions, brate);

    if( tcsetattr(fd, TCSANOW, &toptions) < 0) {
        log_error("Couldn't set term attributes");
        return -1;
    }
#endif

    return 0;
}