Android 应用层如何调用驱动节点

背景介绍:

做系统工程师的,经常会遇到协同开发,驱动同事开发完成后,会给我设备节点,刚好公司新研发了一个项目,我需要在工程模式中开发一个蜂鸣器测试项。

一、蜂鸣器节点

驱动同事给了我蜂鸣器节点:/dev/input/event2 ,我们在adb shell中可以查看到event2的属性
root@yzm7330p0:/ # getevent
add device 1: /dev/input/event2
  name:     "pwm-beeper"
add device 2: /dev/input/event0
  name:     "comip-gpio-keys"
add device 3: /dev/input/event3
  name:     "comip_snd_soc Headset"
add device 4: /dev/input/event1
  name:     "comip-powerkey"

Android可以使用sendevent来模拟触屏,键盘以及其他类型的event事件,

sendevent /dev/input/eventX type code value

/dev/input/eventX 对应一个event设备,可以通过getevent获得可用的event设备

type, code, value的定义可参看kernel/include/Linux/input.h

type如下定义

[html]  view plain  copy
  1. /*  
  2.  * Event types  
  3.  */  
  4. #define EV_SYN          0x00  
  5. #define EV_KEY          0x01  
  6. #define EV_REL          0x02  
  7. #define EV_ABS          0x03  
  8. #define EV_MSC          0x04  
  9. #define EV_SW           0x05  
  10. #define EV_LED          0x11  
  11. #define EV_SND          0x12  
  12. #define EV_REP          0x14  
  13. #define EV_FF           0x15  
  14. #define EV_PWR          0x16  
  15. #define EV_FF_STATUS        0x17  
  16. #define EV_MAX          0x1f  
  17. #define EV_CNT          (EV_MAX+1)  
格式为 device: type code value,即 设备、输入设备类型、按键扫描码、附加码,具体定义可从kernel/include/linux/input.h中获得,至于这个头文件,途径之一是从google官网源码中获取: 

type: 输入设备类型,在手机系统中经常使用的键盘(keyboard)和小键盘(kaypad)属于按键设 
备EV_KEY,轨迹球属于相对设备EV_REL,触摸屏属于绝对设备EV_ABS 
code: 按键扫描码,区别于ASCII码和SDK中KeyEvent的键码 
value: 附加码,1/0 down/up 
按照此格式那么我们蜂鸣器的节点查询后得到:sendevent /dev/input/event2 18 1 1 及 sendevent /dev/input/event2 18 1 0 

二、将数据写入节点

这边我实现了个cmd输入
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
public static String execShellCommand(String cmd) {
        String returnString = "";
        Process pro = null;
        Runtime runTime = Runtime.getRuntime();

        Log.d(TAG, "execShellCommand : " + cmd);
        if (runTime == null) {
            Log.e(TAG, "Create runtime false!");
            return null;
        }

        try {
            pro = runTime.exec(cmd);
            BufferedReader input = new BufferedReader(new InputStreamReader(pro.getInputStream()));
            PrintWriter output = new PrintWriter(new OutputStreamWriter(pro.getOutputStream()));
            String line;
            while ((line = input.readLine()) != null) {
                returnString = returnString + line + "\n";
            }
            input.close();
            output.close();
            pro.destroy();
        } catch (IOException e) {
            e.printStackTrace();
        }

        Log.d(TAG, "execShellCommand result : " + returnString);
        return returnString;
    }

三、权限问题

以上我的思路基本已经实现,然而自己调试的发现,在adb shell中输入节点蜂鸣器响应,而在我写的应用中不会响应,最后查询出来是权限问题。
Android 应用层如何调用驱动节点_第1张图片
大家可以看到对应的节点是input权限,我网上搜索了下input权限一般用于驱动层的service中。
为了解决这个问题,我取了个巧,将event2 这个节点的权限改为了system权限
具体操作是在device\leadcore\common 中的init.rc中修改了他的权限。init.rc 是当我们机器重启的第一时间会执行的文件。
# MAT just have system permissions,set event2 to system
    chown root system /dev/input/event2





你可能感兴趣的:(Android,Linux,驱动)