futurebigniu 发表于 2014-09-21 15:54

访问/dev/ttyS0并且读写数据,一块2440采用ssh可以,pcduino板上无法实现

本帖最后由 futurebigniu 于 2014-09-21 15:55 编辑

//串口信息结构体
typedef struct tty_info_t
{
                int fd;//设备id
                pthread_mutex_t mt;//互斥锁
                char name;//串口设备文件名,如/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 = 0;
                ptty->ntm.c_cc = 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 = {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, 8);
                        printf("write = %d, %s\n", nread, buff);

                        nread = recvnTTY(ptty, buff1, 8);
                        printf("read =%d, %s\n", nread, buff1);
                        j--;
                }


                cleanTTY(ptty);
                return 0;
}
代码如上所示,配置的串口波特率115200,8个数据位,无校验,1个停止位,在这个函数里1和2这两句无法正常打印,除非在1后面加上一个sleep函数才可以完整打印出,3和4无法打印出来,接下来对ttyS0读写也无法实现,一直在阻塞中,请问是什么问题?在2440板子上跑过程序,没问题的,

调皮的小五郎 发表于 2014-09-21 17:21


http://www.zxmh.net/html/book10/


随便看看,不发表意见
页: [1]
查看完整版本: 访问/dev/ttyS0并且读写数据,一块2440采用ssh可以,pcduino板上无法实现