zoukankan      html  css  js  c++  java
  • Android驱动开发之Hello实例

    Android驱动开发之Hello实例:
     
    驱动部分
    modified:   kernel/arch/arm/configs/msm8909-1gb_w100_hd720p-perf_defconfig
    modified:   kernel/arch/arm/configs/msm8909-1gb_w100_hd720p_defconfig
    modified:   kernel/drivers/input/misc/Kconfig
    modified:   kernel/drivers/input/misc/Makefile
                    kernel/drivers/input/misc/hello.c
     
    FFBM部分:用来测试驱动是否正常运行
    modified:   vendor/qcom/proprietary/common/build/fastmmi/mmi.mk
    modified:   vendor/qcom/proprietary/fastmmi/res/config/mmi-W200_W.cfg
    modified:   vendor/qcom/proprietary/fastmmi/res/layout/Android.mk
    modified:   vendor/qcom/proprietary/fastmmi/res/values/strings.xml
                    vendor/qcom/proprietary/fastmmi/module/hello/
                    vendor/qcom/proprietary/fastmmi/module/hello/Android.mk
                    vendor/qcom/proprietary/fastmmi/module/hello/hello.cpp
                    vendor/qcom/proprietary/fastmmi/res/layout/layout_hello.xml
     
    SELinux安全,用来允许mmi访问/dev/hello节点
    modified:   device/qcom/sepolicy/common/mmi.te
    modified:   external/sepolicy/device.te
    modified:   external/sepolicy/file_contexts
     
     
    1) kernel/drivers/input/misc/hello.c
     
    #include <linux/types.h>
    #include <linux/module.h>
    #include <linux/fs.h>
    #include <linux/init.h>
    #include <linux/cdev.h>
    #include <linux/device.h>
    #include <linux/slab.h>
    #include <asm/uaccess.h>
     
    MODULE_AUTHOR("zhaopuqing");
    MODULE_LICENSE("Dual BSD/GPL");
    MODULE_VERSION("hello v1.0");
    MODULE_ALIAS("Hello");
     
    #define DEVICE_SUM 1
     
    static int hello_open(struct inode *inode, struct file *filp);
    static int hello_release(struct inode *, struct file *filp);
    static ssize_t hello_read(struct file*, char*, size_t, loff_t*);
    static ssize_t hello_write(struct file*, const char*, size_t, loff_t*);
     
    /*the major device number*/
    static int hello_major = 0;
    static int hello_minor = 0;
     
    static struct class* hello_class = NULL;
     
    /*init the file_operations structure*/
    struct file_operations hello_fops = {
        .owner = THIS_MODULE,
        .open = hello_open,
        .release = hello_release,
        .read = hello_read,
        .write = hello_write,
    };
     
    struct cdev *cdev;
     
    static int global_var = 0; /*global var*/
     
    /*module init*/
    static int __init hello_init(void){
        int ret = 0;
        struct device* temp = NULL;
        dev_t devno = 0;
        printk("hello:hello_init. ");
     
        ret = alloc_chrdev_region(&devno, hello_minor, DEVICE_SUM, "hello");
        if(ret < 0){
            printk(KERN_ALERT"hello:Failed to alloc char dev region. ");
    goto fail;
        }
     
        hello_major = MAJOR(devno);
        hello_minor = MINOR(devno);
     
        cdev = cdev_alloc();
        cdev->owner = THIS_MODULE;
        cdev->ops = &hello_fops;
        if((ret = cdev_add(cdev, devno, 1))){
            printk(KERN_NOTICE"Hello:Error%d adding hello. ", ret);
    return 0;
        }else{
            printk(KERN_ALERT"hello:hello register success. ");
        }
     
        hello_class = class_create(THIS_MODULE, "hello");
        if(IS_ERR(hello_class)){
            ret = PTR_ERR(hello_class);
    printk(KERN_ALERT"Failed to create hello class. ");
    goto destroy_cdev;
        }
     
        temp = device_create(hello_class, NULL, devno, "%s", "hello");
        if(IS_ERR(temp)){
         ret = PTR_ERR(temp);
    printk(KERN_ALERT"Failed to create hello device.");
    goto destroy_class;
        }
     
        return ret;
     
        destroy_class:
         class_destroy(hello_class);
        destroy_cdev:
         cdev_del(cdev);
        fail:
         return ret;
    }
     
    static void __exit hello_exit(void){
        
        dev_t devno = MKDEV(hello_major, 0);
        printk(KERN_ALERT"Goodbye, cruel world ");
        
        /*remove cdev from kernel*/
        cdev_del(cdev);
     
        /*unregister the device device driver*/
        unregister_chrdev_region(devno, 1);
     
        /*free the dev structure*/
        if(cdev)
         kfree(cdev);
        cdev = NULL;
    }
     
    /*open device*/
    static int hello_open(struct inode *inode, struct file *filp){
        int ret = 0;
        printk(KERN_ALERT"kernel:open success. ");
        return ret;
    }
     
    /*release device*/
    static int hello_release(struct inode *inode, struct file *filp){
        printk(KERN_ALERT"kernel:release success. ");
        return 0;
    }
     
    /*read device*/
    static int hello_read(struct file *filp, char *buf, size_t len, loff_t *off){
        printk(KERN_ALERT"kernel:reading... ");
        if(copy_to_user(buf, &global_var, sizeof(int))){
            return -EFAULT;
        }
        return sizeof(int);
    }
     
    /*write device*/
    static ssize_t hello_write(struct file *filp, const char *buf, size_t len, loff_t *off){
        printk(KERN_ALERT"kernel:writing... ");
        if(copy_from_user(&global_var, buf, sizeof(int))){
            return -EFAULT;
        }
        return sizeof(int);
    }
     
    /*module register*/
    module_init(hello_init);
    module_exit(hello_exit);
     
    ******************************************************
    2) kernel/drivers/input/misc/Kconfig
    config SENSORS_HELLO
           tristate "Hello"
           depends on SPI=y
           help
             If you say yes here you get supoort for Hello's
             hello test.
     
     
    ******************************************************
    3) kernel/drivers/input/misc/Makefile
    obj-$(CONFIG_SENSORS_HELLO)     += hello.o
     
    ******************************************************
    4) kernel/arch/arm/configs/msm8909-1gb_w100_hd720p-perf_defconfig
    CONFIG_SENSORS_HELLO=y
     
    *******************************************************
    5) kernel/arch/arm/configs/msm8909-1gb_w100_hd720p_defconfig
    CONFIG_SENSORS_HELLO=y
     
    **************************************************
    6) vendor/qcom/proprietary/fastmmi/module/hello/hello.cpp
    #include "mmi_module.h"
     
    #define TAG "Hello"
    #define DEVICE_NAME "/dev/hello"
    #define HELLO_TEST_WAIT "hello test,please waitting...."
    #define HELLO_TEST_SUCCESS "hello test success!"
    #define HELLO_TEST_FAILED "hello test failed!"
     
    static const mmi_module_t* g_module;
    static unordered_map < string, string > paras;
     
    static void cb_function(const char *str, int size){
        if(g_module != NULL){
            g_module->cb_print(paras[KEY_MODULE_NAME].c_str(),SUBCMD_MMI, str, size, PRINT);
        }
    }
     
    int hello_test(){
        ALOGI("%s : %s start! ", TAG, __FUNCTION__);
     
        int fd = -1;
        int val = 0;
     
        fd = open(DEVICE_NAME, O_RDWR);
        if(fd <= 0){
         ALOGI("%s : %s open device [%s] failed! ", TAG, __FUNCTION__, DEVICE_NAME);
    return FAILED;
        }
     
        ALOGI("%s : %s start to read device info! ", TAG, __FUNCTION__);
        read(fd, &val, sizeof(val));
        ALOGI("%s : %s read value=%d ", TAG, __FUNCTION__, val);
     
        ALOGI("******************************************** ");
        val = 5;
        ALOGI("%s : %s start write value %d to %s ", TAG, __FUNCTION__, val, DEVICE_NAME);
        write(fd, &val, sizeof(val));
     
        ALOGI("********************************************* ");
        ALOGI("%s : %s read device value again! ", TAG, __FUNCTION__);
        read(fd, &val, sizeof(val));
        ALOGI("%s : %s read value=%d ", TAG, __FUNCTION__, val);
     
        close(fd);
     
        return SUCCESS;
    }
     
    static int32_t module_init(const mmi_module_t * module, unordered_map < string, string > &params){
        ALOGI("%s : %s start! ", TAG, __FUNCTION__);
        
        if(module == NULL){
         ALOGE("%s : %s NULL point received! ", __FUNCTION__);
    return FAILED;
        }
     
        return SUCCESS;
    }
     
    static int32_t module_deinit(const mmi_module_t * module){
        ALOGI("%s : %s start! ", TAG, __FUNCTION__);
     
        if(module == NULL){
         ALOGE("%s : %s NULL point received! ", TAG, __FUNCTION__);
    return FAILED;
        }
     
        return SUCCESS;
    }
     
    static int32_t module_run(const mmi_module_t * module, const char *cmd, unordered_map < string ,string > &params){
        int ret = FAILED;
     
        if(!module || !cmd){
         ALOGE("%s : %s NULL point received! ", TAG, __FUNCTION__);
    return FAILED;
        }
     
        g_module = module;
        paras = params;
        ALOGI("%s start.command : %s ", __FUNCTION__, cmd);
        cb_function(HELLO_TEST_WAIT, strlen(HELLO_TEST_WAIT));
     
        if(!strcmp(cmd, SUBCMD_MMI)){
    ret = hello_test();
    if(ret != SUCCESS){
        ALOGE("%s : %s open hello module failed! ", TAG, __FUNCTION__);
        cb_function(HELLO_TEST_FAILED, strlen(HELLO_TEST_FAILED));
    }else{
        ALOGI("%s : %s open hello module success! ", TAG, __FUNCTION__);
        cb_function(HELLO_TEST_SUCCESS, strlen(HELLO_TEST_SUCCESS));
    }
        }else if(!strcmp(cmd, SUBCMD_PCBA)){
        
        }else{
         ALOGE("%s : %s Invalid command : %s received! ", TAG, __FUNCTION__, cmd);
    ret = FAILED;
        }
     
        return ret;
    }
     
    static int32_t module_stop(const mmi_module_t *module){
        ALOGI("%s : %s start. ", __FUNCTION__);
        if(module == NULL){
         ALOGE("%s : %s NULL point received! ", TAG, __FUNCTION__);
    return FAILED;
        }
     
        pthread_kill(module->run_pid, SIGUSR1);
        return SUCCESS;
    }
     
    static struct mmi_module_methods_t module_methods = {
        .module_init = module_init,
        .module_deinit = module_deinit,
        .module_run = module_run,
        .module_stop = module_stop,
    };
     
    mmi_module_t MMI_MODULE_INFO_SYM = {
        .version_major = 1,
        .version_minor = 0,
        .name = "Hello",
        .author = "Hello test",
        .methods = &module_methods,
        .module_handle = NULL,
        .supported_cmd_list = NULL,
        .supported_cmd_list_size = 0,
        .cb_print = NULL,
        .run_pid = -1,
    };
     
    *****************************************************
    7) vendor/qcom/proprietary/fastmmi/module/hello/Android.mk
    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_MODULE_OWNER := qti
    LOCAL_PROPRIETARY_MODULE := true
    LOCAL_SRC_FILES := hello.cpp
     
    LOCAL_MODULE := mmi_hello
    LOCAL_CLANG := false
    LOCAL_MODULE_TAGS := optional
    LOCAL_CFLAGS := -Wall
    LOCAL_C_INCLUDES := external/libcxx/include
        $(QC_PROP_ROOT)/fastmmi/libmmi
     
    LOCAL_SHARED_LIBRARIES := libcutils libutils libmmi libhardware libc++
     
    LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
    ifeq ($(TARGET_COMPILE_WITH_MSM_KERNEL), true)
    LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
    endif
     
    include $(BUILD_SHARED_LIBRARY)
     
    ********************************************************
    8) vendor/qcom/proprietary/fastmmi/res/layout/layout_hello.xml
    <?xml version="1.0" encoding="utf-8"?>
    <layout>
        <include layout="header.xml" />
     
        <button
         name="instruction"
    text="hello_notice"
    w_rel="100"
    h_rel="10"
    x_rel="0"
    y_rel="12"
    color="0x007D7DFF" />
        <textview
         name="display"
    text=""
    w_rel="100"
    h_rel="60"
    x_rel="4"
    y_rel="27" />
     
        <include layout="footer.xml" />
    </layout>
     
    ********************************************
    9) vendor/qcom/proprietary/fastmmi/res/values/strings.xml
    <string name="hello">Hello</string>
    <string name="hell_notice">Hello test, just for test!</string>
     
    **************************************************
    10) vendor/qcom/proprietary/fastmmi/res/layout/Android.mk
     
    include $(CLEAR_VARS)
    LOCAL_SRC_FILES := layout_hello.xml
    LOCAL_CFLAGS := -Wall
    LOCAL_MODULE := layout_hello.xml
    LOCAL_MODULE_CLASS := ETC
    LOCAL_MODULE_TAGS := optional
    LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/mmi/layout
    include $(BUILD_PREBUILT)
     
    ***************************************************
    11) vendor/qcom/proprietary/fastmmi/res/config/mmi-W200_W.cfg
    [HELLO]
    lib_name=mmi_hello.so
    enable=1
    automation=0
    display_name=hello
    layout=layout_hello.xml
     
    **********************************************
    12) vendor/qcom/proprietary/common/build/fastmmi/mmi.mk
    MMI += mmi_hello
     
    MMI_RES += layout_hello.xml
     
    ************************************************
    13) external/sepolicy/device.te
    #hello test
    type hello_device, dev_type;
     
    ************************************************
    14) external/sepolicy/file_contexts
    #hello test
    /dev/hello    u:object_r:hello_device:s0
     
    ***************************************************
    15) device/qcom/sepolicy/common/mmi.te
    allow mmi hello_device:chr_file {open read write};
     
    以上为全部测试代码:
    打印内核消息为:adb shell cat /proc/kmsg
  • 相关阅读:
    简单的登录模块
    contextmenu
    C#遍历FTP文件夹/下载
    完整的java字符串编码转换代码
    小技巧,把execl.exe转换成dll
    ExcelHelper Excel,Export,Import
    Python 快速统计数据的去重数和去重数据
    Python 库打包分发简易指南
    Python 函数式编程、装饰器以及一些相关概念简介
    Python 二分查找与 bisect 模块
  • 原文地址:https://www.cnblogs.com/wanghuaijun/p/7749414.html
Copyright © 2011-2022 走看看