標(biāo)題優(yōu)化方法郴州seo快速排名
linux內(nèi)核中存在一個(gè)信號(hào)SIGIO,這個(gè)信號(hào)就是用于實(shí)現(xiàn)信號(hào)驅(qū)動(dòng)IO的。當(dāng)應(yīng)用程序中想要以信號(hào)驅(qū)動(dòng)IO的模型讀寫硬件數(shù)據(jù)時(shí),首先注冊一個(gè)SIGIO信號(hào)的信號(hào)處理函數(shù),當(dāng)硬件數(shù)據(jù)就緒,硬件會(huì)發(fā)起一個(gè)中斷,在硬件的中斷處理函數(shù)中向當(dāng)前進(jìn)程發(fā)送SIGIO信號(hào),此時(shí)進(jìn)程捕獲到SIGIO信號(hào),執(zhí)行信號(hào)處理函數(shù),在信號(hào)處理函數(shù)中將準(zhǔn)備好的硬件數(shù)據(jù)讀走.
對(duì)于應(yīng)用程序主程序的執(zhí)行和SIGIO信號(hào)的發(fā)送的過程是一個(gè)異步的過程,信號(hào)驅(qū)動(dòng)IO是唯一一種異步IO。
(異步操作是指在執(zhí)行操作期間不會(huì)阻塞進(jìn)程或線程的操作。在驅(qū)動(dòng)開發(fā)中,異步操作通常是通過使用工作隊(duì)列、定時(shí)器、中斷處理程序等機(jī)制來實(shí)現(xiàn)的。)
驅(qū)動(dòng)代碼
#include <linux/init.h>
#include <linux/module.h>
#include<linux/fs.h>
#include<linux/io.h>
#include<linux/device.h>
#include<linux/uaccess.h>
#include<linux/poll.h>
struct class *cls;
struct device *dev;
unsigned int major;//定義一個(gè)變量保存主設(shè)備號(hào)
char kbuf[128]={0};
struct fasync_struct *fapp;//定義一個(gè)異步對(duì)象指針
//封裝操作方法
int mycdev_open(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}
ssize_t mycdev_read(struct file *file, char *ubuf, size_t size, loff_t *lof)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);if(size>sizeof(kbuf))//用戶的需求內(nèi)核滿足不了{(lán)size=sizeof(kbuf);}long ret;ret=copy_to_user(ubuf,kbuf,size);if(ret){printk("copy_to_user filed\n");return -EIO;}return 0;
}
ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *lof)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);if(size>sizeof(kbuf))//用戶的需求內(nèi)核滿足不了{(lán)size=sizeof(kbuf);}long ret;ret=copy_from_user(kbuf,ubuf,size);//表示模擬硬件數(shù)據(jù)就緒if(ret){printk("copy_from_user filed\n");return -EIO;}//發(fā)送信號(hào)kill_fasync(&fapp,SIGIO,POLL_IN);return 0;
}
//封裝fasync操作方法
int mycdev_fasync(int fd, struct file * file, int on)
{//完成發(fā)生信號(hào)之前的準(zhǔn)備工作fasync_helper(fd,file,on,&fapp);return 0;
}
int mycdev_close(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}
//定義一個(gè)操作方法結(jié)構(gòu)體變量并且初始化
struct file_operations fops={.open=mycdev_open,.release=mycdev_close,.read=mycdev_read,.fasync=mycdev_fasync,.write=mycdev_write,
};
static int __init mycdev_init(void)
{//注冊字符設(shè)備驅(qū)動(dòng)major=register_chrdev(0,"mychrdev",&fops);if(major<0){printk("注冊字符設(shè)備驅(qū)動(dòng)失敗\n");return major;}printk("注冊字符設(shè)備驅(qū)動(dòng)成功major=%d\n",major);// 向上提交目錄cls = class_create(THIS_MODULE, "myled");if (IS_ERR(cls)){printk("向上提交目錄失敗\n");return -PTR_ERR(cls);}printk("向上提交目錄信息成功\n");// 向上提交設(shè)備節(jié)點(diǎn)信息dev = device_create(cls, NULL, MKDEV(major, 0), NULL, "mycdev");if (IS_ERR(dev)){printk("向上提交設(shè)備節(jié)點(diǎn)信息失敗\n");return -PTR_ERR(dev);}printk("向上提交設(shè)備節(jié)點(diǎn)成功\n");return 0;
}
static void __exit mycdev_exit(void)
{// 銷毀節(jié)點(diǎn)信息device_destroy(cls, MKDEV(major, 0));// 銷毀目錄信息class_destroy(cls);//注銷字符設(shè)備驅(qū)動(dòng)unregister_chrdev(major,"mychrdev");}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
應(yīng)用程序-讀數(shù)據(jù)
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/epoll.h>
#include <signal.h>
/* According to earlier standards */
#include <sys/time.h>char buf[128] = {0};
int fd;
// 定義信號(hào)處理函數(shù)
void sigio_handler(int sig)
{// 讀取硬件數(shù)據(jù)read(fd, buf, sizeof(buf));printf("buf:%s\n", buf);
}
int main(int argc, char const *argv[])
{// 打開文件fd = open("/dev/mycdev", O_RDWR);if (fd < 0){printf("打開設(shè)備文件失敗\n");exit(-1);}// 注冊SIGIO的信號(hào)處理函數(shù)signal(SIGIO, sigio_handler);// 回調(diào)驅(qū)動(dòng)中的fasync方法,完成驅(qū)動(dòng)中發(fā)生信號(hào)之前的準(zhǔn)備工作int flags = fcntl(fd, F_GETFL); // 獲取文件描述符的相關(guān)屬性fcntl(fd, F_SETFL, flags | FASYNC); // 當(dāng)文件描述符中有FASYNC這個(gè)標(biāo)志時(shí),驅(qū)動(dòng)中fasync方法就會(huì)被調(diào)用// 設(shè)置文件描述符fd對(duì)應(yīng)的驅(qū)動(dòng)發(fā)生SIGIO信號(hào)只發(fā)送給當(dāng)前進(jìn)程fcntl(fd, F_SETOWN, getpid());while (1){printf("aaaaa\n");sleep(1);}return 0;
}
應(yīng)用程序-模擬中斷
#include<stdlib.h>
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<unistd.h>
#include<string.h>int main(int argc, char const *argv[])
{int a,b;char buf[128]="hello world";int fd=open("/dev/mycdev",O_RDWR);if(fd<0){printf("打開設(shè)備文件失敗\n");exit(-1);}write(fd,buf,sizeof(buf));close(fd);return 0;
}