Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.os.linux.development.apps > #152 > unrolled thread

termios

Started bymichel simian <michel@simian.fr>
First post2011-06-17 17:14 +0200
Last post2011-06-26 02:27 +0000
Articles 11 — 4 participants

Back to article view | Back to comp.os.linux.development.apps


Contents

  termios michel simian <michel@simian.fr> - 2011-06-17 17:14 +0200
    Re: termios Jan Panteltje <pNaonStpealmtje@yahoo.com> - 2011-06-17 17:01 +0000
    Re: termios Grant Edwards <invalid@invalid.invalid> - 2011-06-17 20:19 +0000
      Re: termios michel simian <michel@simian.fr> - 2011-06-18 17:17 +0200
        Re: termios Tauno Voipio <tauno.voipio@notused.fi.invalid> - 2011-06-18 19:38 +0300
          Re: termios michel simian <michel@simian.fr> - 2011-06-18 20:01 +0200
            Re: termios Tauno Voipio <tauno.voipio@notused.fi.invalid> - 2011-06-18 22:44 +0300
              Re: termios michel simian <michel@simian.fr> - 2011-06-19 06:56 +0200
              Re: termios michel simian <michel@simian.fr> - 2011-06-24 19:28 +0200
                Re: termios Tauno Voipio <tauno.voipio@notused.fi.invalid> - 2011-06-24 21:42 +0300
                  Re: termios Grant Edwards <invalid@invalid.invalid> - 2011-06-26 02:27 +0000

#152 — termios

Frommichel simian <michel@simian.fr>
Date2011-06-17 17:14 +0200
Subjecttermios
Message-ID<4dfb6e98$0$30769$ba4acef3@reader.news.orange.fr>
Hi,

I develop an industrial application which send and receive from RS485 
device, on linux (2.6.32 i686).

When I c onfigure my /dev/ttSx port, like below :

c _lflag &= ~(ICANON | ECHO | ECHOE)

I always receive an echo of my last write output and a select
returns immediately...

What's wrong ?

Thanks

[toc] | [next] | [standalone]


#154

FromJan Panteltje <pNaonStpealmtje@yahoo.com>
Date2011-06-17 17:01 +0000
Message-ID<itg18v$k2j$1@news.albasani.net>
In reply to#152
On a sunny day (Fri, 17 Jun 2011 17:14:26 +0200) it happened michel simian
<michel@simian.fr> wrote in <4dfb6e98$0$30769$ba4acef3@reader.news.orange.fr>:

>Hi,
>
>I develop an industrial application which send and receive from RS485 
>device, on linux (2.6.32 i686).
>
>When I c onfigure my /dev/ttSx port, like below :
>
>c _lflag &= ~(ICANON | ECHO | ECHOE)
>
>I always receive an echo of my last write output and a select
>returns immediately...
>
>What's wrong ?
>
>Thanks

If
tty.c_lflag = 0;
BUT
RS485 always listens on the same 2 wires it sends no?

[toc] | [prev] | [next] | [standalone]


#155

FromGrant Edwards <invalid@invalid.invalid>
Date2011-06-17 20:19 +0000
Message-ID<itgct7$a04$1@reader1.panix.com>
In reply to#152
On 2011-06-17, michel simian <michel@simian.fr> wrote:

> I develop an industrial application which send and receive from RS485 
> device, on linux (2.6.32 i686).
>
> When I c onfigure my /dev/ttSx port, like below :
>
> c _lflag &= ~(ICANON | ECHO | ECHOE)
>
> I always receive an echo of my last write output and a select
> returns immediately...
>
> What's wrong ?

My guess is that your RS485 hardware is doing the echoing.

-- 
Grant Edwards               grant.b.edwards        Yow! Are we on STRIKE yet?
                                  at               
                              gmail.com            

[toc] | [prev] | [next] | [standalone]


#156

Frommichel simian <michel@simian.fr>
Date2011-06-18 17:17 +0200
Message-ID<4dfcc0dd$0$14684$ba4acef3@reader.news.orange.fr>
In reply to#155
Grant Edwards écrivit de sa plume:
> On 2011-06-17, michel simian <michel@simian.fr> wrote:
> 
>>
>> What's wrong ?
> 
> My guess is that your RS485 hardware is doing the echoing.
> 

