[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转载无需经过作者本人授权 先解开第一个 ...
随机推荐
- activiti Task
UserTask ScriptTask ServiceTask MailTask ManualTask ReceiveTask BusinessRuleTask callActivity
- iframe调用父页面函数用法举例
iframe如何调用父页面函数. window.parent.xxxxx();//xxxxx()代表父页面方法具体列子如下,其中包括easyUI的右键和单击事件parent.jspbody部分代码 & ...
- 微信小程序调用蓝牙功能控制车位锁
第一次学用微信小程序,项目需要,被逼着研究了一下,功能是调用微信小程序的蓝牙功能,连接上智能车位锁,控制升降,大概步骤及调用的小程序接口API如下: 1.打开蓝牙模块 wx.openBluetooth ...
- [CoreOS]CoreOS 实战:CoreOS 及管理工具介绍
转载:http://www.infoq.com/cn/articles/what-is-coreos [编者按]CoreOS是一个基于Docker的轻量级容器化Linux发行版,专为大型数据中心而设计 ...
- [Windows Azure] Developing Multi-Tenant Web Applications with Windows Azure AD
Developing Multi-Tenant Web Applications with Windows Azure AD 2 out of 3 rated this helpful - Rate ...
- 每天一个linux命令(6) ar命令
当我们的程序中有经常使用的模块,而且这种模块在其他程序中也会用到,这时按照软件重用的思想,我们应该将它们生成库,使得以后编程可以减少开发代码量.这里介绍命令ar,用来对库操作. ar命令可以用来创建. ...
- iOS开发-应用管理
// // ViewController.m // 21-应用管理-1 // // Created by hongqiangli on 2017/8/2. // Copyright © 201 ...
- iOS 10.3.3 更新背后的故事
iOS 10.3.3 更新背后的故事 TLDR:赶紧升级! 苹果最近提示大家将系统升级到 iOS 10.3.3,并且描述这个更新的内容是:修复和改进安全性. iOS 10.3.3 includes b ...
- 说说Python程序的执行过程
1. Python是一门解释型语言? 我初学Python时,听到的关于Python的第一句话就是,Python是一门解释性语言,我就这样一直相信下去,直到发现了*.pyc文件的存在.如果是解释型语言, ...
- 三角形(css3)
.userCard .sanjiao {//三角形的制作: width: 0; height: 0; border-left: 10px solid transparent; border-right ...