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 (-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的更多相关文章

  1. [serial]基于select/poll/epoll的串口操作

    转自:http://www.cnblogs.com/darryo/p/selectpollepoll-on-serial-port.html In this article, I will use t ...

  2. Python之路-python(Queue队列、进程、Gevent协程、Select\Poll\Epoll异步IO与事件驱动)

    一.进程: 1.语法 2.进程间通讯 3.进程池 二.Gevent协程 三.Select\Poll\Epoll异步IO与事件驱动 一.进程: 1.语法 简单的启动线程语法 def run(name): ...

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

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

  4. Python自动化 【第十篇】:Python进阶-多进程/协程/事件驱动与Select\Poll\Epoll异步IO

    本节内容: 多进程 协程 事件驱动与Select\Poll\Epoll异步IO   1.  多进程 启动多个进程 进程中启进程 父进程与子进程 进程间通信 不同进程间内存是不共享的,要想实现两个进程间 ...

  5. python 套接字之select poll epoll

    python下的select模块使用 以及epoll与select.poll的区别 先说epoll与select.poll的区别(总结) select, poll, epoll 都是I/O多路复用的具 ...

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

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

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

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

  8. Linux下select&poll&epoll的实现原理(一)

    最近简单看了一把 linux-3.10.25 kernel中select/poll/epoll这个几个IO事件检测API的实现.此处做一些记录.其基本的原理是相同的,流程如下 先依次调用fd对应的st ...

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

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

随机推荐

  1. Apache虚拟主机配置,实现多域名访问本地项目PHP空间,以及配置403Forbidden等错误的解决办法

    第一步: apache主配置文件修改: 用文本编辑器打开apache的conf目录下 httpd.conf 将下面以下代码取消注释 LoadModule rewrite_module  modules ...

  2. log4php的配置

    网上关于log4php配置的文章很多,下面是我的配置,跟网上部分略有不同 (1)添加日志     1.下载log4php,到官网就可以下载到,下载后解压     我的版本是log4php_2.3.0 ...

  3. python练习

    创建一个简单的姓名和编号系统,让用户输入一组人的姓名和编号,实现提供按照编号或姓名排序输出的功能. nums = [] names = [] Afternums = [] Afternames = [ ...

  4. Java web servlet 拦截器 以登陆为例子

    以登陆为例子............... public class LoginFilter implements Filter { @Override public void destroy() { ...

  5. CommonJS Promises/A规范

    本文来自四火哥的翻译 CommonJS是一组javascript编程规范,而promise是其中之一. 简而言之,promises是一种令代码的异步行为变得更加优雅的软件抽象.在基本的定义中,代码可能 ...

  6. html基本选择符的使用

    一.选择符在运用在CSS设计样式时对HTML的指定有至关重要的作用! 二.研究 普通选择符: 1.类型选择符:它可以选择同一个类型的元素! 例如:h1,h2 {              color: ...

  7. C++ 画星号图形——空心梯形(核心代码记录)

    b=a; ;c<=a;c++) { ;d<=a-c;d++) printf(" "); ;e<=b;e++) ||c==a) printf("*&quo ...

  8. Windows 7 常用快捷键

    常用的快捷键 Win键+D 回到桌面/当前界面(切换)Win键+M 回到桌面Win键+E 资源管理器Win键+R 运行 Win键+U 控制面板->所有控制面板项->轻松访问中心 Win键+ ...

  9. ueditor编辑器使用

    下载ueditor1_4_3_3-gbk-asp 解压后重命名为ueditor上传至网站 在需要编辑器的位置增加asp代码: <td style="PADDING-LEFT: 10px ...

  10. vue.js 学习笔记

    /*属性*/ 标签内的属性都用 :attr="xxx" 的形式 /*模板*/ {{ msg }} -> 绑定数据 {{ *msg }} -> 数据只绑定一次 {{{ m ...