RS485:设备的不适当的ioctl [英] RS485: Inappropriate ioctl for device

查看:284
本文介绍了RS485:设备的不适当的ioctl的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用以下代码访问RS485从站,但出现错误:

I am using the following code to access the RS485 slave but I get the error:

读取ioctl端口(25)时出错:设备不正确的ioctl

Error reading ioctl port (25): Inappropriate ioctl for device

我的代码如下:

#include <linux/serial.h>
#include <sys/ioctl.h>


    int fd = open ("/dev/ttyUSB0", O_RDWR);
    if (fd < 0) {
        printf("Error Opening\n");
        exit(0);
    }

    struct serial_rs485 rs485conf;

    /* Enable RS485 mode: */
    rs485conf.flags |= SER_RS485_ENABLED;

    /* Set logical level for RTS pin equal to 1 when sending: */
    rs485conf.flags |= SER_RS485_RTS_ON_SEND;

    /* set logical level for RTS pin equal to 0 after sending: */
    rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND);

    /* Set rts delay before send, if needed: */
    rs485conf.delay_rts_before_send = 0;

    /* Set rts delay after send, if needed: */
    rs485conf.delay_rts_after_send = 0;

    /* Set this flag if you want to receive data even whilst sending data */
    rs485conf.flags |= SER_RS485_RX_DURING_TX;

    if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) {
        fprintf( stderr, "Error reading ioctl port (%d): %s\n",  errno, strerror( errno ));
        exit(0);
    }

    //TODO read and write

    /* Close the device when finished: */
    if (close (fd) < 0) {
        fprintf( stderr, "Error closing device connection (%d): %s\n",  errno, strerror( errno ));
    }

我从 https://www.kernel获取了源代码.org/doc/Documentation/serial/serial-rs485.txt .我正在树莓派上开发应用程序,并使用Quad RS232-HS芯片连接到FTDI USB串行设备.错误的根源可能是什么?\

I took the source code from https://www.kernel.org/doc/Documentation/serial/serial-rs485.txt. I am developing my application on the raspberry pi and am connected to the FTDI USB Serial device using Quad RS232-HS chip. What might be the source of the error?\

当我连接USB设备时,输出

When USB I connect the USB device, output for

dmesg

dmesg

如下:

[16865.640038] usb 3-2: new high-speed USB device number 10 using xhci_hcd
[16865.780365] usb 3-2: New USB device found, idVendor=0403, idProduct=6011
[16865.780367] usb 3-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[16865.780369] usb 3-2: Product: Quad RS232-HS
[16865.780370] usb 3-2: Manufacturer: FTDI
[16866.377940] usbcore: registered new interface driver usbserial
[16866.377969] usbcore: registered new interface driver usbserial_generic
[16866.377994] usbserial: USB Serial support registered for generic
[16866.384018] usbcore: registered new interface driver ftdi_sio
[16866.384045] usbserial: USB Serial support registered for FTDI USB Serial Device
[16866.384203] ftdi_sio 3-2:1.0: FTDI USB Serial Device converter detected
[16866.384247] usb 3-2: Detected FT4232H
[16866.384373] usb 3-2: FTDI USB Serial Device converter now attached to ttyUSB0
[16866.384399] ftdi_sio 3-2:1.1: FTDI USB Serial Device converter detected
[16866.384431] usb 3-2: Detected FT4232H
[16866.384727] usb 3-2: FTDI USB Serial Device converter now attached to ttyUSB1
[16866.384751] ftdi_sio 3-2:1.2: FTDI USB Serial Device converter detected
[16866.384786] usb 3-2: Detected FT4232H
[16866.384897] usb 3-2: FTDI USB Serial Device converter now attached to ttyUSB2
[16866.384917] ftdi_sio 3-2:1.3: FTDI USB Serial Device converter detected
[16866.384950] usb 3-2: Detected FT4232H
[16866.385385] usb 3-2: FTDI USB Serial Device converter now attached to ttyUSB3

