[Q] Working with ionotify() ...

I’ve got a ‘nameless’ server (QNX4 port) that works with ionotify() to
deal with data coming in from a serial device (devc-ser8250) and I
wonder, how I can make sure that

  1. I don’t loose any data.

  2. the device is always armed?

I 'm not sure, if a loop like this is secure (see complete example
at the end of this posting):


nRcvid = MsgReceive ( nChid, &uMsgBuffer, sizeof ( uMsgBuffer ), &tMsgInfo );

if ( 0 == nRcvid )
{
if ( nDevicePulse == uMsgBuffer.tPulse.code )
{
int n;
char szDeviceBuffer[256];
int bInputDataAvailable;

do
{
/*
** Read input data …
*/
n = readcond ( nDeviceFd, szDeviceBuffer, sizeof ( szDeviceBuffer ) - 1,
0, 0, 0);
if(n > 1 )
{
szDeviceBuffer[n] = ‘\0’;

printf(“Input: <%s>\n”, szDeviceBuffer);
}

/*
** Re-Arm the serial resource manager again …
*/
nFlags = ionotify( nDeviceFd, _NOTIFY_ACTION_POLLARM,
_NOTIFY_COND_INPUT, &tEvent);
if ( -1 == nFlags )
{
printf ( “Cannot re-arm device ‘%s’ for input! (%s)\n”,
argv[1], strerror ( errno ) );
bInputDataAvailable = 0;
}
else if ( 0 != ( _NOTIFY_COND_INPUT & nFlags ) )
{
bInputDataAvailable = 1;
}
else
{
bInputDataAvailable = 0;
}

} while ( bInputDataAvailable );
continue;
}


I’d appreciate any hints!

TIA,
Karsten.


Two file snippets follow:



File: driver.c ------------------------------------------------------

#include <stdio.h>
#include <errno.h>
#include <sys/neutrino.h>
#include <sys/netmgr.h>
#include <sys/iomsg.h>
#include <fcntl.h>
#include <termios.h>


int main ( int argc, char argv[] )
{
int nChid;
int nCoid;
union
{
struct _pulse tPulse;
char szMsg[256];
}
uMsgBuffer;
struct _msg_info tMsgInfo;
int nRcvid;
int nMsgLen;
struct sigevent tEvent;
int nDevicePulse;
int nDeviceFd;
int nFlags;


/

** Create a channel
*/
nChid = ChannelCreate ( 0 );
if ( -1 == nChid )
{
printf ( “Cannot create channel! (%s)\n”, strerror ( errno ) );
return ( -1 );
}

/*
** Open connection to own channel
*/
nCoid = ConnectAttach ( ND_LOCAL_NODE, 0, nChid,
_NTO_SIDE_CHANNEL, _NTO_COF_CLOEXEC );
if ( -1 == nCoid )
{
printf ( “Cannot create connection! (%s)\n”, strerror ( errno ) );
return ( -1 );
}

/*
** Define device pulse
*/
nDevicePulse = 10;

/*
** Open serial device
/
nDeviceFd = open(argv[1], O_RDWR);
if ( -1 == nDeviceFd )
{
printf ( “Cannot open device %s! (%s)\n”, argv[1], strerror ( errno ) );
return ( -1 );
}


/

** Prepare the pulse event …
/
SIGEV_PULSE_INIT(&tEvent, nCoid, SIGEV_PULSE_PRIO_INHERIT,
nDevicePulse, 99);


/

** Arm the serial resource manager the first time …
*/
do
{
nFlags = ionotify( nDeviceFd, _NOTIFY_ACTION_POLLARM,
_NOTIFY_COND_INPUT, &tEvent );
if ( -1 == nFlags )
{
printf ( “Cannot arm device ‘%s’ for input! (%s)\n”,
argv[1], strerror ( errno ) );
}
else if ( 0 != (nFlags & _NOTIFY_COND_INPUT ) )
{
printf ( “Data available, discarding.\n”);
tcflush ( nDeviceFd, TCIFLUSH );
}
} while ( 0 != ( nFlags & _NOTIFY_COND_INPUT ) );


do
{
nRcvid = MsgReceive ( nChid, &uMsgBuffer, sizeof ( uMsgBuffer ), &tMsgInfo );

if ( 0 == nRcvid )
{
/*
** Received a pulse
*/
printf ( “Received pulse: %d/%d\n”,
uMsgBuffer.tPulse.code, uMsgBuffer.tPulse.value.sival_int);

if ( nDevicePulse == uMsgBuffer.tPulse.code )
{
int n;
char szDeviceBuffer[256];
int bInputDataAvailable;

do
{
/*
** Read input data …
*/
n = readcond ( nDeviceFd, szDeviceBuffer, sizeof ( szDeviceBuffer ) - 1,
0, 0, 0);
if(n > 1 )
{
szDeviceBuffer[n] = ‘\0’;

printf(“Input: <%s>\n”, szDeviceBuffer);

}
else
{
printf(“n=%d\n”,n);
}

/*
** Re-Arm the serial resource manager again …
*/
nFlags = ionotify( nDeviceFd, _NOTIFY_ACTION_POLLARM,
_NOTIFY_COND_INPUT, &tEvent);
if ( -1 == nFlags )
{
printf ( “Cannot re-arm device ‘%s’ for input! (%s)\n”,
argv[1], strerror ( errno ) );
bInputDataAvailable = 0;
}
else if ( 0 != ( _NOTIFY_COND_INPUT & nFlags ) )
{
bInputDataAvailable = 1;
}
else
{
bInputDataAvailable = 0;
}

} while ( bInputDataAvailable );
continue;
}
else
{
/*
** Handle other pulses here …
**
** Don’t forget the system pulses
**
*/
printf ( “Pulsecode %d (unhandled)\n”, uMsgBuffer.tPulse.code );
}
}
else
{
MsgError ( nRcvid, ENOTSUP );
}
}
while ( nRcvid != -1 );

return ( 0 );
}

File: makefile ------------------------------------------------------


CFLAGS+=-g2
LDFLAGS+=-g2
driver: driver.o

driver.o: driver.c


End of files --------------------------------------------------------


| / | __ ) | Karsten.Hoffmann@mbs-software.de MBS-GmbH
| |/| | _ _
\ Phone : +49-2151-7294-38 Karsten Hoffmann
| | | | |
) |__) | Fax : +49-2151-7294-50 Roemerstrasse 15
|| ||// Mobile: +49-172-3812373 D-47809 Krefeld

