La lecture et l'écriture de données binaires sur le port série

Donc j'ai cherché partout, et je ne pouvais pas trouver exactement ce dont j'avais besoin. J'ai besoin d'aide de la lecture et de l'écriture binaire des données sur un port série, et il serait souhaitable que tous les conseils que vous pourriez avoir. Veuillez noter, j'ai posé une question similaire à cela plus tôt, lorsque j'étais à un stade différent de ce projet.

Ci-dessous sont des programmes. Le premier programme ouvre un fichier "test.jpg", dit-il en mode binaire et stocke le résultat dans une mémoire tampon. Puis, il ferme le fichier, et est censé envoyer ce fichier sur un port série.

Le deuxième programme crée un fichier appelé "testout.jpg" et est censé lire dans les données envoyées par le programme précédent.

J'ai l'intuition que le problème dans mon code se trouve dans la deuxième programme. J'ai peut-être besoin d'utiliser fread pour ça aussi? J'ai essayé, mais je ne peux pas comprendre comment le mettre en œuvre pour un port série comme je suis relativement nouveau à la programmation.

Merci beaucoup pour votre temps.

Série d'écrire:

    #include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
#include <stdlib.h>
int main()
{
//writing
int writeport = open_port("/dev/ttyUSB0");
//open file
FILE *file;
char *buffer;
int fileLen;
file = fopen("test.jpg", "rb");
//get file size
fseek(file, 0, SEEK_END);
fileLen = ftell(file);
fseek(file, 0, SEEK_SET);
buffer = (char *)malloc(fileLen + 1);
//read file contents
fread(buffer, fileLen, 1, file);
fclose(file);
int n = write(writeport, buffer, fileLen + 1);
if (n < 0)
fputs("write() of bytes failed!\n", stderr);
//closing ports
close(writeport);
}
int open_port(char str[])
{
int fd = open(str, O_RDWR | O_NOCTTY | O_NONBLOCK); //?? NDELAY or NONBLOCK?
if (fd == -1)
{
perror("open_port: Unable to open /dev/ttyS0 - ");
}
else
fcntl(fd, F_SETFL, 0);
struct termios options;
tcgetattr(fd, &options); //this gets the current options set for the port
//setting the options
cfsetispeed(&options, B9600); //input baudrate
cfsetospeed(&options, B9600); //output baudrate
options.c_cflag |= (CLOCAL | CREAD); //?? enable receicer and set local mode
//options.c_cflag &= ~CSIZE; /* mask the character size bits */
options.c_cflag |= CS8;    /* select 8 data bits */
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); //choosing raw input
options.c_iflag &= ~INPCK; //disable parity check
options.c_iflag &= ~(IXON | IXOFF | IXANY); //disable software flow control
options.c_oflag |= OPOST; //?? choosing processed output
options.c_cc[VMIN] = 0; //Wait until x bytes read (blocks!)
options.c_cc[VTIME] = 0; //Wait x * 0.1s for input (unblocks!)
//settings for no parity bit
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
tcsetattr(fd, TCSANOW, &options); //set the new options ... TCSANOW specifies all option changes to occur immediately
return (fd);
}

Série lire:

    #include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
int main()
{
//reading      
int readport = open_port("/dev/ttyUSB1");
//open resultant file
FILE *file;
//system("rm testout.jpg");
file = fopen("testout.jpg", "wb");
//trying to read one character at a time
char buff;
int n = 1;
while (n > 0)
{
n = read(readport, &buff, 1);
//printf("%c", buff, buff);
**//I tried these three methods, with little success**
//fprintf(file, "%c", buff);
//fwrite(&buff, 1, 1, file);
//write(file, &buff, 1);
}
//closing ports
close(readport);
fclose(file);
}
int open_port(char str[])
{
int fd = open(str, O_RDWR | O_NOCTTY | O_NONBLOCK); //?? NDELAY or NONBLOCK?
if (fd == -1)
{
perror("open_port: Unable to open /dev/ttyS0 - ");
}
else
fcntl(fd, F_SETFL, 0);
struct termios options;
tcgetattr(fd, &options); //this gets the current options set for the port
//setting the options
cfsetispeed(&options, B9600); //input baudrate
cfsetospeed(&options, B9600); //output baudrate
options.c_cflag |= (CLOCAL | CREAD); //?? enable receicer and set local mode
//options.c_cflag &= ~CSIZE; /* mask the character size bits */
options.c_cflag |= CS8;    /* select 8 data bits */
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); //choosing raw input
options.c_iflag &= ~INPCK; //disable parity check
options.c_iflag &= ~(IXON | IXOFF | IXANY); //disable software flow control
options.c_oflag |= OPOST; //?? choosing processed output
options.c_cc[VMIN] = 0; //Wait until x bytes read (blocks!)
options.c_cc[VTIME] = 0; //Wait x * 0.1s for input (unblocks!)
//settings for no parity bit
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
tcsetattr(fd, TCSANOW, &options); //set the new options ... TCSANOW specifies all option changes to occur immediately
return (fd);
}
  • Vous ne semblez pas avoir toute erreur de manipulation, Avez-vous retiré de réduire la quantité de code que nous avons besoin de savoir lire pour comprendre votre problème ou avez-vous simplement de ne pas l'avoir dans votre code (dans ce cas, vous devriez au moins vérifier les fichiers/les ports à ouvrir sont valides et en bon état!). L'utilisation de O_NONBLOCK suggère que vous n'êtes pas d'attente pour le port à ouvrir (ou suis-je à la lecture de ce mal?).
  • while (n > 0) { n = read(readport, &buff, 1); est wromg. Test de la n immédiatement après la lecture(), et de sortir de la boucle if (n <= 0). (n==0 est spécial: dépend de la bloquant ou non bloquant)
  • Oui vous avez raison sur ces deux choses. O_NONBLOCK a été utilisé car il ne fonctionnait pas avec NDELAY.
  • Il semble que vous utilisez O_NONBLOCK. si (n=read(...) == -1) vous devriez vérifier errno pour EAGAIN/EWOULDBLOCK.
  • Alors serait-ce mieux: while (true) { if (n <= 0) break; else n = read(readport, &buff, 1);} Merci!
  • NON!!! mettez le test après le n=read(...); vous voulez tester le nouveau n, pas un vieux un.. Nouveau: vérifiez errno si n == -1.
  • Bon, je l'ai fait. Est-ce ce que vous vouliez dire: while (1) { n = read(readport, &buff, 1); if (n == -1) printf("%s\n", strerror(errno)); if (n <= 0) break;} Grâce. Si oui, j'ai essayé, et j'obtiens le même résultat à l'aide fprintf.

InformationsquelleAutor capcom | 2012-07-25