本篇博文是为了后面的Android HAL层使用LED而做的准备,板子基于TQIMX6Q,Android 4.3,Android已经编译完成了,如果还没有可以参考前面我的博文:Freescale IMX6 Android: 使用HDMI作为Android显示输出的配置,以及TQ提供的开发者手册。


LED的硬件连接

LED4~6是给用户使用的,如下:



可以看到是GPIO3_21~23。而且是GPIO给高电平的时候接通。


LED软件方面的配置

直接导出使用

看到前面的原理图,在用户态直接将gpio导出来操作(gpiolib)是最容易的了,但是要在/sys/class/gpio中导出来需要知道各组gpio的base number,直接使用cat查看,结果如下:

#for i in gpiochip* ; do echo `cat $i/label`: `cat $i/base` ; done gpio-0: 0gpio-4: 128gpio-5: 160gpio-6: 192gpio-1: 32gpio-2: 64gpio-3: 96</span></span>

可以知道gpio3是从64开始的,gpio3-21为64+21=85,于是直接操作:

#cd /sys/class/gpioecho 85 > exportecho out > gpio85/directionecho 0 > gpio85/value

但是发现不成功,因为gpio已经被使用了,无法导出来,尽管操作的时候没有出现问题log提示。

使用Gpio-led

内核使用的是3.0.35版本的内核,尽管也有dts,但是Freescale在最开始的Linuxkernel中并没有使用,因此都是hard code在board文件中的,例如这里的LED的配置就是在arch/arm/mach-mx6/board-mx6q_sabresd.c中:

#define SABRESD_GPIO_LED0     IMX_GPIO_NR(3, 21)   //home#define SABRESD_GPIO_LED1   IMX_GPIO_NR(3, 22)   //enter#define SABRESD_GPIO_LED2      IMX_GPIO_NR(3, 23)   //esc

忽略注释,然后接下来定义了一个Platform device:

static struct gpio_led imx6q_gpio_leds[] ={GPIO_LED(SABRESD_GPIO_LED0, "led0", 0, 1, "charger-charging"),GPIO_LED(SABRESD_GPIO_LED1, "led1", 0, 1, "charger-charging"),GPIO_LED(SABRESD_GPIO_LED2, "led2", 0, 1, "charger-charging"),/* For the latest B4 board, this GPIO_1 is connected to POR_B,which will reset the whole board if this pin's level is changed,so, for the latest board, we have to avoid using this pin asGPIO.    GPIO_LED(SABRESD_CHARGE_DONE, "chg_done_led", 0, 1,            "charger-full"),*/};static struct gpio_led_platform_data imx6q_gpio_leds_data ={.leds       = imx6q_gpio_leds,.num_leds   = ARRAY_SIZE(imx6q_gpio_leds),};static struct platform_device imx6q_gpio_led_device ={.name       = "leds-gpio",.id     = -1,.num_resources  = 0,.dev        = {.platform_data = &imx6q_gpio_leds_data,}};

直接在代码中HardCode Device信息,这是老内核的通常做法。从上面的代码我们知道注册了leds-gpio设备,这个设备可以在/sys/class/leds中找到,启动的时候probe时候也会打印出设备信息:

<span style="font-family:Microsoft YaHei;">Registered led device: led0Registered led device: led1Registered led device: led2</span>

从前面的imx6q_gpio_leds结构体以及最前面的定义中可以知道LED的对应关系为:

 HW   -------    SW led4led0 led5led1 led6 led2

在对应的目录中我们可以看到device设备信息:

root@sabresd_6dq:/sys/class/leds # ls -llrwxrwxrwx root     root              1970-01-02 09:36 led0 -> ../../devices/platform/leds-gpio/leds/led0lrwxrwxrwx root     root              1970-01-02 09:36 led1 -> ../../devices/platform/leds-gpio/leds/led1lrwxrwxrwx root     root              1970-01-02 09:36 led2 -> ../../devices/platform/leds-gpio/leds/led2

GPIO-LED设备的控制

gpio-led设备的子目录中有一个brightness文件,操作这个文件就可以操作led灯的亮灭,例如下面是点亮:

echo 255 > /class/gpio/leds/led0/brightness

如果写入0,那么就是熄灭。

因为Android中基础小工具都是由Toolbox提供,因此我们可以往toolbox添加一个ledctrl工具来控制灯的亮灭:

#include <sys/cdefs.h>#ifndef lint__COPYRIGHT("@(#) Copyright (c) 1989, 1993, 1994\ The Regents of the University of California.  All rights reserved.");#endif /* not lint */#ifndef lint#if 0static char sccsid[] = "@(#)ledctrl.c8.5 (Berkeley) 5/4/95";#else__RCSID("$NetBSD: ledctrl.c,v 1.33 2008/07/30 22:03:40 dsl Exp $");#endif#endif /* not lint */#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>void ledClose();int ledctrl( int which, int status);int ledOpen();#define ALOGI printf#define LED_NUM 3int leds_fd[LED_NUM];char path_buff[255];int ledctrl( int which, int status){    int ret = -1;    if(status == 1) {ret = write(leds_fd[which], "255", 3);    } else {ret = write(leds_fd[which], "0", 1);    }    if(ret < 0){        return -1;    }    ALOGI("Native ctrl fd = [%d]\n", which);    return 0;}int ledOpen(void){    int i = 0;    for(i=0; i<LED_NUM; i++){        sprintf(path_buff, "/sys/class/leds/led%d/brightness", i);printf("path:%s\n",path_buff);        leds_fd[i] = open(path_buff, O_RDWR);        if(leds_fd[i] < 0){            ALOGI("led%d: %s, open failed\n", i, path_buff);            return -1;        } else {            ALOGI("led%d: %s, open success\n", i, path_buff);        }    }    return 0;}void ledClose(void){    int i = 0;    for(i=0; i< LED_NUM; i++){        close(leds_fd[i]);    }}int ledctrl_main(int argc, char * argv[]){int i = 0;int ret = ledOpen();if (ret < 0){printf("Open failed\n");return -1;}for(i=0; i< LED_NUM; i++){ledctrl(i,1);sleep(1);ledctrl(i,0);}ledClose();return 0;}

