9.Android 添加新模块

本文详述了在Android系统中从驱动层、HAL层、framework层到APP层添加新模块的完整流程,包括代码添加、配置、编译等步骤,并提供了各层的源码位置和关键代码示例。
摘要由CSDN通过智能技术生成

 

 

 

 

框图

这里主要关注➕右下角部分 添加新模块即可。本章节详细解读了android新模块从驱动层、HAL层、framework层、APP层的流程。上面的图添加新模块部分可能会看不清,这里单独截取该部分,如下所示:

这样就清晰多了。本章节主要描述了android系统从上到下添加一个模块的流程,因为仅针对流程,所以关于其使用的原理本部分不会涉及,但在binder以及其他章节中会有所涉及。

1 添加驱动程序(源码见wd_hello_driver),添加流程如下:

1.1 添加代码
对应代码位置-->kernel/drivers/wd_hello,驱动层代码如下:

1 wd_hello.h

#ifndef _WD_HELLO_ANDROID_H_  
#define _WD_HELLO_ANDROID_H_  
 
#include <linux/cdev.h>  
#include <linux/semaphore.h>  
 
#define WD_HELLO_DEVICE_NODE_NAME  "wd_hello"  
#define WD_HELLO_DEVICE_FILE_NAME  "wd_hello"  
#define WD_HELLO_DEVICE_PROC_NAME  "wd_hello"  
#define WD_HELLO_DEVICE_CLASS_NAME "wd_hello"  
 
struct wd_hello_android_dev {  
	int val;  
	struct semaphore sem;  
	struct cdev dev;  
};  
 
#endif  

2 wd_hello.c

#include <linux/init.h>  
#include <linux/module.h>  
#include <linux/types.h>  
#include <linux/fs.h>  
#include <linux/proc_fs.h>  
#include <linux/device.h>  
#include <asm/uaccess.h>  
#include <linux/slab.h>
 
#include "wd_hello.h"  
 
/*主设备和从设备号变量*/  
static int wd_hello_major = 0;  
static int wd_hello_minor = 0;  
 
/*设备类别和设备变量*/  
static struct class* wd_hello_class = NULL;  
static struct wd_hello_android_dev* wd_hello_dev = NULL;  
 
/*传统的设备文件操作方法*/  
static int wd_hello_open(struct inode* inode, struct file* filp);  
static int wd_hello_release(struct inode* inode, struct file* filp);  
static ssize_t wd_hello_read(struct file* filp, char __user *buf, size_t count, loff_t* f_pos);  
static ssize_t wd_hello_write(struct file* filp, const char __user *buf, size_t count, loff_t* f_pos);  
 
/*设备文件操作方法表*/  
static struct file_operations wd_hello_fops = {  
	.owner = THIS_MODULE,  
	.open = wd_hello_open,  
	.release = wd_hello_release,  
	.read = wd_hello_read,  
	.write = wd_hello_write,   
};  

#if 0 
/*访问设置属性方法*/  
static ssize_t wd_hello_val_show(struct device* dev, struct device_attribute* attr,  char* buf);  
static ssize_t wd_hello_val_store(struct device* dev, struct device_attribute* attr, const char* buf, size_t count);  
 
/*定义设备属性*/  
static DEVICE_ATTR(val, S_IRUGO | S_IWUSR, wd_hello_val_show, wd_hello_val_store);  
#endif

///
/*打开设备方法*/  
static int wd_hello_open(struct inode* inode, struct file* filp) {  
	struct wd_hello_android_dev* dev;          
 
	/*将自定义设备结构体保存在文件指针的私有数据域中,以便访问设备时拿来用*/  
	dev = container_of(inode->i_cdev, struct wd_hello_android_dev, dev);  
	filp->private_data = dev;  
 
	return 0;  
}  
 
/*设备文件释放时调用,空实现*/  
static int wd_hello_release(struct inode* inode, struct file* filp) {  
	return 0;  
}  
 
/*读取设备的寄存器val的值*/  
static ssize_t wd_hello_read(struct file* filp, char __user *buf, size_t count, loff_t* f_pos) {  
	ssize_t err = 0;  
	struct wd_hello_android_dev* dev = filp->private_data;          
 
	/*同步访问*/  
	if(down_interruptible(&(dev->sem))) {  
		return -ERESTARTSYS;  
	}  
 
	if(count < sizeof(dev->val)) {  
		goto out;  
	}          
 
	/*将寄存器val的值拷贝到用户提供的缓冲区*/  
	if(copy_to_user(buf, &(dev->val), sizeof(dev->val))) {  
		err = -EFAULT;  
		goto out;  
	}  
 
	err = sizeof(dev->val);  
 
out:  
	up(&(dev->sem));  
	return err;  
}  
 