Hi,

You're right.
In fact, I tried without connecting the cable. I re-read
the bytes I've just sent.
This is a first result. I may perhaps support it.

But, now, when I spy the exchanges with a protocole analyzer
dedicated to RS485, I see my bytes sent, I see the Ack byte returned
by the connected device on the analyzer, but I can't read it.

The same soft using a RS232 port on the same PC, with a 232/485 
converter, works fine.

What's wrong ?

I tried a lot of combination with the setting/unsetting the RTS
with ioctl, and the only one which permits byte outputting is
when I set the RTS before sending, and reset it just after,
even if I'm not sure if the write operation completed.
(in fact, when I use tcdrain, nothing is outputted)

I'me perplexed and lost :)

Thanks for help, if possible.

-- 
L'Amer Michel

[toc] | [prev] | [next] | [standalone]


#157

FromTauno Voipio <tauno.voipio@notused.fi.invalid>
Date2011-06-18 19:38 +0300
Message-ID<itik9n$1bh$1@dont-email.me>
In reply to#156
On 18.6.11 6:17 , michel simian wrote:
> Grant Edwards écrivit de sa plume:
>> On 2011-06-17, michel simian <michel@simian.fr> wrote:
>>
>>>
>>> What's wrong ?
>>
>> My guess is that your RS485 hardware is doing the echoing.
>>
>
> Hi,
>
> You're right.
> In fact, I tried without connecting the cable. I re-read
> the bytes I've just sent.
> This is a first result. I may perhaps support it.
>
> But, now, when I spy the exchanges with a protocole analyzer
> dedicated to RS485, I see my bytes sent, I see the Ack byte returned
> by the connected device on the analyzer, but I can't read it.
>
> The same soft using a RS232 port on the same PC, with a 232/485
> converter, works fine.
>
> What's wrong ?
>
> I tried a lot of combination with the setting/unsetting the RTS
> with ioctl, and the only one which permits byte outputting is
> when I set the RTS before sending, and reset it just after,
> even if I'm not sure if the write operation completed.
> (in fact, when I use tcdrain, nothing is outputted)
>
> I'me perplexed and lost :)
>
> Thanks for help, if possible.


You have found the hard core of RS-485 communications.

The problem is to control the transmiter enable so that
your last character is wholly transmitted, but the response
is not arriving yet, when the transmitter (RTS) is turned off.

Most serial interface chips report ready well ahead in time
before the last character has even started to send. If the
chip can report 'transmitter idle', you can use it, else
you need to have a well-adjusted delay after sending.

-- 

Tauno Voipio

[toc] | [prev] | [next] | [standalone]


#158

Frommichel simian <michel@simian.fr>
Date2011-06-18 20:01 +0200
Message-ID<4dfce742$0$30775$ba4acef3@reader.news.orange.fr>
In reply to#157
Tauno Voipio écrivit de sa plume:
> You have found the hard core of RS-485 communications.
> 
> The problem is to control the transmiter enable so that
> your last character is wholly transmitted, but the response
> is not arriving yet, when the transmitter (RTS) is turned off.
> 
> Most serial interface chips report ready well ahead in time
> before the last character has even started to send. If the
> chip can report 'transmitter idle', you can use it, else
> you need to have a well-adjusted delay after sending.
> 

OK. Thank you.

So, the first hypothesis is that the chip do that,
and the linux driver is correct. Then, when I return
from write operation, (or from a select on the dedicated
write fd_set file descriptor), I can read :

- the bytes from the echo
- and the device answer

But it does not work as described.

If I try to read the echoed bytes before, the analyzer does
not show the bytes sent... and I think they are not sent.

Then, 2nd hypothesis: the chip and the linux driver
does not do the right job, and I must adjust some
'usleep' when I hope they are efficient ?

Yep, may I hope succeeding without putting candles ?

-- 
L'Amer Michel

[toc] | [prev] | [next] | [standalone]


#159

