转自:http://www.cnblogs.com/darryo/p/selectpollepoll-on-serial-port.html

In this article, I will use three asynchronous conferencing--select, poll and epoll on serial port to transmit data between PC and Raspberry pi.


Outline

  1. Character device file of serial port
  2. Naive serial communication
  3. Asynchronous conferencing
  4. Select
  5. Poll
  6. Epoll

Character device of serial port

My device is Raspberry pi with debian system and PC with ubuntu12.04 system.

And I have used a USB-TTL to link the these device.

The character device files on the two device is :

/dev/ttyUSB0 #Ubuntu

/dev/ttyAMA0 #Debian Raspberry pi

These two files are what we must use to achieve the lab.

But there is a little trap of /dev/ttyAMA0.

By default, Raspberry pi uses /dev/ttyAMA0 as a output of serial. Therefor we could use minicom or putty to control our device. However, we have to modify the default function of serial, since we will use our own method to use serial port.

So we should modify two files:

/boot/comdline.txt

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 rootfstype=ext4 elevator=deadline rootwait console=tty1 root=/dev/mmcblk0p2

Delete console=ttyAMA0,115200

/etc/inittab

T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

Comment the line above.


Now, start to code:

Naive version

The naive serial port communication version

Open the device, set the baud rate, and set parity

#include     <stdio.h>      /*标准输入输出定义*/
#include <string.h>
#include <stdlib.h> /*标准函数库定义*/
#include <unistd.h> /*Unix标准函数定义*/
#include <sys/types.h> /**/
#include <sys/stat.h> /**/
#include <fcntl.h> /*文件控制定义*/
#include <termios.h> /*PPSIX终端控制定义*/
#include <errno.h> /*错误号定义*/
#define FALSE 0
#define TRUE 1 void set_speed(int fd) {
struct termios Opt;
tcgetattr(fd, &Opt);
cfsetispeed(&Opt,B115200);
cfsetospeed(&Opt,B115200);
tcsetattr(fd,TCSANOW,&Opt);
return;
} void set_Parity(int fd) {
struct termios options;
tcgetattr(fd, &options);
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/
options.c_oflag &= ~OPOST; /*Output*/
tcsetattr(fd,TCSANOW,&options);
return;
} int OpenSerial(char *Dev) {
int fd = open( Dev, O_RDWR ); //| O_NOCTTY | O_NDELAY
if (- == fd) { /*设置数据位数*/
perror("Can't Open Serial Port");
return -;
}
else {
set_speed(fd);
set_Parity(fd);
return fd;
} } int main(){
int fd;
ssize_t length;
char buff[];
char *dev ="/dev/ttyAMA0";
fd = OpenSerial(dev);
for(;;){
length = read(fd,buff,sizeof(buff));
if(length > ) {
buff[length] = ;
printf("plain:%s\n",buff);
}
}
close(fd);
exit();
}

Select version

#include <sys/time.h>
#include <sys/types.h>
#include "serial/serial.h" int main() {
int fd;
fd_set rfds;
struct timeval tv;
char buff[];
ssize_t length;
fd = OpenSerial("/dev/ttyAMA0"); for(;;) {
FD_ZERO(&rfds);
FD_SET(fd, &rfds); //timeout = 5s
tv.tv_sec = ;
tv.tv_usec = ;
//Wait for 5 seconds, then go
int n;
n = select(fd + , &rfds, NULL, NULL, &tv);
//choose the target from set
if(n > ) {
if (FD_ISSET(fd, &rfds)) {
length = read(fd, &buff, sizeof(buff));
buff[length] = ;
printf("select:%s\n", buff);
}
} else {
printf("No data within 5 seconds.\n");
}
}
return ;
}

Poll version

#include <sys/poll.h>
#include "serial/serial.h"
int main(void) {
struct pollfd fds[];
ssize_t length;
char buff[];
fds[].fd = OpenSerial("/dev/ttyAMA0");
fds[].events = POLLIN ;
for(;;) {
int n;
n = poll( fds, , );
//got data, and look up which fd has data, but we just have 1
if(n > ) {
//if( fds[0].revents & POLLIN ) {
length = read(fds[].fd, buff, sizeof(buff) );
buff[length] = ;
printf("poll:%s\n",buff); } else {
printf("No data within 5 seconds.\n");
}
}
}

Epoll version

#include <sys/epoll.h>
#include "serial/serial.h" #define MAXEVENTS 64 int main(void){
int fd;
int efd;
struct epoll_event event;
struct epoll_event *events;
int length;
char buff[];
fd = OpenSerial("/dev/ttyAMA0");
efd = epoll_create1 ();//initial is 0 event.data.fd = fd;
event.events = EPOLLIN | EPOLLET; epoll_ctl (efd, EPOLL_CTL_ADD, fd, &event);
/* Buffer where events are returned */
events = calloc (MAXEVENTS, sizeof event); /* The event loop */
for(;;) {
int n;
n = epoll_wait (efd, events, MAXEVENTS, );
if(n > ) {
length = read(events[].data.fd, buff, sizeof(buff)); if(length > ) {
buff[length] = ;
printf("epoll:%s\n", buff);
}
} else {
printf("No data whthin 5 seconds.\n");
}
}
free (events);
close (fd);
return ;
}