/*写设备的寄存器值val*/  
static ssize_t wd_hello_write(struct file* filp, const char __user *buf, size_t count, loff_t* f_pos) {  
	struct wd_hello_android_dev* dev = filp->private_data;  
	ssize_t err = 0;          
 
	/*同步访问*/  
	if(down_interruptible(&(dev->sem))) {  
		return -ERESTARTSYS;          
	}          
 
	if(count != sizeof(dev->val)) {  
		goto out;          
	}          
 
	/*将用户提供的缓冲区的值写到设备寄存器去*/  
	if(copy_from_user(&(dev->val), buf, count)) {  
		err = -EFAULT;  
		goto out;  
	}  
 
	err = sizeof(dev->val);  
 
out:  
	up(&(dev->sem));  
	return err;  
}
 #if 0
///
/*读取寄存器val的值到缓冲区buf中,内部使用*/  
static ssize_t __wd_hello_get_val(struct wd_hello_android_dev* dev, char* buf) {  
	int val = 0;          
 
	/*同步访问*/  
	if(down_interruptible(&(dev->sem))) {                  
		return -ERESTARTSYS;          
	}          
 
	val = dev->val;          
	up(&(dev->sem));          
 
	return snprintf(buf, PAGE_SIZE, "%d\n", val);  
}  
 
/*把缓冲区buf的值写到设备寄存器val中去,内部使用*/  
static ssize_t __wd_hello_set_val(struct wd_hello_android_dev* dev, const char* buf, size_t count) {  
	int val = 0;          
 
	/*将字符串转换成数字*/          
	val = simple_strtol(buf, NULL, 10);          
 
	/*同步访问*/          
	if(down_interruptible(&(dev->sem))) {                  
		return -ERESTARTSYS;          
	}          
 
	dev->val = val;          
	up(&(dev->sem));  
 
	return count;  
}  
 
/*读取设备属性val*/  
static ssize_t wd_hello_val_show(struct device* dev, struct device_attribute* attr, char* buf) {  
	struct wd_hello_android_dev* hdev = (struct wd_hello_android_dev*)dev_get_drvdata(dev);          
 
	return __wd_hello_get_val(hdev, buf);  
}  
 
/*写设备属性val*/  
static ssize_t wd_hello_val_store(struct device* dev, struct device_attribute* attr, const char* buf, size_t count) {   
	struct wd_hello_android_dev* hdev = (struct wd_hello_android_dev*)dev_get_drvdata(dev);    
 
	return __wd_hello_set_val(hdev, buf, count);  
}    
 
///
/*读取设备寄存器val的值,保存在page缓冲区中*/  
static ssize_t wd_hello_proc_read(char* page, char** start, off_t off, int count, int* eof, void* data) {  
	if(off > 0) {  
		*eof = 1;  
		return 0;  
	}  
 
	return __wd_hello_get_val(wd_hello_dev, page);  
}  
 
/*把缓冲区的值buff保存到设备寄存器val中去*/  
static ssize_t wd_hello_proc_write(struct file* filp, const char __user *buff, unsigned long len, void* data) {  
	int err = 0;  
	char* page = NULL;  
 
	if(len > PAGE_SIZE) {  
		printk(KERN_ALERT"The buff is too large: %lu.\n", len);  
		return -EFAULT;  
	}  
 
	page = (char*)__get_free_page(GFP_KERNEL);  
	if(!page) {                  
		printk(KERN_ALERT"Failed to alloc page.\n");  
		return -ENOMEM;  
	}          
 
	/*先把用户提供的缓冲区值拷贝到内核缓冲区中去*/  
	if(copy_from_user(page, buff, len)) {  
		printk(KERN_ALERT"Failed to copy buff from user.\n");                  
		err = -EFAULT;  
		goto out;  
	}  
 
	err = __wd_hello_set_val(wd_hello_dev, page, len);  
out:  
	free_page((unsigned long)page);  
	return err;  
}  
 
/*创建/proc/hello文件*/  
sta
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值