FromTauno Voipio <tauno.voipio@notused.fi.invalid>
Date2011-06-18 22:44 +0300
Message-ID<itiv7i$9mj$1@dont-email.me>
In reply to#158
On 18.6.11 9:01 , michel simian wrote:
> Tauno Voipio écrivit de sa plume:
>> You have found the hard core of RS-485 communications.
>>
>> The problem is to control the transmiter enable so that
>> your last character is wholly transmitted, but the response
>> is not arriving yet, when the transmitter (RTS) is turned off.
>>
>> Most serial interface chips report ready well ahead in time
>> before the last character has even started to send. If the
>> chip can report 'transmitter idle', you can use it, else
>> you need to have a well-adjusted delay after sending.
>>
>
> OK. Thank you.
>
> So, the first hypothesis is that the chip do that,
> and the linux driver is correct. Then, when I return
> from write operation, (or from a select on the dedicated
> write fd_set file descriptor), I can read :
>
> - the bytes from the echo
> - and the device answer
>
> But it does not work as described.
>
> If I try to read the echoed bytes before, the analyzer does
> not show the bytes sent... and I think they are not sent.
>
> Then, 2nd hypothesis: the chip and the linux driver
> does not do the right job, and I must adjust some
> 'usleep' when I hope they are efficient ?
>
> Yep, may I hope succeeding without putting candles ?
>

Well, it seems that you have at least to do something to the
serial line driver. Even if the interface chip handles the
transmitter empty condition, it needs a driver able to
understand the condition.

Some interface chips have hardware support to the RTS control
which can be selected with an ioctl(), but evewn here we do
need a co-operating device driver.

Attached is a module running RS-485 packet traffic under
Linux on an Atmel AT91RM920 serial port with hardware control
of transmit enable.

-- 

Tauno Voipio


------ clip clip -----

/*   $Id: serio.c 566 2010-04-22 07:59:29Z tauno $   */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


/*   Module data   */

#define BRATE B38400
#define TICKTIME 10
#define TMOTICKS 3

#define FLAG     0x7e    /* framing flag */

#define IF_UP    (IGNBRK | IGNPAR )
#define IF_DOWN  (INPCK | ISTRIP | BRKINT | ICRNL | INLCR | \
                   IUCLC | IXON | IXANY | IXOFF | IMAXBEL | IUTF8)

#define OF_UP    (0)
#define OF_DOWN  (OPOST)

#define CF_UP    (CS8 | CLOCAL | CREAD)
#define CF_DOWN  (CSIZE | CSTOPB | PARENB | CRTSCTS)

#define LF_UP    (ICANON)
#define LF_DOWN  (ISIG | XCASE | ECHO | ECHOE | ECHOK | ECHONL | \
                   ECHOCTL | ECHOPRT | ECHOKE | TOSTOP | PENDIN | IEXTEN)

#define TIOCM_RS485 0x2000     /* AT91 serial port ioctl: enable 
auto-RS485 */

static int handle;     /* serial I/O port file handle */
static uint8_t codebuf[2 * sizeof(struct packet)];


/*   Update a flag word   */

static void updflgs(tcflag_t *fp, tcflag_t up, tcflag_t down)
	{
	*fp &= ~down;
	*fp |= up;
	}


/*   Open and set up serial port   */

static int opensio(const char *path)
	{
	struct termios tio;
	unsigned int i;
	int fd, flgs;

	fd = open(path, O_RDWR | O_NOCTTY | O_NDELAY);

	if (fd < 0)
		fail("Open serial I/O");

	flgs = fcntl(fd, F_GETFL);

	if (flgs == -1)
		fail("Get serial channel flags");

	flgs &= ~O_NONBLOCK;

	if (fcntl(fd, F_SETFL, flgs) == -1)
		fail("Set serial channel flags");

	if (tcgetattr(fd, &tio) < 0)
		fail("Get serial I/O attributes");

	updflgs(&tio.c_iflag, IF_UP, IF_DOWN);
	updflgs(&tio.c_oflag, OF_UP, OF_DOWN);
	updflgs(&tio.c_cflag, CF_UP, CF_DOWN);
	updflgs(&tio.c_lflag, LF_UP, LF_DOWN);

	cfsetispeed(&tio, BRATE);
	cfsetospeed(&tio, BRATE);

	for (i = 0; i < NCCS; i++)
		tio.c_cc[i] = '\0';

	tio.c_cc[VEOL] = FLAG;

	if (tcsetattr(fd, TCSANOW, &tio) < 0)
		fail("Set serial I/O attributes");

#ifndef PCTEST
	/* Enable RS-485 mode */

	ioctl(fd, TIOCMGET, &flgs);
	flgs |= TIOCM_RS485;

	if (ioctl(fd, TIOCMSET, &flgs) < 0)
		fail("Set RS-485 auto mode");
#endif

	return fd;
	}


