linux下串口的阻塞和非阻塞操作

有两个可以进行控制串口阻塞性(同时控制read和write):一个是在打开串口的时候,open函数是否带O_NDELAY;第二个是可以在打开串口之后通过fcntl()函数进行控制。

阻塞的定义:

对于read,block指当串口输入缓冲区没有数据的时候,read函数将会阻塞在这里,移植到串口输入缓冲区中有数据可读取,read读到了需要的字节数之后,返回值为读到的字节数;

对于write,block指当串口输出缓冲区满,或剩下的空间小于将要写入的字节数,则write将阻塞,一直到串口输出缓冲区中剩下的空间大于等于将要写入的字节数,执行写入操作,返回写入的字节数。

非阻塞的定义:

对于read,no block指当串口输入缓冲区没有数据的时候,read函数立即返回,返回值为0。

对于write,no block指当串口输出缓冲区满,或剩下的空间小于将要写入的字节数,则write将进行写操作,写入当前串口输出缓冲区剩下空间允许的字节数,然后返回写入的字节数。

[cpp] view plaincopy

  1. static int set_opt(int fd, int nSpeed, int nBits, char nEvent, int nStop)
  2. {
  3. struct termios newtio;
  4. struct termios oldtio;
  5. if(tcgetattr(fd,&oldtio) != 0)
  6. {
  7. perror("SetupSerial 1");
  8. return -1;
  9. }
  10. bzero(&newtio,sizeof(newtio));
  11. newtio.c_cflag |= CLOCAL |CREAD;
  12. newtio.c_cflag &= ~CSIZE;
  13. /***********数据位选择****************/
  14. switch(nBits)
  15. {
  16. case 7:
  17. newtio.c_cflag |= CS7;
  18. break;
  19. case 8:
  20. newtio.c_cflag |= CS8;
  21. break;
  22. }
  23. /***********校验位选择****************/
  24. switch(nEvent)
  25. {
  26. case ‘O‘:
  27. newtio.c_cflag |= PARENB;
  28. newtio.c_cflag |= PARODD;
  29. newtio.c_iflag |= (INPCK | ISTRIP);
  30. break;
  31. case ‘E‘:
  32. newtio.c_iflag |= (INPCK |ISTRIP);
  33. newtio.c_cflag |= PARENB;
  34. newtio.c_cflag &= ~PARODD;
  35. break;
  36. case ‘N‘:
  37. newtio.c_cflag &= ~PARENB;
  38. break;
  39. }
  40. /***********波特率选择****************/
  41. switch(nSpeed)
  42. {
  43. case 2400:
  44. cfsetispeed(&newtio,B2400);
  45. cfsetospeed(&newtio,B2400);
  46. break;
  47. case 4800:
  48. cfsetispeed(&newtio,B4800);
  49. cfsetospeed(&newtio,B4800);
  50. break;
  51. case 9600:
  52. cfsetispeed(&newtio,B9600);
  53. cfsetospeed(&newtio,B9600);
  54. break;
  55. case 57600:
  56. cfsetispeed(&newtio,B57600);
  57. cfsetospeed(&newtio,B57600);
  58. break;
  59. case 115200:
  60. cfsetispeed(&newtio,B115200);
  61. cfsetospeed(&newtio,B115200);
  62. break;
  63. case 460800:
  64. cfsetispeed(&newtio,B460800);
  65. cfsetospeed(&newtio,B460800);
  66. break;
  67. default:
  68. cfsetispeed(&newtio,B9600);
  69. cfsetospeed(&newtio,B9600);
  70. break;
  71. }
  72. /***********停止位选择****************/
  73. if(nStop == 1){
  74. newtio.c_cflag &= ~CSTOPB;
  75. }
  76. else if(nStop ==2){
  77. newtio.c_cflag |= CSTOPB;
  78. }
  79. newtio.c_cc[VTIME] = 1;
  80. newtio.c_cc[VMIN] = FRAME_MAXSIZE;   //阻塞条件下有效
  81. tcflush(fd,TCIFLUSH);
  82. if((tcsetattr(fd,TCSANOW,&newtio)) != 0)
  83. {
  84. perror("com set error");
  85. return -1;
  86. }
  87. printf("set done!\n");
  88. return 0;
  89. }

