1. 程式人生 > >異步通知

異步通知

mod 要點 按鍵 signed struct /dev/ %x ret mes

先寫一個測試函數:

#include <stdio.h>

#include <signal.h>    //signal函數的需要

設置信號處理函數!!!用signal1.

void  my_signal_fun(int  signum)

{

  static  int  cnt = 0;

  printf("signal = %d,  %d  times\n",  signum,  ++cnt)

}

作用:打印信號。

int main(int  argc,  char  **argv)

{

  signal(SIGUSR1,  my_signal_fun);

信號和中斷差不多,需要註冊

  while(1)

  {

    sleep(1000);

  }

}

可以用kil命令來發送信號,需要明確進程號,即PID數值。

kill -USR1  833  USR1 = 10

kill -10  833

kil  -9  833  默認退出

要點:

  1.註冊信號處理函數

  2.發送信號,kill -10  833

目標:

按下按鍵時,驅動程序通知應用程序

  1.應用程序要註冊信號處理函數

  2.確定誰發信號(驅動)

  3.發給誰(應用),應用程序告訴內核自己的PID!

  4.怎麽發?驅動調用某個函數發送。kill_fasyn

實施:在中斷程序中發送數據

先定義一個結構體:

  static  struct  fasync_struct  *button_async;

  

在中斷程序wake_up下面再加上:

  kill_fasync(&button_async,  SIGIO,  POLL_IN);

建立新的fileoperation結構體L:

static  struct  file_operations  fifth_drv_fops =  {

  .owner  =  THIS_MODULE,

  .open  =  fifth_drv_open;

  .read  =  fifth_drv_read,

  .release =  fifth_drv_release,

  .poll  =  fifth_drv_poll,   

  .fasync =  fifth_drv_fasync

};

新建相應的處理函數:

static  int  fifth_drv_fasync(int  fd,  struct  file  *filp,  int  on)

{

  return  fasync_helper(fd,  filp,  on,  &button_async);

}

通過F_SETTOWN命令,調用fcntl(fd,F_SETDOWN,pid)應用程序調用這個函數來告訴驅動自己的PID。

應用程序讀出flag,並修改之。

Oflags = fcntl(fd,  F_GETFL);

fcntl(fd,  F_SETFL,  oflags  |  FASYNC);

fasync_helper函數用於初始化結構體,

新的main函數:

void  my_signal_fun(int  signum)

{

  unsigned char key_val;

  read(fd,&key_val,1);

  printf("key_val:0x%x\n",key_val);

}

int main(int argc,  char  **argc)

{

  unsigned char key_val;

  int ret;

  signal(SIGIO,my_signal_fun);    //信號處理函數

  fd = open("/dev/buttons",O_RDWR);

  if(fd < 0)

  {

    printf("can‘t  open!\n");

  }

  fcntl(fd,  F_SETOWN,  getpid())

  Oflags  =  fcntl(fd, F_GETFL);

  fcntl(fd,  F_SETFL,  Oflags  |  FASYNC);

  while(1)

  {

    sleep(1000);

  }

}

異步通知