return 0; } static int snsled_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *data) { int len =sprintf(buf, \); return len; } static int snsled_create_proc_file(void) { struct proc_dir_entry *entry = NULL; entry = create_proc_read_entry(SNSLED_PROC_NAME, 0, NULL, snsled_read_proc, NULL); if(entry) { return 0; } else { return -1; } } static int snsled_delete_proc_file(void) { remove_proc_entry(SNSLED_PROC_NAME, NULL); return 0; } MODULE_LICENSE(\); static int snsled_init(void) { int err = -1; dev_t devt = 0; //[1] alloc node number err = vircdex_alloc_major(); if(0 > err) { printk(KERN_ALERT\); goto ALLOC_MAJOR_ERR; } devt = MKDEV(g_snsled_major, g_snsled_minor);
//[2] device object init g_snsled_ptr = kmalloc(sizeof(struct snsled_cntx), GFP_KERNEL); if(!g_snsled_ptr) { err = -ENOMEM; printk(KERN_ALERT\); goto KMALLOC_ERR; } memset(g_snsled_ptr, 0, sizeof(struct snsled_cntx)); //[3] setup device err = snsled_setup_dev(g_snsled_ptr); if(0 > err) { printk(KERN_ALERT\); goto DEVICE_SETUP_ERR; } //[4] create files in directory \ ///err = snsled_create_devfiles(devt, attr); err = snsled_create_devfiles(devt); if(0 > err) { printk(KERN_ALERT\); goto DEVFILES_CREATE_ERR; } //[5] create proc file err = snsled_create_proc_file(); if(0 > err) { printk(KERN_ALERT\); goto PROC_FILE_CREATE_ERR; } return 0; PROC_FILE_CREATE_ERR: snsled_delete_devfiles(devt); DEVFILES_CREATE_ERR: snsled_unsetup_dev(g_snsled_ptr); DEVICE_SETUP_ERR: kfree(g_snsled_ptr); ALLOC_MAJOR_ERR: snsled_release_major();
KMALLOC_ERR: return err; } static void snsled_exit(void) { dev_t devt = MKDEV(g_snsled_major, g_snsled_minor); snsled_delete_proc_file(); snsled_delete_devfiles(devt); snsled_unsetup_dev(g_snsled_ptr); kfree(g_snsled_ptr); snsled_release_major(); } module_init(snsled_init); module_exit(snsled_exit); 二、配置Kconfig 在snsled目录中,新建Kconfig文件: config SNSLED
tristate \ default n #y ? help
This is the sns led driver.
其中,tristate表示编译选项HELLO支持在编译内核时,hello模块支持以模块、内建和不编译三种编译方法。
三、配置Makefile
1、在snsled目录中,新建snsled文件夹对应的Makefile:
#obj-$(CONFIG_SNSLED) += snsled.o obj-y += snsled.o
上面根据 CONFIG_SNSLED的值确定是否编译,y为编译。 2、修改snsled的父目录 drivers/下的Makefile,加入:
obj-$(CONFIG_HELLO) += snsled/ 这样便能在编译时编译到snsled这个文件夹。
四、配置系统的autoconfig
打开 mediatek/config/bbk73_gb/autoconfig/kconfig/project,加入:
CONFIG_SNSLED=y
在这里定义变量 CONFIG_SNSLED.
ps:目前这里配置好像还不能snsled自动编译进去,目前的操作是直接在用到CONFIG_SNSLED的地方用y替代。
五、编译
./makeMtk bbk73_gb remake kernel bootimage
[编写hal模块]
1新建xxx.h文件
进入\目录,新建vircdev.h文件: #ifndef ANDROID_HELLO_INTERFACE_H #define ANDROID_HELLO_INTERFACE_H #include
}; /*硬件接口结构体*/ struct hello_device_t { struct hw_device_t common; int fd; int (*set_val)(struct hello_device_t* dev, int val); int (*get_val)(struct hello_device_t* dev, int* val); }; __END_DECLS #endif 这里按照Android硬件抽象层规范的要求,分别定义模块ID、模块结构体hello_module_t以及硬件接口结构体hello_device_t。在硬件接口结构体中,fd表示设备文件描述符,对应linux下我们经常接触到的设备文件\,set_val和get_val为该HAL对上提供的函数接口。 2新建xxx.c文件 进入到hardware/libhardware/modules目录,新建hello目录,并添加hello.c文件。 hello.c的内容较多,我们分段来看。 1包含相关头文件和定义相关结构 #define LOG_TAG \ #include