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

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

 



On 04/18/17 11:21, Richard Genoud wrote:
On 14/04/2017 16:28, Rodolfo Giometti wrote:
On 04/14/17 16:24, Richard Genoud wrote:
On 13/04/2017 17:12, Rodolfo Giometti wrote:
On 04/13/17 16:53, Richard Genoud wrote:
On 13/04/2017 14:19, Rodolfo Giometti wrote:
On 04/13/17 12:43, Richard Genoud wrote:
On 11/04/2017 22:12, Rodolfo Giometti wrote:
Multidrop mode differentiates the data characters and the address
characters. Data is transmitted with the parity bit to 0 and
addresses
are transmitted with the parity bit to 1. However this usually slow
down communication by adding a delay between the first byte and the
others.

This patch defines two non-stadard bits PARMD (that enables
multidrop)
and SENDA (that marks the next transmitted byte as address) that can
be used to completely remove the delay during transmission by
correctly managing the parity bit generation in hardware.

Signed-off-by: Rodolfo Giometti <giometti@xxxxxxxx>
---
 include/linux/tty.h                 | 2 ++
 include/uapi/asm-generic/termbits.h | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/include/linux/tty.h b/include/linux/tty.h
index 83b264c..85238ff 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -166,6 +166,8 @@ struct tty_bufhead {
 #define C_CIBAUD(tty)    _C_FLAG((tty), CIBAUD)
 #define C_CRTSCTS(tty)    _C_FLAG((tty), CRTSCTS)
 #define C_CMSPAR(tty)    _C_FLAG((tty), CMSPAR)
+#define C_PARMD(tty)    _C_FLAG((tty), PARMD)
+#define C_SENDA(tty)    _C_FLAG((tty), SENDA)

 #define L_ISIG(tty)    _L_FLAG((tty), ISIG)
 #define L_ICANON(tty)    _L_FLAG((tty), ICANON)
diff --git a/include/uapi/asm-generic/termbits.h
b/include/uapi/asm-generic/termbits.h
index 232b478..7e82859 100644
--- a/include/uapi/asm-generic/termbits.h
+++ b/include/uapi/asm-generic/termbits.h
@@ -140,6 +140,8 @@ struct ktermios {
 #define HUPCL    0002000
 #define CLOCAL    0004000
 #define CBAUDEX 0010000
+#define PARMD   0100000
+#define SENDA   0200000
 #define    BOTHER 0010000
 #define    B57600 0010001
 #define   B115200 0010002

I guess there's a problem with SENDA (bit 16)
It's overlapping with CIBAUD (002003600000 (bits 28,19,18,17,16))

You're right! In this case which bit should I use for SENDA? :(

Since it is referred to output data maybe can we move it into c_oflag
bits?

Well, bits 23 and 24 are free in asm-generic/c_cflag, and since
multidrop uses the parity bit, I'd say it fits better in c_cflag
than in
c_oflag.

I see, but while PARMD defines a special parity usage the SENDA bit is
dedicated to output data only... however if you prefer I use bits 23 and
24 it's OK for me! :-)

But honestly, I find the SENDA bit logic disturbing and not compliant
with the way tc{g,s}etattr() works.

Because, usually, a tcsetattr() call is followed by a tcgetattr() call
to check if everything went well. (tcsetattr return 0 if *any* of the
requested change succeeded).
So, with the proposed implementation, we will have

    struct termios term, check;

    ret = tcgetattr(fd, &term);
    if (ret < 0) {
        perror("tcgetattr");
        exit(-1);
    }
    term.c_cflag |= PARENB | CMSPAR | PARMD | SENDA;
    ret = tcsetattr(fd, TCSADRAIN, &term);
    if (ret < 0) {
        perror("tcsetattr");
        exit(-1);
    }
    ret = tcgetattr(fd, &check);
    if (term.c_cflag != check.c_cflag) {
        /* fail to set all c_cflags */
        exit(-1);
    }
=> it will always fail.

This should be another reason because we should use c_oflag instead of
c_cflag! :-P
Actually it isn't, I gave the example of c_cflag, but it's the same with
c_{i,o,l}flag

I see... so any advice about how to manage SENDA bit in order to avoid
this drawback?

I'm not a tty guru, but I think the proper way to implement this would
be with a new line discipline.

Gosh! A new line discipline for a special parity settings? =8-o

In any case there are no methods to directly manage tty parity settings within a line discipline. The developer still needs to use the tcsetattr() to set the PARMD parity mode.

Maybe we can solve the problem by keeping the multidrop settings within the tcsetattr()+PARMD and then using something similar to the send_break() mechanism called with the TCSBRK ioctl() command. We can add a TCSSENDA ioctl() commands which in turn calls a send_md_address() function implemented as follow:

static int send_md_address(struct tty_struct *tty, unsigned int bytes)
{
        int retval;

        if (tty->ops->senda_ctl == NULL)
                return 0;

        return tty->ops->senda_ctl(tty, bytes);
}

Where the senda_ctl (one per serial driver) do the job! The bytes parameters is just because we may have more than one address bytes...

Do you think that this could be a reasonable solution?

Ciao,

Rodolfo

--

HCE Engineering                      e-mail: giometti@xxxxxxxxxxxxxxxxxxx
GNU/Linux Solutions                          giometti@xxxxxxxxxxxx
Linux Device Driver                          giometti@xxxxxxxx
Embedded Systems                     phone:  +39 349 2432127
UNIX programming                     skype:  rodolfo.giometti
Cosino Project - the quick prototyping embedded system - www.cosino.io
Freelance ICT Italia - Consulente ICT Italia - www.consulenti-ict.it
--
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