Android驱动模型(kernel-hal-framework-app)

来源:互联网 发布:网络安全技术一般包括 编辑:程序博客网 时间:2024/06/06 18:29

读书的时候有写博客的习惯,后面就再也没写过了,发现很多知识点整理在电脑上容易丢失,也不能共享,所以今天又拿起笔开始写博客了,这篇文章的内容是基于兆芯平台的Android架构,实现了一个APP调用hal层来控制导光板的灯光效果。
Android上层平台和底层通信有两种模型: 1.NDK模型(不常用); 2.框架模型
Android驱动开发模型
Android系统使用JNI的原因有:
1、代码保护,Java程序很容易被反编译,C/C++反汇编难度大
2、可以很方便的使用开源库,大部分开源库都是C/C++编写的
3、执行效率的问题,将高执行效率的代码段用C/C++编写
4、Java在文件操作方面,找不到相应的API

1、NDK模型

由内核级别的驱动程序和APP组成,内核级别的驱动程序对外的接口是ioctl,而APP是由JAVA语言写的,JAVA语言并没有(或者并不支持)ioctl接口,所以内核级别的驱动程序和APP是不能直接连接(数据交换),那么就在中间增加了一层C/C++,这层C/C++支持ioctl接口,可以和内核级别的驱动程序连接,而APP的JAVA程序又可以调用C/C++,这样就连接起来了,JAVA通过JNI条用C/C++(JNI:java native interface是专门给java程序调用c/c++提供一种程序调用方法)。通过NDK这个工具将APP和第三方的一些库(C/C++)打包成apk安装包。存在问题:内核级别的驱动程序需要遵循GPL协议,而GPL协议需要开源,但是有些厂家的内核由于包含商业信息,故不完全开源,即一部分开源,一部分不开源,这样就有了框架模型。
Android驱动模型1-NDK驱动模型
NDK驱动程序设计步骤

2、框架模型

开源的一部分是需要遵循GPL协议的,放在内核里面,不开源的一部分就不能放在内核里面,故放在Android系统里面,即HAL,硬件抽象层,与硬件相关的代码,是不想开源的。 在硬件抽象层上面又加了一层硬件服务层,把封装好的硬件服务注册到Android系统中,那么APP通过service manager找到硬件服务层,硬件服务层找到硬件抽象层,硬件抽象层找到驱动程序。
Android驱动模型2-框架模型
框架设计模型设计总共分为4步:

  1. 第一步:是内核级的驱动开发,就是封装Linux驱动方法供hal层调用。
  2. 第二步:设计硬件抽象层HAL程序,下图是设计步骤

框架模型设计步骤

下面是具体的实现代码:
  • sn3199_hal.c (相对android源码路径:hardware/libhardware/modules/sn3199/)
