Linux下利用信号的异步串口中断响应

2023-05-16

    先悔过一下。因为一个月前就在学习这个,当时解决的差不多了,想着抽个空再记录这些,没想到这么短的时间就已经忘得

差不多了,真是不好,应该趁热打铁。废话不多说了,这里主要介绍在Linux下,利用信号来实现异步的串口中断响应。主要思路

很简单,首先是关联信号,在此是关联处理SIGPOLL;其次是等待指定的信号。
    异步I/O的实现有很多方式,【2】中提了几种,还有较新的epoll,和Poll本质上差不多。但本人当时尚不理解这些,没有明

白select、Poll等的具体做法,也采用了多线程。其实万万不该,由于逻辑处理的不好而导致的程序不可预测性太多,因此不太

同意【2】中的观点,只是用来参考使用了。但我这里讲的做法也是在多线程条件下的异步串口通信。
    Linux下信号的概念、原理以及初步的应用【1】中的上、下已经讲解得非常到位了,仔细读读都能找到自己所需要的。下面

具体记录我的实现过程。
    (1)关联信号。
     首先是利用sigaction函数来将指定的信号与处理函数关联,以及通过fcntl函数确定是在哪个线程中,关联哪个设备文件。

那么先是sigaction函数的原型:int sigaction(int signum,const struct sigaction  *act ,struct sigaction  *oldact);

其中struct sigaction 中的内容意义可以看【3】,
        struct sigaction sact;   
        sigemptyset(&sact.sa_mask);             //一般都先清空关注的信号集
        sact.sa_flags=SA_SIGINFO;  //信号的附加信息传递开关,可以在信号SIGIO上传递附加信息,其实就是

//区别POLL_IN,POLL_OUT,为什么要使用附加信息,自己试试SIGIO信号就知道了,它是读写不加区分的
 sact.sa_sigaction=signal_action; //信号处理函数,由于利用了信号附加信息,函数原型为
//void handler(int signum,siginfo_t *info,void *context);关键是siginfo_t结构体中的si_code,其中存储了POLL_IN等。
//到时候利用info->si_code== POLL_IN或POLL_OUT在串口有读或写时做相应的处理
好了,利用sigaction(SIGPOLL,&sact,NULL);完成信号关联;再通过下面的操作完成指定的设备文件、线程
       fcntl(fd, F_SETOWN, tid);    //tid就是获取的线程号,嵌入式环境下可以使用syscall(SYS_gettid);  
       fcntl(fd, F_SETSIG,SIGPOLL );    //关心SIGPOLL信号
       fcntl(fd,F_SETFL,O_ASYNC|O_NONBLOCK);   //异步的
     (2)等待信号
      其实按照上面的做法,完全可以达到当串口有指定数据时进行相应的处理,只要指定的线程在,信号处理函数将会一直起

作用。另一种做法是在接收线程等待信号的发生,而后做相应的处理,自认为双保险,其实很混乱,只是记下来。注意的是在信

号等待或者屏蔽函数中要区分是对线程起作用的还是作用在进程上的。【1】中和【6】中说了很多,我这里只是用到了在线程中

等待信号传递过来的函数sigwaitinfo(),要是想加上时间限制也可以使用sigtimedwait();函数原型:
int sigwaitinfo(const sigset_t *set,siginfo_t *info);按照man中的说法只有当你指定的信号(在参数set信号集中)被传递到使用这个函数的线程时,该函数返回,并将信号的信息存储到后面的info中,也可以供你使用。
     (3)嵌入式环境下,在编译的时候会遇到【4】中的莫名奇妙的问题,其实加上编译开关选项即可-D_GNU_SOURCE,原因么自己看【5】了。
      好了,就这么多了,其实啥也没说,只是把一些可能用到的提了下,跟着路线走,应该能找到自己需要的了。写得太烂了,谁叫给忘得差不多了!@@@
