select/poll/epoll on serial port
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 (-1 == fd) { /*设置数据位数*/
perror("Can't Open Serial Port");
return -1;
}
else {
set_speed(fd);
set_Parity(fd);
return fd;
}
}
int main(){
int fd;
ssize_t length;
char buff[512];
char *dev ="/dev/ttyAMA0";
fd = OpenSerial(dev);
for(;;){
length = read(fd,buff,sizeof(buff));
if(length > 0) {
buff[length] = 0;
printf("plain:%s\n",buff);
}
}
close(fd);
exit(0);
}
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[512];
ssize_t length;
fd = OpenSerial("/dev/ttyAMA0");
for(;;) {
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
//timeout = 5s
tv.tv_sec = 5;
tv.tv_usec = 0;
//Wait for 5 seconds, then go
int n;
n = select(fd + 1, &rfds, NULL, NULL, &tv);
//choose the target from set
if(n > 0) {
if (FD_ISSET(fd, &rfds)) {
length = read(fd, &buff, sizeof(buff));
buff[length] = 0;
printf("select:%s\n", buff);
}
} else {
printf("No data within 5 seconds.\n");
}
}
return 0;
}
Poll version
#include <sys/poll.h>
#include "serial/serial.h"
int main(void) {
struct pollfd fds[1];
ssize_t length;
char buff[512];
fds[0].fd = OpenSerial("/dev/ttyAMA0");
fds[0].events = POLLIN ;
for(;;) {
int n;
n = poll( fds, 1, 5000);
//got data, and look up which fd has data, but we just have 1
if(n > 0) {
//if( fds[0].revents & POLLIN ) {
length = read(fds[0].fd, buff, sizeof(buff) );
buff[length] = 0;
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[512];
fd = OpenSerial("/dev/ttyAMA0");
efd = epoll_create1 (0);//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, 5000);
if(n > 0) {
length = read(events[0].data.fd, buff, sizeof(buff));
if(length > 0) {
buff[length] = 0;
printf("epoll:%s\n", buff);
}
} else {
printf("No data whthin 5 seconds.\n");
}
}
free (events);
close (fd);
return 0;
}
select/poll/epoll on serial port的更多相关文章
- [serial]基于select/poll/epoll的串口操作
转自:http://www.cnblogs.com/darryo/p/selectpollepoll-on-serial-port.html In this article, I will use t ...
- Python之路-python(Queue队列、进程、Gevent协程、Select\Poll\Epoll异步IO与事件驱动)
一.进程: 1.语法 2.进程间通讯 3.进程池 二.Gevent协程 三.Select\Poll\Epoll异步IO与事件驱动 一.进程: 1.语法 简单的启动线程语法 def run(name): ...
- 多进程、协程、事件驱动及select poll epoll
目录 -多线程使用场景 -多进程 --简单的一个多进程例子 --进程间数据的交互实现方法 ---通过Queues和Pipe可以实现进程间数据的传递,但是不能实现数据的共享 ---Queues ---P ...
- Python自动化 【第十篇】:Python进阶-多进程/协程/事件驱动与Select\Poll\Epoll异步IO
本节内容: 多进程 协程 事件驱动与Select\Poll\Epoll异步IO 1. 多进程 启动多个进程 进程中启进程 父进程与子进程 进程间通信 不同进程间内存是不共享的,要想实现两个进程间 ...
- python 套接字之select poll epoll
python下的select模块使用 以及epoll与select.poll的区别 先说epoll与select.poll的区别(总结) select, poll, epoll 都是I/O多路复用的具 ...
- Select\Poll\Epoll异步IO与事件驱动
事件驱动与异步IO 事件驱动编程是一种编程规范,这里程序的执行流由外部事件来规定.它的特点是包含一个事件循环,但外部事件发生时使用回调机制来触发响应的处理.另外两种常见的编程规范是(单线程)同步以及多 ...
- Linux 网络编程的5种IO模型:多路复用(select/poll/epoll)
Linux 网络编程的5种IO模型:多路复用(select/poll/epoll) 背景 我们在上一讲 Linux 网络编程的5种IO模型:阻塞IO与非阻塞IO中,对于其中的 阻塞/非阻塞IO 进行了 ...
- Linux下select&poll&epoll的实现原理(一)
最近简单看了一把 linux-3.10.25 kernel中select/poll/epoll这个几个IO事件检测API的实现.此处做一些记录.其基本的原理是相同的,流程如下 先依次调用fd对应的st ...
- select,poll,epoll的归纳总结区分
Select.Poll与Epoll比较 以下资料都是来自网上搜集整理.引用源详见文章末尾. 1 Select.Poll与Epoll简介 Select select本质上是通过设置或者检查存放fd标志位 ...
随机推荐
- Bulk_Collect_Performance 比较
上一篇讲到了调用集锦,这篇关注一下性能问题吧. DECLARE CURSOR c_tool_list IS SELECT descr d1 FROM hardware; l_descr hardwar ...
- VS2013 - 自定义新建文件模版
一直想统一下项目中的关于-(新建文件时,添加个人信息,如:创建者,创建时间等个性化信息). 从网络上学习到方法很简单,只需要把IDE安装目录下的模板进行修改保存,即可每次创建拥有固定的模板呈现. 具体 ...
- IBatis添加信息返当前添加对象ID
在Ibatis中,insert()的返回值为一个Object的主键,其实这个Object的主键是这样的来的:如果在bean的xml文件中设置了插入的keyProperty,则insert()方法返 ...
- jenkins,dns错误log过大
http://stackoverflow.com/questions/31719756/how-to-stop-jenkins-log-from-becoming-huge Recently my j ...
- oracle PL/SQL高级特性
触发器:存放在数据库中,并被隐含执行的存储过程. 由触发事件,触发条件,触发操作组成. DML触发器:指定触发器时机(before or after),触发事件(insert , delete, u ...
- Switch语句的case穿透
Switch语句的case穿透 一 switch语句几点说明: 1. case后面只能是常量,不能是变量,而且,多个case后面的值不能出现相同的. 2.case后面表达式可以接受: 基本数据类型,b ...
- 最难面试的IT公司之ThoughtWorks代码挑战——FizzBuzzWhizz游戏(C#解法)
原题 看到那么多人看到前面这么糟粕的代码各种不忍直视后,楼主还是把最终实现放在页首吧. Console.WriteLine("说出三个不同的特殊数,用','隔开 &q ...
- 【转】logback logback.xml常用配置详解(三) <filter>
原创文章,转载请指明出处:http://aub.iteye.com/blog/1110008, 尊重他人即尊重自己 详细整理了logback常用配置, 不是官网手册的翻译版,而是使用总结,旨在更快更透 ...
- 2.线性表-Linked list
fatal.h #include <stdio.h> #include <stdlib.h> #define Error( Str ) FatalError( Str ) #d ...
- Linux系统glibc库版本信息查看
原文链接:http://www.jbxue.com/LINUXjishu/29946.html 1. CentOS /lib/i386-linux-gnu/libc.so. 或 rpm -qi gli ...