Я тестирую функцию записи библиотеки моего последовательного порта. Сначала я организовал дескриптор файла последовательного порта как неблокирующий дескриптор файла.Затем я вызываю tcdrain (fd) в конце моей настраиваемой функции записи.Но если я не подожду с sleep () после этой настроенной функции записи и немедленно вернусь из приложения, байты фактически не будут записываться через последовательный порт.
Итак, у меня два вопроса.
- Разве tcdrain () не гарантирует отправку байтов?
- Как реализовать настраиваемую функцию записи без вызова функции sleep ().
Я пробую ту же функцию с файлом блокировкидескриптор.Но ничего не изменилось.
Сначала я инициализирую последовательный порт следующим кодом:
struct termios stermios;
tcgetattr ( fd, &stermios );
cfsetispeed ( &stermios, handle->baudrate );
cfsetospeed ( &stermios, handle->baudrate );
stermios.c_cflag &= ~(PARENB | CSTOPB | CRTSCTS );
stermios.c_cflag |= ( CLOCAL | CREAD );
stermios.c_cflag &= ~CSIZE;
stermios.c_cflag |= CS8;
stermios.c_iflag &= (IXON | IXOFF );
stermios.c_oflag &= ~OPOST;
stermios.c_lflag &= ~(ICANON | ECHO | ECHOE );
tcflush ( fd, TCIOFLUSH );
tcsetattr ( fd, TCSANOW, termios_p );
И вот моя настраиваемая функция записи:
static int32_t surely_tcdrain ( SerialPortHandle_t const * handle_p )
{
int32_t retval = -1;
int32_t try_cnt = 0;
while ( ( ++try_cnt < MAX_TCDRAIN_TRY_CNT ) &&\
( -1 == (retval = tcdrain ( fd ) ) ) )
{
if ( EINTR == errno )
{
usleep ( TCDRAIN_DELAY );
}
else
{
fprintf (stderr, "tcdrain() FAILED, %d, %s\n",\
errno, strerror ( errno ) );
try_cnt = MAX_TCDRAIN_TRY_CNT; // Dont try again, break the loop. //
}
}
return retval;
}
int32_t write_to_serial_port( int32_t fd, void * buff, size_t size )
{
uint8_t try_cnt = 0;
size_t total_write_size = 0;
while ( ( total_write_size < size ) && ( ++try_cnt < 10 ) )
{
ssize_t w_size = -1;
w_size = write (fd, ( ( uint8_t * ) buff + total_write_size ),\
( size - total_write_size ) );
if ( w_size == -1 )
{
if ( ( errno != EINTR ) && ( errno != EAGAIN ) &&\
( errno != EWOULDBLOCK ) )
{
try_cnt = MAX_WRITE_TRY_CNT;
}
else
{
usleep ( WRITE_DELAY );
}
}
else
{
total_write_size += ( ( size_t ) w_size );
}
}
return ( ( surely_tcdrain ( fd ) == 0 ) &&\
( ( total_write_size == size ) ) ) ? 0 : -1;
}
И, наконец,Я закрыл свой дескриптор файла последовательного порта следующей функцией.
static void deinit_fd ( int32_t fd )
{
if ( FD_INVALID != fd )
{
if ( 1 == isatty ( fd ) )
{
tcdrain ( fd ); // Wait for write all output process. //
}
else
{
// fd not referring terminal. So no need to call tcdrain(). //
}
close ( fd );
}
else
{
// fd is invalid. //
}
}
Я вызываю эту функцию записи в main и после этого закрываю свой дескриптор файла и немедленно возвращаюсь из приложения.
Iожидайте, что все байты должны быть записаны через последовательный порт с моей функцией записи.Но моя функция так не работает.