基于tiny4412的andorid开发-------简单的led灯控制

请给我倒杯茶 请给我倒杯茶     2022-09-06     115

关键词:

本文转载自:http://www.cnblogs.com/pengdonglin137/p/3857724.html

基于TINY4412的Andorid开发-------简单的LED灯控制

 

参考资料:

《Andriod系统源代码情景分析》

《嵌入式Linux系统开发完全手册_基于4412_上册》

 

 

作者:彭东林

邮箱:pengdonglin137@163.com

 

 

平台介绍:

主机:Win7 32位

虚拟机:VMware10 + ubuntu-12.04.2-desktop-amd64

Android版本:  android-4.2.2_r1

Linux内核版本:linux-3.5.0

Bootloader:  友善之臂提供的Superboot4412.bin

目标平台:tiny4412ADK+S700 4GB Flash

 

目的: 在Tiny4412上运行的Android系统上,通过点击屏幕上的Button来控制Tiny4412的核心板上的四个LED灯的亮灭。一个有八个Button,每个灯的亮灭通过两个灯来控制,点击ON,相应的LED亮;点击OFF,相应的LED灯灭。

 

下面分几步完成:

1、编写驱动程序

2、测试驱动程序

3、编写HAL代码

4、编写framework代码

5、编写JNI代码

6、编写App

下面开始:

一、编写驱动程序

分析tiny4412的原理图,看一下LED灯的位置:

image

可以知道,LED是低电平亮,高电平灭。

看一下,接到了Exynos4412的哪些引脚上了:

image

可以看到:

LED1  --------- GPM4_0

LED2  --------- GPM4_1

LED3  --------- GPM4_2

LED4  --------- GPM4_3

看一下Exynos4412的芯片手册,看一下GPM4的相关寄存器:

image

图中第二列表示的相对于基地址的偏移量,这里基地址是:0x11000000.

在芯片手册的Page288 ~ Page291对这些寄存器有更详细的介绍。

以GPM4_0引脚为例:

image

为了控制灯,[3:0]应设置为0x01,即输出模式

image

向GPM4DAT的第0位写0,GPM4_0引脚输出低电平,LED1亮;

向GPM4DAT的第0位写1,GPM4_0引脚输出高电平,LED1灭;

接下来,开始写驱动程序,用友善之臂自带的Linux3.5.0内核

   1:  cd linux-3.5/
   2:  cd drivers/
   3:  mkdir android_led
   4:  cd android_led/

在android_led/下创建led_demo.c和led_demo.h文件:

touch  led_demo.c led_demo.h

再在其中创建Makefile和Kconfig文件

touch Makefile Kconfig
  • 修改Kconfig:
   1:  config LED_DEMO
   2:      tristate "Android Led Demo"
   3:      default n
   4:      help
   5:      This is the led demo for Android system.
  • 修改Makefile:
obj-$(CONFIG_LED_DEMO) += led_demo.o
  • 修改drivers/Kconfig,添加 source “drivers/android_led/Kconfig”
   1:  menu "Device Drivers"
   2:   
   3:  source "drivers/android_led/Kconfig"
   4:   
   5:  ......
   6:   
   7:  endmenu
  • 修改drivers/Makefile:
   1:  ......
   2:   
   3:  obj-$(CONFIG_LED_DEMO)  += android_led/
  • 在内核顶层目录下执行make  menuconfig,进入Device Drivers,将 Android Led Demo选择为*,然后保存配置退出。

image

 

注:执行上面这些操作之前,确保已经按照友善之臂的手册,成功编译了Android上用的Linux内核,并且在arch/arm/boot下生成了zImage等文件。

在前期开发的时候,时不时要编译,可以将drivers/android_led/Makefile修改为:

   1:  #obj-$(CONFIG_LED_DEMO) += led_demo.o
   2:  obj-m += led_demo.o

编译的时候,可以使用:

make M=drivers/android_led modules

目的是提高编译速度,最后再将Makfile改回原样。临时测试,可以在Wind7的命令行下,使用adb push将led_demo.ko上传到/data/local下,然后用adb shell登陆板子,进行测试。

  • 修改led_demo.h和led_demo.c