#include <cutils/log.h>#include <stdint.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <fcntl.h>#include <pthread.h>#include <sys/types.h>#include <pthread.h>#include <stdio.h>#include <stdlib.h>#include <sys/ioctl.h>#include <linux/i2c.h>#include <linux/i2c-dev.h>#include <hardware/sn3199_hal.h>#define LOG_TAG "sn3199_hal_default"//全局变量uchar s,t1,t2,flag,N;uchar mode=2;int i2c_fd = -1;const unsigned char PWM64[64]={        0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,        0x08,0x09,0x0b,0x0d,0x0f,0x11,0x13,0x16,        0x1a,0x1c,0x1d,0x1f,0x22,0x25,0x28,0x2e,        0x34,0x38,0x3c,0x40,0x44,0x48,0x4b,0x4f,          0x55,0x5a,0x5f,0x64,0x69,0x6d,0x72,0x77,        0x7d,0x80,0x88,0x8d,0x94,0x9a,0xa0,0xa7,        0xac,0xb0,0xb9,0xbf,0xc6,0xcb,0xcf,0xd6,        0xe1,0xe9,0xed,0xf1,0xf6,0xfa,0xfe,0xff};//adau1761单字节写入函数void single_world_write(unsigned char chip_addr, int i2c_fd, unsigned short reg, unsigned char val){        struct i2c_rdwr_ioctl_data light_guide_plate_data;        light_guide_plate_data.msgs = (struct i2c_msg *)calloc(1, sizeof(struct i2c_msg));        if(!light_guide_plate_data.msgs)        {                perror("light_guide_plate_data.msgs calloc error:\n");                return;        }        //构造写入到adau1761单个寄存器中的消息        light_guide_plate_data.nmsgs = 1;        (light_guide_plate_data.msgs[0]).len = 2; //写入数据的长度为3        (light_guide_plate_data.msgs[0]).addr = chip_addr;        (light_guide_plate_data.msgs[0]).flags = 0;        (light_guide_plate_data.msgs[0]).buf = (unsigned char *)calloc(1,2);        (light_guide_plate_data.msgs[0]).buf[0] = reg;        (light_guide_plate_data.msgs[0]).buf[1] = val;        //使用ioctl写入数据        ioctl(i2c_fd, I2C_RDWR, (unsigned long)&light_guide_plate_data);        return;}//adau1761多字节写入函数void burst_model_write(unsigned char chip_addr, int i2c_fd, unsigned short reg, unsigned char *data, unsigned int data_len){        int i;        struct i2c_rdwr_ioctl_data light_guide_plate_data;        light_guide_plate_data.msgs = (struct i2c_msg *)calloc(1, sizeof(struct i2c_msg));        if(!light_guide_plate_data.msgs)        {                perror("light_guide_plate_data.msgs calloc error:\n");                exit(-1);        }        light_guide_plate_data.nmsgs = 1;        (light_guide_plate_data.msgs[0]).len = data_len + 2; //写入数据的长度为3        (light_guide_plate_data.msgs[0]).addr = chip_addr;        (light_guide_plate_data.msgs[0]).flags = 0;        (light_guide_plate_data.msgs[0]).buf = (unsigned char *)calloc(1,data_len + 1);        (light_guide_plate_data.msgs[0]).buf[0] = reg;        for(i = 0; i < data_len; i++)        {                (light_guide_plate_data.msgs[0]).buf[i + 1] = data[i];        }        //使用ioctl写入数据        ioctl(i2c_fd, I2C_RDWR, (unsigned long)&light_guide_plate_data);        return;}//adau1761单字节读出函数unsigned char single_world_read(unsigned char chip_addr, int i2c_fd, unsigned short reg){        struct i2c_rdwr_ioctl_data light_guide_plate_data;        light_guide_plate_data.msgs = (struct i2c_msg *)calloc(2, sizeof(struct i2c_msg));        if(!light_guide_plate_data.msgs)        {                perror("light_guide_plate_data.msgs calloc error:\n");                exit(-1);        }        //构造从adau1761单个寄存器读数据的消息        //先写偏移地址        light_guide_plate_data.nmsgs = 2;        (light_guide_plate_data.msgs[0]).len = 1;        (light_guide_plate_data.msgs[0]).addr = chip_addr;        (light_guide_plate_data.msgs[0]).flags = 0x0;        (light_guide_plate_data.msgs[0]).buf = (unsigned char *)calloc(1,1);        (light_guide_plate_data.msgs[0]).buf[0] = reg;        (light_guide_plate_data.msgs[1]).len = 1;        (light_guide_plate_data.msgs[1]).addr = chip_addr;        (light_guide_plate_data.msgs[1]).flags = I2C_M_RD;        (light_guide_plate_data.msgs[1]).buf = (unsigned char *)calloc(1,2);        //使用ioctl读取数据        ioctl(i2c_fd, I2C_RDWR, (unsigned long)&light_guide_plate_data);        printf("buf[0] = 0x%x\n",(light_guide_plate_data.msgs[1]).buf[0]);        return (light_guide_plate_data.msgs[1]).buf[0];}//adau1761多字节读出函数unsigned char * burst_model_read(unsigned char chip_addr, int i2c_fd, unsigned short reg, unsigned int data_len){        struct i2c_rdwr_ioctl_data light_guide_plate_data;        light_guide_plate_data.msgs = (struct i2c_msg *)calloc(2, sizeof(struct i2c_msg));        if(!light_guide_plate_data.msgs)        {                perror("light_guide_plate_data.msgs calloc error:\n");                exit(-1);        }        //构造从adau1761单个寄存器读数据的消息        //先写偏移地址        light_guide_plate_data.nmsgs = 2;        (light_guide_plate_data.msgs[0]).len = 2;        (light_guide_plate_data.msgs[0]).addr = chip_addr;        (light_guide_plate_data.msgs[0]).flags = 0x0;        (light_guide_plate_data.msgs[0]).buf = (unsigned char *)calloc(1,1);        (light_guide_plate_data.msgs[0]).buf[0] = reg;        (light_guide_plate_data.msgs[1]).len = data_len;        (light_guide_plate_data.msgs[1]).addr = chip_addr;        (light_guide_plate_data.msgs[1]).flags = I2C_M_RD;        (light_guide_plate_data.msgs[1]).buf = (unsigned char *)calloc(1,data_len);        //使用ioctl读取数据        ioctl(i2c_fd, I2C_RDWR, (unsigned long)&light_guide_plate_data);        return (light_guide_plate_data.msgs[1]).buf;}int reset(){        single_world_write(CHIP_ADDR1, i2c_fd, 0xff,0xff);        single_world_write(CHIP_ADDR1, i2c_fd, 0x00,0x01);         //enable sd chip1        single_world_write(CHIP_ADDR1, i2c_fd, 0x01,0x77);        single_world_write(CHIP_ADDR1, i2c_fd, 0x02,0x07);        single_world_write(CHIP_ADDR1, i2c_fd, 0x04,0x00);        single_world_write(CHIP_ADDR2, i2c_fd, 0xff,0xff);        single_world_write(CHIP_ADDR2, i2c_fd, 0x00,0x01);         //enable sd chip1        single_world_write(CHIP_ADDR2, i2c_fd, 0x01,0x77);        single_world_write(CHIP_ADDR2, i2c_fd, 0x02,0x07);        single_world_write(CHIP_ADDR2, i2c_fd, 0x04,0x00);        return 0;}/************************************************///设置LED 电流大小//0= 20mA , 1 = 15mA, 2= 10mA, 3=5mA, 4= 40mA, 5= 35mA, 6=30mA,7=25mA/*************************************************/void Led_SetCurrent(unsigned char level){        if ( level > 7 ) return;        g_LedEffect |= level<<4;        single_world_write(CHIP_ADDR1, i2c_fd, SN3216_REG_LED_EFFECT, g_LedEffect);        single_world_write(CHIP_ADDR2, i2c_fd, SN3216_REG_LED_EFFECT, g_LedEffect);}/*****************正常工作(音箱本身喇叭不工作)-常亮白色********************   *i2c_fd:i2c文件操作描述符 * ***********************************************************************/int normally_bright_white(){        single_world_write(CHIP_ADDR1, i2c_fd, 0x03, 0x0); //pwm mode        single_world_write(CHIP_ADDR2, i2c_fd, 0x03, 0x0); //pwm mode        single_world_write(CHIP_ADDR1, i2c_fd, 0x07,0xff); //紫色        single_world_write(CHIP_ADDR1, i2c_fd, 0x08,0xff);        single_world_write(CHIP_ADDR1, i2c_fd, 0x09,0xff);        single_world_write(CHIP_ADDR1, i2c_fd, 0x0a,0xff);        single_world_write(CHIP_ADDR1, i2c_fd, 0x0b,0xff);        single_world_write(CHIP_ADDR1, i2c_fd, 0x0c,0xff);        single_world_write(CHIP_ADDR1, i2c_fd, 0x0d,0xff);        single_world_write(CHIP_ADDR1, i2c_fd, 0x0e,0xff);        single_world_write(CHIP_ADDR1, i2c_fd, 0x0f,0xff);        single_world_write(CHIP_ADDR1, i2c_fd, 0x10,0xff);        single_world_write(CHIP_ADDR2, i2c_fd, 0x07,0xff); //紫色        single_world_write(CHIP_ADDR2, i2c_fd, 0x08,0xff);        single_world_write(CHIP_ADDR2, i2c_fd, 0x09,0xff);        single_world_write(CHIP_ADDR2, i2c_fd, 0x0a,0xff);        single_world_write(CHIP_ADDR2, i2c_fd, 0x0b,0xff);        single_world_write(CHIP_ADDR2, i2c_fd, 0x0c,0xff);        single_world_write(CHIP_ADDR2, i2c_fd, 0x0d,0xff);        single_world_write(CHIP_ADDR2, i2c_fd, 0x0e,0xff);        single_world_write(CHIP_ADDR2, i2c_fd, 0x0f,0xff);        single_world_write(CHIP_ADDR2, i2c_fd, 0x10,0xff);        ALOGD("normally_bright_white:i2c_cfd = %d\n", i2c_fd);        return 0;}/*****************待机-白色呼吸灯效果******************** * ******************************************************/int standby_mode() //RGB单色呼吸{        single_world_write(CHIP_ADDR1, i2c_fd, 0x03,0x70); //One shot mode        single_world_write(CHIP_ADDR1, i2c_fd, 0x06,0x10); //INTB  OUT1        single_world_write(CHIP_ADDR1, i2c_fd, 0x04,0x80);  //从模式        single_world_write(CHIP_ADDR1, i2c_fd, 0x1a,0x81); //T1~T3;  T3=2T1=2*260*2ms,T2=260        single_world_write(CHIP_ADDR1, i2c_fd, 0x1b,0x81);        single_world_write(CHIP_ADDR1, i2c_fd, 0x1c,0x81);        single_world_write(CHIP_ADDR1, i2c_fd, 0x1d,0x01); //T4=2*260ms        single_world_write(CHIP_ADDR1, i2c_fd, 0x1e,0x01);        single_world_write(CHIP_ADDR1, i2c_fd, 0x1f,0x01);        single_world_write(CHIP_ADDR1, i2c_fd, 0x20,0x01);        single_world_write(CHIP_ADDR1, i2c_fd, 0x21,0x01);        single_world_write(CHIP_ADDR1, i2c_fd, 0x22,0x01);        single_world_write(CHIP_ADDR1, i2c_fd, 0x23,0x01);        single_world_write(CHIP_ADDR1, i2c_fd, 0x24,0x01);        single_world_write(CHIP_ADDR1, i2c_fd, 0x25,0x01);        single_world_write(CHIP_ADDR1, i2c_fd, 0x26,0xff);        single_world_write(CHIP_ADDR1, i2c_fd, 0x10,0xff);        single_world_write(CHIP_ADDR1, i2c_fd, 0x07,0xff);     //雪白        single_world_write(CHIP_ADDR1, i2c_fd, 0x08,0xfa);        single_world_write(CHIP_ADDR1, i2c_fd, 0x09,0xfa);        single_world_write(CHIP_ADDR1, i2c_fd, 0x0a,0xff);        single_world_write(CHIP_ADDR1, i2c_fd, 0x0b,0xfa);        single_world_write(CHIP_ADDR1, i2c_fd, 0x0c,0xfa);        single_world_write(CHIP_ADDR1, i2c_fd, 0x0d,0xff);        single_world_write(CHIP_ADDR1, i2c_fd, 0x0e,0xfa);        single_world_write(CHIP_ADDR1, i2c_fd, 0x0f,0xfa);        single_world_write(CHIP_ADDR1, i2c_fd, 0x10,0xff);        single_world_write(CHIP_ADDR2, i2c_fd, 0x03,0x70); //One shot mode        single_world_write(CHIP_ADDR2, i2c_fd, 0x06,0x0); //INTB  OUT1        single_world_write(CHIP_ADDR2, i2c_fd, 0x04,0x0);  //主模式        single_world_write(CHIP_ADDR2, i2c_fd, 0x1a,0x81); //T1~T3;  T3=2T1=2*260*2ms,T2=260        single_world_write(CHIP_ADDR2, i2c_fd, 0x1b,0x81);        single_world_write(CHIP_ADDR2, i2c_fd, 0x1c,0x81);        single_world_write(CHIP_ADDR2, i2c_fd, 0x1d,0x01); //T4=2*260ms        single_world_write(CHIP_ADDR2, i2c_fd, 0x1e,0x01);        single_world_write(CHIP_ADDR2, i2c_fd, 0x1f,0x01);        single_world_write(CHIP_ADDR2, i2c_fd, 0x20,0x01);        single_world_write(CHIP_ADDR2, i2c_fd, 0x21,0x01);        single_world_write(CHIP_ADDR2, i2c_fd, 0x22,0x01);        single_world_write(CHIP_ADDR2, i2c_fd, 0x23,0x01);        single_world_write(CHIP_ADDR2, i2c_fd, 0x24,0x01);        single_world_write(CHIP_ADDR2, i2c_fd, 0x25,0x01);        single_world_write(CHIP_ADDR2, i2c_fd, 0x26,0xff);        single_world_write(CHIP_ADDR2, i2c_fd, 0x10,0xff);        single_world_write(CHIP_ADDR2, i2c_fd, 0x07,0xff);         //雪白        single_world_write(CHIP_ADDR2, i2c_fd, 0x08,0xfa);        single_world_write(CHIP_ADDR2, i2c_fd, 0x09,0xfa);        single_world_write(CHIP_ADDR2, i2c_fd, 0x0a,0xff);        single_world_write(CHIP_ADDR2, i2c_fd, 0x0b,0xfa);        single_world_write(CHIP_ADDR2, i2c_fd, 0x0c,0xfa);        single_world_write(CHIP_ADDR2, i2c_fd, 0x0d,0xff);        single_world_write(CHIP_ADDR2, i2c_fd, 0x0e,0xfa);        single_world_write(CHIP_ADDR2, i2c_fd, 0x0f,0xfa);        single_world_write(CHIP_ADDR2, i2c_fd, 0x10,0xff);        ALOGD("standby_mode:i2c_cfd = %d\n", i2c_fd);        return 0;}/*****************正在开机-蓝色呼吸灯******************** *  * ****************************************************/ int boot_system_state() //RGB单色呼吸 {         single_world_write(CHIP_ADDR1, i2c_fd, 0x03,0x70); //One shot mode         single_world_write(CHIP_ADDR1, i2c_fd, 0x06,0x10); //INTB  OUT1         single_world_write(CHIP_ADDR1, i2c_fd, 0x04,0x80);  //从模式         single_world_write(CHIP_ADDR1, i2c_fd, 0x1a,0x81); //T1~T3;  T3=2T1=2*260*2ms,T2=260         single_world_write(CHIP_ADDR1, i2c_fd, 0x1b,0x81);         single_world_write(CHIP_ADDR1, i2c_fd, 0x1c,0x81);         single_world_write(CHIP_ADDR1, i2c_fd, 0x1d,0x01); //T4=2*260ms         single_world_write(CHIP_ADDR1, i2c_fd, 0x1e,0x01);         single_world_write(CHIP_ADDR1, i2c_fd, 0x1f,0x01);         single_world_write(CHIP_ADDR1, i2c_fd, 0x20,0x01);         single_world_write(CHIP_ADDR1, i2c_fd, 0x21,0x01);         single_world_write(CHIP_ADDR1, i2c_fd, 0x22,0x01);         single_world_write(CHIP_ADDR1, i2c_fd, 0x23,0x01);         single_world_write(CHIP_ADDR1, i2c_fd, 0x24,0x01);         single_world_write(CHIP_ADDR1, i2c_fd, 0x25,0x01);         single_world_write(CHIP_ADDR1, i2c_fd, 0x26,0xff);         single_world_write(CHIP_ADDR1, i2c_fd, 0x10,0xff);         single_world_write(CHIP_ADDR1, i2c_fd, 0x07,0x0);     //雪白         single_world_write(CHIP_ADDR1, i2c_fd, 0x08,0x0);         single_world_write(CHIP_ADDR1, i2c_fd, 0x09,0xff);         single_world_write(CHIP_ADDR1, i2c_fd, 0x0a,0x0);         single_world_write(CHIP_ADDR1, i2c_fd, 0x0b,0x0);         single_world_write(CHIP_ADDR1, i2c_fd, 0x0c,0xff);         single_world_write(CHIP_ADDR1, i2c_fd, 0x0d,0x0);         single_world_write(CHIP_ADDR1, i2c_fd, 0x0e,0x0);         single_world_write(CHIP_ADDR1, i2c_fd, 0x0f,0xff);         single_world_write(CHIP_ADDR1, i2c_fd, 0x10,0xff);         single_world_write(CHIP_ADDR2, i2c_fd, 0x03,0x70); //One shot mode         single_world_write(CHIP_ADDR2, i2c_fd, 0x06,0x0); //INTB  OUT1         single_world_write(CHIP_ADDR2, i2c_fd, 0x04,0x0);  //主模式         single_world_write(CHIP_ADDR2, i2c_fd, 0x1a,0x81); //T1~T3;  T3=2T1=2*260*2ms,T2=260         single_world_write(CHIP_ADDR2, i2c_fd, 0x1b,0x81);         single_world_write(CHIP_ADDR2, i2c_fd, 0x1c,0x81);         single_world_write(CHIP_ADDR2, i2c_fd, 0x1d,0x01); //T4=2*260ms         single_world_write(CHIP_ADDR2, i2c_fd, 0x1e,0x01);         single_world_write(CHIP_ADDR2, i2c_fd, 0x1f,0x01);         single_world_write(CHIP_ADDR2, i2c_fd, 0x20,0x01);         single_world_write(CHIP_ADDR2, i2c_fd, 0x21,0x01);         single_world_write(CHIP_ADDR2, i2c_fd, 0x22,0x01);         single_world_write(CHIP_ADDR2, i2c_fd, 0x23,0x01);         single_world_write(CHIP_ADDR2, i2c_fd, 0x24,0x01);         single_world_write(CHIP_ADDR2, i2c_fd, 0x25,0x01);         single_world_write(CHIP_ADDR2, i2c_fd, 0x26,0xff);         single_world_write(CHIP_ADDR2, i2c_fd, 0x10,0xff);         single_world_write(CHIP_ADDR2, i2c_fd, 0x07,0x0);         //雪白         single_world_write(CHIP_ADDR2, i2c_fd, 0x08,0x0);         single_world_write(CHIP_ADDR2, i2c_fd, 0x09,0xff);         single_world_write(CHIP_ADDR2, i2c_fd, 0x0a,0x0);         single_world_write(CHIP_ADDR2, i2c_fd, 0x0b,0x0);         single_world_write(CHIP_ADDR2, i2c_fd, 0x0c,0xff);         single_world_write(CHIP_ADDR2, i2c_fd, 0x0d,0x0);         single_world_write(CHIP_ADDR2, i2c_fd, 0x0e,0x0);         single_world_write(CHIP_ADDR2, i2c_fd, 0x0f,0xff);         single_world_write(CHIP_ADDR2, i2c_fd, 0x10,0xff);         ALOGD("boot_system_state:i2c_cfd = %d\n", i2c_fd);         return 0; }/*****************网络异常状态-常亮红色******************** *  * ****************************************************/ int network_anomaly_state() {        single_world_write(CHIP_ADDR1, i2c_fd, 0x03, 0x0); //pwm mode        single_world_write(CHIP_ADDR2, i2c_fd, 0x03, 0x0); //pwm mode        single_world_write(CHIP_ADDR1, i2c_fd, 0x07,0xff); //红色        single_world_write(CHIP_ADDR1, i2c_fd, 0x08,0x0);        single_world_write(CHIP_ADDR1, i2c_fd, 0x09,0x0);        single_world_write(CHIP_ADDR1, i2c_fd, 0xa,0xff); //红色        single_world_write(CHIP_ADDR1, i2c_fd, 0xb,0x0);        single_world_write(CHIP_ADDR1, i2c_fd, 0xc,0x0);        single_world_write(CHIP_ADDR1, i2c_fd, 0xd,0xff); //红色        single_world_write(CHIP_ADDR1, i2c_fd, 0xe,0x0);        single_world_write(CHIP_ADDR1, i2c_fd, 0xf,0x0);        single_world_write(CHIP_ADDR1, i2c_fd, 0x10,0xff); //更新数据到各PWM寄存器里面        single_world_write(CHIP_ADDR2, i2c_fd, 0x07,0xff);        single_world_write(CHIP_ADDR2, i2c_fd, 0x08,0x0);        single_world_write(CHIP_ADDR2, i2c_fd, 0x09,0x0);        single_world_write(CHIP_ADDR2, i2c_fd, 0x0a,0xff);        single_world_write(CHIP_ADDR2, i2c_fd, 0x0b,0x0);        single_world_write(CHIP_ADDR2, i2c_fd, 0x0c,0x0);        single_world_write(CHIP_ADDR2, i2c_fd, 0x0d,0xff);     //        single_world_write(CHIP_ADDR2, i2c_fd, 0x0e,0x0);        single_world_write(CHIP_ADDR2, i2c_fd, 0x0f,0x0);        single_world_write(CHIP_ADDR2, i2c_fd, 0x10,0xff); //更新数据到各PWM寄存器里面          ALOGD("network_anomaly_state:i2c_cfd = %d\n", i2c_fd);        return 0;  }/*****************程序系统异常状态-红色闪烁******************** *  seconds:红色闪烁状态间隔时间 * ****************************************************/int abnormal_state(unsigned int seconds){        single_world_write(CHIP_ADDR1, i2c_fd, 0x03, 0x0); //pwm mode        single_world_write(CHIP_ADDR2, i2c_fd, 0x03, 0x0); //pwm mode        while(1)        {                single_world_write(CHIP_ADDR1, i2c_fd, 0x07,0xff); //红色                single_world_write(CHIP_ADDR1, i2c_fd, 0x08,0x0);                single_world_write(CHIP_ADDR1, i2c_fd, 0x09,0x0);                single_world_write(CHIP_ADDR1, i2c_fd, 0xa,0xff); //红色                single_world_write(CHIP_ADDR1, i2c_fd, 0xb,0x0);                single_world_write(CHIP_ADDR1, i2c_fd, 0xc,0x0);                single_world_write(CHIP_ADDR1, i2c_fd, 0xd,0xff); //红色                single_world_write(CHIP_ADDR1, i2c_fd, 0xe,0x0);                single_world_write(CHIP_ADDR1, i2c_fd, 0xf,0x0);                single_world_write(CHIP_ADDR1, i2c_fd, 0x10,0xff); //更新数据到各PWM寄存器里面                single_world_write(CHIP_ADDR2, i2c_fd, 0x07,0xff);     //红色                single_world_write(CHIP_ADDR2, i2c_fd, 0x08,0x0);                single_world_write(CHIP_ADDR2, i2c_fd, 0x09,0x0);                single_world_write(CHIP_ADDR2, i2c_fd, 0x0a,0xff);     //红色                single_world_write(CHIP_ADDR2, i2c_fd, 0x0b,0x0);                single_world_write(CHIP_ADDR2, i2c_fd, 0x0c,0x0);                single_world_write(CHIP_ADDR2, i2c_fd, 0x0d,0xff);     //红色                single_world_write(CHIP_ADDR2, i2c_fd, 0x0e,0x0);                single_world_write(CHIP_ADDR2, i2c_fd, 0x0f,0x0);                single_world_write(CHIP_ADDR2, i2c_fd, 0x10,0xff); //更新数据到各PWM寄存器里面                sleep(seconds);                single_world_write(CHIP_ADDR1, i2c_fd, 0x07,0x0); //黑色                single_world_write(CHIP_ADDR1, i2c_fd, 0x08,0x0);                single_world_write(CHIP_ADDR1, i2c_fd, 0x09,0x0);                single_world_write(CHIP_ADDR1, i2c_fd, 0xa,0x0); //黑色                single_world_write(CHIP_ADDR1, i2c_fd, 0xb,0x0);                single_world_write(CHIP_ADDR1, i2c_fd, 0xc,0x0);                single_world_write(CHIP_ADDR1, i2c_fd, 0xd,0x0); //黑色                single_world_write(CHIP_ADDR1, i2c_fd, 0xe,0x0);                single_world_write(CHIP_ADDR1, i2c_fd, 0xf,0x0);                single_world_write(CHIP_ADDR1, i2c_fd, 0x10,0xff); //更新数据到各PWM寄存器里面                single_world_write(CHIP_ADDR2, i2c_fd, 0x07,0x0);                single_world_write(CHIP_ADDR2, i2c_fd, 0x08,0x0);                single_world_write(CHIP_ADDR2, i2c_fd, 0x09,0x0);                single_world_write(CHIP_ADDR2, i2c_fd, 0x0a,0x0);                single_world_write(CHIP_ADDR2, i2c_fd, 0x0b,0x0);                single_world_write(CHIP_ADDR2, i2c_fd, 0x0c,0x0);                single_world_write(CHIP_ADDR2, i2c_fd, 0x0d,0x0);     //                single_world_write(CHIP_ADDR2, i2c_fd, 0x0e,0x0);                single_world_write(CHIP_ADDR2, i2c_fd, 0x0f,0x0);                single_world_write(CHIP_ADDR2, i2c_fd, 0x10,0xff); //更新数据到各PWM寄存器里面                sleep(seconds);        }        abnormal_state_thread = -1;        pthread_exit(0);        ALOGD("abnormal_state:i2c_cfd = %d\n", i2c_fd);        return 0;}/***************跟随音乐跳动状态********************** * * ****************************************************/int audio_mode() //Audio mode{        single_world_write(CHIP_ADDR1, i2c_fd, 0x03, 0x04); //PWM mode; AE AGC        single_world_write(CHIP_ADDR1, i2c_fd, 0x04, 0x6); //5mA, 18dB        single_world_write(CHIP_ADDR2, i2c_fd, 0x03, 0x04); //PWM mode; AE AGC        single_world_write(CHIP_ADDR2, i2c_fd, 0x04, 0x6); //5mA, 18dB        single_world_write(CHIP_ADDR1, i2c_fd, 0x07,0xff);        single_world_write(CHIP_ADDR1, i2c_fd, 0x08,0x0);        single_world_write(CHIP_ADDR1, i2c_fd, 0x09,0x0);        single_world_write(CHIP_ADDR1, i2c_fd, 0xa,0xff);        single_world_write(CHIP_ADDR1, i2c_fd, 0xb,0xff);        single_world_write(CHIP_ADDR1, i2c_fd, 0xc,0xff);        single_world_write(CHIP_ADDR1, i2c_fd, 0xd,0xff);        single_world_write(CHIP_ADDR1, i2c_fd, 0xe,0xff);        single_world_write(CHIP_ADDR1, i2c_fd, 0xf,0x0);        single_world_write(CHIP_ADDR1, i2c_fd, 0x10,0xff); //更新数据到各PWM寄存器里面        single_world_write(CHIP_ADDR2, i2c_fd, 0x07,0x0);        single_world_write(CHIP_ADDR2, i2c_fd, 0x08,0xff);        single_world_write(CHIP_ADDR2, i2c_fd, 0x09,0x0);        single_world_write(CHIP_ADDR2, i2c_fd, 0x0a,0x0);        single_world_write(CHIP_ADDR2, i2c_fd, 0x0b,0x0);        single_world_write(CHIP_ADDR2, i2c_fd, 0x0c,0xff);        single_world_write(CHIP_ADDR2, i2c_fd, 0x0d,0x0);        single_world_write(CHIP_ADDR2, i2c_fd, 0x0e,0xff);        single_world_write(CHIP_ADDR2, i2c_fd, 0x0f,0xff);        single_world_write(CHIP_ADDR2, i2c_fd, 0x10,0xff); //更新数据到各PWM寄存器里面        ALOGD("audio_mode:i2c_cfd = %d\n", i2c_fd);        return 0;}int sn3199_init(){        //打开通用设备驱动文件        i2c_fd = open("/dev/i2c-1", O_RDWR);        if(i2c_fd < 0)        {                ALOGD("Open /dev/i2c-1 error:\n");                return -1;        }        ALOGD("sn3199_init:i2c_cfd = %d\n", i2c_fd);        return 0;}static struct sn3199_device_t sn3199_dev = {        .sn3199_device =         {                .tag = HARDWARE_DEVICE_TAG,                .close = sn3199_close,        },        .set_light_state = set_light_state,};//logcat -s "SN3199_HAL"//实现open函数static int open_sn3199_hal(const struct hw_module_t* module, char const* id, struct hw_device_t** device){    ALOGD("open_sn3199 exec.....");    sn3199_init();   //获取i2c设备符   /* struct sn3199_device_t *dev = calloc(1, sizeof(struct sn3199_device_t));    dev->sn3199_device.tag = HARDWARE_DEVICE_TAG;    dev->sn3199_device.close = (int (*)(struct hw_device_t *))sn3199_close;    dev->set_light_state = set_light_state;    *device = (struct hw_device_t*)dev;*/    *device = &sn3199_dev;    return 0;}int set_light_state(struct sn3199_device_t *dev, int state){    ALOGD("set_light_state exec....");    g_Flag = 0;    reset();    switch (state) {    case 1:            ALOGD("standby_mode....");            standby_mode();            break;    case 2:            ALOGD("normally_bright_white....");            normally_bright_white();            break;    case 3:            ALOGD("abnormal_state");            pthread_create(&abnormal_state_thread, NULL, (void *)&abnormal_state, (void *)1);            g_Flag = 1;            //pthread_join(abnormal_state_thread, NULL);            break;    case 4:            ALOGD("audio_mode");            audio_mode();            break;    case 5:            ALOGD("network_anomaly_state");            network_anomaly_state();            break;    case 6:            ALOGD(" boot_system_state");            boot_system_state();            break;    default:            break;    }    return 0;}static int sn3199_close(struct sn3199_device_t *dev){    if(i2c_fd > 0)    {        close(i2c_fd);        i2c_cfd = -1;       }     if(dev)        free(dev);    g_Flag = -1;    return 0;}//定义HAL_MODULE_INFO_SYM,并对其进行初始化static hw_module_methods_t sn3199_methods ={    .open = open_sn3199_hal,};struct hw_module_t HAL_MODULE_INFO_SYM ={    .tag = HARDWARE_MODULE_TAG,    .id = **SN3199_HARDWARE_MODULE_ID**,     //该id起到了承上启下的作用,硬件服务层会匹配该id,一般这里使用宏定义(VIBRATOR_HARDWARE_MODULE_ID),不然可能会出错    .author = "yjd",         .methods = &sn3199_methods,};
  • sn3199_hal.h(相对android源码路径:hardware/libhardware/include/)