Karsten.Hoffmann@mbs-software.de wrote:

I’ve got a ‘nameless’ server (QNX4 port) that works with ionotify() to
deal with data coming in from a serial device (devc-ser8250) and I
wonder, how I can make sure that

  1. I don’t loose any data.

  2. the device is always armed?

I 'm not sure, if a loop like this is secure (see complete example
at the end of this posting):

Is there anybody in this newsgroup, who can have a look at this,
please!?!

Or am I the only one, who doesn’t understand, how ionotify() should
work :slight_smile:).

Thanks a lot,


Karsten.


| / | __ ) | Karsten.Hoffmann@mbs-software.de MBS-GmbH
| |/| | _ _
\ Phone : +49-2151-7294-38 Karsten Hoffmann
| | | | |
) |__) | Fax : +49-2151-7294-50 Roemerstrasse 15
|| ||// Mobile: +49-172-3812373 D-47809 Krefeld

<Karsten.Hoffmann@mbs-software.de> wrote in message
news:b31vap$nel$1@mbs-software.de

Karsten.Hoffmann@mbs-software.de > wrote:

I’ve got a ‘nameless’ server (QNX4 port) that works with ionotify() to
deal with data coming in from a serial device (devc-ser8250) and I
wonder, how I can make sure that

  1. I don’t loose any data.

  2. the device is always armed?

I 'm not sure, if a loop like this is secure (see complete example
at the end of this posting):


Is there anybody in this newsgroup, who can have a look at this,
please!?!

Or am I the only one, who doesn’t understand, how ionotify() should
work > :slight_smile:> ).

I can’t find your original post, hence I can’t look at your code, but proper
usage of ionotify should not result in any data lost.

Basicaly if you set ionotify to POLL and ARM it will trigger the event if
there is data and or wait until there is some.

If after each event that you received you perform an ionotify with POLL ARM
everything should be ok. Obviously between each event you should perform a
read().

Personaly every think became clear once I understood that the serial driver
starts buffering incoming data as soon as open() is called. Hence data
isn’t lost in between a read and ionotify.

Thanks a lot,


Karsten.


| / | __ ) | > Karsten.Hoffmann@mbs-software.de > MBS-GmbH
| |/| | _ _
\ Phone : +49-2151-7294-38 Karsten Hoffmann
| | | | |
) |__) | Fax : +49-2151-7294-50 Roemerstrasse 15
|| ||// Mobile: +49-172-3812373 D-47809 Krefeld

Mario Charest postmaster@127.0.0.1 wrote:

I can’t find your original post, hence I can’t look at your code, but proper
usage of ionotify should not result in any data lost.

I’ll put it at the end again …

Basicaly if you set ionotify to POLL and ARM it will trigger the event if
there is data and or wait until there is some.

So I have to loop somehow, until ionotify() armed the resource
manager, right?

If after each event that you received you perform an ionotify with POLL ARM
everything should be ok. Obviously between each event you should perform a
read().

