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.\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

时间: 2024-10-23 18:35:42

Android驱动开发之Hello实例的相关文章

Android驱动开发之earlysuspend睡眠模式--实现代码【转】

本文转载自:http://blog.csdn.net/MyArrow/article/details/8136018 (1)添加头文件: #include <linux/earlysuspend.h> (2)在特定驱动结构体中添加early_suspend结构: #ifdef CONFIG_HAS_EARLYSUSPENDstruct early_suspend early_suspend;#endif (3)在驱动probe函数中注册相关early_suspend结构体: #ifdef CO

Android底层开发之Audio HAL

http://blog.csdn.net/kangear/article/details/44939429 Android底层开发之Audio HAL 在Android音频底层调试-基于tinyalsa中以「抛开Android的天生复杂,回归嵌入式Linux的本质」的方式介绍如何调试Linux内核中的音频驱动. 这里向上再伸展一下进入HAL层,看是如何将tinyalsa封装给Frameworks使用的. 基于4.2.2版本源码进行讨论.Android官方教程是Audio Implementing

Android底层开发之Linux输入子系统要不要推断系统休眠状态上报键值

Android底层开发之Linux输入子系统要不要推断系统休眠状态上报键值 题外话:一个问题研究到最后,那边记录文档的前半部分基本上都是没用的,甚至是错误的. 重点在最后,前边不过一些假想猜測. http://blog.csdn.net/kangear/article/details/40072707 在调试一下红外遥控器input驱动时,直接採用的是一个半成品的驱动在上边实现的自己的设备的匹配,但同一时候遇到了一些关于input输入子系统的疑惑. 按键一般有「按下和抬起」两个状态一般使用0和1

Android底层开发之Linux输入子系统要不要判断系统休眠状态上报键值

Android底层开发之Linux输入子系统要不要判断系统休眠状态上报键值 题外话:一个问题研究到最后,那边记录文档的前半部分基本上都是无用的,甚至是错误的.重点在最后,前边仅仅是一些假想推测. http://blog.csdn.net/kangear/article/details/40072707 在调试一下红外遥控器input驱动时,直接采用的是一个半成品的驱动在上边实现的自己的设备的匹配,但同时遇到了一些关于input输入子系统的疑惑. 按键一般有「按下和抬起」两个状态一般使用0和1来分

Android 安全开发之 ZIP 文件目录遍历

1.ZIP文件目录遍历简介 因为ZIP压缩包文件中允许存在"../"的字符串,攻击者可以利用多个"../"在解压时改变ZIP包中某个文件的存放位置,覆盖掉应用原有的文件.如果被覆盖掉的文件是动态链接so.dex或者odex文件,轻则产生本地拒绝服务漏洞,影响应用的可用性,重则可能造成任意代码执行漏洞,危害用户的设备安全和信息安全.比如近段时间发现的"寄生兽"漏洞.海豚浏览器远程命令执行漏洞.三星默认输入法远程代码执行漏洞等都与ZIP文件目录遍历有

Android快速开发之appBase——(6).HttpReq和APICloudSDK

Android快速开发之appBase--(6).HttpReq和APICloudSDK HttpReq和APICloudSDK都是网络请求组件,都是基于xUtils的HttpUtils重新封装的.接下来讲一下使用方法. 1.HttpReq 看以看到有这么几个方法 GET:GET方式请求 POST:普通的POST表单提交 POST:将数据以流的形式传递 /** * POST请求,用InputStream的方式传递请求参数 * * @param api * 接口地址 * @param reques

Android快速开发之appBase——(1).appBase介绍

Android快速开发之appBase--(1).appBase介绍 一直想写博客,苦于自己的文笔实在不行,在CSDN潜水了好几年,中间差不多3年没有写过博客.原因有二:1.文笔差:2.没时间. 今年开始,时间充裕了,开始计划练练自己的文笔,也让自己成长起来,希望从中能够提升自己的能力.望大家多多支持和关注!! 导读:appBase是什么? appBase是一个Android app开发的基础集合,目的是任何应用都可以在这个基础之上开发app,省去了搭建框架的时间. appBase=xutils

Android快速开发之appBase——(2).万能的Adapter

Android快速开发之appBase--(2).万能的Adapter android的Adapter是常用的一个组件,自定义的adapter基本上都是集成BaseAdapter,然后实现getView等一系列方法.时间长了,难免让人感觉到写的重复性代码过多,那么万能的Adapter讲解放你的双手. 对比 BaseAdapter package com.snicesoft.appbase.demo; import java.util.ArrayList; import java.util.Lis

android软件开发之webView.addJavascriptInterface循环渐进【二】

说明 文章列表 android软件开发之webView.addJavascriptInterface循环渐进[一]: http://www.sollyu.com/android-software-development-webview-addjavascriptinterface-cycle-of-gradual-oneandroid软件开发之webView.addJavascriptInterface循环渐进[二]: http://www.sollyu.com/586 上一篇文章发布之后,得到