Pregunta

Resulta que todo este malentendido de la open() en comparación con fopen() se deriva de un buggy I2C conductor en el Linux kernel 2.6.14 en un BRAZO.Adaptando cambios de trabajo poco rota controlador de resolver la causa raíz del problema estaba tratando de abordar aquí.

Estoy tratando de averiguar un problema con una serie de controlador de dispositivo en Linux (I2C).Parece que mediante la adición de temporizado OS pausas (duerme) entre lecturas y escrituras en el dispositivo funcionan las cosas ...(mucho) mejor.

A un lado: La naturaleza de I2C es que cada byte leído o escrito por el maestro es reconocido por el dispositivo en el otro extremo del alambre (esclavo) - las pausas mejorar las cosas me animan a pensar que el conductor como el trabajo de forma asincrónica - algo que no me puedo reconciliar con cómo el autobús funciona.Anyhoo ...

Me gustaría tanto como a ras el escribir para estar seguro de que (en lugar de utilizar fija la duración de la pausa), o probar de alguna manera que la escritura/lectura de transacción completado en un multi-threaded manera amistosa.

El problema con el uso de fflush(fd); es que no requiere 'fd' para ser puntero de stream (no es un descriptor de archivo), es decir,

FILE * fd = fopen("filename","r+");
... // do read and writes
fflush(fd);

Mi problema es que me requieren el uso de la ioctl(), que no utilice un chorro de puntero.es decir,

int fd = open("filename",O_RDWR);
ioctl(fd,...);

Sugerencias?

¿Fue útil?

Solución

Usted tiene dos opciones:

  1. Uso fileno() para obtener el descriptor de fichero asociado con el stdio puntero de stream

  2. No uso <stdio.h> a todos, de esa manera usted no necesita preocuparse acerca de enjuagar bien - todas las escrituras de ir para el dispositivo de inmediato y para dispositivos de caracteres de la write() llame a no regresar hasta que el nivel inferior IO ha completado (en teoría).

Para que el dispositivo IO-yo diría que es bastante inusual para uso stdio.Me gustaría recomendar encarecidamente el uso de los de nivel inferior open(), read() y write() funciones en lugar de (basado en su respuesta):

int fd = open("/dev/i2c", O_RDWR);
ioctl(fd, IOCTL_COMMAND, args);
write(fd, buf, length);

Otros consejos

Creo que lo que estás buscando puede ser

int fsync(int fd);

o

int fdatasync(int fd);

fsync vaciará el archivo del búfer del núcleo al disco. fdatasync también lo hará, excepto los metadatos.

fflush() sólo se vacía el búfer añadido por la stdio fopen() capa, mediante la gestión de la FILE * objeto.El archivo subyacente en sí, como se ve por el kernel, no se almacenan en este nivel.Esto significa que escribe que la derivación de la FILE * la capa, utilizando fileno() y raw write(), tampoco están en el búfer de una manera que fflush() sería de color.

Como otros han señalado, trate de no la mezcla de los dos.Si necesita utilizar el "raw" funciones de e/S, tales como ioctl(), a continuación, open() el archivo usted mismo directamente, sin el uso de fopen<() y los amigos de stdio.

Parece que lo que está buscando es la función fsync () (o fdatasync ()?), o puede usar el indicador O_SYNC en su llamada abierta ().

Si desea ir al revés (asociar ARCHIVO * con el descriptor de archivo existente), use fdopen ():

                                                          FDOPEN(P)

NAME

       fdopen - associate a stream with a file descriptor

SYNOPSIS

       #include <stdio.h>

       FILE *fdopen(int fildes, const char *mode);

¿Has intentado deshabilitar el almacenamiento en búfer?

setvbuf(fd, NULL, _IONBF, 0);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top