Re: [RFC PATCH 0/3] UART slave device bus

From: Oleksij Rempel
Date: Fri Aug 19 2016 - 16:20:57 EST


Am 19.08.2016 um 19:50 schrieb H. Nikolaus Schaller:
> Hi,
>
>> Am 19.08.2016 um 09:49 schrieb Oleksij Rempel <linux@xxxxxxxxxxxxxxxx>:
>>
>> Hallo Nikolaus,
>>
>> do i understand it correctly. This driver is to make kind of interchip
>> communication and represent uart as a bus to allow use this bus from
>> multiple kernel driver or expose it to user space?
>
> The idea for UART slave devices is to handle devices connected on an
> embedded board to an UART port in kernel. Currently most such devices
> are just passed through to some /dev/tty and handled by user-space daemons.
>
> So it is not necessarily about multiple kernel drivers to use the same UART, although
> that could also be required.
>
> A single one is already difficult... And some scenarios need to shield the UART
> from user space (currently there is always one /dev/tty per UART - unless the
> UART is completely disabled).
>
> Some ideas where it might be needed:
> * bluetooth HCI over UART
> * a weird GPS device whose power state can only reliably be detected by monitoring data activity
> * other chips (microcontrollers) connected through UART - similar to I2C slave devices
> * it potentially could help to better implement IrDA (although that is mostly legacy)
>
> What it is not about are UART/RS232 converters connected through USB or virtual
> serial ports created for WWAN modems (e.g. /dev/ttyACM, /dev/ttyHSO). Or BT devices
> connected through USB (even if they also run HCI protocol).

Ah... ok. thank you for explanation.

I was thinking it is going in similar direction with my project - use
SPI for communication between two SoCs. It is based on SSI32 protocol
from Bosch.

In case it is going to this direction:
Master implementation for linux side (tested on Banana Pi and iMX6):
https://github.com/olerem/linux-2.6/commits/bpi-spi-variant2-2016.07.26.2

Slave implementation for stm32f303 (tested on f3 discovery):
https://github.com/olerem/libopencm3-examples/commits/ssi32-2016.08.17.1

protocol decoder for logic analyzer (sigrok):
https://github.com/olerem/libsigrokdecode/commits/ssi32_dec-2016.08.11

