Hi,
Here is a test code:
#include <termios.h>
#include <unistd.h>
#include <sys/iomsg.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/types.h>
int main(int argc, char *argv[])
{
int iComDesc = 0;
struct termios stInfoCom = {0};
struct sigevent m_EventCom;
int iChid = 0;
int iCoid = 0;
unsigned char ucBuffer[16] = {0};
int iSizeRead = 0;
errno = EOK;
int iRcvId = 0;
struct _pulse stPulse = {0};
int iRet = 0;
unsigned long ulNbRead = 0;
unsigned long ulNbBytes = 0;
printf("[---------- SERIAL TEST ON %s ----------]\n",argv[1]);
/********************************************************/
/* OPEN PORT */
/********************************************************/
iComDesc = open( argv[1], O_RDWR | O_NONBLOCK );
if( iComDesc == -1 )
return 0;
iRet = tcgetattr( iComDesc, &stInfoCom );
if( iRet == -1 )
return 0;
iRet = cfmakeraw( &stInfoCom );
if( iRet == -1 )
return 0;
stInfoCom.c_iflag = 0;
stInfoCom.c_oflag = 0;
stInfoCom.c_cflag &= ~CSIZE;
stInfoCom.c_cflag |= CS8;
stInfoCom.c_cflag &= ~PARENB;
stInfoCom.c_cflag &= ~CSTOPB;
stInfoCom.c_lflag = 0;
for( int iCpt=0; iCpt< (int)sizeof(stInfoCom.c_cc); iCpt++)
{
stInfoCom.c_cc[iCpt] = 0;
}
iRet = cfsetispeed( &stInfoCom, 115200 );
if( iRet == -1 )
return 0;
iRet = cfsetospeed (&stInfoCom, 115200 );
if( iRet == -1 )
return 0;
iRet = tcsetattr( iComDesc, TCSANOW, &stInfoCom );
if( iRet == -1 )
return 0;
/********************************************************/
/* ARM NOTIFICATION */
/********************************************************/
iChid = ChannelCreate( 0 );
iCoid = ConnectAttach( 0, 0, iChid,_NTO_SIDE_CHANNEL, 0 );
SIGEV_PULSE_INIT( &m_EventCom, iCoid, SIGEV_PULSE_PRIO_INHERIT,
( _PULSE_CODE_MINAVAIL + atoi(argv[2]) ), 0 );
iRet = ionotify( iComDesc, _NOTIFY_ACTION_TRANARM,
_NOTIFY_COND_INPUT, &m_EventCom );
if( iRet == -1 )
return 0;
iRet = tcflush( iComDesc, TCIFLUSH );
if( iRet == -1 )
return 0;
/********************************************************/
/* READ DATA 2 PER 2 */
/********************************************************/
while(1)
{
iRcvId = MsgReceive( iChid, &stPulse, sizeof(stPulse), NULL );
if ( ( stPulse.code == ( _PULSE_CODE_MINAVAIL + atoi(argv[2]) ) ) || ( iRcvId > 0 ) )
{
iRet = ionotify( iComDesc, _NOTIFY_ACTION_TRANARM,
_NOTIFY_COND_INPUT, &m_EventCom );
do
{
errno=0;
iSizeRead = read( iComDesc, ucBuffer, 2);
ulNbRead++;
ulNbBytes = ulNbBytes + iSizeRead;
if ( ( iSizeRead == -1 && errno != EAGAIN ) || ( iSizeRead > 2 ) )
{
printf("[ERROR][System][read]-[fildes:%X,buf:%X,nbyte:%u]-[return:%d]-[errno:%d;%s]\n",
iComDesc, ucBuffer, 2, iSizeRead, errno, strerror( errno ) );
iSizeRead = read( iComDesc, ucBuffer+2, iSizeRead-2);
printf("\t");
for (int iCpt2=0; iCpt2<16; iCpt2++)
{
printf("%02hhX ",ucBuffer[iCpt2]);
}
printf(" +iSizeRead:%d\n",iSizeRead);
printf("[----------------------------------------------]\n");
return 0;
}
} while( iSizeRead > 0 );
}
iSizeRead = 0;
printf("\r[INFO]-[READ]- NbRead:%015lu NbOctet:%015lu",ulNbRead,ulNbBytes);
fflush(stdout);
}
printf("[INFO]-[READ]- Data read...finish\n");
printf("[----------------------------------------------]\n");
return 0;
}
With this code I produce my problem, the read function reads more characters than requested. However it does not provide in my buffer.
The result is identical with _NOTIFY_ACTION_POLLARM.
I made another application with a simple blocking read, it does not seem to have any problem.
For information I use 4 serial ports along with an instance of the application, an instance of a driver and different interrupt for each port