Personaly every think became clear once I understood that the serial driver
starts buffering incoming data as soon as open() is called. Hence data
isn’t lost in between a read and ionotify.

I hope so :slight_smile:


Thanks for your help!

Karsten.


And here’s my example:


File: driver.c -------------------------------------------------------------

#include <stdio.h>
#include <errno.h>
#include <sys/neutrino.h>
#include <sys/netmgr.h>
#include <sys/iomsg.h>
#include <fcntl.h>
#include <termios.h>


int main ( int argc, char argv[] )
{
int nChid;
int nCoid;
union
{
struct _pulse tPulse;
char szMsg[256];
}
uMsgBuffer;
struct _msg_info tMsgInfo;
int nRcvid;
int nMsgLen;
struct sigevent tEvent;
int nDevicePulse;
int nDeviceFd;
int nFlags;


/

** Create a channel
*/
nChid = ChannelCreate ( 0 );
if ( -1 == nChid )
{
printf ( “Cannot create channel! (%s)\n”, strerror ( errno ) );
return ( -1 );
}

/*
** Open connection to own channel
*/
nCoid = ConnectAttach ( ND_LOCAL_NODE, 0, nChid,
_NTO_SIDE_CHANNEL, _NTO_COF_CLOEXEC );
if ( -1 == nCoid )
{
printf ( “Cannot create connection! (%s)\n”, strerror ( errno ) );
return ( -1 );
}

/*
** Define device pulse
*/
nDevicePulse = 10;

/*
** Open serial device
/
nDeviceFd = open(argv[1], O_RDWR);
if ( -1 == nDeviceFd )
{
printf ( “Cannot open device %s! (%s)\n”, argv[1], strerror ( errno ) );
return ( -1 );
}


/

** Prepare the pulse event …
/
SIGEV_PULSE_INIT(&tEvent, nCoid, SIGEV_PULSE_PRIO_INHERIT,
nDevicePulse, 99);


/

** Arm the serial resource manager the first time …
*/
do
{
nFlags = ionotify( nDeviceFd, _NOTIFY_ACTION_POLLARM,
_NOTIFY_COND_INPUT, &tEvent );
if ( -1 == nFlags )
{
printf ( “Cannot arm device ‘%s’ for input! (%s)\n”,
argv[1], strerror ( errno ) );
}
else if ( 0 != (nFlags & _NOTIFY_COND_INPUT ) )
{
printf ( “Data available, discarding.\n”);
tcflush ( nDeviceFd, TCIFLUSH );
}
} while ( 0 != ( nFlags & _NOTIFY_COND_INPUT ) );


do
{
nRcvid = MsgReceive ( nChid, &uMsgBuffer, sizeof ( uMsgBuffer ), &tMsgInfo );

if ( 0 == nRcvid )
{
/*
** Received a pulse
*/
printf ( “Received pulse: %d/%d\n”,
uMsgBuffer.tPulse.code, uMsgBuffer.tPulse.value.sival_int);

if ( nDevicePulse == uMsgBuffer.tPulse.code )
{
int n;
char szDeviceBuffer[256];
int bInputDataAvailable;

do
{
/*
** Read input data …
*/
n = readcond ( nDeviceFd, szDeviceBuffer, sizeof ( szDeviceBuffer ) - 1,
0, 0, 0);
if(n > 1 )
{
szDeviceBuffer[n] = ‘\0’;

printf(“Input: <%s>\n”, szDeviceBuffer);

}
else
{
printf(“n=%d\n”,n);
}

/*
** Re-Arm the serial resource manager again …
*/
nFlags = ionotify( nDeviceFd, _NOTIFY_ACTION_POLLARM,
_NOTIFY_COND_INPUT, &tEvent);
if ( -1 == nFlags )
{
printf ( “Cannot re-arm device ‘%s’ for input! (%s)\n”,
argv[1], strerror ( errno ) );
bInputDataAvailable = 0;
}
else if ( 0 != ( _NOTIFY_COND_INPUT & nFlags ) )
{
bInputDataAvailable = 1;
}
else
{
bInputDataAvailable = 0;
}

} while ( bInputDataAvailable );
continue;
}
else
{
/*
** Handle other pulses here …
**
** Don’t forget the system pulses
**
*/
printf ( “Pulsecode %d (unhandled)\n”, uMsgBuffer.tPulse.code );
}
}
else
{
MsgError ( nRcvid, ENOTSUP );
}
}
while ( nRcvid != -1 );

return ( 0 );
}

File: makefile -------------------------------------------------------------

CFLAGS+=-g2
LDFLAGS+=-g2
driver: driver.o

driver.o: driver.c

End of files ---------------------------------------------------------------