用户层与驱动层阻塞读写

来源:互联网 发布:24周胎儿发育标准数据 编辑:程序博客网 时间:2024/04/30 21:06

 方法一:poll调用

 1、内核层

static unsigned int xxx_poll(struct file *filp, poll_table *wait){struct xxx_info *p = filp->private_data; unsigned int mask = 0;poll_wait(filp, &p->read_wait, wait);if (Lx != Hx){mask |= POLLIN|POLLRDNORM;}return mask;}


2、用户层

void *read_thread(void *arg) {INT ret = -1;BYTE buf[300];struct pollfd read_fds;memset(&read_fds, 0, sizeof(read_fds));read_fds.fd = fd;read_fds.events = POLLIN|POLLRDNORM;while (1){if (poll(&read_fds, 1, -1) > 0){if ((read_fds.revents & (POLLIN|POLLRDNORM)) == (POLLIN|POLLRDNORM)){ret = read(fd, buf, 300);if (ret > 0){xxxxxxx(buf,ret);}}}}return NULL;}


 

 

 

方法二:signal

1、内核层

#include <linux/miscdevice.h>#include <linux/delay.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/init.h>#include <linux/mm.h>#include <linux/types.h>#include <linux/delay.h>#include <linux/moduleparam.h>#include <linux/slab.h>#include <linux/errno.h>#include <linux/ioctl.h>#include <linux/cdev.h>#include <linux/string.h>#include <linux/list.h>#include <linux/fs.h>#include <asm/uaccess.h>#include <linux/sched.h>#include <asm/atomic.h>#include <asm/unistd.h>#include <linux/device.h>#include <linux/rtc.h>#include <linux/types.h>#include <linux/stat.h>#include <linux/kthread.h>#define SIG_MYINT  33#define PS_PID     1296static pid_t get_pid_by_name(char *name){struct task_struct *tsk;pid_t pid = -1;for_each_process(tsk) {if (!strcmp(tsk->comm, name)){pid = tsk->pid;    break;}} printk("%s pid = %d\n", name, pid);return pid;}static int send_signal_function(void *arg){siginfo_t info;struct task_struct *p;pid_t pid = -1;info.si_signo= SIG_MYINT;info.si_code= -1;//__SI_RT;info.si_int= 0x8; while (1){  msleep(1000);  /*  pid = get_pid_by_name("./signaltest");  if (pid != -1){   printk("post signal=================\n");   send_sig_info(SIG_MYINT, &info, p);  }  */     for_each_process(p){    if (!strcmp(tsk->comm, "signaltest")){          printk("post signal=================\n");     send_sig_info(SIG_MYINT, &info, p);    }    else{     printk("post signal error\n");    }   }  }  else{   printk("pid not find\n");  } }  return 0;}static struct file_operations signal_fops = {.owner =   THIS_MODULE,};static struct miscdevice misc = {.minor = 255,.name  = "my_signal",.fops  = &signal_fops,};static int __init signal_init(void){int ret = -1;struct task_struct *signal_task; //注册设备ret = misc_register(&misc);if (ret){return ret;}signal_task = kthread_run(send_signal_function, NULL,"send_signal_function");if (IS_ERR(signal_task)){printk("signal thread create error!\n");return -1;}printk("sinal initialization 2011-10-17\n");return ret;}static void __exit signal_exit(void){//注销设备misc_deregister(&misc);  printk("signal unload\n");}module_init(signal_init);module_exit(signal_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("My.Inc.");


2、用户层

#include <stdio.h>#include <stdlib.h>#include <signal.h>#define SIG_MYINT33void my_handler(int signo, siginfo_t *info, void *context){printf("signal number: signo = %d, info->si_signo = %d\n", signo,info->si_signo);printf("info->si_int = %d\n", info->si_int);}int main(int argc, char **argv){struct sigaction new_sa;new_sa.sa_sigaction= my_handler;sigemptyset(&new_sa.sa_mask);new_sa.sa_flags = SA_RESTART | SA_SIGINFO;new_sa.sa_restorer = NULL;sigaction(SIG_MYINT, &new_sa, NULL);while (1){sleep(100);}}


 

 

 