[cpp] view plaincopy

  1. static int open_port(int fd,int comport)
  2. {
  3. /***********打开串口1****************/
  4. if(comport == 1)
  5. {
  6. fd = open("/dev/ttyAT1",O_RDWR|O_NOCTTY|O_NDELAY);
  7. if(fd == -1){
  8. perror("Can‘t Open Serial Port");
  9. return -1;
  10. }
  11. }
  12. /***********打开串口2****************/
  13. else if(comport == 2)
  14. {
  15. fd = open("/dev/ttyAT2",O_RDWR|O_NOCTTY|O_NDELAY);
  16. if(fd == -1){
  17. perror("Can‘t Open Serial Port");
  18. return -1;
  19. }
  20. }
  21. /***********打开串口3****************/
  22. else if(comport == 3)
  23. {
  24. fd = open("/dev/ttyAT3",O_RDWR|O_NOCTTY|O_NDELAY);
  25. if(fd == -1){
  26. perror("Can‘t Open Serial Port");
  27. return -1;
  28. }
  29. }
  30. if(comport == 1)
  31. {
  32. if(fcntl(fd,F_SETFL,FNDELAY) < 0)//非阻塞,覆盖前面open的属性
  33. {
  34. printf("fcntl failed\n");
  35. }
  36. else{
  37. printf("fcntl=%d\n",fcntl(fd,F_SETFL,FNDELAY));
  38. }
  39. }
  40. else
  41. {
  42. if(fcntl(fd,F_SETFL,0) < 0){   //阻塞,即使前面在open串口设备时设置的是非阻塞的,这里设为阻塞后,以此为准
  43. printf("fcntl failed\n");
  44. }
  45. else{
  46. printf("fcntl=%d\n",fcntl(fd,F_SETFL,0));
  47. }
  48. }
  49. if(isatty(STDIN_FILENO) == 0){
  50. printf("standard input is not a terminal device\n");
  51. }
  52. else{
  53. printf("isatty sucess!\n");
  54. }
  55. printf("fd-open=%d\n",fd);
  56. return fd;
  57. }

所以,linux的串口的阻塞性通过fcntl()函数进行设置即可。

[cpp] view plaincopy

  1. 阻塞:fcntl(fd,F_SETFL,0)

[cpp] view plaincopy

    1. 非阻塞:fcntl(fd,F_SETFL,FNDELAY)
时间: 2024-11-12 10:33:52

linux下串口的阻塞和非阻塞操作的相关文章

Linux下文件的阻塞与非阻塞对部分系统调用的影响

1.基本概念 所谓的阻塞,即内核在对文件操作I/O系统调用时,如果条件不满足(可能需要产生I/O),则内核会将该进程挂起.非阻塞则是发现条件不满足就会立即返回.此外需要注意的是非阻塞并不是轮询,不然就和阻塞没多大区别了,它只是调用不成功就直接返回了,不会在去看啥时候会满足条件,而是有你自己去选择接下来该咋办,系统以不再负责 2.read/write阻塞与非阻塞的理解 read/write系统调用,并不会去直接读写文件,而只是去操作文件所对应的内存页(此时的页为虚拟内存),对于read如果在页中找

Linux下阻塞与非阻塞IO

阻塞:顾名思义,就是指在执行设备操作时若不能获得资源则挂起操作,直到满足可操作的条件后再进行操作,被挂起的进程进入休眠状态,被从调度器的运行队列移走,直到等待的条件满足. 非阻塞:就是反过来,进程在不能进行设备操作时并不挂起,它或者放弃,或者不停的查询,直到可以进行位置. Socket编程中,阻塞与非阻塞的区别: 阻塞:一般的I/O操作可以在新建的流中运用.在服务器回应前它等待客户端发送一个空白的行.当会话结束时,服务器关闭流和客户端socket. 如果在队列中没有请示将会出现什么情况呢?那个方

Linux设备驱动中的阻塞和非阻塞I/O

[基本概念] 1.阻塞 阻塞操作是指在执行设备操作时,托不能获得资源,则挂起进程直到满足操作所需的条件后再进行操作.被挂起的进程进入休眠状态(不占用cpu资源),从调度器的运行队列转移到等待队列,直到条件满足. 2.非阻塞 非阻塞操作是指在进行设备操作是,若操作条件不满足并不会挂起,而是直接返回或重新查询(一直占用CPU资源)直到操作条件满足为止. 当用户空间的应用程序调用read(),write()等方法时,若设备的资源不能被获取,而用户又希望以阻塞的方式来访问设备,驱动程序应当在设备驱动层的