[serial]基于select/poll/epoll的串口操作的更多相关文章

  1. Python异步非阻塞IO多路复用Select/Poll/Epoll使用,线程,进程,协程

    1.使用select模拟socketserver伪并发处理客户端请求,代码如下: import socket import select sk = socket.socket() sk.bind((' ...

  2. 转一贴,今天实在写累了,也看累了--【Python异步非阻塞IO多路复用Select/Poll/Epoll使用】

    下面这篇,原理理解了, 再结合 这一周来的心得体会,整个框架就差不多了... http://www.haiyun.me/archives/1056.html 有许多封装好的异步非阻塞IO多路复用框架, ...

  3. select/poll/epoll on serial port

    In this article, I will use three asynchronous conferencing--select, poll and epoll on serial port t ...

  4. 多进程、协程、事件驱动及select poll epoll

    目录 -多线程使用场景 -多进程 --简单的一个多进程例子 --进程间数据的交互实现方法 ---通过Queues和Pipe可以实现进程间数据的传递,但是不能实现数据的共享 ---Queues ---P ...

  5. select,poll,epoll的归纳总结区分

    Select.Poll与Epoll比较 以下资料都是来自网上搜集整理.引用源详见文章末尾. 1 Select.Poll与Epoll简介 Select select本质上是通过设置或者检查存放fd标志位 ...

  6. Select\Poll\Epoll异步IO与事件驱动

    事件驱动与异步IO 事件驱动编程是一种编程规范,这里程序的执行流由外部事件来规定.它的特点是包含一个事件循环,但外部事件发生时使用回调机制来触发响应的处理.另外两种常见的编程规范是(单线程)同步以及多 ...

  7. I/O多路复用之select,poll,epoll简介

    一.select 1.起源 select最早于1983年出现在4.2BSD中(BSD是早期的UNIX版本的分支). 它通过一个select()系统调用来监视多个文件描述符的数组,当select()返回 ...

  8. Linux 网络编程的5种IO模型:多路复用(select/poll/epoll)

    Linux 网络编程的5种IO模型:多路复用(select/poll/epoll) 背景 我们在上一讲 Linux 网络编程的5种IO模型:阻塞IO与非阻塞IO中,对于其中的 阻塞/非阻塞IO 进行了 ...

  9. 哪5种IO模型?什么是select/poll/epoll?同步异步阻塞非阻塞有啥区别?全在这讲明白了!

    系统中有哪5种IO模型?什么是 select/poll/epoll?同步异步阻塞非阻塞有啥区别? 本文地址http://yangjianyong.cn/?p=84转载无需经过作者本人授权 先解开第一个 ...

随机推荐

  1. iOS Terminating app due to uncaught exception &#39;NSInternalInconsistencyException&#39;, reason: &#39;unable to

    刚接触iOS,依照教程操作执行出现错误 Terminating app due to uncaught exception 'NSInternalInconsistencyException', re ...

  2. java 传址或传值

    原文链接: http://blog.csdn.net/jdluojing/article/details/6962893 java是传值还是传址,这个问题已经讨论了很久了,有些人说是传值的,有些人说要 ...

  3. 如何提升RDS响应速度

    如果采用短连接的方式连接RDS,请在与RDS相连的云服务器上执行以下命令来提升RDS响应速度.(注:云服务器要有公网带宽) 1.安装nscd 云服务器上执行命令 Ubuntu系统执行:apt-get  ...

  4. PyCharm黄色波浪线提示: Simplify chained comparison

    译过来就是,可简化连锁比较: case 1 if a >= 0 and a <= 9: 1 可简化为: if 0 <= a <= 9: 1 就像我们的数学表达式一样.显然这种情 ...

  5. mybatis-generator自动生成dao,mapping,model

    mybatis-generator下载地址:https://github.com/mybatis/generator/releases/tag/mybatis-generator-1.3.2 下载好后 ...

  6. Scala语言开发入门

    在本系列的第一篇文章 <使用递归的方式去思考>中,作者并没有首先介绍 Scala 的语法,这样做有两个原因:一是由于过多的陷入语法的细节其中,会分散读者的注意力.反而忽略了对于基本概念,基 ...

  7. C++中关于指针运算符->的重载问题

    #include<iostream>using namespace std;struct date{ int year; int month; int day;};struct Perso ...

  8. 转:CentOS 6.x 挂载读写NTFS分区(fuse-ntfs-3g)

    from: http://mtd527.blog.163.com/blog/static/222723720151208127898/ 运行环境:CentOS 6.6  x64版本 CentOS不像F ...

  9. Hive怎样加入第三方JAR

    以增加elsaticsearch-hadoop-2.1.2.jar为例,讲述在Hive中增加第三方jar的几种方式. 1,在hive shell中增加 [hadoop@hadoopcluster78 ...

  10. C#中int、long、float、double、decimal最大值最小值

    最近在将java上写的一个简单的表达式求值计算器移植到Windows Phone 8,java中double的精度问题是很明显的,解决办法是改用BigDecimal类.所以觉得C#中用double也是 ...