led_demo.h

   1:  #ifndef __LED_DEMO_H__
   2:  #define __LED_DEMO_H__
   3:   
   4:  #include <linux/cdev.h>
   5:   
   6:  #define LED_ON    _IOW('L', 0, int)
   7:  #define LED_OFF    _IOW('L', 1, int)
   8:   
   9:  #define LED_DEMO_DEVICE_NODE_NAME  "led_demo"
  10:  #define LED_DEMO_DEVICE_CLASS_NAME "led_demo"
  11:  #define LED_DEMO_DEVICE_FILE_NAME  "led_demo"
  12:   
  13:  #define EXYNOS4412_GPM4CON    0x110002E0
  14:  #define EXYNOS4412_GPM4DAT    0x110002E4
  15:   
  16:   
  17:  struct led_demo_dev
  18:  {
  19:      struct cdev dev;
  20:  };
  21:   
  22:  #endif

 

led_demo.c

   1:  #include <linux/kernel.h>
   2:  #include <linux/module.h>
   3:  #include <linux/fs.h>
   4:  #include <linux/slab.h>
   5:  #include <linux/device.h>
   6:   
   7:  #include <asm/io.h>
   8:  #include <asm/uaccess.h>
   9:   
  10:   
  11:  #include "led_demo.h"
  12:   
  13:   
  14:  MODULE_LICENSE("GPL");
  15:   
  16:   
  17:  static int led_demo_major;
  18:  static int led_demo_minor;
  19:  static int number_of_dev = 1;
  20:   
  21:  static struct led_demo_dev  *led_dev = NULL;
  22:   
  23:  static unsigned int *GPM4CON = NULL;
  24:  static unsigned int *GPM4DAT = NULL;
  25:   
  26:  static struct class *led_demo_class = NULL;
  27:   
  28:   
  29:  static int led_open (struct inode *node, struct file *fops)
  30:  {
  31:      struct led_demo_dev *dev;
  32:   
  33:      dev = container_of(node->i_cdev, struct led_demo_dev, dev);
  34:   
  35:      fops->private_data = dev;
  36:   
  37:      return 0;
  38:  }
  39:  static int led_close (struct inode *node, struct file *fops)
  40:  {
  41:      return 0;
  42:  }
  43:   
  44:  static long led_ioctl (struct file *fops, unsigned int cmd, unsigned long data)
  45:  {
  46:      //struct led_demo_dev * led_dev = (struct led_demo_dev *)fops->private_data;
  47:   
  48:      if((data < 1) || (data > 4))
  49:      {
  50:          printk(KERN_ALERT"parameter is no valid.\n");
  51:          return -EINVAL;
  52:      }
  53:      
  54:      switch (cmd)
  55:      {
  56:          case LED_OFF:
  57:              writel(readl(GPM4DAT) | (0x1<<(data-1)), GPM4DAT);
  58:              break;
  59:          case LED_ON:
  60:              writel(readl(GPM4DAT) & ~(0x1<<(data-1)), GPM4DAT);
  61:              break;
  62:          default:
  63:              return -EINVAL;
  64:              break;
  65:      }
  66:   
  67:      
  68:      return 0;
  69:  }
  70:   
  71:  struct file_operations led_fops =
  72:  {
  73:      .owner = THIS_MODULE,
  74:      .open = led_open,
  75:      .unlocked_ioctl = led_ioctl,
  76:      .compat_ioctl = led_ioctl,
  77:      .release = led_close,
  78:  };
  79:   
  80:  static int __led_setup_dev(struct led_demo_dev * dev)
  81:  {
  82:      int err = -1;
  83:   
  84:      dev_t devno = MKDEV(led_demo_major, led_demo_minor);
  85:   
  86:      memset(dev, 0, sizeof(struct led_demo_dev));
  87:   
  88:      cdev_init(&(dev->dev), &led_fops);
  89:   
  90:      dev->dev.owner = THIS_MODULE;
  91:   
  92:      err = cdev_add(&(dev->dev), devno, number_of_dev);
  93:      if(err < 0)
  94:      {
  95:          return err;
  96:      }
  97:      
  98:      return 0;
  99:  }
 100:   
 101:  static int led_demo_init(void)
 102:  {
 103:      int err = -1;
 104:      dev_t dev;
 105:      struct device *temp = NULL;
 106:   
 107:      printk(KERN_ALERT"Initializing led demo device.\n");
 108:   
 109:      err = alloc_chrdev_region(&dev, 0, number_of_dev, LED_DEMO_DEVICE_NODE_NAME);
 110:      if(err < 0)
 111:      {
 112:          printk(KERN_ALERT"fail to alloc char dev region.\n");
 113:          goto fail;
 114:      }
 115:   
 116:      led_demo_major = MAJOR(dev);
 117:      led_demo_minor = MINOR(dev);
 118:   
 119:      led_dev = kmalloc(sizeof(struct led_demo_dev), GFP_KERNEL);
 120:      if(!led_dev)
 121:      {
 122:          err = -ENOMEM;
 123:          printk(KERN_ALERT"Failed to alloc led device.\n");
 124:          goto unregister;
 125:      }
 126:   
 127:      err = __led_setup_dev(led_dev);
 128:      if (err < 0)
 129:      {
 130:          printk(KERN_ALERT"Failed to setup led device.\n");
 131:          goto clean_up;
 132:      }
 133:   
 134:      GPM4CON = (unsigned int *)ioremap(EXYNOS4412_GPM4CON, 4);
 135:      if(!GPM4CON)
 136:      {
 137:          err = -ENOMEM;
 138:          goto destroy_cdev;
 139:      }
 140:      
 141:      GPM4DAT = (unsigned int *)ioremap(EXYNOS4412_GPM4DAT, 4);
 142:      if(!GPM4DAT)
 143:      {
 144:          err = -ENOMEM;
 145:          goto unmap1;
 146:      }
 147:   
 148:      writel((readl(GPM4CON) & ~0xffff) | 0x1111, GPM4CON);
 149:      writel(readl(GPM4DAT)| 0xf, GPM4DAT);
 150:   
 151:      led_demo_class = class_create(THIS_MODULE, LED_DEMO_DEVICE_CLASS_NAME);
 152:      if(IS_ERR(led_demo_class))
 153:      {
 154:          err = PTR_ERR(led_demo_class);
 155:          printk(KERN_ALERT"Failed to create led demo class.\n");
 156:          goto unmap2;
 157:      }
 158:   
 159:      temp = device_create(led_demo_class, NULL, dev, NULL, "%s", LED_DEMO_DEVICE_FILE_NAME);
 160:      if(IS_ERR(temp))
 161:      {
 162:          err = PTR_ERR(temp);
 163:          printk(KERN_ALERT"Failed to create led demo device.\n");
 164:          goto destroy_class;
 165:      }
 166:   
 167:      dev_set_drvdata(temp, (void *)led_dev);
 168:   
 169:      printk(KERN_ALERT"Succeed to initialize led demo device.\n");
 170:          
 171:      return 0;
 172:   
 173:  destroy_class:
 174:      class_destroy(led_demo_class);
 175:      
 176:  unmap2:
 177:      iounmap(GPM4DAT);
 178:      
 179:  unmap1:
 180:      iounmap(GPM4CON);
 181:      
 182:  destroy_cdev:
 183:      cdev_del(&(led_dev->dev));
 184:   
 185:  clean_up:
 186:      kfree(led_dev);
 187:      
 188:  unregister:
 189:      unregister_chrdev_region(MKDEV(led_demo_major, led_demo_minor), number_of_dev);
 190:      
 191:  fail:
 192:   
 193:      return err;
 194:  }
 195:   
 196:  static void led_demo_exit(void)
 197:  {
 198:      if(led_demo_class)
 199:      {
 200:          device_destroy(led_demo_class, MKDEV(led_demo_major, led_demo_minor));
 201:          class_destroy(led_demo_class);
 202:      }
 203:      
 204:      iounmap(GPM4DAT);
 205:      iounmap(GPM4CON);
 206:   
 207:      if(led_dev)
 208:      {
 209:          cdev_del(&(led_dev->dev));
 210:          kfree(led_dev);
 211:      }
 212:   
 213:      unregister_chrdev_region(MKDEV(led_demo_major, led_demo_minor), number_of_dev);
 214:  }
 215:   
 216:   
 217:   
 218:  module_init(led_demo_init);
 219:  module_exit(led_demo_exit);
 220:   

 

