poll函数和串口设置.DOC

2015.1.24

今天星期六,多云,早晨8:17起床的,今天是来南京起床最迟的一天,因为昨晚睡得有点迟,今天又不用上课,整个人有点放松。收拾好来到教室,教室门没有开,胡明
也到了,其他人还在宿舍睡觉,等了10分钟还没有人来开门,就决定出去逛逛,看看南京市有什么好玩的或者特别的。9点没到从鸿运大厦出门,回来的时候10点10分左右,走了
一个多小时,百度地图还是有点管用的,起码没有让我迷路。逛了一圈,以前觉得南京算是个大城市,应该比较繁华或者时尚之类的,但是现在完全没有这种感觉,想到以后
的工作,我就想:此地不宜久留。如果可以,我会选择不在南京工作,这里找不到归属感,貌似工资也不好。
因外买了过年回家的车票,对这边车站不熟,就决定今天下去去把车票取了,1:40左右走的,和张恒斌一起,来回公交车都是他刷的卡,到南京北站后发现车站挺小的,取完票就
出来了,因为根本不需要去熟悉他,太小了。出站后就问张恒斌,要不要再这边逛逛,他说:好啊,这边要去不就去桥上(南京长江大桥:全桥长4589米,公路桥长1600多米)嘛!,我对
到处逛还是比较有兴趣的,在杭州的时候就一个人在钱塘江复兴大桥上走了一个来回,那时候是晚上。走上桥后发现南京长江大桥挺长的,一咬牙继续走,就这样,我和张恒斌两个人
边走边聊,桥上风挺大的,走热了的时候我把衣服脱了,但是没一会就冷了。南京这边天气污染很严重,桥上灰蒙蒙的,桥下面有很多货船,拍了一些照片,记录了一下这段旅程。回到
宿舍4:10左右了,因为走了很长的路,所以感觉比较累,口也比较干燥,吃了个梨子后,在床上睡了会,起来的时候6点多了,清醒过后下楼吃晚饭,去排档叫了份红烧鲫鱼。有点奢侈
了,每天吃盖浇饭有点受不了,就这样,一天过去了,晚上就该学习了!

poll函数实现的IO多路复用!,结合昨天的select函数一起看,他们在这里实现的是相同的功能,但是poll函数效率更高!使用范围更广!

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <fcnt1.h>

#include <poll.h>

#define MAX_BUFFER_SIZE 1024
#define IN_FELES 3
#define TIME_DELAY 60
#define MAX(a, b) ((a > b) ? (a):(b))

