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
  • 相关阅读:
    SQL Azure (17) SQL Azure V12
    Microsoft Azure News(5) Azure新DV2系列虚拟机上线
    Azure Redis Cache (3) 在Windows 环境下使用Redis Benchmark
    Azure PowerShell (11) 使用自定义虚拟机镜像模板,创建Azure虚拟机并绑定公网IP(VIP)和内网IP(DIP)
    Windows Azure Virtual Machine (31) 迁移Azure虚拟机
    Windows Azure Web Site (16) Azure Web Site HTTPS
    Azure China (12) 域名备案问题
    一分钟快速入门openstack
    管理员必备的Linux系统监控工具
    Keepalived+Nginx实现高可用和双主节点负载均衡
  • 原文地址:https://www.cnblogs.com/wanghuaijun/p/7749414.html
Copyright © 2011-2022 走看看