1、MTK Android添加驱动模块 1编写linux驱动程序1.1一、编写驱动核心程序1.2二、配置Kconfig1.3三、配置Makefile1.4四、配置系统的autoconfig1.5五、编译 2编写hal模块2.1一、新建xxx.h文件2.2二、新建xxx.c文件2.2.11、包含相关头文件和定义相关结构2.2.22、定义hello_device_open函数2.2.33、定义自定义的api函数2.3三、在hello目录下新建Android.mk文件2.4四、编译、重新打包Android系统镜像system.img3编写jni3.1一、新建com_android_server_Hell
2、oService.cpp文件3.1.11、包括头文件3.1.22、编写jni接口3.1.33、定义jni加载函数,注册jni方法表3.2二、修改onload.cpp,使系统启动时自动加载JNI方法调用表3.3三、修改Android.mk文件,添加编译路径3.4四、编译和重新生成system.img 4编写Framework接口4.1一、定义通信接口4.1.11、新增接口文件4.1.22、添加编译路径4.1.33、编译接口文件4.2二、建立java文件,编写Framework接口4.3三、在ServerThread:run函数中增加加载代码4.4四、编译、重新打包system.img5App访问
3、编写linux驱动程序编写驱动核心程序这里说的驱动核心程序是指运行在内核空间的,完全按linux驱动格式编写的,基本上与android没什么关系,一般包括xxx.h和xxx.c文件。进入到kernel/drivers目录,新建snsled目录,然后建立对应的snsled.h和snsled.c文件:/snsled.h#ifndef _SNSLED_H_#define _SNSLED_H_#define SNSLED_NUM (1)#define SNSLED_CLASS_NAME snsled#define SNSLED_DEVICE_NAME snsled#define SNSLED_NODE
4、_NAME snsled#define SNSLED_PROC_NAME snsled#define SNSLED_IOC_MAGIC k#define SNSLED_IO_ON 2323 /_IO(SNSLED_IOC_MAGIC, 0)#define SNSLED_IO_OFF 2324 /_IO(SNSLED_IOC_MAGIC, 1)#define SNSLED_IOW_PWM 2325 /_IOW(SNSLED_IOC_MAGIC, 2, int)#define SNSLED_IOR_PWM 232 /_IOR(SNSLED_IOC_MAGIC, 3, int)struct snsl
5、ed_cntx int r1; struct semaphore sem; struct cdev cdev;#endif/snsled.c#include #include #include #include /* printk() */#include /* kmalloc() */#include /* everything. */#include /* error codes */#include /* size_t */#include #include /* O_ACCMODE */#include #include #include /* cli(), *_flags */#in
6、clude /* copy_*_user */#include /* semaphore */#include #include /*class_create*/ #include snsled.h /* local definitions */*#include #include #include #include #include #include #include #include #include #include #include */#if defined (CONFIG_ARCH_MT6573)#include #include #include #elif defined (C
7、ONFIG_ARCH_MT6516)#include #include #endif/*=macros=*/#define BUF_SIZE (64)#define SNS_LED_CONTROL_LINE GPIO99 /GPIO39#define SNS_LED_CONTROL_LINE_GPIO_MODE GPIO_MODE_00 #define SNS_LED_CONTROL_LINE_PWM_MODE GPIO_MODE_01/*=declares=*/ssize_t snsled_read(struct file *filp, char _user *buf, size_t cou
8、nt, loff_t *f_pos);ssize_t snsled_write(struct file *filp, const char _user *buf, size_t count, loff_t *f_pos);long snsled_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);int snsled_open(struct inode *inode, struct file *filp);int snsled_release(struct inode *inode, struct fil
9、e *filp);int snsled_turn_on(void);int snsled_turn_off(void);int snsled_set_pwm(int arg);/*=global=*/static int g_snsled_major = 0;static int g_snsled_minor = 0;struct snsled_cntx *g_snsled_ptr = NULL;struct class *g_snsled_class = 0;static struct file_operations g_snsled_fops = .owner = THIS_MODULE,
10、 .read = snsled_read, .write = snsled_write, .unlocked_ioctl = snsled_unlocked_ioctl, .open = snsled_open, .release = snsled_release,;/*=implements=*/ssize_t snsled_read(struct file *filp, char _user *buf, size_t count, loff_t *f_pos) #if 1 printk(KERN_ALERT Snsled read.n);#else char tmp_buf512 = 0;
11、 int len =sprintf(tmp_buf, snsled read.n); if (copy_to_user(buf, tmp_buf, count) /do nothing #endif return 0;ssize_t snsled_write(struct file *filp, const char _user *buf, size_t count, loff_t *f_pos) printk(KERN_ALERT Snsled write.n); return count;long snsled_unlocked_ioctl(struct file *filp, unsig
12、ned int cmd, unsigned long arg) int err = 0; long retval = 0; printk(KERN_ALERT Snsled ioctl:cmd=%d, arg=%d.n, cmd, arg); /* /extract the type and number bitfields, and dont decode /wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok() if (_IOC_TYPE(cmd) != SNSLED_IOC_MAGIC) return -ENO
13、TTY; /if (_IOC_NR(cmd) SNSLED_IOC_MAXNR) return -ENOTTY; /to verify *arg is in user space if (_IOC_DIR(cmd) & _IOC_READ) err = !access_ok(VERIFY_WRITE, (void _user *)arg, _IOC_SIZE(cmd); else if (_IOC_DIR(cmd) & _IOC_WRITE) err = !access_ok(VERIFY_READ, (void _user *)arg, _IOC_SIZE(cmd); if (err) re
14、turn -EFAULT; */ switch(cmd) case SNSLED_IO_ON: printk(KERN_ALERT Snsled ioctl:on.n); /if(mt_set_gpio_out(SNS_LED_CONTROL_LINE,GPIO_OUT_ONE)printk(Snsled set gpio failed! n); snsled_turn_on(); break; case SNSLED_IO_OFF: printk(KERN_ALERT Snsled ioctl:off.n); /if(mt_set_gpio_out(SNS_LED_CONTROL_LINE,
15、GPIO_OUT_ZERO)printk(Snsled set gpio failed! n); snsled_turn_off(); break; case SNSLED_IOW_PWM: printk(KERN_ALERT Snsled ioctl:set pwm, arg=%d.n, arg); /retval = _get_user(g_snsled_ptr-r1, (int _user *)arg); snsled_set_pwm(int _user *)arg); break; case SNSLED_IOR_PWM: #if 0 retval = _put_user(g_snsl
16、ed_ptr-r1, (int _user *)arg); printk(KERN_ALERT Snsled ioctl:read r1:%i.n, g_snsled_ptr-r1); #endif printk(KERN_ALERT Snsled ioctl:read pwm - not configured yet.n); break; default: printk(KERN_ALERT Snsled ioctl:you got the wrong command.n); break; return retval;int snsled_open(struct inode *inode,
17、struct file *filp) printk(KERN_ALERT Snsled: snsled_open.n);#if 0 if(mt_set_gpio_mode(SNS_LED_CONTROL_LINE,SNS_LED_CONTROL_LINE_GPIO_MODE)printk(Snsled set gpio mode failed! n); if(mt_set_gpio_dir(SNS_LED_CONTROL_LINE,GPIO_DIR_OUT)printk(Snsled set gpio dir failed! n); if(mt_set_gpio_out(SNS_LED_CON
18、TROL_LINE,GPIO_OUT_ONE)printk(Snsled set gpio failed! n);#endif return 0;int snsled_release(struct inode *inode, struct file *filp) printk(KERN_ALERT Snsled: snsled_release.n);#if 0 if(mt_set_gpio_mode(SNS_LED_CONTROL_LINE,SNS_LED_CONTROL_LINE_GPIO_MODE)printk(Snsled set gpio mode failed! n); if(mt_
19、set_gpio_dir(SNS_LED_CONTROL_LINE,GPIO_DIR_OUT)printk(Snsled set gpio dir failed! n); if(mt_set_gpio_out(SNS_LED_CONTROL_LINE,GPIO_OUT_ZERO)printk(Snsled set gpio failed! n);#endif return 0;int snsled_turn_on(void) printk(KERN_ALERT Snsled: snsled_turn_on.n); if(mt_set_gpio_mode(SNS_LED_CONTROL_LINE
20、,SNS_LED_CONTROL_LINE_PWM_MODE)printk(Snsled set gpio mode failed! n); if(mt_set_gpio_dir(SNS_LED_CONTROL_LINE,GPIO_DIR_OUT)printk(Snsled set gpio dir failed! n); if(mt_set_gpio_out(SNS_LED_CONTROL_LINE,GPIO_OUT_ZERO)printk(Snsled set gpio failed! n); return 0;int snsled_turn_off(void) printk(KERN_A
21、LERT Snsled: snsled_turn_off.n); if(mt_set_gpio_mode(SNS_LED_CONTROL_LINE,SNS_LED_CONTROL_LINE_GPIO_MODE)printk(Snsled set gpio mode failed! n); if(mt_set_gpio_dir(SNS_LED_CONTROL_LINE,GPIO_DIR_OUT)printk(Snsled set gpio dir failed! n); if(mt_set_gpio_out(SNS_LED_CONTROL_LINE,GPIO_OUT_ZERO)printk(Sn
22、sled set gpio failed! n); return 0;/for old mode/*struct _PWM_OLDMODE_REGS U16 IDLE_VALUE; /0 U16 GUARD_VALUE; /0 U16 GDURATION; / U16 WAVE_NUM; /0 U16 DATA_WIDTH; /high level, 13bits, 08191 U16 THRESH; /tPWM_MODE_OLD_REGS;*/int snsled_set_pwm(int arg) struct pwm_spec_config pwm_setting; pwm_setting
23、.pwm_no = PWM1; printk(KERN_ALERT Snsled: snsled_open begin.n); pwm_setting.mode = PWM_MODE_OLD; pwm_setting.clk_div = CLK_DIV16;/CLK_DIV128; pwm_setting.clk_src = PWM_CLK_OLD_MODE_32K; pwm_setting.PWM_MODE_OLD_REGS.IDLE_VALUE = 0; pwm_setting.PWM_MODE_OLD_REGS.GUARD_VALUE = 0; pwm_setting.PWM_MODE_
24、OLD_REGS.GDURATION = 8100; pwm_setting.PWM_MODE_OLD_REGS.WAVE_NUM = 0; pwm_setting.PWM_MODE_OLD_REGS.DATA_WIDTH = 8100; pwm_setting.PWM_MODE_OLD_REGS.THRESH = 8100; pwm_set_spec_config(&pwm_setting); printk(KERN_ALERT Snsled: snsled_open done.n); return 0;/alloc device majorstatic int vircdex_alloc_
25、major(void) dev_t devt = 0; int result = 0; result = alloc_chrdev_region(&devt, g_snsled_minor, SNSLED_NUM, SNSLED_NODE_NAME); g_snsled_major = MAJOR(devt); return result;static int snsled_release_major(void) dev_t devt = MKDEV(g_snsled_major, g_snsled_minor); unregister_chrdev_region(devt, 1); retu
26、rn 0;static int snsled_setup_dev(struct snsled_cntx *dev) int err, devno = MKDEV(g_snsled_major, g_snsled_minor); cdev_init(&(dev-cdev), &g_snsled_fops); dev-cdev.owner = THIS_MODULE; err = cdev_add(&dev-cdev, devno, 1); if(err) return err; /init_MUTEX(&(dev-sem); sema_init(&(dev-sem), 1); return 0;
27、static int snsled_unsetup_dev(struct snsled_cntx *dev) cdev_del(&(dev-cdev); return 0;static int snsled_create_devfiles(dev_t devt) /, const struct device_attribute *attr) int err = -1; struct device *dev = NULL; g_snsled_class = class_create(THIS_MODULE, SNSLED_CLASS_NAME); if(IS_ERR(g_snsled_class) err = PTR_ERR(g_snsled_class); printk(KERN_ALERT Failed to create class.n); goto CLASS_CREATE_ERR; dev = device_create(g_snsled_class, NULL, devt, NULL, SNSLED_DEVICE_NAME); /dev = device_create(hello_class, NULL, dev, %s, HELLO_DEVICE_FILE_NAME); /device_create( my_class, NULL, MKDEV(hello_m
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1