编写完成后,在内核源码的顶层目录执行make zImage –jN,然后就会在arch/arm/boot/生成zImage文件,利用友善之臂提供的Minitools将zImage烧写到板子上。具体步骤,参考友善之臂提供的PDF文档:《Tiny4412用户手册》

二、编写代码测试驱动程序

在android-4.2.2_r1源码顶层目录下

   1:  external/led_demo/
   2:  ├── Android.mk
   3:  ├── led_demo.c
   4:  └── led_demo.h

即,在external/下创建led_demo目录,并在其中创建Android.mk、led_demo.c以及led_demo.h文件.

Android.mk:

   1:  LOCAL_PATH:= $(call my-dir)
   2:  include $(CLEAR_VARS)
   3:  LOCAL_MODULE_TAGS := optional
   4:  LOCAL_SRC_FILES := $(call all-subdir-c-files)
   5:  LOCAL_MODULE := led_demo_test
   6:  include $(BUILD_EXECUTABLE)
   7:   

led_demo.h:

   1:  #ifndef __LED_DEMO_H__
   2:  #define __LED_DEMO_H__
   3:   
   4:  #define LED_ON    _IOW('L', 0, int)
   5:  #define LED_OFF    _IOW('L', 1, int)
   6:   
   7:  #endif

led_demo.c:

   1:  #include <stdio.h>
   2:  #include <sys/types.h>
   3:  #include <sys/stat.h>
   4:  #include <fcntl.h>
   5:  #include <stdlib.h>
   6:  #include <sys/ioctl.h>
   7:   
   8:  #include "led_demo.h"
   9:   
  10:  int main(int argc, const char *argv[])
  11:  {
  12:      int fd;
  13:      int i;
  14:   
  15:      fd = open("/dev/led_demo", O_RDWR);
  16:      if (fd < 0)
  17:      {
  18:          perror("failed to open.\n");   
  19:          exit(-1);
  20:      }                    
  21:   
  22:      while(1)
  23:      {
  24:          for(i=0; i<4; i++)
  25:          {
  26:              ioctl(fd, LED_OFF, i+1);
  27:              sleep(1);
  28:              ioctl(fd, LED_ON, i+1);
  29:              sleep(1);
  30:              ioctl(fd, LED_OFF, i+1);
  31:              sleep(1);
  32:          }
  33:      }
  34:   
  35:      close(fd);
  36:   
  37:      return 0;
  38:  }

