[serial]基于select/poll/epoll的串口操作
转自: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
- Character device file of serial port
- Naive serial communication
- Asynchronous conferencing
- Select
- Poll
- 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的串口操作的更多相关文章
- Python异步非阻塞IO多路复用Select/Poll/Epoll使用,线程,进程,协程
1.使用select模拟socketserver伪并发处理客户端请求,代码如下: import socket import select sk = socket.socket() sk.bind((' ...
- 转一贴,今天实在写累了,也看累了--【Python异步非阻塞IO多路复用Select/Poll/Epoll使用】
下面这篇,原理理解了, 再结合 这一周来的心得体会,整个框架就差不多了... http://www.haiyun.me/archives/1056.html 有许多封装好的异步非阻塞IO多路复用框架, ...
- select/poll/epoll on serial port
In this article, I will use three asynchronous conferencing--select, poll and epoll on serial port t ...
- 多进程、协程、事件驱动及select poll epoll
目录 -多线程使用场景 -多进程 --简单的一个多进程例子 --进程间数据的交互实现方法 ---通过Queues和Pipe可以实现进程间数据的传递,但是不能实现数据的共享 ---Queues ---P ...
- select,poll,epoll的归纳总结区分
Select.Poll与Epoll比较 以下资料都是来自网上搜集整理.引用源详见文章末尾. 1 Select.Poll与Epoll简介 Select select本质上是通过设置或者检查存放fd标志位 ...
- Select\Poll\Epoll异步IO与事件驱动
事件驱动与异步IO 事件驱动编程是一种编程规范,这里程序的执行流由外部事件来规定.它的特点是包含一个事件循环,但外部事件发生时使用回调机制来触发响应的处理.另外两种常见的编程规范是(单线程)同步以及多 ...
- I/O多路复用之select,poll,epoll简介
一.select 1.起源 select最早于1983年出现在4.2BSD中(BSD是早期的UNIX版本的分支). 它通过一个select()系统调用来监视多个文件描述符的数组,当select()返回 ...
- Linux 网络编程的5种IO模型:多路复用(select/poll/epoll)
Linux 网络编程的5种IO模型:多路复用(select/poll/epoll) 背景 我们在上一讲 Linux 网络编程的5种IO模型:阻塞IO与非阻塞IO中,对于其中的 阻塞/非阻塞IO 进行了 ...
- 哪5种IO模型?什么是select/poll/epoll?同步异步阻塞非阻塞有啥区别?全在这讲明白了!
系统中有哪5种IO模型?什么是 select/poll/epoll?同步异步阻塞非阻塞有啥区别? 本文地址http://yangjianyong.cn/?p=84转载无需经过作者本人授权 先解开第一个 ...
随机推荐
- FaceBook登陆API -- Login with API calls
Login with API calls Related Topics Understanding sessions FBSession Error handling FBError FBLoginC ...
- Knockout: 让ViewModel从htm中剥离出去。
在一些Knockout例子中,直接在htm中添加scripts写viewmodel,如何能将让ViewModel从htm中剥离出去呢?从knockout官网上找到了解决方法,如下: 1.knockou ...
- Mac下命令行下载android源代码并构建apk过程
前提是java .sdk.ndk .cmake.gradle .gradlew都已经安装和配置好. 1.下载源码: git clone http://git-ma.xxxx.com.cn/xxxx/x ...
- 持续集成(1)gitlab的安装
操作系统:centos 6.5 关闭selinux # 修改/etc/selinux/config 文件 将SELINUX=enforcing改为SELINUX=disabled ,然后重启电脑 # ...
- Recyclerview 出现 java.lang.IndexOutOfBoundsException: Inconsistency detected 异常
使用 RecyclerView 的时候报错 java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view hold ...
- 设计模式-建造者模式(Builder Pattern)
建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 建造者模式要求建造过程中是稳定的. Android 用到的 Builder 模 ...
- CentOS 7 安装开发者环境
在vagrant box中安装了基本的centos7的box,但是,该环境没有安装编译软件,所以要求自行安装. 1.查看群组安装的源包数量: yum group list ,搜索Development ...
- 在eclipse-oxygen-sts中,关于快捷键[CTRL + SHIFT + O]失效的问题
这是sts的一个bug,没关系,重新设置接口 按照如图位置修改即可 下图截自于stackoverflow
- Unity GPU Instancing的使用尝试
似乎是在Unity5.4中开始支持GPU Instacing,但如果要比较好的使用推荐用unity5.6版本,因为这几个版本一直在改. 这里测试也是使用unity5.6.2进行测试 在5.6的版本里, ...
- 事件,委托,action与func文章不错的
https://www.cnblogs.com/yinqixin/p/5056307.html https://www.cnblogs.com/BLoodMaster/archive/2010/07/ ...