RS485: Inappropriate ioctl for device

前端 未结 2 1332
离开以前
离开以前 2020-12-04 03:57

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

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

2条回答
  •  借酒劲吻你
    2020-12-04 04:43

    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.

    Quoting from the Kernel document you referenced

    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...

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

    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

    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.

    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;
    

    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;
    

    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.

    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

    • 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

提交回复
热议问题