方法三:fasync

1、内核层

static int xxx_fasync(int fd, struct file *filp, int mode){struct xxx_info *p = filp->private_data;if (IS_ERR_OR_NULL(p))return -1;return fasync_helper(fd, filp, mode, &p->async_queue);}


 

static void post_msg_to_user(){if(p->async_queue)kill_fasync(&p->async_queue, SIGIO, POLL_IN);}


 

 

2、用户层

static void read_handler(int num){int ret = 0;BYTE buf[300];ret = read(fd, buf, 300);if (ret > 0){xxxxx(buf, ret);}}static void set_fasync_mode(void){struct sigaction action;memset(&action, 0, sizeof(action));action.sa_sigaction = read_handler;action.sa_flags = 0;sigaction(SIGIO, &action, NULL);fcntl(fd, F_SETOWN, getpid());fcntl(fd, F_SETFL, fcntl(fd, F_GETFL)|FASYNC);}

 

方法四:select()

long serial_read(int fd, unsigned char *buf, int len) {       fd_set read_fds;long ret = -1;struct timeval tv_timeout;
         FD_ZERO(&read_fds);FD_SET(fd, &read_fds);tv_timeout.tv_sec = 1;tv_timeout.tv_usec = 0;switch (select(fd+1, &read_fds, NULL, NULL, &tv_timeout)){case -1:break;//("select error");case 0://("select timeout");break;default:if (FD_ISSET(fd, &read_fds)){//读取数据ret = read(fd, buf, len);}break;}return ret; }


 


 用户层与用户层

#include <stdio.h>   #include <stdlib.h>   #include <signal.h>   #include <string.h>#include <sys/types.h>  #define SIG_MYINT   35   union sigval mysigval; #define PS_COMMAND "ps -ax"#define PROCESS_NAME "./user_one"int lookup_pid(char *name){  FILE *fp;  int  pid = -1;char buf[1024],s[5][64];  fp = popen(PS_COMMAND, "r");if (fp == NULL){printf("\npopen err");return -1;   }while(fgets(buf, sizeof(buf), fp)){sscanf(buf,"%s %s %s %s %s",s[0],s[1],s[2],s[3],s[4]);printf("\n%s,%s,%s,%s,%s", s[0],s[1],s[2],s[3],s[4]);if (!memcmp(s[4], name, strlen(name))){//printf("\nfind.......pid=%s\n", s[0]);//printf("\npid=%d",atoi(s[0])); pid = atoi(s[0]);break;}}fclose(fp);  return pid;} int main(int argc, char **argv)  {  int pid;pid = lookup_pid(PROCESS_NAME);if (pid == -1) {    printf("Error reading pid of %s\n", PROCESS_NAME);    return -1;  }         while (1)      {  printf("\n send signal :%d", SIG_MYINT);//mysigval.sival_int = 333;//system("pidof user_one");//sigqueue(pid,SIG_MYINT,mysigval);/*if(raise(SIG_MYINT)){printf("\n send signal err!");}*/ kill (pid, SIG_MYINT);        sleep(1);      }  } 


 

#include <stdio.h>   #include <stdlib.h>   #include <signal.h>     #define SIG_MYINT   35     void my_handler(int signo, siginfo_t *info, void *context)  {      printf("signal number: signo = %d, info->si_signo = %d\n", signo,info->si_signo);      printf("info->si_int = %d\n", info->si_int);  }    int main(int argc, char **argv)  {      struct sigaction new_sa;        new_sa.sa_sigaction = my_handler;      sigemptyset(&new_sa.sa_mask);      new_sa.sa_flags = SA_RESTART | SA_SIGINFO;      new_sa.sa_restorer = NULL;            sigaction(SIG_MYINT, &new_sa, NULL);        while (1)      {          sleep(100);      }  }