Sto tentando di leggere e scrivere dati da e verso una scheda FPGA. La scheda stessa è arrivata con un driver che crea un dispositivo terminale chiamato ttyUSB0 ogni volta che la scheda viene collegata. Sull'Fpga, sono stati implementati un ricevitore e un trasmettitore asincroni e sembrano funzionare.Come configurare correttamente la comunicazione seriale su Linux
Tuttavia, sembra esserci un problema sul lato C delle cose. Ho usato alcuni vettori di test per verificare se l'FPGA sta emettendo le informazioni corrette. Ho notato alcune cose cose:
- Il dispositivo a volte non si apre correttamente
- Il terminale attributi a volte non riescono a essere recuperata o impostata.
- La lettura a volte non è bloccante e non recupera il valore corretto.
Di seguito viene illustrato come impostare le opzioni del descrittore di terminale e di file. Gran parte di esso è stata presa da qui: http://slackware.osuosl.org/slackware-3.3/docs/mini/Serial-Port-Programming
Qualsiasi consiglio o commento sul perché il programma potrebbe fallire sarebbe di grande aiuto.
#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 open_port(void){
int fd; // File descriptor for the port
fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY);
if (fd == -1){
fprintf(stderr, "open_port: Unable to open /dev/ttyUSB0 %s\n",strerror(errno));
exit(EXIT_FAILURE);
}
return (fd);
}
int main(void){
int fd = 0; // File descriptor
struct termios options; // Terminal options
fd = open_port(); // Open tty device for RD and WR
fcntl(fd, F_SETFL); // Configure port reading
tcgetattr(fd, &options); // Get the current options for the port
cfsetispeed(&options, B230400); // Set the baud rates to 230400
cfsetospeed(&options, B230400);
options.c_cflag |= (CLOCAL | CREAD); // Enable the receiver and set local mode
options.c_cflag &= ~PARENB; // No parity bit
options.c_cflag &= ~CSTOPB; // 1 stop bit
options.c_cflag &= ~CSIZE; // Mask data size
options.c_cflag |= CS8; // Select 8 data bits
options.c_cflag &= ~CRTSCTS; // Disable hardware flow control
// Enable data to be processed as raw input
options.c_lflag &= ~(ICANON | ECHO | ISIG);
// Set the new attributes
tcsetattr(fd, TCSANOW, &options);
////////////////////////////////////
// Simple read and write code here//
////////////////////////////////////
// Close file descriptor & exit
close(fd)
return EXIT_SUCCESS
}
UPDATE Ho modificato il mio codice in base alla prima risposta. Questo è quello che ho adesso:
#include <errno.h> // Error number definitions
#include <stdint.h> // C99 fixed data types
#include <stdio.h> // Standard input/output definitions
#include <stdlib.h> // C standard library
#include <string.h> // String function definitions
#include <unistd.h> // UNIX standard function definitions
#include <fcntl.h> // File control definitions
#include <termios.h> // POSIX terminal control definitions
// Open usb-serial port for reading & writing
int open_port(void){
int fd; // File descriptor for the port
fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY);
if (fd == -1){
fprintf(stderr, "open_port: Unable to open /dev/ttyUSB0 %s\n",strerror(errno));
exit(EXIT_FAILURE);
}
return fd;
}
int main(void){
int fd = 0; // File descriptor
struct termios options; // Terminal options
int rc; // Return value
fd = open_port(); // Open tty device for RD and WR
// Get the current options for the port
if((rc = tcgetattr(fd, &options)) < 0){
fprintf(stderr, "failed to get attr: %d, %s\n", fd, strerror(errno));
exit(EXIT_FAILURE);
}
// Set the baud rates to 230400
cfsetispeed(&options, B230400);
// Set the baud rates to 230400
cfsetospeed(&options, B230400);
cfmakeraw(&options);
options.c_cflag |= (CLOCAL | CREAD); // Enable the receiver and set local mode
options.c_cflag &= ~CSTOPB; // 1 stop bit
options.c_cflag &= ~CRTSCTS; // Disable hardware flow control
options.c_cc[VMIN] = 1;
options.c_cc[VTIME] = 2;
// Set the new attributes
if((rc = tcsetattr(fd, TCSANOW, &options)) < 0){
fprintf(stderr, "failed to set attr: %d, %s\n", fd, strerror(errno));
exit(EXIT_FAILURE);
}
////////////////////////////////
// Simple Read/Write Code Here//
////////////////////////////////
// Close file descriptor & exit
close(fd);
return EXIT_SUCCESS;
}
solo per chiarire, l'uso 8 bit ricevitore e trasmettitore di dati, 1 bit di stop e nessun bit di parità.
Grazie, ci provo e ti aggiorno. – sj755
Ho effettuato un aggiornamento e pubblicato il mio codice corrente. Per qualche ragione il programma non è in grado di leggere nulla dalla lavagna, attende solo la funzione di lettura. qualche idea? – sj755
Non hai bisogno di 'c_cflag & = ~ PARENB' dato che' cfmakeraw() 'lo gestirà. Probabilmente hai bisogno di 'c_cflag & = ~ CSTOPB' e' c_cflag & = ~ CRTSCTS' che sono stati rimossi! Ognuno di questi potrebbe uccidere la lettura. – sawdust