Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.os.linux.development.apps > #152 > unrolled thread
| Started by | michel simian <michel@simian.fr> |
|---|---|
| First post | 2011-06-17 17:14 +0200 |
| Last post | 2011-06-26 02:27 +0000 |
| Articles | 11 — 4 participants |
Back to article view | Back to comp.os.linux.development.apps
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
| From | michel simian <michel@simian.fr> |
|---|---|
| Date | 2011-06-17 17:14 +0200 |
| Subject | termios |
| 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]
| From | Jan Panteltje <pNaonStpealmtje@yahoo.com> |
|---|---|
| Date | 2011-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]
| From | Grant Edwards <invalid@invalid.invalid> |
|---|---|
| Date | 2011-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]
| From | michel simian <michel@simian.fr> |
|---|---|
| Date | 2011-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]
| From | Tauno Voipio <tauno.voipio@notused.fi.invalid> |
|---|---|
| Date | 2011-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]
| From | michel simian <michel@simian.fr> |
|---|---|
| Date | 2011-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]
| From | Tauno Voipio <tauno.voipio@notused.fi.invalid> |
|---|---|
| Date | 2011-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]
| From | michel simian <michel@simian.fr> |
|---|---|
| Date | 2011-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]
| From | michel simian <michel@simian.fr> |
|---|---|
| Date | 2011-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]
| From | Tauno Voipio <tauno.voipio@notused.fi.invalid> |
|---|---|
| Date | 2011-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]
| From | Grant Edwards <invalid@invalid.invalid> |
|---|---|
| Date | 2011-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