I am currently trying to work on how to write and read on a serial port on Linux. Yesterday my program worked with no issue but since this morning it seems stuck in a loop.
Here is the part which causes the issue:
void *ReadModBusRTU(void *threadarg) {
cout << "thread lecture" << endl;
i = 0;
bufptr = buffer;
while(1) {
cout << "enter while loop" << endl;
if ( (nbytes = read(fd, bufptr, 1) ) > 0) {
cout << std::hex << bufptr;
lecture[i] = buffer[0];
//cout << " lecture[" << i << "] : " << lecture[i] << endl;
i++;
// cout << "i : " << i << endl;
cout.flush();
} else {
cout << "lecture du port serie..." << endl;
}
}
pthread_exit(NULL);
}
Normally it should stay in the while(1)
loop and do what it must but since this morning it is doing the cout "enter while loop" and then nothing.
Not the else, not cout "enter while loop" once again. It simply is stuck after the cout. I am kind of lost on why this is happening since it worked well yesterday. I have another pthread with a similar architecture and it is working well.
Edit code read :
#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 "iostream"
#include "pthread.h"
/*
* 'open_port()' - Open serial port 1.
*
* Returns the file descriptor on success or -1 on error.
*/
using namespace std;
int open_port(void);
int rc;
volatile int i=0;
pthread_t threads[2];
char buffer[255]; /* Input buffer */
volatile char lecture[255];
char donnees[255];
char *bufptr; /* Current char in buffer */
int nbytes; /* Number of bytes read */
int tries; /* Number of tries so far */
int fd; /* File descriptor for the port */
struct termios options;
struct thread_data{
float limite;
int threadcible;
int prise;
};
struct thread_data td[1];
void *ReadModBusRTU(void *threadarg){
/* read characters into our string buffer until we get a CR or NL */
cout<<"thread lecture"<<endl;
i=0;
bufptr = buffer;
while(1){
//if ((nbytes = read(fd, bufptr, buffer + sizeof(buffer) - bufptr - 1)) > 0)
if ((nbytes = read(fd, bufptr, 1)) > 0)
{
cout<<std::hex<<bufptr;
lecture[i]=buffer[0];
//cout<<" lecture["<<i<<"] : "<<lecture[i]<<endl;
i++;
//cout<<"i : "<<i<<endl;
cout.flush();
}
}
pthread_exit(NULL);
}
void *TravailModBusRTU(void *threadarg){
cout<<"thread travail"<<endl;
while(1)
{
if(lecture[0]=='1' && lecture[1]=='2')
{
cout<<"lecture 12"<<endl;
if((nbytes = read(fd, bufptr, 1))==0)
{
cout<<"lecture terminee"<<endl;
int j=0;
for(j=0;j<=254;j++)
{
donnees[j]=lecture[j];
}
cout<<"donnee : "<<donnees<<endl;
//cout.flush();
for(i=0;i<=254;i++)
{
lecture[i]='Z';
}
i=0;
}
}
}
pthread_exit(NULL);
}
int main(){
//close(fd);
open_port();
for(i=0;i<=254;i++){
lecture[i]='Z';
}
rc = pthread_create(&threads[2], NULL, TravailModBusRTU, (void *)&td);
if (rc){
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
rc = pthread_create(&threads[1], NULL, ReadModBusRTU, (void *)&td);
if (rc){
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
while(1){
}
return 0;
}
int open_port(void)
{
/*
* Get the current options for the port...
*/
tcgetattr(fd, &options);
/*
* Set the baud rates to 57600...
*/
cfsetispeed(&options, B57600);
cfsetospeed(&options, B57600);
//No parity (8N1):
options.c_cflag &= ~PARENB;
//options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_iflag &= ~(IXON | IXOFF | IXANY);
//no hardware control flow
//options.c_cflag &= ~CNEW_RTSCTS;
/*
* Enable the receiver and set local mode...
*/
//options.c_cflag |= (CLOCAL | CREAD);
/*
* Set the new options for the port...
*/
tcsetattr(fd, TCSANOW, &options);
options.c_cflag &= ~CSIZE; /* Mask the character size bits */
options.c_cflag |= CS8; /* Select 8 data bits */
fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
{
/*
* Could not open the port.
*/
cout<<"open_port: Unable to open /dev/ttyf1 - "<<endl;
}
else{
fcntl(fd, F_SETFL, 0);}
return (fd);
}
code write :
#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 "iostream"
/*
* 'open_port()' - Open serial port 1.
*
* Returns the file descriptor on success or -1 on error.
*/
using namespace std;
int open_port(void);
int main(){
open_port();
}
int open_port(void)
{
char buffer[255]; /* Input buffer */
char *bufptr; /* Current char in buffer */
int nbytes; /* Number of bytes read */
int tries; /* Number of tries so far */
int fd; /* File descriptor for the port */
struct termios options;
/*
* Get the current options for the port...
*/
tcgetattr(fd, &options);
/*
* Set the baud rates to 57600...
*/
cfsetispeed(&options, B57600);
cfsetospeed(&options, B57600);
//No parity (8N1):
options.c_cflag &= ~PARENB;
//options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
//no hardware control flow
//options.c_cflag &= ~CNEW_RTSCTS;
/*
* Enable the receiver and set local mode...
*/
options.c_cflag |= (CLOCAL | CREAD);
/*
* Set the new options for the port...
*/
tcsetattr(fd, TCSANOW, &options);
options.c_cflag &= ~CSIZE; /* Mask the character size bits */
options.c_cflag |= CS8; /* Select 8 data bits */
fd = open("/dev/ttyS1", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
{
/*
* Could not open the port.
*/
cout<<"open_port: Unable to open /dev/ttyS1 - "<<endl;
}
else{
fcntl(fd, F_SETFL, 0);}
int n;
char test[]="123";
n=write(fd,test,sizeof(test));
return (fd);
}
答案 0 :(得分:0)
在open_port
中,如果打开成功,您似乎清除O_NDELAY
/ O_NONBLOCK
标志。这意味着当您执行fd
时,ReadModBusRTU
处于阻止模式。
我猜测dev/ttyS0
是一个特殊文件,数据可能无法立即显示......