深入浅出~Linux设备驱动中的阻塞和非阻塞I/O

今天意外收到一个消息,真是惊呆我了,博客轩给我发了信息,说是俺的博客文章有特色可以出本书,,这简直让我受宠若惊,俺只是个大三的技术宅,写的博客也是自己所学的一些见解和在网上看到我一些博文以及帖子里综合起来写的,,总之这又给了额外的动力,让自己继续前进,,希望和大家能够分享一些自己的经验,,在最需要奋斗的年级以及在技术的领域踽踽独行的过程中有共同的伙伴继续前进~ 今天写的是Linux设备驱动中的阻塞和非阻塞I/0,何谓阻塞与非阻塞I/O?简单来说就是对I/O操作的两种不同的方式,驱动程序可以灵活的

简述linux同步与异步、阻塞与非阻塞概念以及五种IO模型

1.概念剖析 相信很多从事linux后台开发工作的都接触过同步&异步.阻塞&非阻塞这样的概念,也相信都曾经产生过误解,比如认为同步就是阻塞.异步就是非阻塞,下面我们先剖析下这几个概念分别是什么含义. 同步:所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回.也就是必须一件一件事做,等前一件做完了才能做下一件事. 例如普通B/S模式(同步):提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事 异步:异步的概念和同步相对.当一个异步过程

linux网络IO模型——阻塞、非阻塞和同步、异步

最近几天在学习nginx的时候了解了一下linux网络IO模型,在此谈谈我自己的理解,如有错误请多多指教.本文参考书籍Richard Stevens的“UNIX® Network Programming Volume 1, Third Edition: The Sockets Networking ”,6.2节“I/O Models ”. Linux网络IO请求数据分为两段: 1.数据准备 2.将数据从内核拷贝到进程空间 其实,阻塞.非阻塞和同步.异步的不同就在于这两个阶段的不同. 同步和异步关

Linux设备驱动中的IO模型---阻塞和非阻塞IO【转】

在前面学习网络编程时,曾经学过I/O模型 Linux 系统应用编程——网络编程(I/O模型),下面学习一下I/O模型在设备驱动中的应用. 回顾一下在Unix/Linux下共有五种I/O模型,分别是: a -- 阻塞I/Ob -- 非阻塞I/Oc -- I/O复用(select和poll)d -- 信号驱动I/O(SIGIO)e -- 异步I/O(Posix.1的aio_系列函数) 下面我们先学习阻塞I/O.非阻塞I/O .I/O复用(select和poll),先学习一下基础概念 a -- 阻塞 

Hasen的linux设备驱动开发学习之旅--阻塞与非阻塞I/O

/** * Author:hasen * 参考 :<linux设备驱动开发详解> * 简介:android小菜鸟的linux * 设备驱动开发学习之旅 * 主题:阻塞与非阻塞I/O * Date:2014-11-05 */ 阻塞操作是指在执行设备操作时,若不能获得资源,则挂起进程直到满足可操作的条件后再进行操作.被 挂起的进程进入休眠状态,被从调度器的运行队列移走,直到等待的条件被满足.而非阻塞操作的进程在不能 进行设备操作时,并不挂起,它或者放弃,或者不停地查询,直到条件满足以进行操作为止.

linux阻塞与非阻塞,同步与异步、I/O模型

1. 概念理解      在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式: 同步: 所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回.也就是必须一件一件事做,等前一件做完了才能做下一件事. 例如普通B/S模式(同步):提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事 异步: 异步的概念和同步相对.当一个异步过程调用发出后,调用者不能立刻得到结果.实际处理这个调用的部件

linux同步与异步、阻塞与非阻塞概念以及五种IO模型

1.概念剖析 相信很多从事linux后台开发工作的都接触过同步&异步.阻塞&非阻塞这样的概念,也相信都曾经产生过误解,比如认为同步就是阻塞.异步就是非阻塞,下面我们先剖析下这几个概念分别是什么含义. 同步:所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回.也就是必须一件一件事做,等前一件做完了才能做下一件事. 例如普通B/S模式(同步):提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事 异步:异步的概念和同步相对.当一个异步过程