- 论坛徽章:
- 0
|
本帖最后由 futurebigniu 于 2014-09-21 15:55 编辑
//串口信息结构体
typedef struct tty_info_t
{
int fd;//设备id
pthread_mutex_t mt;//互斥锁
char name[24];//串口设备文件名,如/dev/ttys0
struct termios ntm;//新串口设备选项
struct termios otm;//旧串口设备选项
}TTY_INFO;
//初始化串口设备并进行原有设置的保存
TTY_INFO *readyTTY(int id)
{
TTY_INFO *ptty = (TTY_INFO*)malloc(sizeof(TTY_INFO));
if (ptty == NULL)
{
printf("malloc TTY_INFO error\n" ;
return NULL;
}
memset(ptty, 0, sizeof(TTY_INFO));
//pthread_mutex_init(&ptty->mt, NULL);
sprintf(ptty->name, "/dev/ttyS%d", id);
printf("ttyname:%s\n",ptty->name);。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。1
//打开串口
ptty->fd = open(ptty->name, O_RDWR | O_NDELAY | O_NOCTTY);
printf("fd:%d\n",ptty->fd);.。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。2
if (ptty->fd < 0)
{
printf("open error\n" ;
free(ptty);
ptty = NULL;
return NULL;
}
//取得并且保存原来的设置
if(tcgetattr(ptty->fd, &ptty->otm) == -1)
{
perror("tcgetattr otm" ;
return NULL;
}
return ptty;
}
//清理串口设备资源
int cleanTTY(TTY_INFO *ptty)
{
if(ptty->fd > 0)
{
if(tcsetattr(ptty->fd, TCSANOW, &ptty->otm) != 0)
{
perror("tcsetattr error" ;
return 1;
}
close(ptty->fd);//关闭设备
free(ptty);
ptty = NULL;
}
return 0;
}
int setTTYSpeed(TTY_INFO *ptty, int speed)
{
int i = 0;
bzero(&ptty->ntm, sizeof(ptty->ntm));
if(tcgetattr(ptty->fd, &ptty->ntm) != 0)
{
perror("tcgetattr ntm" ;
return 1;
}
ptty->ntm.c_cflag = CLOCAL | CREAD;//终端硬件使用接收器,忽略调制解调器线路状态
switch(speed)
{
case 300:
ptty->ntm.c_cflag |= B300;//?
break;
case 1200:
ptty->ntm.c_cflag |= B1200;
break;
case 2400:
ptty->ntm.c_cflag |= B2400;
break;
case 4800:
ptty->ntm.c_cflag |= B4800;
break;
case 9600:
ptty->ntm.c_cflag |= B9600;
break;
case 19200:
ptty->ntm.c_cflag |= B19200;
break;
case 38400:
ptty->ntm.c_cflag |= B38400;
break;
case 115200:
ptty->ntm.c_cflag |= B115200;
break;
default:
break;
}
ptty->ntm.c_iflag = IGNPAR;//控制终端输入忽略奇偶校验错误
ptty->ntm.c_oflag = 0;//?
tcflush(ptty->fd, TCIFLUSH);//清除正接收到的数据且不会读取出来
if(tcsetattr(ptty->fd, TCSANOW, &ptty->ntm) != 0)
{
perror("tcsetattr ntm" ;
return 1;
}
return 0;
}
//设置串口数据位,停止位和校验位
int setTTYParity(TTY_INFO *ptty, int databits, char parity, int stopbits)
{
if(tcgetattr(ptty->fd, &ptty->ntm) != 0)
{
printf("SetupSerial %s\n", ptty->name);
return 1;
}
//设置串口参数
bzero(&ptty->ntm, sizeof(ptty->ntm));
ptty->ntm.c_cflag = CLOCAL | CREAD;
ptty->ntm.c_iflag = IGNPAR;
ptty->ntm.c_cflag &= ~CSIZE;
switch(databits)
{
case 7:
ptty->ntm.c_cflag |= CS7;
break;
case 8:
ptty->ntm.c_cflag |= CS8;
break;
default:
printf("Unsupported databits\n" ;
return 5;
}
//设置奇偶校验位
switch(parity)
{
case 'n':
case 'N'://无校验
ptty->ntm.c_cflag &= ~PARENB;
ptty->ntm.c_iflag &= ~INPCK;
break;
case 'o':
case 'O'://奇校验
ptty->ntm.c_cflag |= PARODD | PARENB;
ptty->ntm.c_iflag |= INPCK;
break;
case 'e':
case 'E'://偶校验
ptty->ntm.c_cflag |= PARENB;
ptty->ntm.c_cflag &= ~PARODD;
ptty->ntm.c_iflag |= INPCK;
break;
case 's':
case 'S':
ptty->ntm.c_cflag &= ~PARENB;
ptty->ntm.c_cflag &= ~CSTOPB;
break;
default:
printf("Unsupported parity\n" ;
return 2;
}
switch(stopbits)
{
case 1:
ptty->ntm.c_cflag &= ~CSTOPB;
break;
case 2:
ptty->ntm.c_cflag |= CSTOPB;
break;
default:
printf("UNsupported stop bits\n" ;
return 3;
}
ptty->ntm.c_lflag = 0;
ptty->ntm.c_cc[VTIME] = 0;
ptty->ntm.c_cc[VMIN] = 1;
tcflush(ptty->fd, TCIFLUSH);
if(tcsetattr(ptty->fd, TCSANOW, &ptty->ntm) != 0)
{
return 1;
}
return 0;
}
int recvnTTY(TTY_INFO *ptty, char *pbuf, int size)
{
int ret = 0, bytes = 0;
int left = size;
while(left > 0)
{
ret = 0;
bytes = 0;
//pthread_mutex_lock(&ptty->mt);
ioctl(ptty->fd, FIONREAD, &bytes);
if(bytes > 0)
{
ret = read(ptty->fd, pbuf, left);
}
if(ret > 0)
{
left -= ret;
pbuf += ret;
}
}
return size;
}
int sendnTTY(TTY_INFO *ptty, char *pbuf, int size)
{
int ret = 0, nleft = size;
char *ptemp = pbuf;
while(nleft > 0)
{
//pthread_mutex_lock(&ptty->mt);
ret = write(ptty->fd, ptemp, nleft);
//pthread_mutex_unlock(&ptty->mt);
if(ret > 0)
{
nleft -= ret;
ptemp += ret;
}
}
return size;
}
int lockTTY(TTY_INFO *ptty)
{
if(ptty->fd < 0)
return 1;
return flock(ptty->fd, LOCK_EX);
}
int unlockTTY(TTY_INFO *ptty)
{
if(ptty->fd < 0)
return 1;
return flock(ptty->fd, LOCK_UN);
}
int main(void)
{
char *buff = "hello";
char buff1[8] = {0};
int j = 10;
TTY_INFO *ptty = readyTTY(0);
if(ptty == NULL)
{
printf("readytty error\n" ;
return 1;
}
//lockTTY(ptty);
/*
if(setTTYSpeed(ptty, 115200) > 0)
{
printf("setTTYSpeed\n");。。。。。。。。。。。。。。。。。。。。。。。。。。。。。3
printf("setTTYSpeed error\n");
return 1;
}
if(setTTYParity(ptty, 8, 'N', 1) > 0)
{
printf("setTTYParity\n");.。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。4
printf("setTTYParity error\n");
return 1;
}
*/
while(j)
{
printf("send and recv\n");
int nread = sendnTTY(ptty, buff, ;
printf("write = %d, %s\n", nread, buff);
nread = recvnTTY(ptty, buff1, ;
printf("read =%d, %s\n", nread, buff1);
j--;
}
cleanTTY(ptty);
return 0;
}
代码如上所示,配置的串口波特率115200,8个数据位,无校验,1个停止位,在这个函数里1和2这两句无法正常打印,除非在1后面加上一个sleep函数才可以完整打印出,3和4无法打印出来,接下来对ttyS0读写也无法实现,一直在阻塞中,请问是什么问题?在2440板子上跑过程序,没问题的, |
|