/*   Wait for serial data   */
/*   Waits in 10 ms ticks and checks that the output buffer is empty   */

static bool waitread(void)
	{
	int code, count, qlen;
	struct timeval tmo;
	fd_set input;

	for (count = TMOTICKS; count > 0; )
		{
		FD_ZERO(&input);
		FD_SET(handle, &input);

		tmo.tv_usec = 1000 * TICKTIME;
		tmo.tv_sec = 0;

		code = select(handle + 1, &input, NULL, NULL, &tmo);

		if (code > 0)
			return true;

		/* timeout - refresh the count if packet is not sent yet,
		   else deceŕement the count */

		if (ioctl(handle, TIOCOUTQ, &qlen) < 0)
			fail("Get output queue length");

		if (qlen != 0)
			count = TMOTICKS;
		else
			count--;
		}

	return false;
	}


/*   Serial data receive   */

static int siorec(uint8_t *recv, unsigned int maxlen)
	{
	unsigned int total;
	int count;

	memset(recv, 0, maxlen);
	total = 0;

	do
		{
		if (!waitread())
			break;

		count = read(handle, recv, maxlen);

		if (count <= 0)
			break;

		total += count;

		if (recv[count - 1] != FLAG)
			{
			recv += count;
			maxlen -= count;
			}
		else

		if (total == 1)
			total--;
		else
			return total;
		}
	while (maxlen > 0);

	return 0;
	}


/*   Exchange bus packets   */

int busxch(struct packet *pktp, unsigned int count)
	{
	unsigned int n;

	pktp -> snode = A_MASTER;

#if 0
	printlog("Sending %d bytes, rx %u, tx %u, tp %u, ch %u\n",
	          count, pktp -> rnode, pktp -> snode,
	          pktp -> type, pktp -> channel);
#endif
	trace(pktp, count);

	n = encode(pktp, codebuf, count);

	tcflush(handle, TCIFLUSH);
	write(handle, codebuf, n);

	do
		{
		n = siorec(codebuf, sizeof(codebuf));

		if (n == 0)
			return 0;      /* timeout */

		n = decode(pktp, codebuf, n);
		}
	while (n < HDRSZ || pktp -> snode == A_MASTER);

#if 0
	printlog("Received %d bytes, rx %u, tx %u, tp %u, ch %u\n",
	        n, pktp -> rnode, pktp -> snode, pktp -> type, pktp -> channel);
#endif
	trace(pktp, n);
	return n;
	}


/*   Initialize bus handling   */

void init_bus(void)
	{
#ifdef PCTEST
	handle = opensio("/dev/ttyUSB0");
#else
	handle = opensio("/dev/ttyS1");
#endif
	}

[toc] | [prev] | [next] | [standalone]


#160

Frommichel simian <michel@simian.fr>
Date2011-06-19 06:56 +0200
Message-ID<4dfd80b3$0$14659$ba4acef3@reader.news.orange.fr>
In reply to#159
Tauno Voipio écrivit de sa plume:

> 
> Well, it seems that you have at least to do something to the
> serial line driver. Even if the interface chip handles the
> transmitter empty condition, it needs a driver able to
> understand the condition.
> 
> Some interface chips have hardware support to the RTS control
> which can be selected with an ioctl(), but evewn here we do
> need a co-operating device driver.
> 
> Attached is a module running RS-485 packet traffic under
> Linux on an Atmel AT91RM920 serial port with hardware control
> of transmit enable.
> 