#ifndef _SN3199_HAL_H_#define _SN3199_HAL_H_#include <hardware/hardware.h>#include <pthread.h>#define SN3216_REG_LED_EFFECT       0x04void single_world_write(unsigned char chip_addr, int i2c_fd, unsigned short reg, unsigned char val);void burst_model_write(unsigned char chip_addr, int i2c_fd, unsigned short reg, unsigned char *data, unsigned int data_len);unsigned char single_world_read(unsigned char chip_addr, int i2c_fd, unsigned short reg);unsigned char * burst_model_read(unsigned char chip_addr, int i2c_fd, unsigned short reg, unsigned int data_len);int reset();int normally_bright_white();int standby_mode();int boot_system_state(); //RGB单色呼吸int network_anomaly_state();int abnormal_state(unsigned int seconds);int audio_mode(); //Audio modestatic unsigned char g_Ledctrl1=0,g_Ledctrl2=0,g_LedEffect = 0;static unsigned char g_Flag = 0;pthread_t abnormal_state_thread = -1;#define CHIP_ADDR1 0x64#define CHIP_ADDR2 0x67#define uchar unsigned char#define uint unsigned int#define SN3199_HARDWARE_MODULE_ID "sn3199"//自定义一个对外的结构体struct sn3199_device_t{    struct hw_device_t sn3199_device;    int (*set_light_state)(struct sn3199_device_t *dev, int state);};static int sn3199_close(struct sn3199_device_t *dev);int set_light_state(struct sn3199_device_t *dev, int state);#endif
  • Anddroid.mk
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := sn3199.default    #sn3199_hal_default.so# HAL module implementation stored in# hw/<VIBRATOR_HARDWARE_MODULE_ID>.default.soLOCAL_MODULE_RELATIVE_PATH := hw    #/system/lib/hw/LOCAL_C_INCLUDES := hardware/libhardwareLOCAL_SRC_FILES := sn3199_hal.cLOCAL_SHARED_LIBRARIES := liblogLOCAL_MODULE_TAGS := optionalinclude $(BUILD_SHARED_LIBRARY)