int main(void)
{
struct pollfd fds[IN_FILES];
char buf[MAX_BUFFER_SIZE];
int i, res, real_read, maxfd;
/*首先按一定的权限打开另个源文件*/
fds[0].fd = 0;
if((fds[1].fd = open("in1",O_RDONLY | O_NONBLOCK)) < 0)
{
printf("open in1 error\n");
return 1;
}

if((fds[2].fd = open("in2",O_RDONLY | O_NONBLOCK)) < 0)
{
printf("open in2 error\n");
return 1;
}

for(i = 0; i < IN_FILES; i++)
{
fds[i].events = POLLIN;
}
/*循环测试该文件描述符是否准备就绪,并调用select函数对相关文件描述符做对应操作*/
while(fds[0].events || fds[1].events || fds[2].events)
{
if(poll(fds,IN_FILES,0) < 0)
{
printf("poll error\n");
return 1;

}

for(i = 0; i < IN_FILES; i++)
{
if(fds[i].revents)
{
memset(buf ,0, MAX_BUFFER_SIZE);
real_read = read(fds(fds[i].fd,buf,MAX_BUFFER_SIZE);

if(real_read < 0)
{
if(errno != EAGAIN)
{
return 1;
}
}

else if(!real_read)
{
close(fds[i].fd);
fds[i].events = 0;
}
else
{
if(i == 0)
{
if((buf[0] == ‘q‘) || (buf[0] == ‘Q‘))
{
return 1;
}
}
else
{
buf[real_read] = ‘\0‘;
printf("%s,buf");
}
}
}
}
}
exit(0);
}

串口设置详解:

串口设置主要是设置struct termios结构体的各成员值:

#include <termios.h>
struct termios
{
unsigned short c_iflag; //输入模式标志
unsigned short c_oflag; 输出模式标志
unsigned short c_cflag; //控制模式标志
unsigned short c_lglag; 本地模式标志
unsigned char c_line; 线路规程
unsigned char c_cc[NCC]; //控制特性
speed_t c_ispeed; 输入速度
speed_t c_ospeed; 输出速度
}

不能对c_cflag成员初始化,而要将其通过“与”“或”操作使用其中的某些选项
输入模式标志c_iflag用于控制端口接收端的字符输入处理。

下面详细讲解设置串口属性的基本流程:

1.保存原先串口的配置:

if(tcgetattr(fd,&old_cfg) != 0)
{
perror("tvgetattr");
return -1;
}

2.激活选项:CLOCAL和CREAD分别用于本地连接和接受使能,用位掩码

newtio.c_cflag |= CLOCAL | CREAD;

调用dfmakeraw()函数将终端设置为原始模式

cfmakeraw(&new_cfg);

3.设置波特率;设置波特率有专门的函数,
cfsetispeed(&new_cfg,B115200);
cfsetospeed(&new_cfg,B115200);
一般的,用户需要将终端的输入和输出的波特率设置成一样的,这几个函数在成功时返回0,失败时返回-1.

4.设置字符大小,用位掩码:一般首先清除数据位中的位掩码再重新安要求设置

new_cfg.c_cflag &= ~CSIZE; 用数据位掩码清空数据位设置
new_cfg.c_cflag |= CS8;

5.设置奇偶校验位:首先激活c_cflag中的校验位使能标志PARENB和是否要进行偶校验,同时还要
激活c_iflag中的对于输入数据的奇偶校验使能INPCK;

new_cfg.c_cflag |= (PARODD | PARENB);
new_cfg.c_iflag |= INPCK;

使能偶校验时,代码如下:
new_cfg.c_cflag |= PARENB
new_cfg.c_cflag &= ~PARODD 清除偶校验标志,则配置为奇校验
new_cfg.c_iflag |= INPCK;

6.设置停止位

若停止位为一个,则清除CSTOPB,如停止位为两个,则激活CSTOPB.以下分别是停止位为一个和两个比特时的代码
new_cfg.c_cflag &= ~CSTOPB; 将停止位设置为一个比特
new_cfg.c_cflag |= CSTOPB; 将停止位设置为两个比特

7.设置最少字符和等待时间:
在对就收字符和字符时间没有特别要求的情况下,可以将其设置为0,则在任何情况下read()函数立即返回:
new_cfg.c_cc[VTIME] = 0;
new_cfg.c_cc[VMIN] = 0;

8.清除串口缓冲:
int tcdrain(int fd); 使程序阻塞,直到输出缓冲区的数据全部发送完毕
int tcflow(int fd,int action); 用于暂停或重新开始输出
int tcflush(int fd,int queue_selectot); 用于清空输入、输出缓冲区

9.激活配置
tcsetattr(int fd, int optional_actions, const struct termios *termios_p);

函数调用如下:
if((tcsetattr(fd,TCSANOW,&new_cfg)) != 0)
{
perror("tcsetattr");
return -1;
}

**********************************************************************************************************************************************************
**********************************************************************************************************************************************************
**********************************************************************************************************************************************************

时间: 2024-11-25 08:25:11

poll函数和串口设置.DOC的相关文章

linux poll函数

poll函数与select函数差不多 函数原型: #include <poll.h> int poll(struct pollfd fd[], nfds_t nfds, int timeout); struct pollfd的结构如下: struct pollfd{ int fd: // 文件描述符 short event:// 请求的事件 short revent:// 返回的事件 } 每个pollfd结构体指定了一个被监视的文件描述符.第一个参数是一个数组,即poll函数可以监视多个文件描

串口设置的一般步骤

1) 串口时钟使能,GPIO 时钟使能 2) 串口复位 3) GPIO 端口模式设置 4) 串口参数初始化 5) 开启中断并且初始化 NVIC(如果需要开启中断才需要这个步骤) 6) 使能串口 7) 编写中断处理函数 .串口时钟使能.串口是挂载在 APB2 下面的外设,所以使能函数为: RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1): 2.串口复位.当外设出现异常的时候可以通过复位设置,实现该外设的复位,然后重新配置 这个外设达到让其重新工作的目的.一