OK. Thank you.
I will as soon (just after a cofee, it's early, here)
analyze your module and merge with my code.

-- 
L'Amer Michel

[toc] | [prev] | [next] | [standalone]


#161

Frommichel simian <michel@simian.fr>
Date2011-06-24 19:28 +0200
Message-ID<4e04c885$0$30751$ba4acef3@reader.news.orange.fr>
In reply to#159
Tauno Voipio écrivit de sa plume:

> 
> Attached is a module running RS-485 packet traffic under
> Linux on an Atmel AT91RM920 serial port with hardware control
> of transmit enable.
> 

So, it was a bit difficult to adapt, -I'm speaking about your sample - 
but I realize that my kernel was a little bit too old (2.6.26). Some of
serial.h defintion was'nt there.
I tried it on a 2.6.32, and I had to find the include files containing
some define of ioctl...
Then finally, I install a 2.6.35 and I could read the device's answer.
But I could not find how to disable the automatic echoing.
modifying the CREAD termios bit will block the write.
modifying the ECHO termios bit doesn't have any effect.

I have to try and to search more. :)

Thanks

-- 
L'Amer Michel

[toc] | [prev] | [next] | [standalone]


#162

FromTauno Voipio <tauno.voipio@notused.fi.invalid>
Date2011-06-24 21:42 +0300
Message-ID<iu2lqg$4pq$1@dont-email.me>
In reply to#161
On 24.6.11 8:28 , michel simian wrote:
> Tauno Voipio écrivit de sa plume:
>
>>
>> Attached is a module running RS-485 packet traffic under
>> Linux on an Atmel AT91RM920 serial port with hardware control
>> of transmit enable.
>>
>
> So, it was a bit difficult to adapt, -I'm speaking about your sample -
> but I realize that my kernel was a little bit too old (2.6.26). Some of
> serial.h defintion was'nt there.
> I tried it on a 2.6.32, and I had to find the include files containing
> some define of ioctl...
> Then finally, I install a 2.6.35 and I could read the device's answer.
> But I could not find how to disable the automatic echoing.
> modifying the CREAD termios bit will block the write.
> modifying the ECHO termios bit doesn't have any effect.
>
> I have to try and to search more. :)
>
> Thanks
>

The echo is in hardware - learn about RS-485. The transmit
and receive use the same wires, so everything sent to the
bus ends up t the own receiver, too.

-- 

-Tauno

[toc] | [prev] | [next] | [standalone]


#163

FromGrant Edwards <invalid@invalid.invalid>
Date2011-06-26 02:27 +0000
Message-ID<iu65dr$ijj$1@reader1.panix.com>
In reply to#162
On 2011-06-24, Tauno Voipio <tauno.voipio@notused.fi.invalid> wrote:
> On 24.6.11 8:28 , michel simian wrote:
>> Tauno Voipio ??crivit de sa plume:
>>
>>> Attached is a module running RS-485 packet traffic under
>>> Linux on an Atmel AT91RM920 serial port with hardware control
>>> of transmit enable.
>>
>> So, it was a bit difficult to adapt, -I'm speaking about your sample
>> - but I realize that my kernel was a little bit too old (2.6.26).
>> Some of serial.h defintion was'nt there. I tried it on a 2.6.32, and
>> I had to find the include files containing some define of ioctl...
>> Then finally, I install a 2.6.35 and I could read the device's
>> answer. But I could not find how to disable the automatic echoing.
>> modifying the CREAD termios bit will block the write. modifying the
>> ECHO termios bit doesn't have any effect.
>>
>> I have to try and to search more. :)
>
> The echo is in hardware - learn about RS-485.

What he said. :)


> The transmit and receive use the same wires, so everything sent to
> the bus ends up t the own receiver, too.

Sometimes there's a jumper that controls the read-back of tx data.  If
not, you're going to have to write your software so that it ignores
the echoed data.

-- 
Grant

[toc] | [prev] | [standalone]


Back to top | Article view | comp.os.linux.development.apps


csiph-web