On Tue, 2022-07-12 at 09:24 +0000, Zimoch Dirk (PSI) via Tech-talk wrote:
> You could write an asynInterpose driver that chops the output into 16 bytes chunks. (And maybe delays in between if
> necessary.)
I have extended an existing interpose driver which should fulfill your needs.
https://github.com/paulscherrerinstitute/asynInterposeDelay
(The repo does not have a standard EPICS configure directory and uses a PSI specific GNUmakefile. Feel free to adapt it
to the standard EPICS or any other your build system or simply add it to asyn.)
I wrote this interpose driver to chop output into single bytes with delay. Now you can tell it to use any chunk size
(with 0 delay or longer, as you need).
Dirk
>
> On Tue, 2022-07-12 at 07:56 +0000, Zimoch Dirk (PSI) via Tech-talk wrote:
> > Hi Florian,
> >
> > If the output buffer is not able to accept all bytes at once, then the write() function should have returned 16
> > instead
> > of 17 and drvAsynSerialPort writeIt() would try again with the remaining bytes, waiting for writeTimeout and failing
> > with asynTimeout if it cannot send.
> >
> > But if the kernel driver implements write() in a way that discards bytes, then all hope is lost.
> >
> > Try with some other program, for example from the command line:
> > echo "this is a string longer than 16 chars" > /dev/ttyAMA0
> >
> > Dirk
> >
> > On Tue, 2022-07-12 at 09:44 +0200, Florian Feldbauer via Tech-talk wrote:
> > > Hey all,
> > >
> > > we have a small vacuum chamber to test our sensor modules after production.
> > > The 2 Pumps and 2 valves are controlled via a Raspberry Pi CM4 running
> > > linux-aarch64.
> > >
> > > The Turbo pump and digital gauge are from Pfeiffer Vacuum and controlled
> > > via RS485.
> > >
> > > I noticed some strange issue. I was able to read all parameters from
> > > those devices, but changing them fails.
> > >
> > > To further investigate I attached a 2nd PC to the RS485 bus just
> > > listening and found the following:
> > >
> > > > epics> asynSetTraceIOMask rs485, 0, ASYN_TRACEIO_ESCAPE
> > > > epics> asynSetTraceMask rs485, 0, ASYN_TRACEIO_DRIVER
> > > > epics> dbpf SCATTERCHAMBER:VACUUM:TP:CtrlViaInt RS485
> > > > DBF_STRING: "RS485"
> > > > 2022/07/12 09:25:52.084 /dev/ttyAMA0 write 17
> > > > 0011006003002125\r
> > > > 2022/07/12 09:25:52.721930 rs485 SCATTERCHAMBER:VACUUM:TP:CtrlViaInt:
> > > > No reply within 500 ms to "0011006003002125<0d>"
> > > > 2022/07/12 09:25:52.722 /dev/ttyAMA0 write 16
> > > > 0010006002=?101\r
> > > > 2022/07/12 09:25:52.762 /dev/ttyAMA0 read 16
> > > > 0011006003002125
> > > > 2022/07/12 09:25:52.766 /dev/ttyAMA0 read 1
> > > > \r
> > > >
> > > > epics>
> > >
> > > The 2nd PC received this:
> > >
> > > > Got 16 bytes:
> > > > 0011006003002125 [30 30 31 31 30 30 36 30 30 33 30 30 32 31 32 35]
> > > > Got 16 bytes:
> > > > 0010006002=?101\r [30 30 31 30 30 30 36 30 30 32 3d 3f 31 30 31 0d]
> > > > Got 17 bytes:
> > > > 0011006003002125\r [30 30 31 31 30 30 36 30 30 33 30 30 32 31 32 35 0d]
> > >
> > > As you can see, on the first message which was send from the IOC, the CR
> > > is missing.
> > >
> > > I guess the issue is, that asyn tries to write all 17 bytes at once, but
> > > the tx buffer on the Raspberry Pi can only hold 16 byte, so the CR gets
> > > lost.
> > >
> > > Is there a way to limit the number of bytes written in a single write
> > > call with asyn?
> > >
> > > Luckily in this case the length of the telegrams is well known and I
> > > could simply use 2 OUT statements in my protocol file to work around
> > > this problem, but what if I want to control a device where the length
> > > depends on the payload data?
> > >
> > > Cheers,
> > > Florian
> > >
> > >