瑞芯微SDK移植

瑞芯微SDK移植

1、编译配置文件

自定义一个配置文件:/device/rockchip/rk3308/BoardConfig_RK3308BS_32bit_CDN.mk

#!/bin/bash

CMD=`realpath $BASH_SOURCE`
CUR_DIR=`dirname $CMD`

source $CUR_DIR/BoardConfig.mk

# Target arch
export RK_ARCH=arm
# Uboot defconfig
export RK_UBOOT_DEFCONFIG=rk3308-aarch32
# SPL INI
export RK_SPL_INI_CONFIG=RK3308MINIALL_UART4.ini
# Kernel defconfig
export RK_KERNEL_DEFCONFIG=rk3308_linux_aarch32_debug_defconfig
# Kernel dts
export RK_KERNEL_DTS=rk3308bs-evb-amic-v11-aarch32
# kernel image path
export RK_KERNEL_IMG=kernel/arch/arm/boot/zImage
# parameter for GPT table
export RK_PARAMETER=parameter-ab-32bit.txt
# Buildroot config
export RK_CFG_BUILDROOT=rockchip_rk3308_bs_32_release
# loader name
export RK_LOADER_NAME=*_loader_uart4_v*.bin
# Set rootfs type, including ext2 ext4 squashfs
export RK_ROOTFS_TYPE=ext2
# Define package-file for update_ab.img
export RK_PACKAGE_FILE_AB=rk3308-package-file-ab
# Define package-file for ota update_ota.img
export RK_PACKAGE_FILE_OTA=rk3308-package-file-ota
#choose enable Linux A/B	新增
#export RK_LINUX_AB_ENABLE=true


修改parameter-ab-32bit.txt文件:

FIRMWARE_VER:8.1
MACHINE_MODEL:RK3308
MACHINE_ID:007
MANUFACTURER: RK3308
MAGIC: 0x5041524B
ATAG: 0x00200800
MACHINE: 3308
CHECK_MASK: 0x80
PWR_HLD: 0,0,A,0,1
TYPE: GPT
CMDLINE:mtdparts=rk29xxnand:0x00001100@0x00002000(uboot),0x00001100@0x00003100(trust),0x00000800@0x00004200(misc),0x0000A000@0x00004A00(boot_a),0x0000A000@0x0000EA00(boot_b),0x00080000@0x00018A00(system_a),0x00080000@0x00098A00(system_b),0x00020000@0x00118A00(oem),-@0x00138A00(userdata:grow)
uuid:rootfs=614e0000-0000-4b53-8000-1d28000054a9


编译时需要配置一下该文件:

./build.sh BoardConfig_RK3308BS_32bit_CDN.mk
./build.sh

2、uboot前置阶段日志输出

BoardConfig_RK3308BS_32bit_CDN.mk选用的loader文件时RK3308MINIALL_UART4.ini,RK3308MINIALL_UART4.ini中的串口文件是:rk3308_ddr_589MHz_uart4_m0_v2.06.bin

因此修改串口时需要修改:/rkbin/tools/ddrbin_param.txt

uart id=
uart iomux=
uart baudrate=
以串口2 m0为例:
修改:
uart id=2
uart iomux=0
uart baudrate=1500000

在/rkbin/tools/下执行以下命令替换:rk3308_ddr_589MHz_uart4_m0_v2.06.bin

./ddrbin_tool ddrbin_param.txt ../bin/rk33/rk3308_ddr_589MHz_uart4_m0_v2.06.bin

3、U-Boot修改

3.1、配置文件

BoardConfig_RK3308BS_32bit_CDN.mk选用的uboot配置文件为:rk3308-aarch32

路径:/u-boot/configs

3.1.1、启动内核延时:

CONFIG_BOOTDELAY=3	#延迟3S

3.1.2、U-Boot阶段的日志输出串口

CONFIG_BAUDRATE=1500000				#波特率
CONFIG_DEBUG_UART_BASE=0xFF0C0000	#串口地址:现为串口2
CONFIG_DEBUG_UART_CLOCK=24000000	#时钟,一般不修改
CONFIG_DEBUG_UART_SHIFT=2			

3.1.3、Linux A/B分区更新

#LINUX A/B分区
CONFIG_AVB_LIBAVB=y
CONFIG_AVB_LIBAVB_AB=y
CONFIG_AVB_LIBAVB_ATX=y
CONFIG_AVB_LIBAVB_USER=y
CONFIG_RK_AVB_LIBAVB_USER=y
CONFIG_ANDROID_AB=y

3.2、设备树

配置文件rk3308-aarch32选用的设备树为:rk3308-evb

路径为:/u-boot/arch/arm/dts

3.2.1、U-Boot阶段的日志输出串口

文件:rk3308-u-boot.dtsi

	chosen {
	    stdout-path = &uart2;	/* 串口2 */
		u-boot,spl-boot-order = &sdmmc, &sfc, &nandc, &emmc;
	};
	
&uart2 {
	u-boot,dm-pre-reloc;
	clock-frequency = <24000000>;
	status = "okay";
};

3.2.2、U-Boot阶段需要使用到网口进行调试

文件:rk3308-u-boot.dtsi

添加:
&mac {
	u-boot,dm-pre-reloc;
};
&mac {
	phy-supply = <&vcc_phy>;
	assigned-clocks = <&cru SCLK_MAC>;
	assigned-clock-parents = <&mac_clkin>;
	clock_in_out = "input";
	pinctrl-names = "default";
	pinctrl-0 = <&rmii_pins &mac_refclk_12ma>;
	snps,reset-gpio = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>;
	snps,reset-active-low;
	snps,reset-delays-us = <0 50000 50000>;
	status = "okay";
};

这时只是打开了mac,还需要以下两个步骤:

  • 通过图形化界面使能产生随机mac地址,要不然网卡不能使用。在uboot文件下执行命令:make menuconfig,路径为:Networking support->Random ethaddr if unset

  • 修改环境变量的存储方式,我这里使用的是EMMC,所以要设置为MMC,要不然设置的ip地址不能保存。路径为:Environment->Select the location of the environment (Environment is not stored)->Environment in an MMC device

3.3、Linux A/B分区更新源码修改

路径为:/u-boot/include/android_avb/avb_ab_flow.h

/* Struct used for recording per-slot metadata.
 *
 * When serialized, data is stored in network byte-order.
 */
typedef struct AvbABSlotData {
  /* Slot priority. Valid values range from 0 to AVB_AB_MAX_PRIORITY,
   * both inclusive with 1 being the lowest and AVB_AB_MAX_PRIORITY
   * being the highest. The special value 0 is used to indicate the
   * slot is unbootable.
   */
  uint8_t priority;

  /* Number of times left attempting to boot this slot ranging from 0
   * to AVB_AB_MAX_TRIES_REMAINING.
   */
  uint8_t tries_remaining;

  /* Non-zero if this slot has booted successfully, 0 otherwise. */
  uint8_t successful_boot;

  /* Reserved for future use. */
  uint8_t reserved[1];
} AVB_ATTR_PACKED AvbABSlotData;

/* Struct used for recording A/B metadata.
 *
 * When serialized, data is stored in network byte-order.
 */
typedef struct AvbABData {
  /* Magic number used for identification - see AVB_AB_MAGIC. */
  uint8_t magic[AVB_AB_MAGIC_LEN];

  /* Version of on-disk struct - see AVB_AB_{MAJOR,MINOR}_VERSION. */
  uint8_t version_major;
  uint8_t version_minor;

  /* Padding to ensure |slots| field start eight bytes in. */
  uint8_t reserved1[2];

  /* Per-slot metadata. */
  AvbABSlotData slots[2];

  /* Reserved for future use. */
  uint8_t last_boot;
  uint8_t reserved2[11];

  /* CRC32 of all 28 bytes preceding this field. */
  uint32_t crc32;
} AVB_ATTR_PACKED AvbABData;


修改为:
/* Struct used for recording per-slot metadata.
 *
 * When serialized, data is stored in network byte-order.
 */
typedef struct AvbABSlotData {
  /* Slot priority. Valid values range from 0 to AVB_AB_MAX_PRIORITY,
   * both inclusive with 1 being the lowest and AVB_AB_MAX_PRIORITY
   * being the highest. The special value 0 is used to indicate the
   * slot is unbootable.
   */
  uint8_t priority;

  /* Number of times left attempting to boot this slot ranging from 0
   * to AVB_AB_MAX_TRIES_REMAINING.
   */
  uint8_t tries_remaining;

  /* Non-zero if this slot has booted successfully, 0 otherwise. */
  uint8_t successful_boot;

  /* Reserved for future use. */
  //uint8_t reserved[1];
    /* Mark update state, mark 1 if the slot is in update state, 0 otherwise. */
    uint8_t is_update : 1;
    /* Reserved for future use. */
    uint8_t reserved : 7;
} AVB_ATTR_PACKED AvbABSlotData;

/* Struct used for recording A/B metadata.
 *
 * When serialized, data is stored in network byte-order.
 */
typedef struct AvbABData {
  /* Magic number used for identification - see AVB_AB_MAGIC. */
  uint8_t magic[AVB_AB_MAGIC_LEN];

  /* Version of on-disk struct - see AVB_AB_{MAJOR,MINOR}_VERSION. */
  uint8_t version_major;
  uint8_t version_minor;

  /* Padding to ensure |slots| field start eight bytes in. */
  uint8_t reserved1[2];

  /* Per-slot metadata. */
  AvbABSlotData slots[2];

  /* Reserved for future use. */
  uint8_t last_boot;
  uint8_t reserved2[11];

  /* CRC32 of all 28 bytes preceding this field. */
  uint32_t crc32;
} AVB_ATTR_PACKED AvbABData;


编译会报错:defined but not used。

路径:/u-boot/common/android_bootloader.c

__attribute__((unused))  static void reset_cpu_if_android_ab(void)
{
	printf("Reset in AB system.\n");
	flushc();
	/*
	 * Since we use the retry-count in ab system, then can
	 * try reboot if verify fail until the retry-count is
	 * equal to zero.
	 */
	reset_cpu(0);
}

编译报错:ERROR: pack uboot failed! u-boot.bin actual: 565765 bytes, max limit: 522240 bytes

路径:/u-boot/make.sh

fixup_platform_configure()
{
	local count plat

# <*> Fixup rsa/sha pack mode for platforms
	# RK3308/PX30/RK3326/RK1808 use RSA-PKCS1 V2.1, it's pack magic is "3"
	if [ $RKCHIP = "PX30" -o $RKCHIP = "RK3326" -o $RKCHIP = "RK3308" -o $RKCHIP = "RK1808" ]; then
		PLATFORM_RSA="--rsa 3"
	# RK3368 use rk big endian SHA256, it's pack magic is "2"
	elif [ $RKCHIP = "RK3368" ]; then
		PLATFORM_SHA="--sha 2"
	# other platforms use default configure
	fi

# <*> Fixup images size pack for platforms
	if [ $RKCHIP = "RK3308" ]; then
		if grep -q '^CONFIG_ARM64_BOOT_AARCH32=y' ${OUTDIR}/.config ; then
			#PLATFORM_UBOOT_IMG_SIZE="--size 512 2"		/*512修改为1024*/
			#PLATFORM_TRUST_IMG_SIZE="--size 512 2"		/*512修改为1024*/
			PLATFORM_UBOOT_IMG_SIZE="--size 1024 2"
			PLATFORM_TRUST_IMG_SIZE="--size 1024 2"
		else
			PLATFORM_UBOOT_IMG_SIZE="--size 1024 2"
			PLATFORM_TRUST_IMG_SIZE="--size 1024 2"
		fi
	elif [ $RKCHIP = "RK1808" ]; then
		PLATFORM_UBOOT_IMG_SIZE="--size 1024 2"
		PLATFORM_TRUST_IMG_SIZE="--size 1024 2"
	fi

# <*> Fixup AARCH32 for ARM64 cpu platforms
	if grep -q '^CONFIG_ARM64_BOOT_AARCH32=y' ${OUTDIR}/.config ; then
		if [ $RKCHIP = "RK3308" ]; then
			RKCHIP_LABEL=${RKCHIP_LABEL}"AARCH32"
			RKCHIP_TRUST=${RKCHIP_TRUST}"AARCH32"
		elif [ $RKCHIP = "RK3326" ]; then
			RKCHIP_LABEL=${RKCHIP_LABEL}"AARCH32"
			RKCHIP_LOADER=${RKCHIP_LOADER}"AARCH32"
		fi
	fi
}

4、kernel修改

4.1、设备树修改

BoardConfig_RK3308BS_32bit_CDN.mk选用kernel设备树为:rk3308bs-evb-amic-v11-aarch32

路径为:/kernel/arch/arm/boot/dts

文件:rk3308bs-evb-amic-v11-aarch32

// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
 * Copyright (c) 2021 Rockchip Electronics Co., Ltd
 */

#include "arm64/rockchip/rk3308bs-evb-amic-v11.dts"

/ {
	model = "Rockchip RK3308bs evb amic v11 board (AArch32)";
	compatible = "rockchip,rk3308bs-evb-amic-v11-aarch32", "rockchip,rk3308";
	
	
	/*添加*/
	chosen {
		bootargs = "earlycon=uart8250,mmio32,0xff0e0000 swiotlb=1 console=ttyFIQ0 root=PARTUUID=614e0000-0000 rootfstype=ext2 rootwait snd_aloop.index=7 snd_aloop.use_raw_jiffies=1";
	};
	
	
	/*添加*/
    leds {
        status = "okay";
        compatible = "gpio-leds";	                    //兼容性,源码根据这个注册设备
        sys_red {
            label = "sys_red"; 		                    //标签,设备名称,会在/sys/class/leds/下生成sys_red
            linux,default-trigger = "ir-user-click";
            default-state = "on";	                    //LED等默认打开	
            gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_LOW>;	//指定对应的IO口,并默认高电平
        };
        
        sys_green {
            label = "sys_green";
            linux,default-trigger = "ir-user-click";
            default-state = "on";
            gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_LOW>;
        };

        sys_blue {
            label = "sys_blue";
            linux,default-trigger = "ir-user-click";
            default-state = "off";
            gpios = <&gpio4 RK_PB2 GPIO_ACTIVE_LOW>;
        };
    };
    
    
    cdn_cpu_key {
		compatible = "gpio-keys";
		autorepeat;

		pinctrl-names = "default";
		pinctrl-0 = <&cdn_cpu_key_reset>;
		cdn {
			gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>;
			linux,code = <KEY_1>;
			label = "GPIO Key cdn cpu";
			debounce-interval = <100>;
		};
	};
	
	cdn_wifi_key {
		compatible = "gpio-keys";
		autorepeat;

		pinctrl-names = "default";
		pinctrl-0 = <&cdn_wifi_key_reset>;
		cdn {
			gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_LOW>;
			linux,code = <KEY_2>;
			label = "GPIO Key cdn wifi";
			debounce-interval = <100>;
		};
	};
	
	wireless-bluetooth {
    	status = "disabled";
    };

    wireless-wlan {
    	status = "disabled";
    };
};

&ramoops_mem {
	reg = <0x0 0x30000 0x0 0x20000>;
};

&ramoops {
	record-size = <0x0 0x00000>;
	console-size = <0x0 0x20000>;
};


/*添加*/
&emmc {
	status = "okay";
};

&mac {
	phy-supply = <&vcc_phy>;
	assigned-clocks = <&cru SCLK_MAC>;
	assigned-clock-parents = <&mac_clkin>;
	clock_in_out = "input";
	pinctrl-names = "default";
	pinctrl-0 = <&rmii_pins &mac_refclk_12ma>;
	snps,reset-gpio = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>;
	snps,reset-active-low;
	snps,reset-delays-us = <0 50000 50000>;
	status = "okay";
};

&pinctrl {
	buttons {
		cdn_cpu_key_reset: cdn-cpu-key-reset {
			rockchip,pins = <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>;
		};
		cdn_wifi_key_reset: cdn-wifi-key-reset {
			rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>;
		};
	};
};

&vccio_flash {		
	regulator-min-microvolt = <1800000>;//<3300000>;
	regulator-max-microvolt = <1800000>;//<3300000>;
};

&vcc_ddr {
	regulator-min-microvolt = <1500000>;
	regulator-max-microvolt = <1500000>;
};

&vdd_log {
	regulator-min-microvolt = <1050000>;//<1000000>;
	regulator-max-microvolt = <1050000>;//<1000000>;
};

&io_domains {
	vccio3-supply = <&vccio_flash>;
};

&uart1 {
	pinctrl-names = "default";
	pinctrl-0 = <&uart1_xfer>;
	status = "okay";
};

&uart2 {
	pinctrl-names = "default";
	pinctrl-0 = <&uart2m0_xfer>;
	status = "okay";
};

&fiq_debugger {
	rockchip,serial-id = <4>;
	status = "okay";
};

&tsadc {
	status = "disabled";
};

&i2c1 {
    status = "disabled";
};




因为有一些IO口被重复使用,需要屏蔽掉。

路径为:/kernel/arch/arm64/boot/dts/rockchip

文件:rk3308b-evb-v10.dtsi
/*gpio-keys {
		compatible = "gpio-keys";
		autorepeat;

		pinctrl-names = "default";
		pinctrl-0 = <&pwr_key>;

		power {
			gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_LOW>;
			linux,code = <KEY_POWER>;
			label = "GPIO Key Power";
			wakeup-source;
			debounce-interval = <100>;
		};
	};*/
	
&emmc {
	bus-width = <8>;
	cap-mmc-highspeed;
	//mmc-hs200-1_8v;
	supports-emmc;
	disable-wp;
	non-removable;
	num-slots = <1>;
	status = "disabled";
};
    
	buttons {
		/*pwr_key: pwr-key {
			rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>;
		};*/
	};

4.2、eventx编号修改

路径:/kernel/drivers/input/evdev.c

static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
			 const struct input_device_id *id)
{
	struct evdev *evdev;
	int minor;
	int dev_no;
	int error;

	//minor = input_get_new_minor(EVDEV_MINOR_BASE, EVDEV_MINORS, true);
	
	if(strcmp(dev->name, "cdn_cpu_key") == 0){
		printk("evdev_connect: Ares Debug cdn_cpu_key fixed to event0. \r\n");
		minor = EVDEV_MINOR_BASE + 0;
	}
	else{
		minor = input_get_new_minor(EVDEV_MINOR_BASE, EVDEV_MINORS, true);
		if(minor == EVDEV_MINOR_BASE + 0){
			//已经被注册 遍历下一个
			printk("evdev_connect: Ares Debug event0 has been registed, turn to next. \r\n");
			minor = input_get_new_minor(EVDEV_MINOR_BASE, EVDEV_MINORS, true);
		}
		printk("evdev_connect: %s: minor = %d\r\n",dev->name,minor);
	}
	
	
	
	if (minor < 0) {
		error = minor;
		pr_err("failed to reserve new minor: %d\n", error);
		return error;
	}

	evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL);
	if (!evdev) {
		error = -ENOMEM;
		goto err_free_minor;
	}

	INIT_LIST_HEAD(&evdev->client_list);
	spin_lock_init(&evdev->client_lock);
	mutex_init(&evdev->mutex);
	init_waitqueue_head(&evdev->wait);
	evdev->exist = true;

	dev_no = minor;
	/* Normalize device number if it falls into legacy range */
	if (dev_no < EVDEV_MINOR_BASE + EVDEV_MINORS)
		dev_no -= EVDEV_MINOR_BASE;
	dev_set_name(&evdev->dev, "event%d", dev_no);

	evdev->handle.dev = input_get_device(dev);
	evdev->handle.name = dev_name(&evdev->dev);
	evdev->handle.handler = handler;
	evdev->handle.private = evdev;

	evdev->dev.devt = MKDEV(INPUT_MAJOR, minor);
	evdev->dev.class = &input_class;
	evdev->dev.parent = &dev->dev;
	evdev->dev.release = evdev_free;
	device_initialize(&evdev->dev);

	error = input_register_handle(&evdev->handle);
	if (error)
		goto err_free_evdev;

	cdev_init(&evdev->cdev, &evdev_fops);
	evdev->cdev.kobj.parent = &evdev->dev.kobj;
	error = cdev_add(&evdev->cdev, evdev->dev.devt, 1);
	if (error)
		goto err_unregister_handle;

	error = device_add(&evdev->dev);
	if (error)
		goto err_cleanup_evdev;

	return 0;

 err_cleanup_evdev:
	evdev_cleanup(evdev);
 err_unregister_handle:
	input_unregister_handle(&evdev->handle);
 err_free_evdev:
	put_device(&evdev->dev);
 err_free_minor:
	input_free_minor(minor);
	return error;
}

5、buildroot修改

5.1、配置文件

BoardConfig_RK3308BS_32bit_CDN.mk选用buildroot配置文件为:rockchip_rk3308_bs_32_release

路径:/buildroot/configs

通过图形化界面进行配置

source envsetup.sh      #选择25
make menuconfig			#进入图形化界面进行配置

5.1.1、linux A/B分区更新

#linux A/B分区
BR2_PACKAGE_RECOVERY_BOOTCONTROL=y #开启引导控制脚本
BR2_PACKAGE_RECOVERY_RETRY=y #引导方式为retry模式,不配置则默认为successful_boot模式
  • Target packages->rockchip BSP packages->Linux AB bool control

5.1.2、打开ssh

#打开ssh
BR2_PACKAGE_OPENSSH=y
BR2_TARGET_ENABLE_ROOT_LOGIN=y		/*需要手动添加*/
BR2_TARGET_GENERIC_ROOT_PASSWD="root"
  • Target packages->Networking applications->openssh

  • System configuration->

5.1.3、rootfs大小

BR2_TARGET_ROOTFS_EXT2_SIZE="256M"
  • Filesystem images->exact size

保存配置:

make savedefconfig

5.1.4、syslog配置

需要将该文件内容复制到文件:/buildroot/package/busybox/S01logging

#!/bin/sh

DAEMON="syslogd"
PIDFILE="/var/run/$DAEMON.pid"

[ -d /data/log ] || {
        mkdir -p /data/log
}

loglevel=8

SYSLOGD_ARGS="-O /data/log/messages -s 50000 -b 10 -l $loglevel -S"

# shellcheck source=/dev/null
[ -r "/etc/default/$DAEMON" ] && . "/etc/default/$DAEMON"

# BusyBox' syslogd does not create a pidfile, so pass "-n" in the command line
# and use "-m" to instruct start-stop-daemon to create one.
start() {
        printf 'Starting %s: ' "$DAEMON"
        # shellcheck disable=SC2086 # we need the word splitting
        start-stop-daemon -b -m -S -q -p "$PIDFILE" -x "/sbin/$DAEMON" \
                -- -n $SYSLOGD_ARGS
        status=$?
        if [ "$status" -eq 0 ]; then
                echo "OK"
        else
                echo "FAIL"
        fi
        return "$status"
}

stop() {
        printf 'Stopping %s: ' "$DAEMON"
        start-stop-daemon -K -q -p "$PIDFILE"
        status=$?
        if [ "$status" -eq 0 ]; then
                rm -f "$PIDFILE"
                echo "OK"
        else
                echo "FAIL"
        fi
        return "$status"
}

restart() {
        stop
        sleep 1
        start
}

case "$1" in
        start|stop|restart)
                "$1";;
        reload)
                # Restart, since there is no true "reload" feature.
                restart;;
        *)
                echo "Usage: $0 {start|stop|restart|reload}"
                exit 1
esac

exit $?


到此需要进行编译一下,之后才能进行自定义APP的添加

6、buildroot修改

6.1、添加自己的APP

6.1.1、/buildroot/package修改

  • 路径:/buildroot/package/Config.in
menu "Target packages"

	source "package/busybox/Config.in"
	source "package/rockchip/Config.in"
	source "package/skeleton/Config.in"
	source "package/skeleton-custom/Config.in"
	source "package/skeleton-init-common/Config.in"
	source "package/skeleton-init-none/Config.in"
	source "package/skeleton-init-systemd/Config.in"
	source "package/skeleton-init-sysv/Config.in"
	source "package/cdn_app/Config.in"

6.1.2、添加文件

在/buildroot/package下创建文件夹cdn_app,并在文件夹cdn_app创建cdn_app.mk,Config.in文件,注文件命名要求。

文件:cdn_app.mk

include $(sort $(wildcard package/cdn_app/*/*.mk))



文件:Config.in


#CDN软件

source "package/cdn_app/cdn_led/Config.in"
source "package/cdn_app/cdn_xiaomi/Config.in"


  • 在cdn_app下创建cdn_led文件夹,并创建cdn_led.mk、Config.in文件,注文件命名要求。
文件:cdn_led.mk
###########################################################
#	cdn led
###########################################################
 
CDN_LED_VERSION = 1.0.0
CDN_LED_SITE = $(TOPDIR)/../external/cdn_app/cdn_led
CDN_LED_SITE_METHOD = local
CDN_LED_INSTALL_TARGET = YES

define CDN_LED_BUILD_CMDS
	$(MAKE) CC="$(TARGET_CC)" LD="$(TARGET_LD)" -C $(@D) all
endef

define CDN_LED_INSTALL_TARGET_CMDS
	$(INSTALL) -D -m 777 $(@D)/cdn_led $(TARGET_DIR)/usr/bin
endef
 


$(eval $(generic-package))


文件:Config.in

config BR2_PACKAGE_CDN_LED
	bool "cdn led"
	help
		This is a cdn led app.
  • 在cdn_app下创建cdn_xiaomi文件夹,并创建cdn_xiaomi.mk、Config.in文件,注文件命名要求。
文件:cdn_xiaomi.mk

###########################################################
#	cdn xiaomi
###########################################################
 
CDN_XIAOMI_VERSION = 1.0.0
CDN_XIAOMI_SITE = $(TOPDIR)/../external/cdn_app/cdn_xiaomi
CDN_XIAOMI_SITE_METHOD = local
CDN_XIAOMI_INSTALL_TARGET = YES



define CDN_XIAOMI_INSTALL_TARGET_CMDS
    mkdir $(TARGET_DIR)/root/cdn_xiaomi
    cp -r -p $(TOPDIR)/../external/cdn_app/cdn_xiaomi/cdn_script $(TARGET_DIR)/root/cdn_xiaomi
    cp -r -p $(TOPDIR)/../external/cdn_app/cdn_xiaomi/PLC_SDK $(TARGET_DIR)/root/cdn_xiaomi
    $(INSTALL) -D -m 777 $(@D)/S100cdn_xiaomi $(TARGET_DIR)/etc/init.d/
endef
 


$(eval $(generic-package))


文件:Config.in

config BR2_PACKAGE_CDN_XIAOMI
	bool "cdn xiaomi"
	help
		This is a cdn xiaomi SDK.

6.1.3、添加源码

  • 在external文件夹下创建cdn_app文件夹、
  • 在cdn_app文件夹下创建cdn_led文件夹,并添加文件cdn_led.c、Makefile:
文件:cdn_led.c

//文件:cdn_test.c

#include <linux/input.h>         
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdio.h>

#define INPUT_RED_DEV "/sys/class/leds/sys_red/brightness"
#define INPUT_BLUE_DEV "/sys/class/leds/sys_blue/brightness"
#define INPUT_GREEN_DEV "/sys/class/leds/sys_green/brightness"

int main(int argc, char* const argv[])
{
    printf("\n\n\n");
    printf("this a test code suncong\n");
    printf("\n\n\n");
    
    
    int red_fd = 0, blue_fd = 0, green_fd = 0;
    red_fd = open(INPUT_RED_DEV,O_RDWR);
    if(red_fd < 0){
        perror("open INPUT_RED_DEV err\r\n");
        exit(1);        
    }
    blue_fd = open(INPUT_BLUE_DEV,O_RDWR);
    if(blue_fd < 0){
        perror("open INPUT_BLUE_DEV err\r\n");
        exit(1);        
    }
    green_fd = open(INPUT_GREEN_DEV,O_RDWR);    
    if(green_fd < 0){
        perror("open INPUT_GREEN_DEV err\r\n");
        exit(1);        
    }
    write(red_fd, "1", 1);
    write(blue_fd, "1", 1);
    write(green_fd, "1", 1);
    
    close(red_fd);
    close(blue_fd);
    close(green_fd);
       
    return 0;
}


文件:Makefile

CPPFLAGS +=
LDLIBS +=
 
all: cdn_led
 
analyzestack: cdn_led.o
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)
 
clean:
	rm -f *.o cdn_led
 
.PHONY: all clean

  • 在cdn_app文件夹下创建cdn_xiaomi文件夹,并创建文件夹cdn_script、PLC_SDK:存放小米SDK、
    • 创建文件S100cdn_xiaomi:存放启动文件,放在etc/init.d
  • cdn_script文件下包含:cdn_start.sh、miio_client_helper_nomqtt2.sh、ota_succ.sh
文件:cdn_start.sh

#!/bin/sh



#开始cdn的代码


cd /

#执行测试APP
./usr/bin/cdn_led &


#检测是否存在启动文件,因为瑞芯微的SDK在刚烧录后第一次启动会初始化掉uaerdata,所以需要重启一下
if [ ! -e /data/cdn_gateway ]; then
    mkdir /data/cdn_gateway
    echo "/data/cdn_gateway not exist, reboot"
    exec reboot
fi
echo "/data/cdn_gateway exist"


#给小米SDK启动脚本执行权限,并执行
cd /tmp/cdn_xiaomi/PLC_SDK
chmod 777 start_all.sh
./start_all.sh &

#给小米helper脚本赋执行权限
cd /tmp/cdn_xiaomi/cdn_script
chmod 777 miio_client_helper_nomqtt2.sh

#将升级脚本拷贝到/bin下,并赋予执行权限
cp -r -p /tmp/cdn_xiaomi/cdn_script/ota_succ.sh /bin/
chmod 777 /bin/ota_succ.sh

#执行小米helper脚本
exec /tmp/cdn_xiaomi/cdn_script/miio_client_helper_nomqtt2.sh > /dev/null 2>&1 &

cd /

文件:ota_succ.sh

#!/bin/sh


unzip $1 -d /userdata

updateEngine --image_url=/userdata/update_ota.img --update --reboot


sleep 60s

文件:miio_client_helper_nomqtt2.sh


#!/bin/sh


#脚本变量
CDN_SDK_VER="_0002"
WIFI_START_SCRIPT="./wifi_start.sh"
MIIO_RECV_LINE="/tmp/cdn_xiaomi/cdn_script/miio_recv_line"
MIIO_SEND_LINE="/tmp/cdn_xiaomi/cdn_script/miio_send_line"
JSHON="/tmp/cdn_xiaomi/PLC_SDK/bin/jshon"
WIFI_MAX_RETRY=5
WIFI_RETRY_INTERVAL=3
WIFI_SSID=

#获取版本信息的脚本
GET_VER_CMD=/tmp/cdn_xiaomi/PLC_SDK/bin/mgetprop

GLIBC_TIMEZONE_DIR="/usr/share/zoneinfo"
UCLIBC_TIMEZONE_DIR="/usr/share/zoneinfo/uclibc"


YOUR_LINK_TIMEZONE_FILE="/mnt/data/TZ"
YOUR_TIMEZONE_DIR=$UCLIBC_TIMEZONE_DIR

DINFO_FILE_PATH="/data/cdn_gateway/device.conf"

datadir=/data/local/miio_client/
token_file=${datadir}device.token
wificonf_file=${datadir}wifi.conf
dcountry_file=${datadir}device.country
uid_file=${datadir}device.uid



:<<EOF
	contains(string, substring)
	
	Returns 0 if the specified string contains the specified substring,
	otherwise returns 1.
EOF
contains() {
    string="$1"
    substring="$2"
	
	#从左开始第一个相同的将其删除
	#如果结果与原字符串不相同,说明包含
	#如果结果与原字符串相同,说明没有可以删除的,说明不包含
    if test "${string#*$substring}" != "$string"
    then
        return 0    # $substring is in $string
    else
        return 1    # $substring is not in $string
    fi
}

#检测wifi脚本
sanity_check() {
:<<EOF
	if [ ! -e $WIFI_START_SCRIPT ]; then
		echo "Can't find wifi_start.sh: $WIFI_START_SCRIPT"
		echo 'Please change $WIFI_START_SCRIPT'
		exit 1
	if
EOF
	echo "check wifi_start.sh pass!"
}

#发送helper脚本已经准备好
send_helper_ready() {
    ready_msg="{\"method\":\"_internal.helper_ready\"}"
    echo $ready_msg
    $MIIO_SEND_LINE "$ready_msg"
}

#关闭wifi
set_wifi_down() {
	STRING=`ifconfig enp0s3 down`
	REQ_WIFI_DOWN_STATUS_RESPONSE="{\"method\":\"_internal.res_wifi_down\",\"params\":1}"
	echo $REQ_WIFI_DOWN_STATUS_RESPONSE
	$MIIO_SEND_LINE "$REQ_WIFI_DOWN_STATUS_RESPONSE"
}

#打开wifi
set_wifi_up() {
	STRING=`ifconfig enp0s3 up`
	REQ_WIFI_UP_STATUS_RESPONSE="{\"method\":\"_internal.res_wifi_up\",\"params\":1}"
	echo $REQ_WIFI_UP_STATUS_RESPONSE
	$MIIO_SEND_LINE "$REQ_WIFI_UP_STATUS_RESPONSE"
}

#设置wifi ap模式
set_wifi_ap() {
	msg="{\"method\":\"_internal.wifi_ap_mode\",\"params\":null}";
	echo $msg
	$MIIO_SEND_LINE "$msg"
}

#wifi重连
wifi_reassociate() {
    newwork_id=`wpa_cli -i $ifname list_network | grep $ssid | cut -f 1`
    wpa_cli -i $ifname set_network $newwork_id bssid $1
    wpa_cli -i $ifname disable_network $newwork_id
    wpa_cli -i $ifname enable_network $newwork_id
}

#wifi选择
wifi_choose() {
    bbssid=`wpa_cli -i $ifname scan_result | grep $ssid | sort -n -r -k 3 | cut -f 1 | head -1`
    echo "best bssid is $bbssid"
    bssid_old=` wpa_cli status |grep bssid | cut -d '=' -f 2`
    if [ $bbssid == $bssid_old ];then
        reassociate_status="best bssid already connected" 
    else
        wifi_reassociate $bbssid
        reassociate_status="wifi reassociate"
    fi
}

#请求设备网络状态信息
internal_info() {

	#获取wifi状态-->空
	STRING=`wpa_cli status`
	
	#ifname=${STRING#*\'}
	#ifname=${ifname%%\'*}
	# test linux pc
	#以太网名称
	ifname=eth0
	echo "ifname: $ifname"
	
	#获取wifi SIID-->空
	if [ "x$WIFI_SSID" != "x" ]; then
		ssid=$WIFI_SSID
	else
		ssid=${STRING##*ssid=}
		ssid=`echo ${ssid} | cut -d ' ' -f 1`
	fi
	echo "ssid: $ssid"
	    
	#获取bssid-->空
	bssid=${STRING##*bssid=}
	bssid=`echo ${bssid} | cut -d ' ' -f 1 | tr '[:lower:]' '[:upper:]'`
	echo "bssid: $bssid"

	#检测字符串长度是否为0,为0返回 true。
	#如果ifname不为空,则判断是否需要重新选择wifi
	if ! test -z $ifname
	then
		wifi_choose
		STRING=`wpa_cli status`
	fi
	    
	#获取rssi-->0
	rssi=`iwconfig wlan0 |grep 'Signal'`
	rssi=${rssi#*level:}
	rssi=`echo $rssi | cut -d ' ' -f 1`
	if [ "x$rssi" = "x" ]; then
		rssi=0
	fi
	echo "rssi: $rssi"
		
	#获取freq
	freq=${STRING##*freq=}
	freq=`echo ${freq} | cut -d ' ' -f 1`
	echo "freq: $freq"
	
	#获取以太网信息
	STRING=`ifconfig ${ifname}`
	
	#获取IP,
	ip=${STRING##*inet addr:}
	#cut:截取字符串;-d:定义分隔符(空格);需要取哪个字段(第一个字段)
	ip=`echo ${ip} | cut -d ' ' -f 1`
	echo "ip: $ip"
	
	#获取子网掩码netmask
	netmask=${STRING##*Mask:}
	netmask=`echo ${netmask} | cut -d ' ' -f 1`
	echo "netmask: $netmask"

	#获取网关
	#route:显示与设置路由信息;-n:直接显示数字形式的ip地址
	#grep:文本搜索工具;搜索UG所在行
	#tr:字符转换工具;-s删除所有重复出现的字符序列(空格)
	gw=`route -n|grep 'UG'|tr -s ' ' | cut -f 2 -d ' '`
	echo "gw: $gw"
	
	#获取gw_bssid
	#arp:地址解析协议,操纵系统arp缓存;-v显示详细的arp缓存条目,包括缓存条目的统计信息
	#gw_bssid=`arp -v | grep `route -n|grep 'UG'|tr -s ' ' | cut -f 2 -d ' '` | awk '{print $4}'`
	gw_bssid=`arp -v | grep $gw | awk '{print $4}'`
	echo "gw_bssid: $gw_bssid"

	#获取供应商和版本
	# get vendor and then version
	#tr '[:lower:]' '[:upper:]':将取出来的文本小写变成大写
	vendor=`grep "vendor" $DINFO_FILE_PATH | cut -f 2 -d '=' | tr '[:lower:]' '[:upper:]'`
	echo "vendor: $vendor"
	sw_version=`$GET_VER_CMD persist.ota.sdk_ver`
	#检测字符串长度是否为0,为0返回 true。
	if [ -z $sw_version ]; then
		sw_version="unknown"
		echo "get sdk-ver fail, upload internal.info later!"
		return;
	fi	
	
	sw_version="$sw_version""$CDN_SDK_VER"
	
	echo "sw_version: $sw_version"
	
	#获取MCU版本
	mcu_fail_flag=0;
	mcu_ver=`$GET_VER_CMD persist.plcGw.mcu_ver`
	if [ -z $mcu_ver ]; then
		echo "get mcu-ver fail, upload internal.info!"
		mcu_fail_flag=1;
	fi	
	echo "mcu_ver: $mcu_ver"
	

	#填充变量
	msg="{\"method\":\"_internal.info\",\"partner_id\":\"\",\"params\":{\
\"hw_ver\":\"Linux\",\"fw_ver\":\"$sw_version\",\"mcu_fw_ver\":\"$mcu_ver\",\"auto_ota\":true,\
\"ap\":{\
 \"ssid\":\"ethernet\",\"bssid\":\"$gw_bssid\",\"rssi\":\"$rssi\",\"freq\":$freq\
},\
\"netif\":{\
 \"localIp\":\"$ip\",\"mask\":\"$netmask\",\"gw\":\"$gw\"\
}}}"
	
	#检测两个数是否相等,相等返回 true。
	if [ ${mcu_fail_flag} -eq 0 ];then
		echo $msg
		$MIIO_SEND_LINE "$msg"
	else
		echo "get mcu-ver fail, answer internal.info later!";
	fi		
}

#请求设备 Wi-Fi 配置状态
req_wifi_conf_status() {
	
    echo $wificonf_file

    REQ_WIFI_CONF_STATUS_RESPONSE=""
	LOCAL_BLE_CONFIG_ROUTER=""
	
	#检测文件(包括目录)是否存在,如果是,则返回 true。
    if [ -e $wificonf_file ]; then

		WIFI_SSID=`cat $wificonf_file | grep ssid`
		WIFI_SSID=${WIFI_SSID#*ssid=\"}
		WIFI_SSID=${WIFI_SSID%\"*}
		echo "WIFI_SSID: $WIFI_SSID"

		WIFI_PSK=`cat $wificonf_file | grep psk`
		WIFI_PSK=${WIFI_PSK#*psk=\"}
		WIFI_PSK=${WIFI_PSK%\"*}
		echo "WIFI_PSK: $WIFI_PSK"
		
		REQ_WIFI_CONF_STATUS_RESPONSE="{\"method\":\"_internal.res_wifi_conf_status\",\"params\":1,\"ssid\":\"$WIFI_SSID\",\"psk\":\"$WIFI_PSK\"}"
    else
		REQ_WIFI_CONF_STATUS_RESPONSE="{\"method\":\"_internal.res_wifi_conf_status\",\"params\":0}"
		LOCAL_BLE_CONFIG_ROUTER="{\"method\":\"local.ble.config_router\",\"params\":{\"uid\":244877869,\"ssid\":\"ROUTER_SSID\",\"passwd\":\"$WIFI_PSK\",\"tz\":\"\",\"country_domain\":\"\"},\"id\":4}"
	fi
	
	echo $REQ_WIFI_CONF_STATUS_RESPONSE
	$MIIO_SEND_LINE "$REQ_WIFI_CONF_STATUS_RESPONSE"
	
	if [ x$LOCAL_BLE_CONFIG_ROUTER != x ]; then
		sleep 1
		$MIIO_SEND_LINE "$LOCAL_BLE_CONFIG_ROUTER"
	fi
}

#保存wifi配置
save_wifi_conf() {
    miio_ssid=$2
    miio_passwd=$3
    miio_uid=$4
    miio_country=$5
    if [ x"$miio_passwd" = x ]; then
		miio_key_mgmt="NONE"
    else
		miio_key_mgmt="WPA"
    fi

    echo ssid=\"$miio_ssid\" > ${wificonf_file}
    echo psk=\"$miio_passwd\" >> ${wificonf_file}
    echo key_mgmt=$miio_key_mgmt >> ${wificonf_file}
    if [ $miio_uid -ne 0 ]; then
    	echo uid=$miio_uid >> ${wificonf_file}
    fi
    echo $miio_uid > ${uid_file}
    echo $miio_country > ${dcountry_file}
}

#保存tz
save_tz_conf() {
	new_tz=$YOUR_TIMEZONE_DIR/$1
	if [ -f "$new_tz" ]; then
		unlink $YOUR_LINK_TIMEZONE_FILE
		ln -sf  $new_tz $YOUR_LINK_TIMEZONE_FILE
		echo "timezone set success:$new_tz"
	else
		echo "timezone is not exist:$new_tz"
	fi
}

#wifi开始连接
wifi_start() {
	
	wifi_start_string=$1

	wificonf_dir=$(echo "$wifi_start_string" | $JSHON -e params -e datadir -u)
	miio_ssid=$(echo "$wifi_start_string" | $JSHON -e params -e ssid -u)
	miio_passwd=$(echo "$wifi_start_string" | $JSHON -e params -e passwd -u)
	miio_uid=$(echo "$wifi_start_string" | $JSHON -e params -e uid -u)
	miio_country=$(echo "$wifi_start_string" | $JSHON -e params -e country_domain -u)
	miio_tz=$(echo "$wifi_start_string" | $JSHON -e params -e tz -u)
	
	echo "wificonf_dir: $wificonf_dir"
	echo "miio_ssid: $miio_ssid"
	echo "miio_passwd: $miio_passwd"
	echo "miio_uid: $miio_uid"
	echo "miio_country: $miio_country"
	echo "miio_tz: $miio_tz"
	
	save_wifi_conf "$wificonf_dir" "$miio_ssid" "$miio_passwd" "$miio_uid" "$miio_country"
	save_tz_conf "$miio_tz"
	
	CMD=$WIFI_START_SCRIPT
	RETRY=1
	WIFI_SUCC=1
	
	#检测两个数是否相等,相等返回 true。
	if [ $WIFI_SUCC -eq 1 ]; then
		gw=`route -n|grep 'UG'|tr -s ' ' | cut -f 2 -d ' '`	
		gw_bssid=`arp -v | grep $gw | awk '{print $4}'`
		msg="{\"method\":\"_internal.wifi_connected\",\"params\":{\"ssid\":\"ethernet\", \"bssid\":\"$gw_bssid\", \"result\":\"ok\"}}"
		echo $msg
		$MIIO_SEND_LINE "$msg"
	else
		clear_wifi_conf $wificonf_dir
		CMD=$WIFI_START_SCRIPT
		echo "Back to AP mode, CMD=${CMD}"
		${CMD}
		msg="{\"method\":\"_internal.wifi_ap_mode\",\"params\":null}";
		echo $msg
		$MIIO_SEND_LINE "$msg"
	fi
}

#请求设备固化信息,
request_dinfo() {
	
	#del all msq queue, or cause unexpected issues
    rm -f  /dev/mqueue/miio_queue*

    dinfo_dir=$1
    dinfo_dir=${dinfo_dir##*params\":\"}
    dinfo_dir=${dinfo_dir%%\"*}
    dinfo_file="${dinfo_dir}device.conf"
	if [ $dinfo_file != $DINFO_FILE_PATH ]; then
		dinfo_file=$DINFO_FILE_PATH
	fi
    echo "dinfo_file:$dinfo_file"

    dinfo_did=`cat $dinfo_file | grep -v ^# | grep did= | tail -1 | cut -d '=' -f 2`
    dinfo_key=`cat $dinfo_file | grep -v ^# | grep key= | tail -1 | cut -d '=' -f 2`
    dinfo_mjac_i2c=`cat $dinfo_file | grep -v ^# | grep mjac_i2c= | tail -1 | cut -d '=' -f 2`
    dinfo_mjac_gpio=`cat $dinfo_file | grep -v ^# | grep mjac_gpio= | tail -1 | cut -d '=' -f 2`
    dinfo_vendor=`cat $dinfo_file | grep -v ^# | grep vendor= | tail -1 | cut -d '=' -f 2`
    dinfo_mac=`cat $dinfo_file | grep -v ^# | grep mac= | tail -1 | cut -d '=' -f 2`
    dinfo_model=`cat $dinfo_file | grep -v ^# | grep model= | tail -1 | cut -d '=' -f 2`
    dinfo_qrcode=`cat $dinfo_file | grep -v ^# | grep qrcode= | tail -1 | cut -d '"' -f 2`
    dinfo_bootloader_ver= `bootenv -d boot_ver`
    RESPONSE_DINFO="{\"method\":\"_internal.response_dinfo\",\"params\":{"
	#设备did
    if [ x$dinfo_did != x ]; then
		RESPONSE_DINFO="$RESPONSE_DINFO\"did\":$dinfo_did"
    fi
	#设备key
    if [ x$dinfo_key != x ]; then
		RESPONSE_DINFO="$RESPONSE_DINFO,\"key\":\"$dinfo_key\""
    fi
	#设备主版本号
    if [ x$dinfo_mjac_i2c != x ]; then
		RESPONSE_DINFO="$RESPONSE_DINFO,\"mjac_i2c\":\"$dinfo_mjac_i2c\""
    fi
	#设备次版本号
    if [ x$dinfo_mjac_gpio != x ]; then
		RESPONSE_DINFO="$RESPONSE_DINFO,\"mjac_gpio\":\"$dinfo_mjac_gpio\""
    fi
	#设备厂家
    if [ x$dinfo_vendor != x ]; then
		RESPONSE_DINFO="$RESPONSE_DINFO,\"vendor\":\"$dinfo_vendor\""
    fi
	#设备MAC
    if [ x$dinfo_mac != x ]; then
		RESPONSE_DINFO="$RESPONSE_DINFO,\"mac\":\"$dinfo_mac\""
    fi
	#设备型号
    if [ x$dinfo_model != x ]; then
		RESPONSE_DINFO="$RESPONSE_DINFO,\"model\":\"$dinfo_model\""
    fi
	#设备bootloader版本
    if [ x$dinfo_bootloader_ver != x ]; then
		RESPONSE_DINFO="$RESPONSE_DINFO,\"bootloader_ver\":\"$dinfo_bootloader_ver\""
    fi
	#设备二维码
    if [ x$dinfo_qrcode != x ]; then
		RESPONSE_DINFO="$RESPONSE_DINFO,\"OOB\":[{\"mode\":3,\"ctx\":\"$dinfo_qrcode\"},{\"mode\":2,\"ctx\":\"\"}]"
    fi
    #设备mac
    if [ x$dinfo_mac != x ]; then
        dmac=`echo $dinfo_mac | awk -F ":" '{print $1 $2 $3 $4 $5 $6}'`
        sn="12345$dmac"
		RESPONSE_DINFO="$RESPONSE_DINFO,\"sn\":\"$sn\""
    else
		RESPONSE_DINFO="$RESPONSE_DINFO,\"sn\":\"1234567/987654321\""
    fi

    RESPONSE_DINFO="$RESPONSE_DINFO,\"sc_type\":[0,1,2,3,4]"
    RESPONSE_DINFO="$RESPONSE_DINFO,\"eth_type\":true"
    RESPONSE_DINFO="$RESPONSE_DINFO}}"
	
	echo $RESPONSE_DINFO
	$MIIO_SEND_LINE "$RESPONSE_DINFO"
}

#wifi重新加载
wifi_reload() {
    ifconfig $ifname down
    ifconfig $ifname up
    sleep 2
	
	wifi_choose
	REQ_WIFI_RELOAD_RESPONSE="{\"method\":\"_internal.res_wifi_reload\",\"params\":{\"wifi_reload_result\":\"$reassociate_status\",\
\"bssid\":\"$bbssid\"}}"
	echo $REQ_WIFI_RELOAD_RESPONSE
	$MIIO_SEND_LINE "$REQ_WIFI_RELOAD_RESPONSE"
}

#wifi扫描
wifi_scan() {
    for i in 1 2 3; do
        bssid_search=`wpa_cli -i $ifname scan`
        if [ "$bssid_search" == "OK" ]; then
            sleep 2
            wifi_choose
            break
        else
            echo "scan error for $i times"
            sleep 2
        fi
    done
    if [ "$bssid_search" != "OK" ]; then
        reassociate_status="scan error"
        bbssid=""
    fi
}

#wifi重连
wifi_reconnect() {
	wifi_scan
	REQ_WIFI_RECONNECT_RESPONSE="{\"method\":\"_internal.res_wifi_reconnect\",\"params\":{\"wifi_reconnect_result\":\"$reassociate_status\",\
\"bssid\":\"$bbssid\"}}"
	echo $REQ_WIFI_RECONNECT_RESPONSE
	$MIIO_SEND_LINE "$REQ_WIFI_RECONNECT_RESPONSE"
}

#请求令牌
request_dtoken() {

    dtoken_string=$1
    dtoken_token=${dtoken_string##*ntoken\":\"}
    dtoken_token=${dtoken_token%%\"*}

    if [ ! -e ${wificonf_file} ]; then
		rm -f ${token_file}
    fi

    if [ -e ${token_file} ]; then
		dtoken_token=`cat ${token_file}`
    else
		echo ${dtoken_token} > ${token_file}
    fi
    
    if [ -e ${dcountry_file} ]; then
		dcountry_country=`cat ${dcountry_file}`
    else
		dcountry_country=""
    fi
    improve_program=0 #judge whether to upload,If you want to upload offline info, set to 1
    offline_time=0 #assign by record value, if not exsit, ignore it
    offline_reason=0 #assign by record value, if not exsit, ignore it
    offline_ip=0 #assign by record value, if not exsit, ignore it
    offline_port=0 #assign by record value, if not exsit, ignore it

    RESPONSE_DTOKEN="{\"method\":\"_internal.response_dtoken\",\"params\":\"${dtoken_token}\"}"
    RESPONSE_DCOUNTRY="{\"method\":\"_internal.response_dcountry\",\"params\":\"${dcountry_country}\"}"
    RESPONSE_OFFLINE="{\"method\":\"_internal.response_offline\",\"params\":{\"offline_time\":${offline_time},\"offline_reason\":${offline_reason},\"improve_program\":${improve_program},\"offline_ip\":${offline_ip},\"offline_port\":${offline_port}}}"

	echo $RESPONSE_DCOUNTRY
	$MIIO_SEND_LINE "$RESPONSE_DCOUNTRY"
	echo $RESPONSE_OFFLINE
	$MIIO_SEND_LINE "$RESPONSE_OFFLINE"
	echo $RESPONSE_DTOKEN
	$MIIO_SEND_LINE "$RESPONSE_DTOKEN"
}

#请求设备绑定信息
request_ot_config() {
	
    ot_config_string=$1
    
    #get token of msg
    dtoken_token=${ot_config_string##*ntoken\":\"}
    dtoken_token=${dtoken_token%%\"*}

    if [ ! -e ${wificonf_file} ]; then
    	rm -f ${token_file}
    	rm -f ${dcountry_file}
    	rm -f ${uid_file}
    fi
	
    if [ -e ${token_file} ]; then
    	dtoken_token=`cat ${token_file}`
    else
    	echo ${dtoken_token} > ${token_file}
    fi

    dcountry_country=`cat ${dcountry_file}`
    uid=`cat ${uid_file}`
	
    WIFI_SSID=`cat $wificonf_file | grep ssid`
    WIFI_SSID=${WIFI_SSID#*ssid=\"}
    WIFI_SSID=${WIFI_SSID%\"*}
    echo "WIFI_SSID: $WIFI_SSID"

    WIFI_PSK=`cat $wificonf_file | grep psk`
    WIFI_PSK=${WIFI_PSK#*psk=\"}
    WIFI_PSK=${WIFI_PSK%\"*}
    echo "WIFI_PSK: $WIFI_PSK"
	
    RESPONSE_OT_CONFIG="{\"method\":\"_internal.res_ot_config\",\"params\":{"
    RESPONSE_OT_CONFIG="$RESPONSE_OT_CONFIG\"token\":\"$dtoken_token\""
    if [ x$dcountry_country != x ]; then
		RESPONSE_OT_CONFIG="$RESPONSE_OT_CONFIG,\"country\":\"$dcountry_country\""
    fi
	#wifi siid
    if [ x$WIFI_SSID != x ]; then
		RESPONSE_OT_CONFIG="$RESPONSE_OT_CONFIG,\"ssid\":\"$WIFI_SSID\""
    fi
	#wifi psk
    if [ x$WIFI_PSK != x ]; then
		RESPONSE_OT_CONFIG="$RESPONSE_OT_CONFIG,\"password\":\"$WIFI_PSK\""
    fi
	#wifi uid
    if [ x$uid != x ]; then
		RESPONSE_OT_CONFIG="$RESPONSE_OT_CONFIG,\"uid\":$uid"
    fi
    RESPONSE_OT_CONFIG="$RESPONSE_OT_CONFIG}}"
	
	echo $RESPONSE_OT_CONFIG
	$MIIO_SEND_LINE "$RESPONSE_OT_CONFIG"
}

#更新 token 的消息
update_dtoken() {
    update_token_string=$1
    update_dtoken=${update_token_string##*ntoken\":\"}    
    update_token=${update_dtoken%%\"*}

    if [ -e ${token_file} ]; then
    	rm -rf ${token_file}
    fi
    echo ${update_token} > ${token_file}
    RESPONSE_UPDATE_TOKEN="{\"method\":\"_internal.token_updated\",\"params\":\"${update_token}\"}"
	$MIIO_SEND_LINE "$RESPONSE_UPDATE_TOKEN"
}

#记录离线
record_offline() {
	offline_param=$1

	offline_time=$(echo "$offline_param" | jshon -e params -e offline_time -u -Q)
	echo "offline_time is $offline_time"
	offline_reason=$(echo "$offline_param" | jshon -e params -e offline_reason -u -Q)
	echo "offline_reason is $offline_reason"
	
	offline_ip=$(echo "$offline_param" | jshon -e params -e offline_ip -u -Q)
	echo "offline_ip is $offline_ip"
	
	offline_port=$(echo "$offline_param" | jshon -e params -e offline_port -u -Q)
	echo "offline_port is $offline_port"
	if [ $offline_time -eq 0 ]; then
		echo "set offline_time to 0"
	fi
	#save by yourself
}

#主函数
main() {
	#循环体
	while true; do
	
	#接收到数据,并存放到变量中
	BUF=`$MIIO_RECV_LINE`
	
	#-ne 检测两个数是否不相等,不相等返回true;
	#$?:显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
	if [ $? -ne 0 ]; then
		sleep 1;
		continue
	fi
	
	echo "$BUF"
	
	#关闭wifi
	if contains "$BUF" "_internal.setwifidown"; then
		echo "Got _internal.setwifidown"
		set_wifi_down "$BUF"
	fi
	
	#打开wifi
	if contains "$BUF" "_internal.setwifiup"; then
		echo "Got _internal.setwifiup"
		set_wifi_up "$BUF"		
	fi
	
	#设置wifi ap模式
	if contains "$BUF" "_internal.setwifiap"; then
		echo "Got _internal.setwifiap"
		set_wifi_ap	"$BUF"
	fi
	
	#请求设备网络状态信息
	if contains "$BUF" "_internal.info"; then
		echo "Got _internal.info"
		internal_info	"$BUF"
	#请求设备 Wi-Fi 配置状态
	elif contains "$BUF" "_internal.req_wifi_conf_status"; then
		echo "Got _internal.req_wifi_conf_status"
	    req_wifi_conf_status "$BUF"
	#wifi开始连接
	elif contains "$BUF" "_internal.wifi_start"; then
		echo "Got _internal.wifi_start"
		wifi_start "$BUF"
	#请求设备固化信息,
	elif contains "$BUF" "_internal.request_dinfo"; then
		echo "Got _internal.request_dinfo"
		request_dinfo "$BUF"
	#OT 在离线时,间隔 60 分钟会发送_internal.wifi_reload 消息给 helper 脚本
	elif contains "$BUF" "_internal.wifi_reload"; then
	    echo "Got _internal.wifi_reload"
		wifi_reload
	#OT 在离线时,间隔 15 分钟会发送_internal.wifi_reconnect 消息给 helper 脚本
	elif contains "$BUF" "_internal.wifi_reconnect"; then
		echo "Got _internal.wifi_reconnect"
		wifi_reconnect
	#请求令牌
	elif contains "$BUF" "_internal.request_dtoken"; then
	    echo "Got _internal.request_dtoken"
	    request_dtoken "$BUF"
	#请求设备绑定信息
	elif contains "$BUF" "_internal.request_ot_config"; then
		echo "Got _internal.request_ot_config"
		request_ot_config "$BUF"
	#当设备从配网模式到 Wi-Fi 连接成功之后, OT 会发出更新 token 的消息
	elif contains "$BUF" "_internal.update_dtoken"; then
		echo "Got _internal.update_dtoken"
	    update_dtoken "$BUF"
	#helper 脚本收到 _internal.config_tz 消息时,需要解析"tz"字段,并调用 save_tz_conf接口保存时区。
	elif contains "$BUF" "_internal.config_tz"; then
		echo "Got _internal.config_tz"
	    miio_tz=$(echo "$BUF" | $JSHON -e params -e tz -u -Q)
	    save_tz_conf "$miio_tz"
	#记录离线
	elif contains "$BUF" "_internal.record_offline"; then
	    echo "Got _internal.record_offline"
		record_offline "$BUF"
	#其他
	else
	    id_string="$BUF"
	    echo "$id_string"
	    id=${id_string##*id\":}
		echo "$id"
        id=${id%%\,*}
	    echo "$id"
	    msg="{\"id\":$id,\"error\":\"unknown method\"}"
	    echo "$msg"
	    $MIIO_SEND_LINE "$msg $msg"
	fi
	done
}





sanity_check
send_helper_ready
main

文件:S100cdn_xiaomi


#!/bin/sh


#将启动脚本拷贝到tmp文件夹下
cp -r -p /root/cdn_xiaomi /tmp/


cd /tmp/cdn_xiaomi/cdn_script

#给启动脚本执行权限
chmod 777 cdn_start.sh

#执行脚本
./cdn_start.sh &



6.1.4、修改buildroot配置文件

BoardConfig_RK3308BS_32bit_CDN.mk选用buildroot配置文件为:rockchip_rk3308_bs_32_release

路径:/buildroot/configs

#自定义APP
BR2_PACKAGE_CDN_TEST=y
BR2_PACKAGE_CDN_XIAOMI=y

6.3、buildroot打开ssh

6.3.1、打开ssh

BoardConfig_RK3308BS_32bit_CDN.mk选用buildroot配置文件为:rockchip_rk3308_bs_32_release

路径:/buildroot/configs

#打开ssh
BR2_PACKAGE_OPENSSH=y
BR2_TARGET_ENABLE_ROOT_LOGIN=y
BR2_TARGET_GENERIC_ROOT_PASSWD="root"

6.3.2、打开允许root登陆

完成以上配置后,还无法使用ssh实现远程登录,需要打开允许root登陆的配置。

buildroot/output/rockchip_rk3308_bs_32_release/target/etc/ssh/sshd_config:

#LoginGraceTime 2m
#PermitRootLogin prohibit-password
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10


修改
#LoginGraceTime 2m
#PermitRootLogin prohibit-password
PermitRootLogin yes
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10

6.7、buildroot打开gzip

输入命令:

source envsetup.sh  #选择配置文件
make busybox-menuconfig

路径:Archival Utilities->

posted @ 2022-12-13 08:43  Rxin  阅读(19)  评论(0)    收藏  举报