Brillo开发: 在RPI 2B(树莓派)上点亮LED @ brillo-m10-dev

早在brillo-m8-dev分支release的时候,就想在RPi 2B(树莓派)做一个控制LED灯的应用->@<-。但由于其他事情一直忙个不停,这事就给耽搁了。现在brillo-m10-dev分支release出来的,就在上面试试看吧。

2016_03_01_rpi_ledflasher_m10

  • 修改kernel

今天才发现,之前使用的kernel是没有使用dtb的,一直以传统的方式运行。在新增一个overlay dtb文件后,发现运行的时候一直没有生效,才注意到这个问题。按照https://www.raspberrypi.org/documentation/configuration/device-tree.md的说明,在/boot/config.txt中新增device_tree参数,强制使用device tree:

device_tree=kernel7.dtb

在编译完rpi-eng项目之后,会在out/target/product/rpi/下生成kernel.dtb, 将这个文件copy到TF卡brillo系统所在的分区,如/dev/block/mmcblk0p5,这个分区在Brillo系统运行时会被挂载到/boot目录下,所以在Brillo系统运行时,使用adb将其push进去就好:

$ adb push kernel.dtb kernel7.dtb

我们使用gpio的23, 24, 12, 26这几个引脚来做实验

  1. 23脚对应LED1 – 别名verbose
  2. 24脚对应LED2 – 别名debug
  3. 12脚对应LED3 – 别名info
  4. 26脚对应LED4 – 别名warn

为了尽量不修改原有代码,我们使用device tree overlay的方式来做, 在hardware/bsp/kernel/hzak/rpi-4.1.y/arch/arm/boot/dts/overlays/下新增名为rpi-led-flasher-overlay.dts的文件,内容如下:

/dts-v1/;
/plugin/;

/{
	compatible = "brcm,bcm2708";
	fragment@0 {
		target = <&leds>;
		__overlay__ {
			verbose_led: verbose_led {
				label = "verbose";
				linux,default-trigger = "none";
				gpios = <&gpio 23 0>;
			};
			debug_led: debug_led {
				label = "debug";
				linux,default-trigger = "none";
				gpios = <&gpio 24 0>;
			};
			info_led: info_led {
				label = "info";
				linux,default-trigger = "none";
				gpios = <&gpio 12 0>;
			};
			warn_led: warn_led {
				label = "warn";
				linux,default-trigger = "none";
				gpios = <&gpio 26 0>;
			};
		};
	};
};

同时修改同级目录下的Makefile文件,使dts文件能被转换成kernel能够解析的dtb文件:

dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb
dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb
dtb-$(RPI_DT_OVERLAYS) += rpi-led-flasher-overlay.dtb

targets += dtbs dtbs_install
targets += $(dtb-y)

之后再重新编译一下rpi-eng这个项目,最终会在out/target/product/rpi$ ls obj/KERNEL_OBJ/arch/arm/boot/dts/overlays/目录下生成我们所需要的rpi-led-flasher-overlay.dtb文件。

之后,还需要在boot/config.txt中加入dtoverlay参数:

# device tree support
device_tree=kernel7.dtb
dtoverlay=rpi-led-flasher

写个脚本去更新config.txt, kernel7.dtb, kernel7.img, ramdisk7.img和rpi-led-flasher-overlay.dtb文件:

#! /bin/bash

adb wait-for-device

adb push boot/config.txt /boot/
adb push kernel.dtb /boot/kernel7.dtb
adb push kernel /boot/kernel7.img
adb push ramdisk.img /boot/ramdisk7.img

adb shell mkdir -p /boot/overlays
adb push obj/KERNEL_OBJ/arch/arm/boot/dts/overlays/rpi-led-flasher-overlay.dtb /boot/overlays/

adb shell sync

所有的事情都做完之后,重启系统,你就可以在Brillo系统的/sys/class/leds下面看到如下几个文件:

$ adb shell ls -l /sys/class/leds/
total 0
lrwxrwxrwx 1 root root 0 2016-02-27 02:29 debug -> ../../devices/platform/soc/soc:leds/leds/debug
lrwxrwxrwx 1 root root 0 2016-02-27 02:29 info -> ../../devices/platform/soc/soc:leds/leds/info
lrwxrwxrwx 1 root root 0 2016-02-27 02:29 led0 -> ../../devices/platform/soc/soc:leds/leds/led0
lrwxrwxrwx 1 root root 0 2016-02-27 02:30 led1 -> ../../devices/platform/soc/soc:leds/leds/led1
lrwxrwxrwx 1 root root 0 2016-02-27 02:30 verbose -> ../../devices/platform/soc/soc:leds/leds/verbose
lrwxrwxrwx 1 root root 0 2016-02-27 02:29 warn -> ../../devices/platform/soc/soc:leds/leds/warn

NOTE: led0默认是作为TF读写操作指示用的,led1功能未知:

&leds {
    act_led: act {
        label = "led0";
        linux,default-trigger = "mmc0";
        gpios = <&gpio 47 0>;
    };

    pwr_led: pwr {
        label = "led1";
        linux,default-trigger = "input";
        gpios = <&gpio 35 0>;
    };
};
  • 修改lights HAL

lights HAL相关的代码被放在了device/hzak/rpi/bsp/lights/下面,修改相关的路径定义:

char const* const LED1_LED_FILE
        = "/sys/class/leds/verbose/brightness";

char const* const LED2_LED_FILE
        = "/sys/class/leds/debug/brightness";

char const* const LED3_LED_FILE
        = "/sys/class/leds/info/brightness";

char const* const BLUETOOTH_LED_FILE
        = "/sys/class/leds/warn/brightness";

char const* const WIFI_LED_FILE
        = "/sys/class/leds/wlan/brightness";

/**
 * device methods
 */

void init_globals(void)
{
    // init the mutex
    pthread_mutex_init(&g_lock, NULL);
}

static int write_int(char const* path, int value)
{
    FILE *fd;

    fd = fopen(path, "w+");
    if (fd) {
        int bytes = fprintf(fd, "%d", value);
        fclose(fd);
        return (bytes < 0 ? bytes : 0);
    } else {
        ALOGE("write_int failed to open %s\n", path);
        return -errno;
    }
}
  • 修改BroDm apk

实现客户端相关API, 以便能够方便控制LED灯的状态:

  1. /privet/v3/traits
  2. /privet/v3/components
  3. /privet/v3/state
  4. /privet/v3/commandDefs
  5. /privet/v3/commands/status
  6. /privet/v3/commands/list
  7. /privet/v3/commands/execute

相关的代码已经上传到github:

$ git clone https://github.com/brobwind/BroDm.git && cd BroDm
$ git checkout origin/brillo-m10-dev_ledflasher

执行命令的界面如下(执行这个命令会使那四个LED交替闪烁):

2016_03_01_brodm_exec_cmd

执行完命令之后,可以看到返回结果:

2016_03_01_brodm_cmd_result

NOTE:

加入ledflasher service之后,在设备进行paring时,那四个LED会同时闪烁。

  • 参考文档:
  1. https://www.raspberrypi.org/documentation/configuration/device-tree.md

《Brillo开发: 在RPI 2B(树莓派)上点亮LED @ brillo-m10-dev》有6个想法

    1. Brillo没有正式发布出来,但在网上(https://android.googlesource.com/)是可以下载到源代码的

        1. weave(communication protocol)相关的代码在:
          https://android.googlesource.com/platform/external/libweave/
          https://android.googlesource.com/platform/system/weaved/

  1. 你好,我想问一下,关于weave定义的一套标准的设备操作命令Schema,从哪儿可以看呀?

发表评论

电子邮件地址不会被公开。 必填项已用*标注