以上就是hal的代码,通过mm命令最后生成sn3199.default.so

第三步:硬件访问服务程序设计(解决上层访问硬件冲突)
硬件服务流程
下面是具体的代码实现

  • ISn3199Service.aidl(Android源码目录的相对路径:frameworks/base/core/java/android/os/)
package android.os;/** {@hide} */interface ISn3199Service{    int sn3199Open();    //打开sn3199    int setLightState(int state);  //设置sn3199灯光状态}

该文件最后会生成实现Stub类方法的文件ISn3199Service.java(生成文件相对Android源码路径:out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/os)

  • Android.mk(相对Android源码相对路径:frameworks/base)
        .        .        .        core/java/android/os/IVibratorService.aidl \       + core/java/android/os/ISn3199Service.aidl       .       .       .

Sn3199Service.java(相对Android路径:frameworks/base/services/core/java/com/android/server/)

package com.android.server;import android.util.Slog;import android.os.ISn3199Service;public class Sn3199Service extends ISn3199Service.Stub {    private static final String TAG = "Sn3199Service";    public Sn3199Service()    {        Slog.d(TAG, "Sn3199Service");    }    //打开sn3199    public int sn3199Open() throws android.os.RemoteException        {        return nativeSn3199Open();    }    //设置sn3199灯光状态    public int setLightState(int state) throws android.os.RemoteException     {        return nativeSetLightState(state);    }    //声明本地函数    public static native int nativeSn3199Open();    public static native int nativeSetLightState(int state);}

服务层调用hal层通过JNI
这里写图片描述

  • 将硬件服务注册到ServiceManager中去
    SystemServer.java(相对Android源码路径:frameworks/base/services/java/com/android/server/)
 ...... VibratorService vibrator = null; +Sn3199Service sn3199 = null; IAlarmManager alarm = null; .......  Slog.i(TAG, "Vibrator Service");  vibrator = new VibratorService(context);  ServiceManager.addService("vibrator", vibrator);  +Slog.i(TAG, "Sn3199 Service");  +sn3199 = new Sn3199Service();   //我们的构造函数是无参数构造函数,所以这里为空  +ServiceManager.addService("sn3199", sn3199);

实现jni调用

  • com_android_server_Sn3199Service.cpp(相对Android源码目录:frameworks/base/services/core/jni/)
#define LOG_TAG "Sn3199Service"#include "jni.h"#include "JNIHelp.h"#include "android_runtime/AndroidRuntime.h"#include <utils/misc.h>#include <utils/Log.h>#include <hardware/sn3199_hal.h>#include <stdio.h>struct sn3199_device_t *sn3199_dev;namespace android{//JNI调用static jint sn3199Open(JNIEnv *env, jobject clazz){    hw_module_t* module;    hw_device_t* device;    jint err;    err = hw_get_module(SN3199_HARDWARE_MODULE_ID , (hw_module_t const**)&module);     //获取到对应的hal中的modules对象,第一个参数为hal层中的id    if(err == 0)    {        ALOGD("module->methods->open");        module->methods->open(module, NULL, &device); //获取到hal中的device信息        sn3199_dev = (struct sn3199_device_t* )device;        return 0;    }    else    {        ALOGD("hw_get_module exec error");    }    return -1;}static jint setLightState(JNIEnv *env, jobject clazz, int state)   //前面了两个参数是系统带的一定要有的,后面的是用户自定参数{    sn3199_dev->set_light_state(sn3199_dev, state);    return 0;}static JNINativeMethod method_table[] = {    { "nativeSn3199Open", "()I", (void*)sn3199Open },    //第二个参数()参数个数,I-返回值类型    { "nativeSetLightState", "(I)I", (void*)setLightState }};int register_android_server_Sn3199Service(JNIEnv *env){    return jniRegisterNativeMethods(env, "com/android/server/Sn3199Service",            method_table, NELEM(method_table));}};

加载cpp文件到Android.mk中(相对Android源码目录:frameworks/base/services/core/jni)

 $(LOCAL_REL_DIR)/com_android_server_VibratorService.cpp \ +$(LOCAL_REL_DIR)/com_android_server_Sn3199Service.cpp \

调用register_android_server_Sn3199Service函数

  • onload.cpp(相对Android源码目录:frameworks/base/services/core/jni/)
.......int register_android_server_VibratorService(JNIEnv* env);//and by yjd 1. int register_android_server_Sn3199Service(JNIEnv *env);   //定义//end.....register_android_server_VibratorService(env); //and by yjd 2. register_android_server_Sn3199Service(env);   //调用 //endregister_android_server_SystemServer(env);...

hal层问题编译总结:第一个是,自己编写的hal层源码怎么添加进Android的默认编译中去,也就是说在根目录执行make时,自己编写hal源码也会被编译。第二个问题是,编译完成后还要自动安装在指定的系统目录lib/hw下。刚开始时不太了解,总是需要使用mmm来进行编译安装,但是打包之后再编译这是不现实的。为此需要添加到默认中
解决方法:
在写好hardware/libhardware/modules/sn3199工程文件时,要将sn3199目录加到modules的Android.mk中,hardware_modules变量中添加sn3199文件夹的名字即可,这样在默认中就会自动编译这个sn3199的文件,这样虽然可以编译了,但是不会自动安装,如果在源码根目录下编译安装sn3199,还需修改device/s3graphics/zx2000/zx2000.mk这个文件中的PRODUCT_PACKAGES变量,在文件中添加PRODUCT_PACKAGES += sn3199.default代码即可

这样上图中的stub、Java、JNI都完成了(已经凌晨1点了,挺住写完再睡)
在framework/base/目录下执行mm命令进行编译

接下来就是编写APP进行测试了,测试之前要将刚编译框架层中的classes.jar(相对Android源码路径:out/target/common/obj/JAVA_LIBRARIES/framework_intermediates)拷贝出来供APP使用,直接上代码,APP只是测试用,所以就随便写了

  • MainActivity.java
package com.example.yjd.sn3199interfacetest;import android.os.Bundle;import android.os.ISn3199Service;import android.os.RemoteException;import android.os.ServiceManager;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.Button;import android.widget.Toast;public class MainActivity extends AppCompatActivity implements View.OnClickListener {    private ISn3199Service iSn3199Service = null;    private Button[] btnState = new Button[6];    Toast toast;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        iSn3199Service = ISn3199Service.Stub.asInterface(ServiceManager.getService("sn3199"));        if(null != iSn3199Service) {            try {                iSn3199Service.sn3199Open();            } catch (RemoteException e) {                e.printStackTrace();            }        }        btnState[0] = (Button) findViewById(R.id.state1);        btnState[1] = (Button) findViewById(R.id.state2);        btnState[2] = (Button) findViewById(R.id.state3);        btnState[3] = (Button) findViewById(R.id.state4);        btnState[4] = (Button) findViewById(R.id.state5);        btnState[5] = (Button) findViewById(R.id.state6);        for (int i = 0; i < 6; i++) {           btnState[i].setOnClickListener(this);        }    }    public void onClick(View v) {        switch (v.getId()) {            case R.id.state1:    //待机-白色呼吸灯效果                try{                    iSn3199Service.setLightState(1);                }catch(RemoteException e) {                    e.printStackTrace();                }                toast = Toast.makeText(this, "待机-白色呼吸灯效果设置成功", Toast.LENGTH_SHORT);                toast.show();                break;            case R.id.state2:   //正常工作(音箱本身喇叭不工作)-常亮白色                try{                    iSn3199Service.setLightState(2);                }catch(RemoteException e)                {                    e.printStackTrace();                }                toast = Toast.makeText(this, "待机-白色呼吸灯效果设置成功", Toast.LENGTH_SHORT);                toast.show();                break;            case R.id.state3:   //程序系统异常状态-红色闪烁                try{                    iSn3199Service.setLightState(3);                }catch(RemoteException e)                {                    e.printStackTrace();                }                toast = Toast.makeText(this, "程序系统异常状态-红色闪烁设置成功", Toast.LENGTH_SHORT);                toast.show();                break;            case R.id.state4:    //跟随音乐跳动状态                try{                    iSn3199Service.setLightState(4);                }catch(RemoteException e)                {                    e.printStackTrace();                }                toast = Toast.makeText(this, "跟随音乐跳动状态设置成功", Toast.LENGTH_SHORT);                toast.show();                break;            case R.id.state5:   //网络异常状态-常亮红色                try{                    iSn3199Service.setLightState(5);                }catch(RemoteException e)                {                    e.printStackTrace();                }                toast = Toast.makeText(this, "网络异常状态-常亮红色设置成功", Toast.LENGTH_SHORT);                toast.show();                break;            case R.id.state6:     //正在开机-蓝色呼吸灯                try{                    iSn3199Service.setLightState(6);                }catch(RemoteException e)                {                    e.printStackTrace();                }                toast = Toast.makeText(this, "正在开机-蓝色呼吸灯设置成功", Toast.LENGTH_SHORT);                toast.show();                break;            default:                break;        }    }}
  • activity_main.xml
<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.example.yjd.sn3199interfacetest.MainActivity">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="vertical">        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="State1"            android:id="@+id/state1"/>        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="State2"            android:id="@+id/state2"/>        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="State3"            android:id="@+id/state3"/>        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="State4"            android:id="@+id/state4"/>        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="State5"            android:id="@+id/state5"/>        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="State6"            android:id="@+id/state6"/>    </LinearLayout></android.support.constraint.ConstraintLayout>

编译的时候可能会遇到方法超过64K的错误,这里添加两行代码完美解决
这里写图片描述
这里写图片描述
OK,终于写完了,至于怎么添加classes.jar包到Android项目中应该就很简单了,还是贴张图吧
这里写图片描述
这里添加依赖选第3个选模块依赖:ModuleDependency
这里写图片描述

在此特别注意的时候,在调试底层代码的时候,多看main log, 用logcat -v time -b main 命令

如果有什么疑问可以加QQ:1308418494一起讨论学习,欢迎大神指点

阅读全文
0 0