硬件平台: MT7620
程序包含:main.cpp; uart.cpp; uart.h
uart.h
#ifndef UART_H_
#define UART_H_
#include
#include
#include
#include
#include
#include
#include
#include
#include
typedef std::string String;
enum FlowControl
{
FLOW_CONTROL_HARD, FLOW_CONTROL_SOFT, FLOW_CONTROL_NONE,
};
struct tagUARTParam
{
String dev;
int baudRate;
int dataBits;
char parity;
int stopBits;
FlowControl flowControl;
};
class CUART
{
public:
CUART();
virtual ~CUART();
bool open(tagUARTParam& param);
int send(char* buf, int len, int timeout);
int recv(char* buf, int len, int timeout);
void close();
private:
bool setBaudRate(int baudRate);
bool setParity(int parity);
bool setDataBits(int dataBits);
bool setStopBits(int stopBits);
bool setFlowControl(FlowControl flowControl);
private:
/** Character used to signal that I/O can start while using
software flow control with the serial port.
*/
static const char CTRL_Q = 0x11;
/** Character used to signal that I/O should stop while using
software flow control with the serial port.
*/
static const char CTRL_S = 0x13;
int serialfd_;
};
#endif /* SERIALPORT_H_ */
#include
#include
#include
#include
#include
#include "memmap.h"
#include "hi.h"
#include "strfunc.h"
#include "uart.h"
static tagUARTParam UartParam =
{ "/dev/ttyAMA1", 9600, 8, 'N', 1, FLOW_CONTROL_NONE };
CUART mUartItem;
bool mvUartState;
pthread_t m_thread2Handle;
char rcv[512];
void *ConnectStart(void *param)
{
//pthread_mutex_lock(&DialMutex);
//GprsPowerEn(GPIO_CTR_OFF);
//sleep(10);
int ret =0;
while(1)
{
ret = 0;
memset(rcv,0,512);
ret = mUartItem.recv(rcv,512,500);
if(ret > 0)
{
printf("Data >> %s",rcv);
}
printf("[david]printf ConnectStart!!!\n");
sleep(1);
}
return NULL;
}
int main(int argc, char * argv[])
{
mvUartState =false;
//return tmain(argc, argv);
mvUartState = mUartItem.open(UartParam);
if(mvUartState)
{
printf("[david]uart open is ok\n");
pthread_create(&m_thread2Handle,0,ConnectStart,NULL);
}
while(1)
{
sleep(1);
}
return 0;
}
#include
#include
#include
#include "uart.h"
CUART::CUART()
{
serialfd_ = -1;
}
CUART::~CUART()
{
close();
}
bool CUART::open(tagUARTParam& param)
{
serialfd_ = ::open(param.dev.c_str(), O_RDWR|O_NOCTTY);
struct termios opt;
if (-1 == tcgetattr(serialfd_, &opt))
{
return false;
}
cfmakeraw(&opt);
if (-1 == tcsetattr(serialfd_, TCSANOW, &opt))
{
return false;
}
if (!setBaudRate(param.baudRate))
{
close();
return false;
}
if (!setParity(param.parity))
{
close();
return false;
}
if (!setDataBits(param.dataBits))
{
close();
return false;
}
if (!setStopBits(param.stopBits))
{
close();
return false;
}
if (!setFlowControl(param.flowControl))
{
close();
return false;
}
return true;
}
void CUART::close()
{
::close(serialfd_);
serialfd_ = -1;
}
speed_t getBaudRate(int speed)
{
static struct
{
int speed;
speed_t val;
} Map[] =
{
{ 115200, B115200 },
{ 57600, B57600 },
{ 38400, B38400 },
{ 19200, B19200 },
{ 9600, B9600 },
{ 4800, B4800 },
{ 2400, B2400 },
{ 1200, B1200 },
{ 300, B300 } };
unsigned int i;
for (i = 0; i < sizeof(Map) / sizeof(Map[0]); i++)
{
if ((speed == Map[i].speed))
{
return Map[i].val;
}
}
return B9600;
}
bool CUART::setBaudRate(int baudRate)
{
struct termios opt;
if (serialfd_ == -1)
{
return false;
}
if (-1 == tcgetattr(serialfd_, &opt))
{
return false;
}
speed_t s = getBaudRate(baudRate);
tcflush(serialfd_, TCIOFLUSH);
cfsetispeed(&opt, s);
cfsetospeed(&opt, s);
if (-1 == tcsetattr(serialfd_, TCSANOW, &opt))
{
return false;
}
return true;
}
bool CUART::setParity(int parity)
{
if (-1 == serialfd_)
{
return false;
}
struct termios options;
if (tcgetattr(serialfd_, &options) != 0)
{
return false;
}
switch (parity)
{
case 'n':
case 'N':
options.c_cflag &= ~PARENB;
options.c_iflag &= ~INPCK;
break;
case 'o':
case 'O':
options.c_cflag |= (PARODD | PARENB);
options.c_iflag |= INPCK;
break;
case 'e':
case 'E':
options.c_cflag |= PARENB;
options.c_cflag &= ~PARODD;
options.c_iflag |= INPCK;
break;
case 'S':
case 's':
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
break;
default:
return false;
break;
}
if (-1 == tcsetattr(serialfd_, TCSANOW, &options))
{
return false;
}
return true;
}
bool CUART::setDataBits(int dataBits)
{
if (-1 == serialfd_)
{
return false;
}
struct termios options;
if (tcgetattr(serialfd_, &options) != 0)
{
return -1;
}
options.c_cflag &= ~CSIZE;
switch (dataBits)
{
case 7:
options.c_cflag |= CS7;
break;
case 8:
options.c_cflag |= CS8;
break;
default:
return false;
break;
}
if (-1 == tcsetattr(serialfd_, TCSANOW, &options))
{
return false;
}
return true;
}
bool CUART::setStopBits(int stopBits)
{
if (-1 == serialfd_)
{
return false;
}
struct termios options;
if (tcgetattr(serialfd_, &options) != 0)
{
return false;
}
switch (stopBits)
{
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
return false;
break;
}
if (-1 == tcsetattr(serialfd_, TCSANOW, &options))
{
return false;
}
return true;
}
bool CUART::setFlowControl(FlowControl flowControl)
{
if (-1 == tcflush(serialfd_, TCIOFLUSH))
{
return false;
}
struct termios tset;
int retval = tcgetattr(serialfd_, &tset);
if (-1 == retval)
{
return false;
}
if (FLOW_CONTROL_HARD == flowControl)
{
tset.c_iflag &= ~(IXON | IXOFF);
tset.c_cflag |= CRTSCTS;
tset.c_cc[VSTART] = _POSIX_VDISABLE;
tset.c_cc[VSTOP] = _POSIX_VDISABLE;
}
else if (FLOW_CONTROL_SOFT == flowControl)
{
tset.c_iflag |= IXON | IXOFF;
tset.c_cflag &= ~CRTSCTS;
tset.c_cc[VSTART] = CTRL_Q;
tset.c_cc[VSTOP] = CTRL_S;
}
else
{
tset.c_iflag &= ~(IXON | IXOFF);
tset.c_cflag &= ~CRTSCTS;
}
retval = tcsetattr(serialfd_, TCSANOW, &tset);
if (-1 == retval)
{
return false;
}
return true;
}
int CUART::send(char* buf, int len, int timeout)
{
struct timeval tv;
tv.tv_sec = timeout / 1000; //SECOND
tv.tv_usec = (timeout % 1000) * 1000; //USECOND
int ret;
fd_set writefd;
FD_ZERO(&writefd);
FD_SET(serialfd_, &writefd);
ret = select(serialfd_ + 1, NULL, &writefd, NULL, &tv);
if (ret < 0)
{
return ret;
}
if (ret == 0)
{
return 0;
}
if (FD_ISSET(serialfd_, &writefd))
{
return write(serialfd_, buf, len);
}
return 0;
}
int CUART::recv(char* buf, int len, int timeout)
{
int ret;
struct timeval tv;
tv.tv_sec = timeout / 1000; //SECOND
tv.tv_usec = (timeout % 1000) * 1000; //USECOND
fd_set readfd;
FD_ZERO(&readfd);
FD_SET(serialfd_, &readfd);
ret = select(serialfd_ + 1, &readfd, NULL, NULL, &tv);
if (ret > 0 && FD_ISSET(serialfd_, &readfd))
{
return read(serialfd_, buf, len);
}
return 0;
}
注:代码需要根据相应平台做些修改,下面的结果是我根据自己的平台定制的,经测试可行,无BUG,结果如下: