/*
* File: BSerialPort.h
*/
#ifndef BSERIALPORT_H
#define BSERIALPORT_H
class BSerialPort {
public:
friend class BSerialPortManger;
enum SerialType{
Actual, Virtual,
};
BSerialPort();
BSerialPort(const BSerialPort& orig);
BSerialPort(char *filename, SerialType type = Actual);
BSerialPort(const char *filename, SerialType type = Actual);
virtual ~BSerialPort();
/*
* 参数: 串口设备文件路径
* 功能:打开串口,默认设置串口设备参数:9600,N,1
* 返回值:成功 true ; 失败 false
*/
bool open(char *filename);
/*
* 参数: 串口波特率
* 功能: 设置串口模特率,可以是下面的一个值
* 921600, 460800, 230400, 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200, 300
* 返回值: 成功 true ; 失败 false
*/
bool set_Speed(int speed);
/*
* 参数: databits:数据位数
* stopbits:停止位
* parity: 校验位
* 功能: 设置串口的数据位、停止位、校验位。
* 返回值: 成功 true ; 失败 false
*/
bool set_Parity(int databits, int stopbits, char parity);
/*
* 参数:dest:数据读取缓存数组
* bytes:要读取数据的字节数
* 功能:从串口读取数据存储在dest中
* 返回值:实际读取数据字节数,出错返回-1。
*/
int read(char *dest, int bytes);
/*
* 参数:buff:要写入的数据
* bytes:要写入数据的字节数
* 功能:将buff中的数据写入串口
* 返回值:实际写入数据字节数,出错返回-1。
*/
int write(char *buff, int bytes);
/*关闭串口*/
void close(void);
bool operator==(BSerialPort &serial);
private:
/*串口文件描述符*/
int fd;
/*如果是虚拟串口,从设备的文件描述符*/
int sfd;
void (*function)(BSerialPort *serial);
};
#endif /* BSERIALPORT_H */
/*
* File: BSerialPortManger.h
*/
#ifndef BSERIALPORTMANGER_H
#define BSERIALPORTMANGER_H
#include "BSerialPort.h"
#include <vector>
#include <string>
#include <unistd.h>
#include <sys/time.h>
#include <iostream>
using namespace std;
class BSerialPortManger {
public:
BSerialPortManger();
BSerialPortManger(const BSerialPortManger& orig);
virtual ~BSerialPortManger();
/*向串口管理类中添加一个待监控的串口*/
void add(BSerialPort *serial, void (*func)(BSerialPort *serial));
/*从管理类中移除一个串口*/
void remove(BSerialPort *serial);
/*每调用一次,检查一次是否有串口数据到达*/
void read_monitor();
private:
vector<BSerialPort *> list;
int fd_max;
fd_set fd_sets;
fd_set handle_sets;
};
#endif /* BSERIALPORTMANGER_H */
上面我定义了两个类,一个是串口类一个是串口管理类。BSerialPortManger类是BSerialPort的友元类,这样利用BSerialPortManger就能管理所以注册到该类的串口对象,如果有可读数据就调用对应对象的回调函数。
下面展示BSerialPortManger::add的实现
void BSerialPortManger::add(BSerialPort* serial, void (*func)(BSerialPort *serial)){
serial->function = func;
if(serial->fd > 0){
FD_SET(serial->fd, &this->handle_sets);
this->list.push_back(serial);
this->fd_max = 0;
cout << "list_count:" << this->list.size()<<endl;
for(int i = 0; i < this->list.size(); i++){
if(this->list.at(i)->fd > this->fd_max)
this->fd_max = this->list.at(i)->fd;
}
}
}
监控函数的实现是利用select函数来监控所以注册的串口对象是否有数据要读取,如果有则调用相应的回调函数。
void BSerialPortManger::read_monitor(){
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 100000;
this->fd_sets = this->handle_sets;
int rs = select(this->fd_max+1, &this->fd_sets, NULL, NULL, &timeout);
if(rs > 0){
for(int i = 0; i < this->list.size(); i++){
if(FD_ISSET(this->list.at(i)->fd, &this->fd_sets) && this->list.at(i)->function != NULL){
this->list.at(i)->function(this->list.at(i));
}
}
}
}
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是一个个人学习交流的平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽,造成漏登,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。