推荐答案

正如@Richard Chambers在评论中所提到的,您正在使用未初始化的结构.你应该做

As mentioned in the comment by @Richard Chambers you are using the structure uninitialised. You should do

struct serial_rs485 rs485conf = {0};

但是,正如所讨论的那样,并不能解决问题.

However, as discussed that didn't solve the problem.

引用您引用的内核文档

某些CPU/UART(例如Atmel AT91或16C950 UART)包含内置 半双工模式,可通过以下方式自动控制线路方向 切换RTS或DTR信号.可以用来控制外部 半双工硬件,例如RS485收发器...

Some CPUs/UARTs (e.g., Atmel AT91 or 16C950 UART) contain a built-in half-duplex mode capable of automatically controlling line direction by toggling RTS or DTR signals. That can be used to control external half-duplex hardware like an RS485 transceiver...

但是,该设备具有专用于此的称为TXDEN的引脚.引用数据表部分4.3.3

However this device has a dedicated pin called TXDEN for that. Quoting from the Data sheet section 4.3.3

使用RS485,发送器 仅在从UART发送字符时启用. FT4232H上的TXDEN引脚为 正是出于这个目的而提供的,因此发射器使能端已连接到TXDEN

With RS485, the transmitter is only enabled when a character is being transmitted from the UART. The TXDEN pins on the FT4232H are provided for exactly that purpose, and so the transmitter enables are wired to the TXDEN

您会看到RS232输出未在RS485中连接的RTS/DTR,这与RTS变为TXDEN且需要驾驶员干预的设备形成对比.

and you can see that the RS232 outputs RTS / DTR not connected in RS485, this is in contrast to devices where RTS becomes TXDEN which would require an intervention by the driver.

如果我们分开struct serial_rs485,我们可以看到它主要是为了控制RTS.由于该设备具有专用的TXDEN引脚,因此这些控制字段无关.

If we pick apart struct serial_rs485 we can see that it is mostly about controlling RTS for this purpose. Since this device has a dedicated TXDEN pin, those control fields are irrelevant.

此结构中使用的另一个标志:

Another flag that is used in this structure:

  /* Set this flag if you want to receive data even whilst sending data */
rs485conf.flags |= SER_RS485_RX_DURING_TX;

是的,看看电路,您在线路上输入的内容也会收到.看来您无法关闭它. RS485是多点发送的,因此您应该过滤掉未发送给您的消息.这些消息中的某些消息可能源于您这一事实无关紧要.

And yes looking at the circuit, what you put out on the line you will also receive. Looks like you cannot turn that off. RS485 is multidrop, so you should be filtering out messages that were not addressed to you anyway. The fact that some of those messages may have originated from you doesn't matter.

最后(首先),我们有这个

Finally (and firstly) we have this

/* Enable RS485 mode: */
rs485conf.flags |= SER_RS485_ENABLED;

这实际上是在说启用所有受此结构控制的特定于RS485的内容".除了我们只是使所有这些东西无关紧要之外,因此启用它没有任何作用.

That's really saying "enable all the RS485-specific stuff that's controlled by this structure". Except that we've just made all that stuff irrelevant, so enabling it has no effect.

这就是为什么未为该UART实现ioctl的原因.

This is why the ioctl is not implemented for that UART.

您有很多选择,这些只是建议,因此请选择适合您的

You have a number of options, these are just suggestions so pick what suits you

  • 删除不需要的初始化代码部分
  • 有条件地进行编译#if RS485_IOCTLS
  • 有条件地运行
  • 处理该errnoENOTTY表示,在这种情况下,不需要ioctl,实际上您可以像没有错误一样进行操作
  • Delete this section of the initializtion code as it's not needed
  • Compile it conditionally #if RS485_IOCTLS
  • Run it conditionally
  • Treat that errno value ENOTTY as indicating that, in this context the ioctl was not required and you can in fact proceed as if there was no error

这篇关于RS485:设备的不适当的ioctl的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