是高手就进来帮帮忙!ARM9(2440)多线程串口编程,运行错误:__gnu_cxx::__concurrence_broadcast_error

qq361301276 2011-08-09 08:02:23
在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、百度边了也没找到解决方法,各位有什么解决方法或思路不?
希望大家能帮帮忙,多谢!!!!!!!!


//主程序
#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;
}



/*自定义串口类
* 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_ */



/*
* 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;
}
}



#ifndef __CCRITICALSECTION_H
#define __CCRITICALSECTION_H
#include <pthread.h>

class CCriticalSection
{
private:
pthread_mutex_t mutex;
public:
CCriticalSection();
~CCriticalSection();
public:
void Lock();
void Unlock();
};
#endif



#include "CCriticalSection.h"

CCriticalSection::CCriticalSection()
{
pthread_mutex_init(&mutex,NULL);
}
CCriticalSection::~CCriticalSection()
{
pthread_mutex_destroy(&mutex);
}
void CCriticalSection::Lock()
{
pthread_mutex_lock(&mutex);
}
void CCriticalSection::Unlock()
{
pthread_mutex_unlock(&mutex);
}
...全文
676 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq361301276 2012-03-26
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 lvpwin 的回复:]

你好,你的这个问题,我也碰见了,代码用3.4.1编译运行没有问题,现在用4.3.3就出问题了。你的问题解决了吗?
[/Quote]

太久忘了。
貌似后来没用这个类了
直接用Mini2440开发板上自带的串口例子
lvpwin 2012-02-23
  • 打赏
  • 举报
回复
你好,你的这个问题,我也碰见了,代码用3.4.1编译运行没有问题,现在用4.3.3就出问题了。你的问题解决了吗?
qq361301276 2011-08-13
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 xunxun1982 的回复:]

第一个可能原因是pthread的问题
看看你用的arm工具链的pthread库是否正确复制到目标机里了
如果不是系统路径,链接时使用-Wl,-rpath=... -Wl,--dyanmic-linker=...来确定路径

第二个可能原因是有的嵌入式系统不支持异常,这也是1L的说法
如果你确定没有在代码里使用异常,那么尝试在编译开关里加入-fno-exceptions。
[/Quote]

THX~~
系统内核是Linux 2.36.2,/bin下有libpthread.so

没有个SDK开发程序太麻烦了。
准备学QT,用QT写程序。

再次多谢你的回答~
xunxun 2011-08-10
  • 打赏
  • 举报
回复
第一个可能原因是pthread的问题
看看你用的arm工具链的pthread库是否正确复制到目标机里了
如果不是系统路径,链接时使用-Wl,-rpath=... -Wl,--dyanmic-linker=...来确定路径

第二个可能原因是有的嵌入式系统不支持异常,这也是1L的说法
如果你确定没有在代码里使用异常,那么尝试在编译开关里加入-fno-exceptions。
qq361301276 2011-08-10
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 jernymy 的回复:]

楼主是使用的arm编译器是哪个?
terminate called after throwing an instance of '__gnu_cxx::__concurrence_broadcast_error'

这样的错误之前俺也遇到过。
问题是程序编译通过,但是运行是来main函数都没有跑到,然后就抛出异常了。
后来查明是该编译器对stl的支持不好,所以将
C/C++ code……
[/Quote]

不是吧?那岂不是string 那些要用char*来代替?
我试试~
非常多谢你的回帖!!
jernymy 2011-08-09
  • 打赏
  • 举报
回复
楼主是使用的arm编译器是哪个?
terminate called after throwing an instance of '__gnu_cxx::__concurrence_broadcast_error'

这样的错误之前俺也遇到过。
问题是程序编译通过,但是运行是来main函数都没有跑到,然后就抛出异常了。
后来查明是该编译器对stl的支持不好,所以将

<iostream>
<string>
using namespace std;

去掉后,就好了
楼主可以尝试一下,因为arm有编译器局限性还是有的

23,215

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