>> Correct?
>>
>> Am 19.08.2016 um 09:29 schrieb H. Nikolaus Schaller:
>>> Hi,
>>>
>>>> Am 19.08.2016 um 07:21 schrieb Sebastian Reichel <sre@xxxxxxxxxx>:
>>>>
>>>> Hi,
>>>>
>>>> On Thu, Aug 18, 2016 at 06:08:24PM -0500, Rob Herring wrote:
>>>>> On Thu, Aug 18, 2016 at 3:29 PM, Sebastian Reichel <sre@xxxxxxxxxx> wrote:
>>>>>> Thanks for going forward and implementing this. I also started,
>>>>>> but was far from a functional state.
>>>>>>
>>>>>> On Wed, Aug 17, 2016 at 08:14:42PM -0500, Rob Herring wrote:
>>>>>>> Currently, devices attached via a UART are not well supported in
>>>>>>> the kernel. The problem is the device support is done in tty line
>>>>>>> disciplines, various platform drivers to handle some sideband, and
>>>>>>> in userspace with utilities such as hciattach.
>>>>>>>
>>>>>>> There have been several attempts to improve support, but they suffer from
>>>>>>> still being tied into the tty layer and/or abusing the platform bus. This
>>>>>>> is a prototype to show creating a proper UART bus for UART devices. It is
>>>>>>> tied into the serial core (really struct uart_port) below the tty layer
>>>>>>> in order to use existing serial drivers.
>>>>>>>
>>>>>>> This is functional with minimal testing using the loopback driver and
>>>>>>> pl011 (w/o DMA) UART under QEMU (modified to add a DT node for the slave
>>>>>>> device). It still needs lots of work and polish.
>>>>>>>
>>>>>>> TODOs:
>>>>>>> - Figure out the port locking. mutex plus spinlock plus refcounting? I'm
>>>>>>> hoping all that complexity is from the tty layer and not needed here.
>>>>>>> - Split out the controller for uart_ports into separate driver. Do we see
>>>>>>> a need for controller drivers that are not standard serial drivers?
>>>>>>> - Implement/test the removal paths
>>>>>>> - Fix the receive callbacks for more than character at a time (i.e. DMA)
>>>>>>> - Need better receive buffering than just a simple circular buffer or
>>>>>>> perhaps a different receive interface (e.g. direct to client buffer)?
>>>>>>> - Test with other UART drivers
>>>>>>> - Convert a real driver/line discipline over to UART bus.
>>>>>>>
>>>>>>> Before I spend more time on this, I'm looking mainly for feedback on the
>>>>>>> general direction and structure (the interface with the existing serial
>>>>>>> drivers in particular).
>>>>>>
>>>>>> I had a look at the uart_dev API:
>>>>>>
>>>>>> int uart_dev_config(struct uart_device *udev, int baud, int parity, int bits, int flow);
>>>>>> int uart_dev_connect(struct uart_device *udev);
>>>>>>
>>>>>> The flow control configuration should be done separately. e.g.:
>>>>>> uart_dev_flow_control(struct uart_device *udev, bool enable);
>>>>>
>>>>> No objection, but out of curiosity, why?
>>>>
>>>> Nokia's bluetooth uart protocol disables flow control during speed
>>>> changes.
>>>>
>>>>>> int uart_dev_tx(struct uart_device *udev, u8 *buf, size_t count);
>>>>>> int uart_dev_rx(struct uart_device *udev, u8 *buf, size_t count);
>>>>>>
>>>>>> UART communication does not have to be host-initiated, so this
>>>>>> API requires polling. Either some function similar to poll in
>>>>>> userspace is needed, or it should be implemented as callback.
>>>>>
>>>>> What's the userspace need?
>>>>
>>>> I meant "Either some function similar to userspace's poll() is
>>>> needed, ...". Something like uart_dev_wait_for_rx()
>>>>
>>>> Alternatively the rx function could be a callback, that
>>>> is called when there is new data.
>>>>
>>>>> I'm assuming the only immediate consumers are in-kernel.
>>>>
>>>> Yes, but the driver should be notified about incoming data.
>>>
>>> Yes, this is very important.
>>>
>>> If possible, please do a callback for every character that arrives.
>>> And not only if the rx buffer becomes full, to give the slave driver
>>> a chance to trigger actions almost immediately after every character.
>>> This probably runs in interrupt context and can happen often.
>>>
>>> In our proposal some months ago we have implemented such
>>> an rx_notification callback for every character. This allows to work
>>> without rx buffer and implement one in the driver if needed. This
>>> gives the driver full control over the rx buffer dimensions.
>>>
>>> And we have made the callback to return a boolean flag which
>>> tells if the character is to be queued in the tty layer so that the
>>> driver can decide for every byte if it is to be hidden from user
>>> space or passed. Since we pass a pointer, the driver could even
>>> modify the character passed back, but we have not used this
>>> feature.
>>>
>>> This should cover most (but certainly not all) situations of
>>> implementing protocol engines in uart slave drivers.
>>>
>>> Our API therefore was defined as:
>>>
>>> void uart_register_slave(struct uart_port *uport, void *slave);
>>> void uart_register_rx_notification(struct uart_port *uport,
>>> bool (*function)(void *slave, unsigned int *c),
>>> struct ktermios *termios);
>>>
>>> Registering a slave appears to be comparable to uart_dev_connect()
>>> and registering an rx_notification combines uart_dev_config() and
>>> setting the callback.
>>>
>>> Unregistration is done by passing a NULL pointer for 'slave' or 'function'.
>>>
>>> If there will be a very similar API with a callback like this, we won't have
>>> to change our driver architecture much.
>>>
>>> If there is a uart_dev_wait_for_rx() with buffer it is much more difficult
>>> to handle.
>>>
>>> BR,
>>> Nikolaus
>>>
>>>
>>
>>
>> --
>> Regards,
>> Oleksij
>>
>


--
Regards,
Oleksij

Attachment: signature.asc
Description: OpenPGP digital signature