我们在main函数中对每一个LED点亮1秒,然后就熄灭。将这个C代码保存为ledctrl.c,放在system/core/toolbox下面,然后更改toolbox目录下的Android.mk将其添加到toolbox中:

diff --git a/core/toolbox/Android.mk b/core/toolbox/Android.mkindex c764690..a19338e 100644--- a/core/toolbox/Android.mk+++ b/core/toolbox/Android.mk@@ -57,6 +57,7 @@ TOOLS := \        touch \        lsof \        du \+       ledctrl \        md5 \        clear \        getenforce \

直接在toolbox目录下面使用mm命令编译:

$ mm============================================PLATFORM_VERSION_CODENAME=RELPLATFORM_VERSION=4.3TARGET_PRODUCT=sabresd_6dqTARGET_BUILD_VARIANT=engTARGET_BUILD_TYPE=releaseTARGET_BUILD_APPS=TARGET_ARCH=armTARGET_ARCH_VARIANT=armv7-a-neonTARGET_CPU_VARIANT=cortex-a9HOST_ARCH=x86HOST_OS=linuxHOST_OS_EXTRA=Linux-3.13.0-39-generic-x86_64-with-Ubuntu-12.04-preciseHOST_BUILD_TYPE=releaseBUILD_ID=1.1.0-rc4OUT_DIR=out============================================PRODUCT_COPY_FILES device/fsl/common/input/HannStar_P1003_Touchscreen.idc:system/usr/idc/HannStar_P1003_Touchscreen.idc ignored.PRODUCT_COPY_FILES device/fsl/common/input/Novatek_NT11003_Touch_Screen.idc:system/usr/idc/Novatek_NT11003_Touch_Screen.idc ignored.PRODUCT_COPY_FILES device/fsl/common/input/qwerty.idc:system/usr/idc/qwerty.idc ignored.PRODUCT_COPY_FILES device/fsl/common/input/qwerty2.idc:system/usr/idc/qwerty2.idc ignored.No private recovery resources for TARGET_DEVICE sabresd_6dqmake: Entering directory `/home/hexiongjun/iMX6Q/TQIMX6_android-4.3'target thumb C: toolbox <= system/core/toolbox/ledctrl.ctarget Executable: toolbox (out/target/product/sabresd_6dq/obj/EXECUTABLES/toolbox_intermediates/LINKED/toolbox)target Symbolic: toolbox (out/target/product/sabresd_6dq/symbols/system/bin/toolbox)target Strip: toolbox (out/target/product/sabresd_6dq/obj/EXECUTABLES/toolbox_intermediates/toolbox)Install: out/target/product/sabresd_6dq/system/bin/toolboxmake: Leaving directory `/home/hexiongjun/iMX6Q/TQIMX6_android-4.3'

编译完成后toolbox,我们可以重新将system目录的文件拷贝到SD开对应的system分区中,也可以直接将toolbox push到android机器中,在push之前需要先remount system为rw,因此在串口中,或者有root权限的adb shell中输入下面命令:

# mount -t ext4 -r -w -o remount /system    EXT4-fs (mmcblk1p2): re-mounted. Opts: (null)


然后push文件到机器中:

$ adb push $OUT/system/bin/toolbox /system/bin/1309 KB/s (139096 bytes in 0.103s)

然后在机器的console中测试:

# toolbox ledctrl                             path:/sys/class/leds/led0/brightnessled0: /sys/class/leds/led0/brightness, open successpath:/sys/class/leds/led1/brightnessled1: /sys/class/leds/led1/brightness, open successpath:/sys/class/leds/led2/brightnessled2: /sys/class/leds/led2/brightness, open successNative ctrl fd = [0]Native ctrl fd = [0]Native ctrl fd = [1]Native ctrl fd = [1]Native ctrl fd = [2]Native ctrl fd = [2]

如果看到LED点亮1秒然后熄灭,那么说明代码无误。

更多相关文章

  1. 箭头函数的基础使用
  2. NPM 和webpack 的基础使用
  3. Python list sort方法的具体使用
  4. 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程
  5. android 使用html5作布局文件: webview跟javascript交互
  6. Android(安卓)Resource介绍和使用
  7. "Failed to fetch URL https://dl-ssl.google.com/android/repos
  8. 使用NetBeans搭建Android开发环境
  9. android 零星调试笔记

随机推荐

  1. JAVA WEB 中添加中科院分词系统ICTCLAS
  2. Java转dex,dex转smali,smali转Java
  3. Java类的加载和对象创建流程的详细分析
  4. java线程实现与进程(二)
  5. 201521123113 《Java程序设计》第2周学习
  6. java的三大特性之一(继承)
  7. Java使用socket网络编程实现多人聊天室
  8. Java7并发编程--3.4、Phaser并发阶段任务
  9. java并发包之阻塞队列BlockingQueue
  10. Javadoc转换chm帮助文档的四种方法总结