编写完成后,在android-4.2.2_r1源码顶层目录下执行:

   1:    mmm ./external/led_demo/
   2:   
   3:   ./gen-img.sh

然后将顶层目录下新生成的system.img利用友善之臂提供的Minitools烧写到板子上。

烧写完成后,重启板子。

使用串口终端登陆板子,使用su命令进入root用户模式,然后进入/system/bin目录下,执行./led_demo_test,观察现象,可以看到,TINY4412的核心板上的四个LED灯循环亮灭。也可以使用wind7下的控制终端,用adb shell登陆板子,进行测试。

三、编写HAL代码

在hardware/libhardware/include/hardware/下创建文件led_demo_hal.h

在hardware/libhardware/modules/下创建目录led_demo_hal,然后进入led_demo_hal,创建两个文件,分别是Android.mk和

led_demo_hal.cpp。

下面是文件内容:

hardware/libhardware/include/hardware/led_demo_hal.h

   1:  #ifndef ANDROID_LED_DEMO_HAL_H
   2:  #define ANDROID_LED_DEMO_HAL_H
   3:   
   4:  #include <hardware/hardware.h>
   5:   
   6:  __BEGIN_DECLS
   7:   
   8:  #define LED_DEMO_HARDWARE_MODULE_ID   "led_demo_hal"  //模块ID 需要与下面的Android.mk中的LOCAL_MODULE 匹配,否则无法加载该HAL模块
   9:  #define LED_DEMO_HARDWARE_DEVICE_ID   "led_demo"      // 设备ID   
  10:   
  11:   
  12:  struct led_demo_module_t
  13:  {
  14:          struct hw_module_t common;
  15:  };
  16:   
  17:  struct led_demo_device_t
  18:  {
  19:          struct hw_device_t common;
  20:          int fd;
  21:          int (*set_on)(struct led_demo_device_t *dev, int val);  //用于控制LED,点亮第val个LED灯
  22:          int (*set_off)(struct led_demo_device_t *dev, int val); //熄灭第val个LED灯
  23:  };
  24:   
  25:  __END_DECLS
  26:   
  27:   
  28:  #endif

 

hardware/libhardware/modules/led_demo_hal/led_demo_hal.cpp

   1:  #define LOG_TAG "LED_DEMO_HALSTUB"   //将来可以用DDMS的LogCat工具进行调试,便于查看打印信息
   2:   
   3:  #include <hardware/hardware.h>
   4:  #include <hardware/led_demo_hal.h>
   5:   
   6:  #include <fcntl.h>
   7:  #include <errno.h>
   8:   
   9:  #include <utils/Log.h>
  10:  #include <cutils/atomic.h>
  11:   
  12:   
  13:  #define DEVICE_NAME    "/dev/led_demo"    //设备结点,有Linux驱动程序自动创建
  14:  #define MODULE_NAME    "led_demo"
  15:  #define MODULE_AUTHOR  "pengdonglin137@163.com"
  16:   
  17:  #define LED_ON  0x40044c00     //点灯的命令,其实就是_IOW('L', 0, int)的值,_IOW在编译时无法识别,待以后解决
  18:  #define LED_OFF 0x40044c01     //灭灯命令,其实就是_IOW('L', 1, int)的值,可以在上面的led_demo.c中加打印,看一下这个值是多少
  19:   
  20:   
  21:  static int led_demo_open(const struct hw_module_t* module, const char* id,
  22:          struct hw_device_t** device);
  23:   
  24:  static int led_demo_close(struct hw_device_t* device);
  25:   
  26:  static int led_demo_set_on(struct led_demo_device_t *dev, int val);
  27:   
  28:  static int led_demo_set_off(struct led_demo_device_t *dev, int val);
  29:   
  30:   
  31:  static hw_module_methods_t led_demo_module_methods =
  32:  {
  33:      open:led_demo_open,
  34:  };
  35:   
  36:  struct led_demo_module_t HAL_MODULE_INFO_SYM = 
  37:  {
  38:      common:{
  39:          tag:HARDWARE_MODULE_TAG,
  40:          version_major:1,
  41:          version_minor:0,
  42:          id:LED_DEMO_HARDWARE_MODULE_ID,
  43:          name:MODULE_NAME,
  44:          author:MODULE_AUTHOR,
  45:          methods:&led_demo_module_methods,
  46:      }
  47:  };
  48:   
  49:  static int led_demo_open(const struct hw_module_t* module, const char* id,
  50:          struct hw_device_t** device)
  51:  {
  52:      if(!strcmp(id, LED_DEMO_HARDWARE_DEVICE_ID))
  53:      {
  54:          struct led_demo_device_t *dev;
  55:   
  56:          dev = (struct led_demo_device_t *)malloc(sizeof(struct led_demo_device_t));
  57:          if(!dev)
  58:          {
  59:              ALOGE("Failed to alloc space for struct led_demo_device_t.");
  60:              return -EFAULT;
  61:          }
  62:   
  63:          memset(dev, 0, sizeof(struct led_demo_device_t));
  64:   
  65:          dev->common.tag = 
HARDWARE_DEVICE_TAG
;
  66:          dev->common.version = 0;
  67:          dev->common.module = (struct hw_module_t *)module;
  68:          dev->common.close = led_demo_close;
  69:          dev->set_on = led_demo_set_on;
  70:          dev->set_off = led_demo_set_off;
  71:   
  72:          if((dev->fd = open(DEVICE_NAME, O_RDWR)) == -1)
  73:          {
  74:              ALOGE("Failed to open device %s ---- %s\n.", DEVICE_NAME, strerror(errno));
  75:              free(dev);
  76:              return -EFAULT;
  77:          }
  78:   
  79:          *device = &(dev->common);
  80:   
  81:          ALOGE("Open device file %s successfully.", DEVICE_NAME);
  82:   
  83:      }
  84:   
  85:      return -EFAULT;
  86:  }
  87:   
  88:  static int led_demo_close(struct hw_device_t* device)
  89:  {
  90:      struct led_demo_device_t *led_device = (struct led_demo_device_t *)device;
  91:      if(led_device)
  92:      {
  93:          close(led_device->fd);
  94:          free(led_device);
  95:      }
  96:   
  97:      return 0;
  98:  }
  99:   
 100:  static int led_demo_set_on(struct led_demo_device_t *dev, int val)
 101:  {
 102:      if(!dev)
 103:      {
 104:          ALOGE("Null dev pointer.");
 105:          return -EFAULT;
 106:      }
 107:      
 108:      if(ioctl(dev->fd, LED_ON, val) < 0)
 109:      {
 110:          ALOGE("ioctl error --- %s.", strerror(errno));
 111:          return -EFAULT;
 112:      }
 113:   
 114:      return 0;
 115:      
 116:  }
 117:   
 118:  static int led_demo_set_off(struct led_demo_device_t *dev, int val)
 119:  {
 120:      if(!dev)
 121:      {
 122:          ALOGE("Null dev pointer.");
 123:          return -EFAULT;
 124:      }
 125:      
 126:      if(ioctl(dev->fd, LED_OFF, val) < 0)
 127:      {
 128:          ALOGE("ioctl error --- %s.", strerror(errno));
 129:          return -EFAULT;
 130:      }
 131:   
 132:      return 0;
 133:      
 134:  }
 135:   

 

