异步通知 fasync 用法积累

最近工作中用的一个features需要在native层监听kernel层的interrupt上报,最开始使用的方式是最简单的轮询方式,native层开一个线程通过ioctrl的方式去不断的check 驱动的状态,返回check到的data,不过后面发现这样效率有些低下,而且不断的ioctrl操作驱动,功耗方面会比较大,所以就学习了使用异步通知fasync的方式+阻塞来做,下面简单总结下用法:


Kernel层:

1、定义  fasync_struct 结构体指针:
1
static  struct  fasync_struct * fasync_queue  = NULL;

2、填充fasync_helper回调函数:
1
2
3
4
5
static  int  elan_fp_fasync( int  fd,  struct  file * filp,  int  on)
{
     printk( "%s enter \n" ,__func__);
     return  fasync_helper(fd, filp, on, & fasync_queue );
}

3、增加fasync回调函数到文件操作接口:
1
2
3
4
5
6
7
8
9
10
11
12
static  const  struct  file_operations efsa120s_fops = {
     .owner             = THIS_MODULE,
     .open          = efsa120s_open,
     .read          = efsa120s_read,
     .write             = efsa120s_write,
     .unlocked_ioctl = efsa120s_ioctl,
     .compat_ioctl  = efsa120s_compat_ioctl,
     .release       = efsa120s_close,
     .poll          = efsa120s_poll,
     . fasync  =  elan_fp_fasync ,
     
};

4、发送异步通知:
1
2
3
4
5
6
7
8
static  void  efsa120s_fp_work_func( struct  work_struct *work)
{
...
         if  (fasync_queue) {
             kill_fasync (& fasync_queue , SIGIO, POLL_IN);
         }
...
}


Native层:

1、fasync信号 SIGIO注册函数实现:
1
2
3
4
5
6
7
8
9
10
11
void  register_fasync_notify( int  fd)
{
     int  flag;
 
     LOGD(TAG "[%s]\n" , __func__);
     signal (SIGIO,  fasync_input_handler );
     flag = fcntl(fd, F_GETFL);
     flag |= FASYNC;
     fcntl(fd, F_SETFL, flag);
     fcntl(fd, F_SETOWN, getpid());
}

2、fasync 信号响应回调函数实现:
1
2
3
4
5
void  fasync_input_handler ( int  signum)  
{
     LOGD(TAG  "[%s] : %d \n" , __func__, signum);
     sem_post (&wk_sem);  //解除阻塞  
}

3、初始化注册fasync信号监听:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int  elan_dev_init( void )
{
     int  fd;
     int  ret;
  
     LOGD(TAG  "-->[%s]\n" ,__func__);  
  
     if ((fd = open(DRV_ELAN, O_RDWR)) < 0)
     {
         LOGD(TAG  "open:%s err!\n" , DRV_GOODIX);  
         return  -1;
     }
  
     register_fasync_notify (fd);
 
     if (pthread_create(&thd_id, NULL, thread_update_callback, NULL) )
     {
          LOGD(TAG  " thd_id thread create failed.!\n" );
          return  -1;
     }
...

4、最后是业务处理线程函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
static  void  *thread_update_callback( void  *arg)
{
     int  state = 0;  
     int  ret = 0;
 
     LOGD(TAG  "[%s]\n" ,__func__);  
 
     while (1)
     {
         LOGD(TAG  "sem_wait(wk_sem)...\n" );  
         
         sem_wait (&wk_sem);   //阻塞等待.
 
         //do you want do anything...
     }
     
     pthread_exit(NULL);   
     return  NULL;
}











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值