是高手就进来帮帮忙!ARM9(2440)多线程串口编程,运行异常:gnu_cxx:concurrence_broadcast_error
是高手就进来帮帮忙!ARM9(2440)多线程串口编程,运行错误:__gnu_cxx::__concurrence_broadcast_error
在ARM9运行多线程串口程序是抛出这样的异常:terminate called after throwing an instance of '__gnu_cxx::__concurrence_broadcast_error'
what(): __gnu_cxx::__concurrence_broadcast_error
只要以调用OpenPort就报错。
该源代码在Fedora9上编译、运行都没问题,程序中用了网上找到的一个多线程串口类。
编译器用的是gcc 4.4.3
Google、百度边了也没找到解决方法,各位有什么解决方法或思路不?
希望大家能帮帮忙,多谢!!!!!!!!
在ARM9运行多线程串口程序是抛出这样的异常:terminate called after throwing an instance of '__gnu_cxx::__concurrence_broadcast_error'
what(): __gnu_cxx::__concurrence_broadcast_error
只要以调用OpenPort就报错。
该源代码在Fedora9上编译、运行都没问题,程序中用了网上找到的一个多线程串口类。
编译器用的是gcc 4.4.3
Google、百度边了也没找到解决方法,各位有什么解决方法或思路不?
希望大家能帮帮忙,多谢!!!!!!!!
- C/C++ code
//主程序 #include "CSerial.h" #include <string> using namespace std; int main(int argc, char* argv[]) { CSerial::CSerial serial; serial.OpenPort("/dev/ttySAC0", 115200, 8, 1, 'N');//报错!! while(1); return 0; }
- C/C++ code
/*自定义串口类 * CSerial.h * * Created on: 2010-7-20 * Author: yzm */ #ifndef CSERIAL_H_ #define CSERIAL_H_ #include <pthread.h> #include <time.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> /*文件控制定义*/ #include <termios.h> /*PPSIX 终端控制定义*/ #include <errno.h> /*错误号定义*/ #include <string.h> #include <string> #include "CCriticalSection.h" using namespace std; #define BUFFER_LENGTH 1024 namespace CSerial { class CSerial { private: string m_PortName; int m_baudrate; int m_databits; int m_stopbits; char m_parity; //通讯线程标识符ID pthread_t m_thread; CCriticalSection mutex; // 串口数据接收线程 static void* ReceiveThreadFunc( void* lparam ); public: CSerial(); virtual ~CSerial(); // 已打开的串口文件描述符 int m_fd; int m_DatLen; unsigned char DatBuf[BUFFER_LENGTH]; int m_ExitThreadFlag; // 按照指定的串口参数打开串口,并创建串口接收线程 int OpenPort( string PortName, int baudrate, int databits, int stopbits, char parity ); // 关闭串口并释放相关资源 int ClosePort( ); // 向串口写数据 int WritePort( unsigned char* Buf, int len ); // 接收串口数据处理函数 virtual int PackagePro( unsigned char* Buf, int len ); private: void set_speed(int fd, int speed); int set_Parity(int fd,int databits,int stopbits,int parity); }; } #endif /* CSERIAL_H_ */
- C/C++ code
/* * CSerial.cpp * * Created on: 2010-7-20 * Author: yzm */ #include "CSerial.h" #include <sys/select.h> #include <sys/time.h> #include <stdlib.h> #include <unistd.h> /*Unix 标准函数定义*/ namespace CSerial { int speed_arr[] = {B115200,B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600, B4800, B2400, B1200, B300, }; int name_arr[] = {115200,38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400, 1200, 300, }; string BYTE2HEX(unsigned char* buffer,int nSize) { char buf[1024]; memset(buf,0,1024); int len = 0; for(int i = 0;i < nSize;i++) { int tmp = sprintf(buf + len,"%02x ",buffer); len += tmp; } string str(buf); return str; } CSerial::CSerial() { m_ExitThreadFlag = false; m_PortName = "/dev/ttyS0"; m_baudrate = 2400; m_databits = 8; m_stopbits = 1; m_parity = 'e'; } CSerial::~CSerial() { ClosePort( ); } int CSerial::OpenPort(string PortName, int baudrate, int databits, int stopbits, char parity) { /*以读写方式打开串口*/ m_fd = open(PortName.data(), O_RDWR); if (-1 == m_fd) { /* 不能打开串口一*/ perror(" 提示错误!"); return -1; } else { m_PortName = PortName; m_baudrate = baudrate; m_databits = databits; m_stopbits = stopbits; m_parity = parity; //设置参数 set_speed(m_fd, baudrate); set_Parity(m_fd, databits, stopbits, parity); pthread_create(&m_thread,NULL,CSerial::CSerial::ReceiveThreadFunc,this); return 1; } } int CSerial::ClosePort( ) { m_ExitThreadFlag = true; close(m_fd); pthread_join(m_thread,NULL); return 1; } int CSerial::PackagePro( unsigned char* Buf, int len ) { string str = BYTE2HEX(Buf,len); printf("%s\r\n",str.data()); WritePort(Buf,len); return 1; } void* CSerial::ReceiveThreadFunc(void* lparam) { CSerial *pSer = (CSerial*) lparam; fd_set fdRead; int ret; struct timeval aTime; while (1) { //收到退出事件,结束线程 //printf("Thread...\r\n"); if (pSer->m_ExitThreadFlag) { break; } FD_ZERO(&fdRead); FD_SET(pSer->m_fd,&fdRead); aTime.tv_sec = 2; aTime.tv_usec = 100; ret = select(pSer->m_fd + 1, &fdRead, NULL, NULL, &aTime); if (ret < 0) { //关闭串口 pSer->ClosePort(); break; } if (ret > 0) { //判断是否读事件 if (FD_ISSET(pSer->m_fd,&fdRead)) { //data available, so get it! pSer->m_DatLen = read(pSer->m_fd, pSer->DatBuf, BUFFER_LENGTH); // 对接收的数据进行处理,这里为简单的数据回发 if (pSer->m_DatLen > 0) { pSer->PackagePro(pSer->DatBuf, pSer->m_DatLen); } // 处理完毕 } } } printf("ReceiveThreadFunc finished\n"); pthread_exit(NULL); return 0; } /** *@brief 设置串口通信速率 *@param fd 类型 int 打开串口的文件句柄 *@param speed 类型 int 串口速度 *@return void */ void CSerial::set_speed(int fd, int speed) { unsigned int i; int status; struct termios Opt; tcgetattr(fd, &Opt); for (i = 0; i < sizeof(speed_arr) / sizeof(int); i++) { if (speed == name_arr) { tcflush(fd, TCIOFLUSH); cfsetispeed(&Opt, speed_arr); cfsetospeed(&Opt, speed_arr); status = tcsetattr(fd, TCSANOW, &Opt); if (status != 0) { perror("tcsetattr fd1"); return; } tcflush(fd, TCIOFLUSH); } } } /** *@brief 设置串口数据位,停止位和效验位 *@param fd 类型 int 打开的串口文件句柄 *@param databits 类型 int 数据位 取值 为 7 或者8 *@param stopbits 类型 int 停止位 取值为 1 或者2 *@param parity 类型 int 效验类型 取值为N,E,O,,S */ int CSerial::set_Parity(int fd, int databits, int stopbits, int parity) { struct termios options; if (tcgetattr(fd, &options) != 0) { perror("SetupSerial 1"); return (false); } options.c_cflag &= ~CSIZE; switch (databits) /*设置数据位数*/ { case 7: options.c_cflag |= CS7; break; case 8: options.c_cflag |= CS8; break; default: fprintf(stderr, "Unsupported data size\n"); return (false); } switch (parity) { case 'n': case 'N': options.c_cflag &= ~PARENB; /* Clear parity enable */ options.c_iflag &= ~INPCK; /* Enable parity checking */ break; case 'o': case 'O': options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/ options.c_iflag |= INPCK; /* Disnable parity checking */ break; case 'e': case 'E': options.c_cflag |= PARENB; /* Enable parity */ options.c_cflag &= ~PARODD; /* 转换为偶效验*/ options.c_iflag |= INPCK; /* Disnable parity checking */ break; case 'S': case 's': /*as no parity*/ options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; break; default: fprintf(stderr, "Unsupported parity\n"); return (false); } /* 设置停止位*/ switch (stopbits) { case 1: options.c_cflag &= ~CSTOPB; break; case 2: options.c_cflag |= CSTOPB; break; default: fprintf(stderr, "Unsupported stop bits\n"); return (false); } options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG | IEXTEN); /*Input*/ options.c_iflag &= ~(IXON | IXOFF | IXANY);//关流控 options.c_iflag &= ~(INLCR | IGNCR | ICRNL | IUCLC | IGNBRK|BRKINT|PARMRK|ISTRIP); options.c_oflag &= ~(ONLCR | OCRNL | ONLRET | ONOCR | OLCUC | OFILL | CRTSCTS); options.c_oflag &= ~OPOST; /*Output*/ /* Set input parity option */ if (parity != 'n') options.c_iflag |= INPCK; tcflush(fd, TCIFLUSH); options.c_cc[VTIME] = 50; /* 设置超时15 seconds*/ options.c_cc[VMIN] = 0; /* Update the options and do it NOW */ if (tcsetattr(fd, TCSANOW, &options) != 0) { perror("SetupSerial 3"); return (false); } return (true); } int CSerial::WritePort( unsigned char* Buf, int len ) { mutex.Lock(); int ToWrite = len; int hasWrite = 0; int wPos = 0; while(ToWrite > 0){ hasWrite = write(m_fd, Buf + wPos, ToWrite); if(hasWrite <= 0)break; ToWrite -= hasWrite; wPos += hasWrite; } mutex.Unlock(); return len - ToWrite; } }