hardware/libhardware/modules/led_demo_hal/Android.mk

   1:  LOCAL_PATH := $(call my-dir)
   2:  include $(CLEAR_VARS)
   3:  LOCAL_MODULE_TAGS := optional
   4:  LOCAL_PRELINK_MODULE := false
   5:  LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
   6:  LOCAL_SHARED_LIBRARIES := liblog
   7:  LOCAL_SRC_FILES := led_demo_hal.cpp
   8:  LOCAL_MODULE := led_demo_hal.default
   9:  include $(BUILD_SHARED_LIBRARY)

 

编写完成后,在Android源码的顶层目录执行:

mmm ./hardware/libhardware/modules/led_demo_hal/

最终out/target/product/tiny4412/system/lib/hw/目录下得到一个led_demo_hal.default.so文件。

下面处理一下硬件设备访问权限问题

在硬件抽象层模块中,我们是调用open函数来打开对应的设备文件的,在默认情况下,只有root用户才有权限访问系统的设备文件。但是一般的应用程序是没有root用户权限的。

解决办法,赋予root之外的其他用户访问设别文件/dev/led_demo的权限。做法如下:

在Android源码顶层目录下,修改system/core/rootdir/ueventd.rc,添加如下内容:

/dev/led_demo             0666   root       root

修改了ueventd.rc文件后,需要重新编译Android源代码工程,编译时,文件system/core/rootdir/ueventd.rc会拷贝到out/target/product/tiny4412/root/下,并且最终打包在ramdisk.img中。对于友善之臂,执行完make -jN后,还需要执行./gen-img.sh脚本,然后在Android源码顶层目录中会生成ramdisk-u.img文件,利用MiniTools将其烧写到板子上。

四、编写Framework代码

  • 定义硬件访问服务接口

在frameworks/base/core/java/android/os/创建文件ILed_demo_service.aidl,内容如下:

   1:  package android.os;
   2:   
   3:  interface ILed_demo_service
   4:  {
   5:      void led_set_ON(int val);
   6:      void led_set_OFF(int val);
   7:  }

然后,修改frameworks/base/Android.mk

   1:  LOCAL_SRC_FILES += \
   2:      ......
   3:      core/java/android/os/IVibratorService.aidl \
   4:      core/java/android/os/ILed_demo_service.aidl \

最后,在Android源码顶层目录下执行

mmm ./frameworks/base/

编译后得到的framework.jar文件就包含了ILed_demo_service接口。

  • 实现硬件访问服务

在frameworks/base/services/java/com/android/server/创建文件Led_demo_Service.java,内容如下:

   1:  package com.android.server;
   2:  import android.content.Context;
   3:  import android.os.ILed_demo_service;
   4:  import android.util.Slog;
   5:   
   6:   
   7:  public class Led_demo_Service extends ILed_demo_service.Stub
   8:  {
   9:          private static final String TAG = "Led_demo_Service";  //方便DDMS提供的LogCat工具看打印信息
  10:   
  11:          private int mPtr = 0;
  12:   
  13:          Led_demo_Service()
  14:          {
  15:                  mPtr = init_native();  //硬件访问服务Led_demo_Service在启动时,会通过JNI方法init_native
  16:   
  17:                  if(mPtr == 0)
  18:                  {
  19:                          Slog.e(TAG, "Failed to initialize Led demo Service.");
  20:                  }
  21:          }
  22:   
  23:          public void led_set_ON(int val)
  24:          {
  25:                  if(mPtr == 0)
  26:                  {
  27:                          Slog.e(TAG, "Led demo Service is not initialized.");
  28:                          return;
  29:                  }
  30:   
  31:                  set_ON_native(mPtr, val);
  32:          }
  33:   
  34:          public void led_set_OFF(int val)
  35:          {
  36:                  if(mPtr == 0)
  37:                  {
  38:                          Slog.e(TAG, "Led demo Service is not initialized.");
  39:                          return;
  40:                  }
  41:   
  42:                  set_OFF_native(mPtr, val);
  43:          }
  44:   
  45:   
  46:          private static native int init_native();
  47:          private static native void set_OFF_native(int mPtr, int val);
  48:          private static native void set_ON_native(int mPtr, int val);
  49:   
  50:   
  51:  };

编写完成后,在Android源码顶层目录下执行:

mmm ./frameworks/base/services/java/

编译后得到的services.jar文件就包含有Led_demo_Service类。

 

五、编写JNI代码

