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. MongoDB-C#驱动帮助

    查增改删 链接字符串 MongoDB超管+(admin) 单独库用户不加 static string mongoR = string.Format("mongodb://{0}(admin) ...

  2. zeromq中两个dealer 通过一个router进行通信

    发现有童鞋不是很清楚ZMQ中的“请求-回复”模式中的ROUTER怎么用,所以简单介绍一下“请求-回复”模式的使用(最后付代码). 一.讲一讲 1.要使用zmq 通过一个router进行通信,你首先需要 ...

  3. python 之sqlalchemy many to one

    通过查询多个父亲,对应一个儿子 #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ @author: zengchuny ...

  4. sqlserver跨服务器数据库sql语句

    1.启用Ad Hoc Distributed Queries:exec sp_configure 'show advanced options',1reconfigureexec sp_configu ...

  5. C++STL 常用 函数 用法

    学完c++快一年了,感觉很有遗憾,因为一直没有感觉到c++的强大之处,当时最大的感觉就是这个东西的输入输出比C语言要简单好写. 后来我发现了qt,opencv,opengl,原来,c++好玩的狠. 在 ...

  6. centos无法正常启动,报chown: invalid user:'root:root'

    现象: 系统无法正常启动,启动界面卡在上图的位置 注意错误信息:chown: invalid user:'root:root' 原因:/etc/passwd文件损坏或者被清空 尝试:1.grub菜单项 ...

  7. iOS开发之CocoaLumberjack

    Cocoa LumberJack是一个功能强大的NSlog,是通用的Cocoa日志框架之一.它可以提供更高级的log功能,比如记录log至文件或网络,并可根据log的级别(info.debug.war ...

  8. noip200802排座椅

    排座椅 难度级别:B: 运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 上课的时候总有一些同学和前后左右的人交头接耳,这是令小学班主任十分头疼的 ...

  9. redis 简单应用

    Incr $views = Redis::incr('views'); $article_views = Redis::incr('article:' . $article_id . ':views' ...

  10. 从程序员到CTO的Java技术路线图(我爱分享)

    在技术方面无论我们怎么学习,总感觉需要提升自已不知道自己处于什么水平了.但如果有清晰的指示图供参考还是非常不错的,这样我们清楚的知道我们大概处于那个阶段和水平. Java程序员 高级特性 反射.泛型. ...