1. 程式人生 > >Android驅動開發之Hello實例

Android驅動開發之Hello實例

oid kcon src fas inux tar ins view instr

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.\n"); ret = alloc_chrdev_region(&devno, hello_minor, DEVICE_SUM, "hello"); if(ret < 0){ printk(KERN_ALERT"hello:Failed to alloc char dev region.\n"); 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.\n", ret); return 0; }else{ printk(KERN_ALERT"hello:hello register success.\n"); } 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.\n");
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\n"); /*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.\n"); return ret; } /*release device*/ static int hello_release(struct inode *inode, struct file *filp){ printk(KERN_ALERT"kernel:release success.\n"); return 0; } /*read device*/ static int hello_read(struct file *filp, char *buf, size_t len, loff_t *off){ printk(KERN_ALERT"kernel:reading...\n"); 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...\n"); 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!\n", TAG, __FUNCTION__); int fd = -1; int val = 0; fd = open(DEVICE_NAME, O_RDWR); if(fd <= 0){ ALOGI("%s : %s open device [%s] failed!\n", TAG, __FUNCTION__, DEVICE_NAME); return FAILED; } ALOGI("%s : %s start to read device info!\n", TAG, __FUNCTION__); read(fd, &val, sizeof(val)); ALOGI("%s : %s read value=%d\n", TAG, __FUNCTION__, val); ALOGI("********************************************\n"); val = 5; ALOGI("%s : %s start write value %d to %s\n", TAG, __FUNCTION__, val, DEVICE_NAME); write(fd, &val, sizeof(val)); ALOGI("*********************************************\n"); ALOGI("%s : %s read device value again!\n", TAG, __FUNCTION__); read(fd, &val, sizeof(val)); ALOGI("%s : %s read value=%d\n", 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!\n", TAG, __FUNCTION__); if(module == NULL){ ALOGE("%s : %s NULL point received!\n", __FUNCTION__); return FAILED; } return SUCCESS; } static int32_t module_deinit(const mmi_module_t * module){ ALOGI("%s : %s start!\n", TAG, __FUNCTION__); if(module == NULL){ ALOGE("%s : %s NULL point received!\n", 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!\n", TAG, __FUNCTION__); return FAILED; } g_module = module; paras = params; ALOGI("%s start.command : %s\n", __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!\n", TAG, __FUNCTION__); cb_function(HELLO_TEST_FAILED, strlen(HELLO_TEST_FAILED)); }else{ ALOGI("%s : %s open hello module success!\n", 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!\n", TAG, __FUNCTION__, cmd); ret = FAILED; } return ret; } static int32_t module_stop(const mmi_module_t *module){ ALOGI("%s : %s start.\n", __FUNCTION__); if(module == NULL){ ALOGE("%s : %s NULL point received!\n", 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

Android驅動開發之Hello實例