在frameworks/base/services/jni/下创建文件com_android_server_led_demo_service.cpp,内容如下:

   1:  #define LOG_TAG  "LED_DEMO_Service_JNI"   //方便LogCat调试工具查看打印信息
   2:   
   3:  #include "jni.h"
   4:  #include "JNIHelp.h"
   5:  #include "android_runtime/AndroidRuntime.h"
   6:   
   7:  #include <utils/misc.h>
   8:  #include <utils/Log.h>
   9:  #include <hardware/hardware.h>
  10:  #include <hardware/led_demo_hal.h>
  11:   
  12:  #include <stdio.h>
  13:   
  14:   
  15:  namespace android
  16:  {
  17:   
  18:      static void led_demo_setOFF(JNIEnv *env, jobject clazz, jint ptr, jint value)
  19:      {
  20:          led_demo_device_t *device = (led_demo_device_t *)ptr;
  21:          if(!device)
  22:          {
  23:              ALOGE("Device led demo is not open.");
  24:              return ;
  25:          }
  26:   
  27:          int val = value;
  28:   
  29:          ALOGI("Set value %d to device led demo.", val);
  30:   
  31:          device->set_off(device, value);
  32:      }
  33:   
  34:      static void led_demo_setON(JNIEnv *env, jobject clazz, jint ptr, jint value)
  35:      {
  36:          led_demo_device_t *device = (led_demo_device_t *)ptr;
  37:          if(!device)
  38:          {
  39:              ALOGE("Device led demo is not open.");
  40:              return ;
  41:          }
  42:   
  43:          int val = value;
  44:   
  45:          ALOGI("Set value %d to device led demo.", val);
  46:   
  47:          device->set_on(device, value);
  48:      }
  49:      
  50:   
  51:      static inline int led_demo_device_open(const hw_module_t *module, struct led_demo_device_t **device)
  52:      {
  53:          return module->methods->open(module, LED_DEMO_HARDWARE_DEVICE_ID, (struct hw_device_t **)device);    
  54:      }
  55:   
  56:   
  57:   
  58:      static jint led_demo_init(JNIEnv *env, jclass clazz)
  59:      {
  60:          struct led_demo_module_t *module;
  61:          struct led_demo_device_t *device;
  62:   
  63:   
  64:          ALOGI("Initializing HAL stub led ......");
  65:   
  66:          if(hw_get_module(
LED_DEMO_HARDWARE_MODULE_ID
, (const struct hw_module_t **)&module) == 0)
  67:          {
  68:              ALOGE("Device led demo found.");
  69:   
  70:              if(led_demo_device_open(&(module->common), &device))
  71:              {tiny4412--uboot移植时钟(代码片段)

...可以仅用于测试,不用时接地XUSBXTI:24MZH。因为IROM设计基于24兆赫输入时钟。有XUSBXTI、XUSBXTO两个引脚,且之间需要5mΩ的并联电阻在友善之臂tiny4412的开发板中, XRTCXTI 上没有外接晶振,系统时钟来源是XUSBXTI引脚上接 查看详情

tiny4412--uboot移植串口(代码片段)

开发环境:win1064位 +VMware12+Ubuntu14.0432位工具链:linaro提供的gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi要移植的u-boot版本:u-boot-2016-11Tiny4412开发板硬件版本为:  底板:  Tiny4412SDK1312B  核心板:Tiny4412-1306 ... 查看详情

使用nfs启动tiny4412开发板根文件系统

 1、Ubuntu14.04上搭建NFS服务1.1、安装NFS服务        $sudoapt-getinstallnfs-kernel-server  //安装NFS服务1.2创建Tiny4412开发板根文件系统   这部分内容参考《Busybox构建根 查看详情

tiny4412开发板支持linux吗

Android和Linux是两码事,Android系统是基于Linux内核的。我们编译的Android源码是Android系统本身的源码,而内核是指通过原生Linux源码移植过来的内核源码,所以它们需要我们分别编译。并且Android系统的版本号和Linux源码的版本号是... 查看详情

tiny4412开发板支持linux吗

Android和Linux是两码事,Android系统是基于Linux内核的。我们编译的Android源码是Android系统本身的源码,而内核是指通过原生Linux源码移植过来的内核源码,所以它们需要我们分别编译。并且Android系统的版本号和Linux源码的版本号是... 查看详情

tiny4412led之buildjni实现(代码片段)

...ff1a;Tiny4412led之NDKJNI实现,介绍的是通过NDK工具进行JNI开发,*.so文件是通过NDK工具进行编译生成的,这次就介绍如何通过arm-linux-gcc编译生成对应的*.so文件,深入了解JNI底层的开发流程;驱动代码、JNI接口、andr... 查看详情

tiny4412学习杂记

1.Android挂载NFS使用busyboxmount来替代mount命令2.修改Uboot中fastboot最大buff 使用U-boot烧写Android5.0的时候出现remote:datatoolarge将 include/configs/tiny4412.h 改大一点3.tiny4412内核中trustzone配置开关tiny4412 trust 查看详情

tiny4412uboot

1.Builduboota)安装好toolchain(arm-linux-gcc-4.5.1-v6-vfp-20120301.tgz)并设置好环境变量PATH,保证可以正常使用。b)解压uboot_tiny4412-20130729.tgz并进入相应的目录tarxzfuboot_tiny4412-20130729.tgzc)配置uboot并编译cduboot_tiny4412maketiny441 查看详情

博客文章分类导航

嵌入式开发基础开发板硬件配置   Tiny4412开发板硬件版本为:   底板:Tiny4412/Super4412SDK1506   核心板:Tiny4412-1412           &nbs 查看详情

tiny4412的中断资源连接关系示意图

在tiny4412的设备树中可以发现,中断资源是以树的形式呈现的,下面是我画的一张图,大致描述了tiny4412上中断资源的连接关系。可以到http://pan.baidu.com/s/1ge0sz6N下载。其中,红色的表示的是rootinterruptcontroller(中断资源的生产者... 查看详情

tiny4412sdk1161下的hd700驱动设置

...台:Tiny4412SDK1161B+HD700kernel:linux3.5手头有一块友善之臂的开发板,需要使用HD700屏来显示图片,但是移植好内核后/dev/fb0设备并不能用,看屏幕显示了三排小企鹅,并且存在色差,怀疑lcd驱动并不配套HD700之个型号,故需要做调整... 查看详情

tiny4412u-boot烧写及根文件系统制作(不进入终端问题)

...n.net/article/details?id=51400196(转) VMware12环境:ubuntu12.4开发板:tiny4412首先烧写bootloader,我用一个8G的内存卡,现在不说sd卡的制作过程了,网上可以参考。现在就把我给arm的emmc烧写过程开始说。用sd卡启动,开发板的右下角... 查看详情

armcortex-a9(tiny4412)(代码片段)

要求移植linux增加系统调用并烧写至开发板详细步骤一、搭建linux编译环境1、GCC编译器的安装:tarxzvfarm-linux-gcc-4.5.1-v6-vfp-20120301.tgz-C/arm-linux-gcc-v//查看GCC版本2、gedit~/.bashrcexportPATH=$PATH:/opt/FriendlyARM/toolschain/4.5.1/bin3、rebo 查看详情

tiny4412裸机程序说明

本文转载自:http://blog.csdn.net/eshing/article/details/37109115首先、我想说明为什么我写这个文档?我自己想学点东西,过于求成,又过于自信,直接买了Tiny4412的板子,但网上关于4412的资料太少,我一直没办法啃动,只能尽可能找来... 查看详情

exynos4412的外部中断是如何安排的?

...email protected] 平台Linux4.9tiny4412 概述结合tiny4412开发板分析一下Exynos4412的外部中断是如何组织的。 正文在Exynos4412的用户手册第9章InterruptController列出了支持的外部中断: 图1 第1列是按Shared PeripheralInte 查看详情

tiny4412开机动画开机界面的定制原创

关键词:Android linux开机logo开机动画 平台信息:内核:linux3.0.68 系统:android/android5.1平台:tiny4412作者:庄泽彬(欢迎转载,请注明作者)邮箱:[email protected]摘要:最近晚上回到宿舍有点无聊,搞一下打发时间,如有... 查看详情

tiny4412移植opencv2.4.7手记

在买了新的4412板子后。打算趁着刚成功在6410上移植过的经验,速度解决下。不想出现了各种问题。小结下:1、关于opencv的移植:tiny4412的linux3.5上,须要把opencv的lib内so尽数复制到板子根文件夹lib下。并依照pc的arm-opencv路径。复... 查看详情

lcd驱动端与设备端名称匹配过程分析(tiny4412)

​LCD驱动端与设备端名称匹配过程在tiny4412提供的内核下,LCD屏的平台设备名字和平台驱动名字不匹配也能驱动屏点亮,​这是怎么回事的呢?下面我们来分析这是如何实现的。​硬件平台​Cpu:exynos4412​板子:tiny4412​Linux内... 查看详情