📄 commserial.c
字号:
#include "CommSerial.h"
/******************************************************************************/
const int speed_arr[] = {B460800, B230400, B115200, B38400, B19200, B9600, B4800, B2400, B1200, B600, B300,};
const int name_arr[] = {460800, 230400, 115200, 38400, 19200, 9600, 4800, 2400, 1200, 600, 300,};
static HANDLE g_hPort;
/*
* set baudrate
*/
int set_speed(int fd, int speed)
{
int i;
int status;
struct termios Opt;
tcgetattr(fd, &Opt);
for (i = 0; i < sizeof(speed_arr) / sizeof(int); i++)
{
if (speed == name_arr[i])
{
tcflush(fd, TCIOFLUSH);
cfsetispeed(&Opt, speed_arr[i]);
cfsetospeed(&Opt, speed_arr[i]);
status = tcsetattr(fd, TCSANOW, &Opt);
if (status != 0)
return false;
else
return true;
}
}
return false;
}
/*
* set databits, stopbits and parity
*/
int set_parity(int fd, int databits, int stopbits, int parity)
{
struct termios options;
if (tcgetattr(fd, &options) != 0)
return false;
options.c_cflag &= ~CSIZE;
/* set databits */
switch (databits)
{
case 7:
options.c_cflag |= CS7;
break;
case 8:
options.c_cflag |= CS8;
break;
default:
return false;
}
/* set parity */
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;
default:
return false;
}
/* set stopbits */
switch (stopbits)
{
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
return false;
}
/* set input parity option */
if (parity != 'n')
options.c_iflag |= INPCK;
options.c_cc[VTIME] = 150; /* 15 seconds */
options.c_cc[VMIN] = 0;
/* add by baiwei */
options.c_cflag |= (CLOCAL | CREAD);
options.c_iflag &= ~(INLCR | ICRNL );
options.c_iflag &= ~(IXON | IXOFF | IXANY );
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_oflag &= ~OPOST;
tcflush(fd, TCIFLUSH); /* update the options and do it now */
if (tcsetattr(fd, TCSANOW,&options) != 0)
return false;
return true;
}
/*
* open device file
*/
int openComDevFile(char* com, int* fd)
{
*fd = open(com, O_RDWR); /*| O_NOCTTY | O_NDELAY */
if (-1 == *fd)
{
perror( "open serial error:" );
return false;
}
else
return true;
}
/*
* receive thread
*/
void* RcvThrdProc(void* arg)
{
int num;
BYTE buf [512];
SERIALPORTINFO* spi;
spi = (SERIALPORTINFO*) arg;
while (1)
{
while ((num = read(spi->fd, buf, sizeof(buf)/sizeof(BYTE) - 1)) > 0)
{
spi->rcvTick++;
buf [num] = 0;
if (spi->fnOnReceive)
spi->fnOnReceive(spi->userData, buf, num);
}
Sleep(10);
}
}
BOOL SerialPortIsOpen()
{
SERIALPORTINFO* info = (SERIALPORTINFO*) g_hPort;
if (info==NULL)
return false;
return info->isOpen;
}
int SerialPortOpen(SERIALPORT* sp, RCVCALLBACK fnOnReceive, void* userData,int mode)
{
SERIALPORTINFO* spi;
int fd;
//char dev [256];
pthread_attr_t attr;
g_hPort = malloc( sizeof(SERIALPORTINFO) );
if (g_hPort==NULL)
return 6;
memset( g_hPort, 0, sizeof(SERIALPORTINFO) );
spi = (SERIALPORTINFO*) g_hPort;
/* if (sp->com == 1 || sp->com == 2)
sprintf(dev, "/dev/ttyS%d", sp->com - 1);
else
sprintf(dev, "/dev/ttyM%d", sp->com - 3);
*/
//sprintf(dev, "/dev/usb/tts/%d", sp->com); // 07.03.2008
//printf("Input serial port(/dev/usb/tts/): ");
//scanf( "%s", dev);
//strcpy( dev, sp->scom );
if (false == openComDevFile(sp->scom, &fd))
return -1;
//printf("serial fd:%d\n", fd);
// rs232/422/485
// ioctl(fd, 0x9000, &mode);
// set_link_mode(sp->com,mode);
if (false == set_speed(fd, sp->baudrate))
{
close(fd);
perror("set_speed error");
return -2;
}
if (false == set_parity(fd, sp->databits, sp->stopbits, sp->parity))
{
close(fd);
perror("set_parity error");
return -3;
}
spi->fd = fd;
spi->fnOnReceive = fnOnReceive;
spi->userData = userData;
pthread_attr_init(&attr);
pthread_attr_setschedpolicy(&attr, 1);
if (pthread_create(&spi->tid, &attr, RcvThrdProc, spi) != 0)
{
close(fd);
return -4;
}
if (pthread_detach(spi->tid) != 0)
{
close(fd);
/* to add */
return -5;
}
spi->isOpen = true;
return 0;
}
void SerialPortClose()
{
SERIALPORTINFO* spi = (SERIALPORTINFO*) g_hPort;
if ( spi==NULL )
return;
if (spi->isOpen)
{
/* to add */
close(spi->fd);
spi->isOpen = false;
}
free( g_hPort );
}
int SerialPortSend(BYTE* buf, int len)
{
SERIALPORTINFO* spi;
int writeNum;
if ( buf==NULL || len<=0 )
return -1;
spi = (SERIALPORTINFO*) g_hPort;
writeNum = 0;
//printf("spi->isOpen:%d, spi->fd:%d\n", spi->isOpen, spi->fd);
if (spi->isOpen)
writeNum = write(spi->fd, buf, len);
if ( writeNum<=0 )
perror("send data to serial error:");
return writeNum;
}
void SerialPortSetRcvTicker(UINT tick)
{
SERIALPORTINFO* info = (SERIALPORTINFO*) g_hPort;
info->rcvTick = tick;
}
UINT SerialPortGetRcvTicker()
{
SERIALPORTINFO* info = (SERIALPORTINFO*) g_hPort;
return info->rcvTick;
}
static BOOL IsBadWritePtr(void* ptr, int len)
{
if (ptr == NULL)
return TRUE;
return FALSE;
}
static BOOL IsBadStringPtr(void* ptr, int len)
{
if (ptr == NULL)
return TRUE;
return FALSE;
}
static int find_char(char* string, char ch, int* pos, int sizePosBuf)
{
char* head = string;
char* dest = NULL;
int len = strlen(string);
int n = 0;
while ((dest = strchr(head, ch)) != NULL)
{
if (n > sizePosBuf - 1)
break;
if ((pos[n++] = dest - string) == len - 1)
break;
else
head = dest + 1;
}
return n;
}
int ParseSerialCommParaStr(char* para, SERIALPORT* port)
{
int len, commaPos[10];
char tmp[64] = {0};
if ( para==NULL || port==NULL )
return 6;
if (IsBadStringPtr(para, 1) || IsBadWritePtr(port, sizeof(SERIALPORT)))
return 1;
len = strlen(para);
if (len >= 64)
return 3;
if (4 != find_char(para, ',', commaPos, 10))
return 4;
memcpy( port->scom, para, commaPos[0]);
Pt("port->scom=%s\n", port->scom);
//port->com = atoi(tmp);
memset(tmp, 0, 64);
memcpy(tmp, para + commaPos[0] + 1, commaPos[1] - commaPos[0] - 1);
port->baudrate = atoi(tmp);
memset(tmp, 0, 64);
memcpy(tmp, para + commaPos[1] + 1, commaPos[2] - commaPos[1] - 1);
port->databits = atoi(tmp);
memset(tmp, 0, 64);
memcpy(tmp, para + commaPos[2] + 1, commaPos[3] - commaPos[2] - 1);
port->stopbits = atoi(tmp);
memset(tmp, 0, 64);
strcpy(tmp, para + commaPos[3] + 1);
if (tmp[0] == 'n' || tmp[0] == 'N' || tmp[0] == 'o' || tmp[0] == 'O' || tmp[0] == 'e' || tmp[0] == 'E')
port->parity = tmp[0];
else
return 5;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -