barrux
Posts: 25
Joined: Sat Feb 16, 2013 4:10 pm

[C++] Segmentation fault (core dumped) , come risolvo ?

Sun Mar 17, 2013 12:24 pm

Ciao a tutti, ho creato questo programmino in C++ per leggere i dati inviati da un microcontrollore PIC attaccato all' USB del RaspberryPi tramite un convertitore USB --> TTL. Prima di tutto dico che in qualsiasi computer (tra cui anche uno con ArchLinux) che ci ho attaccato il PIC e ho fatto girare il programma, tutto va a buon fine e legge i dati, quindi non ci sono errori di compilazione o altro. Solo che con il mio RaspberryPi non vuole proprio partire (ho ArchARM e la versione del Rasp è la B), il codice di Example1.cpp è questo:

Code: Select all

#include <stdio.h>
#include "serialib.h"
#define     DEVICE_PORT   "/dev/ttyUSB0"  // Imposta la porta USB di ArchLinux
int main()
{
    serialib LS;
    int Ret;
    int i=1;
    int j;
    char Stringa[10];		 //Dichiaro il buffer Stringa
    // Apro la porta seriale
    Ret=LS.Open(DEVICE_PORT,9600);                     // Apro il dispositivo seriale con 9600 bit/s
    if (Ret!=1) {                                      // Se c' è un errore...
        printf ("Errore nell' aprire la porta\n");     // ...Visualizza un messaggio...
        return Ret;                                    // ...Esce dall' applicazione
    }
    printf ("Porta seriale aperta con successo!\n");   //Sennò visualizza che tutto è OK
do{                                             //Creo un ciclo infinito per non uscire dal processo a fine TimeOut
                                                // Legge le stringe dalla seriale
    Ret=LS.ReadString(Stringa,'*',10,12000);    //Leggo il valore della seriale fino al carattere '*'
    if (Ret>0)     {
    printf ("%s",Stringa," "); 		        //stampo nella shell il valore corrente 
    }
    else
    printf ("TimeOut terminato. Nessun dato ricevuto!\n");  //Messaggio di fine Timeout senza dati ricevuti 
    //Creazione file di log
    FILE* pFile = fopen("logFile.txt", "w");     //creo o apro un file in modalità scrittura
    fprintf(pFile, "Stringa: %s\n",Stringa);     //stampo il valore Stringa
    fclose(pFile); 	                         //chiudo il file
} 
while (i=1);                			 //condizione sempre vera 
LS.Close();                 			 // Chiude la connessione con il dispositivo seriale
return 0;
}


Compilando con questo comando:

Code: Select all

g++ -Wall Example1.cpp serialib.cpp -o test
mi da solo questi Warning:

Code: Select all

Example1.cpp: In function âint main()â:
Example1.cpp:39:29: warning: too many arguments for format [-Wformat-extra-args]
Example1.cpp:40:29: warning: too many arguments for format [-Wformat-extra-args]
Example1.cpp:41:26: warning: too many arguments for format [-Wformat-extra-args]
Example1.cpp:42:30: warning: too many arguments for format [-Wformat-extra-args]
Example1.cpp:96:12: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
serialib.cpp: In member function âint serialib::ReadStringNoTimeOut(char*, char, unsigned int)â:
serialib.cpp:319:38: warning: converting to non-pointer type âunsigned intâ from NULL [-Wconversion-null]
E quando lancio il programma mi scrive il seguente:

Code: Select all

Porta seriale aperta con successo!
TimeOut terminato. Nessun dato ricevuto!
Segmentation fault (core dumped)
La libreria e il file serialib.cpp li potete trovare a questo link: http://serialib.free.fr/html/index.html

barrux
Posts: 25
Joined: Sat Feb 16, 2013 4:10 pm

Re: [C++] Segmentation fault (core dumped) , come risolvo ?

Sun Mar 17, 2013 3:28 pm

Edit: ho risolto la parte che mi dice del Segmentation fault (core dumped), era quando toglievo il carattere di controllo per far venir fuori una stringa pulita. Però non riesce a leggere i dati, mi dice in continuazione che non ha ricevuto nessun dato, perchè ? Grazie.

PS: La seriale la apre con successo, solo che non riesce a leggere i dati.

3-4-Fun
Posts: 50
Joined: Sun Dec 23, 2012 3:25 pm

Re: [C++] Segmentation fault (core dumped) , come risolvo ?

Sun Mar 17, 2013 5:36 pm

Sembra tutto ok, a parte che dopo il while ci andrebbe la condizione (i==1) invece che l'assegnazione, ma è un dettaglio insignificante per l'esempio in questione.

Dovresti verificare quale codice di errore ti ritorna la readString per capire come rimediare.
Returns:
>0 success, return the number of bytes read
0 timeout is reached
-1 error while setting the Timeout
-2 error while reading the byte
-3 MaxNbBytes is reached

Se ritorna 0 (timeout), probabilmente è un problema di settaggio dei parametri della seriale, ho notato che la libreria è molto spartana e mancano almeno i seguenti settaggi, che devono essere uguali per i due partner:
-numero bit di dati, e bit di stop e parità (di solito 8,1,None)
-handshake (d solito none)

Inoltre fai attenzione alla piedinatura del cavo seriale...

barrux
Posts: 25
Joined: Sat Feb 16, 2013 4:10 pm

Re: [C++] Segmentation fault (core dumped) , come risolvo ?

Sun Mar 17, 2013 7:57 pm

Innanzitutto grazie per l' aiuto 3-4-Fun molto gentile. Ho effettuato le seguenti modifiche:
-Cambiato il ciclo di loop con un semplice for(;;)
- Ho messo 4 else if in base a ciò che mi ritorna.

Quando avvio il programma mi ritorna l' errore 0, ossia il timeout, da come Lei spiega dovrebbe essere un problema dei settaggi della seriale, ma com' è possibile che su altri computer mi funziona ? Eventualmente come potrei risolvere e/o ci sono librerie che effettuano lo stesso compito magari più complete ? Grazie.

3-4-Fun
Posts: 50
Joined: Sun Dec 23, 2012 3:25 pm

Re: [C++] Segmentation fault (core dumped) , come risolvo ?

Mon Mar 18, 2013 10:37 pm

Ciao, purtroppo non ho esempi recenti di programmazione.
Ti posso passare alcune routine che avevo utilizzato qualche (molti) anni fa per comunicare con un ricevitore satellite. Era un programma in C e utilizzava funzioni standard unix termios per gestire i terminali. (cerca con google termios examples per avere maggiori notizie)
La funzione set_port_options() imposta i parametri di comunicazione (velocità, bit di stop, ecc) e poi imposta la seriale in modo che vi sia un timeout della funzione read() se non riceve un carattere entro 1s.
Ho messo anche la funzione GetAttention() che inviava il comando "CBEG" e si aspettava come risposta "OK".

Ciao


int StopCom ( int fd)
{
if (fd==0)
return ERROR_WRONG_PARAMETER;
else
return close(fd);
}


int StartCom(int *fd, const char *comport)
{
if((*fd=open_port(comport))!=-1)
return set_port_options(*fd,10);
else
return ERROR_COM_PORT_OPEN;
}



/*
* 'open_port()' - Open serial port
* Returns the file descriptor on success or -1 on error.
*/

int open_port(const char* comport)
{
int fd; /* File descriptor for the port */
fd = open(comport, O_RDWR);
return (fd);
}

/*
* set_port_options(read_timeout)' - Set options to 38400, 8N1, raw I/O
* paremeter: read_timeout represents the timeout in reading (in tenth/second)
* Returns the file descriptor on success or -1 on error.
*/
int set_port_options(int fd, int read_timeout)
{

struct termios options;
int result;

result = tcgetattr (fd, &options);
if (result < 0)
return ERROR_GETTING_PORT_ATTRIBUTES;

/*
* Set the baud rate to 38400 for bot I/O...
*/
result=cfsetspeed(&options, B38400);
if (result < 0)
return ERROR_SETTING_PORT_SPEED;

/* raw input/output */
cfmakeraw(&options);
/*
* If MIN > 0 and TIME = 0, MIN sets the number of characters to receive
* before the read is satisfied. As TIME is zero, the timer is not used.
*
* If MIN = 0 and TIME > 0, TIME serves as a timeout value. The read will
* be satisfied if a single character is read, or TIME is exceeded (t =
* TIME *0.1 s). If TIME is exceeded, no character will be returned.
*
* If MIN = 0 and TIME = 0, read will be satisfied immediately. The
* number of characters currently available, or the number of characters
* requested will be returned. According to Antonino (see contributions),
* you could issue a fcntl(fd, F_SETFL, FNDELAY); before reading to get
* the same result.
*
* Both TIME and MIN are nonzero. In this case, TIME specifies how long
* to wait after each input character to see if more input arrives.
* After the first character received, read keeps waiting until either MIN
* bytes have arrived in all, or TIME elapses with no further input.
* Read always blocks until the first character arrives, even if TIME elapses
* first. read can return more than MIN characters if more than MIN happen
* to be in the queue.
*/
options.c_cc[VTIME] = read_timeout; /* timeout 1 sec.*/
options.c_cc[VMIN] = 0; /* don't block read... */
/*
* Set the new options for the port...
*/
result=tcsetattr(fd, TCSANOW, &options);
if (result < 0)
return ERROR_SETTING_PORT_ATTRIBUTES;
tcflush(fd, TCIOFLUSH);
return (0);
}


int GetAttention(int fd)
{
static char link_sequence[5]={"CBEG"};
long bytes_transferred, index;
unsigned char string[256];

/* azzero i buffer di IO */
tcflush(fd, TCIOFLUSH);
/* invio il comando di get attention (CBEG=CommunicationBEGin ? )*/
bytes_transferred=write(fd,link_sequence,4);
if(bytes_transferred!=4)
return ERROR_WRITING_PORT;
/* Leggo l'OK da parte del NOKIA (due bytes) */
index=0;
do
{
bytes_transferred=read(fd,string+index,3);
if(bytes_transferred==0 && index<3)
/* errore di timeout in lettura: Nokia non risponde */
return ERROR_READ_TIMEOUT;
else
if(bytes_transferred<0)
g_print("%d\n",errno);
else
index+=bytes_transferred;
}while(index<3);

g_print("GetAttention: %x %x %x\n",string[0],string[1],string[2]);
if(strstr(string,"OK")==NULL)
return ERROR_ANSWER_NOT_OK;
return 0;

}

Return to “Italiano”