select在并发中的两点限制与poll函数的使用

用select实现的并发服务器,能达到的并发数,受两方面限制: 一个进程能打开的最大文件描述符限制.这可以通过调整内核参数. select中的fd_set集合容量的限制(FD_SETSIZE) ,这需要重新编译内核.//这个不能通过调整内核参数来限制  FD_SETSIZE宏等于1024在一个头文件中设置 改变它需要重新编译内核. ulinit   -n来查询最大文件描述符 得到1024   可以通过sudo  bash 换位root用户    ulimit  -n  2048进行修改最大文件描

【unix网络编程第三版】阅读笔记(五):I/O复用:select和poll函数

本博文主要针对UNP一书中的第六章内容来聊聊I/O复用技术以及其在网络编程中的实现 1. I/O复用技术 I/O多路复用是指内核一旦发现进程指定的一个或者多个I/O条件准备就绪,它就通知该进程.I/O复用适用于以下场合: (1) 当客户处理多个描述符(一般是交互式输入或网络套接字),必须适用I/O复用 (2) 当一个客户处理多个套接字时,这种情况很少见,但也可能出现 (3) 当一个TCP服务器既要处理监听套接字,又要处理已连接套接字,一般就要使用I/O复用 (4) 如果一个服务器既要适用TCP,

嵌入式linux串口设置(一)

在linux中,所有的设备文件一般都位于“/dev”下,串口1和串口2对应的设备名依次为“/dev/ttyS0”, “/dev/ttyS1”,而且USB转串口的设备名通常为“/dev/ttyUSB0”,在linux下对设备的操作方法与对文件的操作方法一样. 串口开发步骤: 串口的设置主要是设置struct termios结构体的各成员值 #include<termios> struct termios { Unsigned short c_iflag;            /*输入模式标志*

Unix网络编程学习笔记之第6章 I/O复用:select和poll函数

一.I/O复用应用场合 1. 当客户处理多个描述符(既有标准输入,又有网络套接字)时,必须使用IO复用. 2. 一个客户同时处理多个套接字是可能的. 3. 如果一个服务器既要处理监听套接字,又要处理已连接套接字,一般就要使用I/O复用. 4. 如果一个服务器既要处理TCP,又要处理UDP,一般就要I/O复用. 5. 如果一个服务器要处理多个服务或协议,就要用到I/O复用. 其实IO复用就是一个进程/线程处理多个套接字描述符. 二. I/O模型 Unix提供了5种I/O模型: 1. 阻塞式I/O模

Linux串口设置及编程(转)

用户常见的数据通信的基本方式可分为并行通信和串行通信. 并行通信是指利用多条数据传输线将一个资料的各位同时传送.特点是传输速度快,适用于短距离通信,但要求传输速度较高的应用场合. 串行通信是指利用一条传输线将资料一位位的顺序传送.特点是通信线路简单,利用简单的线缆就可以实现通信,减低成本,适用于远距离通信,但传输速度慢的应用场合.常用的串口有RS-232-C接口(全称是“数据终端设备(DTE)和数据通讯设备(DCE)之间串行二进制数据交换接口技术标准”). UART控制器:可以工作在Interr

Linux网络编程——I/O复用之poll函数

一.回顾前面的select select优点: 目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点 select缺点: 1.每次调用 select(),都需要把 fd 集合从用户态拷贝到内核态,这个开销在 fd 很多时会很大,同时每次调用 select() 都需要在内核遍历传递进来的所有 fd,这个开销在 fd 很多时也很大. 2.单个进程能够监视的文件描述符的数量存在最大限制,在 Linux 上一般为 1024,可以通过修改宏定义甚至重新编译内核的方式提升这一限制,但是这样也会造成效

[STM32F10x] 使用printf函数进行串口调试问题

硬件:STM32F103C8T6 平台:Keil ARM-MDk V5.11 利用printf函数通过串口(USART)进行调试时遇到的一个问题: printf("Hello, Mini-M3"); 本意是想输出"Hello, Mini-M3",但是通过串口调试助手,得到的输出是"ello, Mini-M3",也就是第一个数据没有接收到,而且这种情况只会在初始化USART后第一次 发送数据时出现. USART发送数据的代码如下: int fput