学习参考文献:
【1】http://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index1.html
【2】http://blog.csdn.net/boldeagle/archive/2008/10/18/3095930.aspx
【3】http://baike.baidu.com/view/1748537.htm
【4】http://bbs.chinaunix.net/thread-1731238-1-1.html
【5】http://hi.chinaunix.net/?uid-483016-action-viewspace-itemid-42665
【6】《Unix环境高级编程》

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux下利用信号的异步串口中断响应 的相关文章

  • 如何将一个文本文件拆分为多个 *.txt 文件?

    我有一个文本文件file txt 12 MB 包含 something1 something2 something3 something4 有没有办法分开file txt分成 12 个 txt 文件 比方说file2 txt file3 t
  • Linux中如何避免sleep调用因信号而中断?

    我在 Linux 中使用实时信号来通知串行端口中新数据的到达 不幸的是 这会导致睡眠呼叫在有信号时被中断 有人知道避免这种行为的方法吗 我尝试使用常规信号 SIGUSR1 但我不断得到相同的行为 来自 nanosleep 联机帮助页 nan
  • 对于任何真实数据集,数据压缩比的最小可能值是多少

    我在写信ZLIB类似于嵌入式硬件压缩器的 API 它使用 deflate 算法来压缩给定的输入流 在进一步讨论之前 我想解释一下数据压缩率 数据压缩率定义为未压缩大小与压缩大小之间的比率 压缩比通常大于一 这意味着压缩数据通常比未压缩数据小
  • 如何获取与 shell 中的文件名模式匹配的所有文件的总文件大小?

    我正在尝试仅使用 shell 来计算与文件名模式匹配的所有文件 在目录树中 的总大小 以字节为单位 这是我到目前为止所拥有的 find name undo exec stat c s awk 总计 1 END 打印总计 有没有更简单的方法来
  • bash 将输出重定向到文件,但结果不完整

    重定向命令输出的问题已经被问过很多次了 但是我有一个奇怪的行为 我使用的是 bash shell debian 版本 4 3 30 1 release 并尝试将输出重定向到文件 但并非所有内容都记录在文件中 我尝试运行的 bin 文件是 l
  • 如何从 Bash 命令行在后台 Vim 打开另一个文件?

    我正在从使用 Gvim 过渡到使用控制台 Vim 我在 Vim 中打开一个文件 然后暂停 Vim 在命令行上运行一些命令 然后想返回到 Vim Ctrl Z 在正常模式下 暂停 Vim 并返回到控制台 fg可用于将焦点返回到 Vim job
  • MySQL 与 PHP 的连接无法正常工作

    这是我的情况 我正在尝试使用 Apache 服务器上的 PHP 文件连接到 MySQL 数据库 现在 当我从终端运行 PHP 时 我的 PHP 可以连接到 MySQL 数据库 使用 php f file php 但是当我从网页执行它时 它只
  • Ruby:在 Ubuntu 上安装 rmagick

    我正在尝试在 Ubuntu 10 04 上安装 RMagick 看起来here https stackoverflow com questions 1482823 is there an easy way to install rmagic
  • 为什么此 NASM 代码会打印我的环境变量?

    本学期我刚刚完成计算机体系结构课程 除其他外 我们一直在涉足 MIPS 汇编并在 MARS 模拟器中运行它 今天 出于好奇 我开始在我的 Ubuntu 机器上摆弄 NASM 基本上只是将教程中的内容拼凑起来 并感受一下 NASM 与 MIP
  • 如何在 Linux 和 C 中使用文件作为互斥体?

    我有不同的进程同时访问 Linux 中的命名管道 并且我想让此访问互斥 我知道可以使用放置在共享内存区域中的互斥体来实现这一点 但作为一种家庭作业 我有一些限制 于是 我想到的是对文件使用锁定原语来实现互斥 我做了一些尝试 但无法使其发挥作
  • 使用 libusb 输出不正确

    我用libusb编写了一个程序 我怀疑输出是否正确 因为所有条目都显示相同的供应商和产品 ID 以下是代码 include
  • Linux无法删除文件

    当我找到文件时 我在删除它们时遇到问题 任务 必须找到带有空格的文件并将其删除 我的尝试 rm find L root grep i 但我有错误 rm cannot remove root test No such file or dire
  • Python 3.4.3 subprocess.Popen 在没有管道的情况下获取命令的输出?

    我试图将命令的输出分配给变量 而不让命令认为它正在通过管道传输 原因是 如果正在通过管道传输 则相关命令会给出未格式化的文本作为输出 但如果从终端运行 则会给出颜色格式化的文本 我需要获取这种颜色格式的文本 到目前为止我已经尝试了一些事情
  • 如何在不使用 IDE 的情况下在 Linux 上运行 Java 项目

    我是 Java 新手 基本上 我开发了一个java项目 其中包含Eclipse中的多个Java包 该项目在我安装了 redhat Linux 的桌面上运行正常 然而 我需要在一个更强大的没有安装X11的Linux服务器 redhat ent
  • 如何才能将 TCP 连接返回到同一端口?

    机器是 RHEL 5 3 内核 2 6 18 有时我在 netstat 中注意到我的应用程序有连接 建立了 TCP 连接本地地址 and 国外地址是一样的 其他人也报告了同样的问题 症状与链接中描述的相同 客户端连接到本地运行的服务器的端口
  • grep 排除文件的数组参数

    我想从我的文件中排除一些文件grep命令 为此我使用参数 exclude excluded file ext 为了更容易阅读 我想使用包含排除文件的 bash 数组 EXCLUDED FILES excluded file ext 然后将
  • 批量删除文件名中包含 BASH 中特殊字符的子字符串

    我的目录中有一个文件列表 opencv calib3d so2410 so opencv contrib so2410 so opencv core so2410 so opencv features2d so2410 so opencv
  • 适用于 Linux 的轻量级 IDE [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 调用 printf 系统子例程在汇编代码中输出整数错误[重复]

    这个问题在这里已经有答案了 来回 在windows7控制台窗口中运行gcc s2 asm 然后生成一个exe文件 运行a exe 然后崩溃 为什么 s2 asm 代码由以下源代码生成 int m m 1 iprint m s2 asm请参考
  • 通过 Visual Studio 2017 使用远程调试时 Linux 控制台输出在哪里?

    我的Visual Studio 2017 VS2017 成功连接Linux系统 代码如下 include

随机推荐