Re: [PATCH 1/2] tty: add bits to manage multidrop mode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 21/04/17 21:07, Rodolfo Giometti wrote:
> I don't understand how you can manage the sending of the address bytes
> inside the serial driver... you have to intercept the write() system
> call in some ways and then prepend the address bytes, is that right? If
> so how you can avoid delays between the two writes?

Okay, I had previously read up on TTY drivers, and had seen this in
struct tty_driver:
>  * int (*write)(struct tty_struct * tty,
>  *               const unsigned char *buf, int count);
>  *
>  *      This routine is called by the kernel to write a series of
>  *      characters to the tty device.  The characters may come from
>  *      user space or kernel space.  This routine will return the
>  *      number of characters actually accepted for writing.
>  *
>  *      Optional: Required for writable devices.

I am assume (perhaps naïvely) that there's a UART-level equivalent,
wherein you take the contents of `buf` and start pushing that into the
serial device buffer; thus could grab data from elsewhere and push that
first before returning to do `buf`.

Often the UART will send an interrupt when it starts sending the last
character… unless your UART baud rate is high (>2Mbps), that still gives
you at least 5µs to start queueing up the next characters.

If done within the driver, that'll be much faster than doing the same
from userspace.

> Note that with my solution we just have to inform the serial controller
> about how many address bytes will arrive in the next message and it will
> do the job for us.

This is true.  As I say, a much more elegant solution to what I was
thinking of.

>> The thorny issue IMO is on receive.  Userspace really needs to know
>> where the address starts and ends.  You can assume a fixed size, but if
>> the protocol uses a variable address length, you're screwed.
> [snip]
> 
> This can be resolved by using the parity check as below:
> 
>         term.c_iflag |= PARENB | PARMD | PARMRK |INPCK;
>         term.c_iflag &= ~IGNPAR;
> 
> In fact by using this setting all received bytes are marked in case of "parity error" and then we can distinguish between address and data bytes which have different parity value (1 for address and 0 for data). 

Ahh okay, just having a read of `man termios` now:
>        PARMRK If this bit is set, input bytes with parity or framing errors  are  marked
>               when passed to the program.  This bit is meaningful only when INPCK is set
>               and IGNPAR is not set.  The way erroneous bytes are  marked  is  with  two
>               preceding  bytes,  \377  and  \0.   Thus, the program actually reads three
>               bytes for one erroneous byte received from the terminal.  If a valid  byte
>               has  the  value \377, and ISTRIP (see below) is not set, the program might
>               confuse it with the prefix that marks a parity error.  Therefore, a  valid
>               byte \377 is passed to the program as two bytes, \377 \377, in this case.
> 
>               If  neither IGNPAR nor PARMRK is set, read a character with a parity error
>               or framing error as \0.

I can see how that resolution works now.  Effectively byte stuffing:
byte with 9th bit set will be sent as 0xff 0x00 0x??; a literal 0xff is
sent as 0xff 0xff.  I wouldn't have thought to describe the 9th bit as a
"parity error". :-)

Not pretty to deal with in userspace code, but at least it can be dealt
with.
-- 
Stuart Longland (aka Redhatter, VK4MSL)

I haven't lost my mind...
  ...it's backed up on a tape somewhere.
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux