[RK3506]基于RK3506的AP+AP的AMP设备树解读
多核异构
RK3506芯片是一颗多核异构的芯片,由三颗Cortex-A7 CPU和一颗Cortex-M0 CPU组成,A核支持运行Linux、裸机HAL、RTOS(RT-thread)。利用多核异构的特性,我们可以通过不同组合的方式运行这些CPU,例如,两颗A核运行Linux,一颗A核运行RT-Thread,也就是AP+AP的模式;三颗A核运行Linux,一颗M核运行底层一些辅助任务,也就是AP+MCU模式。我们以AP+AP模式为主,两颗A核运行Linux,一颗A核运行RT-Thread,或者是两颗A核运行Linux,一颗A核运行EtherCat的控制任务。
AP+AP模式设备树解读
以飞凌嵌入式开发版OK3506J-S 256MB+256MB为例,开发板厂商的amp设备树文件ok3506-amp-rtt.dtsi如下:
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2024 Rockchip Electronics Co., Ltd.
*/
#include <dt-bindings/soc/rockchip-amp.h>
#define CPU_GET_AFFINITY(cluster, cpu) (cpu)
/ {
cpus {
/delete-node/ cpu@f02;
};
rockchip_amp: rockchip-amp {
compatible = "rockchip,amp";
clocks = <&cru HCLK_M0>, <&cru STCLK_M0>,
<&cru SCLK_UART2>, <&cru PCLK_UART2>,
<&cru PCLK_GPIO1>, <&cru DBCLK_GPIO1>, //GPIO1
<&cru CLK_I2C2>, <&cru PCLK_I2C2>, //I2C2
<&cru CLK_SARADC>, <&cru PCLK_SARADC>,
<&cru CLK_SPI1>, <&cru PCLK_SPI1>,
<&cru CLK_PWM1>, <&cru PCLK_PWM1>,
<&cru CLK_CAN0>, <&cru HCLK_CAN0>,
<&cru PCLK_TIMER>, <&cru CLK_TIMER0_CH5>, <&cru CLK_TIMER0_CH2>,
<&cru CLK_MAC0>, <&cru CLK_MAC0_PTP>,
<&cru PCLK_MAC0>, <&cru ACLK_MAC0>;
pinctrl-names = "default";
pinctrl-0 = <&rm_io2_uart2_tx>, <&rm_io0_uart2_rx>,
<&rm_io28_pwm1_ch1 &rm_io29_pwm1_ch0 >,
<&rm_io24_spi1_clk &rm_io25_spi1_mosi &rm_io26_spi1_miso &rm_io27_spi1_csn0>,
<&rm_io19_can0_tx &rm_io20_can0_rx>
;
amp-cpu-aff-maskbits = /bits/ 64 <0x0 0x1 0x1 0x2 0x2 0x4>;
amp-irqs = /bits/ 64 <
/* GPIO EXT */
GIC_AMP_IRQ_CFG_ROUTE(36, 0x80, CPU_GET_AFFINITY(0, 2)) //GPIO 1
GIC_AMP_IRQ_CFG_ROUTE(32, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(40, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(44, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(48, 0xd0, CPU_GET_AFFINITY(0, 2))
/* GMAC0 */
GIC_AMP_IRQ_CFG_ROUTE(98, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(99, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(100, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(101, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(178, 0xd0, CPU_GET_AFFINITY(0, 2))
/* SARADC */
GIC_AMP_IRQ_CFG_ROUTE(89, 0xd0, CPU_GET_AFFINITY(0, 2))
/* I2C2 */
GIC_AMP_IRQ_CFG_ROUTE(74, 0xd0, CPU_GET_AFFINITY(0, 2))
/* CAN0 */
GIC_AMP_IRQ_CFG_ROUTE(77, 0xd0, CPU_GET_AFFINITY(0, 2))
/* TIME6 */
GIC_AMP_IRQ_CFG_ROUTE(132, 0xd0, CPU_GET_AFFINITY(0, 2))
/* TIME7 */
GIC_AMP_IRQ_CFG_ROUTE(133, 0x80, CPU_GET_AFFINITY(0, 2))
/* TIME8 */
GIC_AMP_IRQ_CFG_ROUTE(134, 0xd0, CPU_GET_AFFINITY(0, 2))
/* TIME9 */
GIC_AMP_IRQ_CFG_ROUTE(135, 0xd0, CPU_GET_AFFINITY(0, 2))
/* TIME10 */
GIC_AMP_IRQ_CFG_ROUTE(136, 0xd0, CPU_GET_AFFINITY(0, 2))
/* SPI1 */
GIC_AMP_IRQ_CFG_ROUTE(76, 0xd0, CPU_GET_AFFINITY(0, 2))
/* PWM1_CH0 */
GIC_AMP_IRQ_CFG_ROUTE(58, 0xd0, CPU_GET_AFFINITY(0, 2))
/* PWM1_CH1 */
GIC_AMP_IRQ_CFG_ROUTE(59, 0xd0, CPU_GET_AFFINITY(0, 2))
/* UART2 */
GIC_AMP_IRQ_CFG_ROUTE(68, 0xd0, CPU_GET_AFFINITY(0, 2))
/* MAILBOX */
GIC_AMP_IRQ_CFG_ROUTE(176, 0xd0, CPU_GET_AFFINITY(0, 2))>;
status = "okay";
};
rpmsg: rpmsg@3c00000 {
compatible = "rockchip,rpmsg";
mbox-names = "rpmsg-rx", "rpmsg-tx";
mboxes = <&mailbox0 0 &mailbox2 0>;
rockchip,vdev-nums = <1>;
/* CPU2: link-id 0x02; */
rockchip,link-id = <0x02>;
reg = <0x3c00000 0x20000>;
memory-region = <&rpmsg_dma_reserved>;
status = "okay";
};
};
&arm_pmu {
interrupt-affinity = <&cpu0>, <&cpu1>;
};
&mailbox0 {
rockchip,txpoll-period-ms = <1>;
status = "okay";
};
&mailbox2 {
rockchip,txpoll-period-ms = <1>;
status = "okay";
};
&reserved_memory {
/* remote amp core address */
amp_shmem_reserved: amp-shmem@3b00000 {
reg = <0x03b00000 0x100000>;
no-map;
};
rpmsg_reserved: rpmsg@3c00000 {
reg = <0x03c00000 0x100000>;
no-map;
};
rpmsg_dma_reserved: rpmsg-dma@3d00000 {
compatible = "shared-dma-pool";
reg = <0x03d00000 0x100000>;
no-map;
};
// rpmsg_ddr_reserved: rpmsg-ddr@4000000 {
// reg = <0x04600000 0x0100000>;
// no-map;
// };
/* mcu address */
mcu_reserved: mcu@fff80000 {
reg = <0xfff80000 0xc000>;
no-map;
};
amp_reserved: amp@3e00000 {
reg = <0x03e00000 0x800000>;
no-map;
};
};
&gmac0 {
status = "disabled";
};
&uart2 {
status = "disabled";
};
一、\ 根节点的配置
1. 删除cpu2
cpus {
/delete-node/ cpu@f02;
};delete-node 是删除节点的意思,cpu@f02 是待删除节点的路径,在设备树编译结束后,CPU2将从Linux中调离,只会有CPU0和CPU1注册到Linux系统中。
2. Rockchip 平台AMP的核心配置
rockchip_amp: rockchip-amp {
compatible = "rockchip,amp";
clocks = <&cru HCLK_M0>, <&cru STCLK_M0>,
<&cru SCLK_UART2>, <&cru PCLK_UART2>,
<&cru PCLK_GPIO1>, <&cru DBCLK_GPIO1>, //GPIO1
<&cru CLK_I2C2>, <&cru PCLK_I2C2>, //I2C2
<&cru CLK_SARADC>, <&cru PCLK_SARADC>,
<&cru CLK_SPI1>, <&cru PCLK_SPI1>,
<&cru CLK_PWM1>, <&cru PCLK_PWM1>,
<&cru CLK_CAN0>, <&cru HCLK_CAN0>,
<&cru PCLK_TIMER>, <&cru CLK_TIMER0_CH5>, <&cru CLK_TIMER0_CH2>,
<&cru CLK_MAC0>, <&cru CLK_MAC0_PTP>,
<&cru PCLK_MAC0>, <&cru ACLK_MAC0>;
pinctrl-names = "default";
pinctrl-0 = <&rm_io2_uart2_tx>, <&rm_io0_uart2_rx>,
<&rm_io28_pwm1_ch1 &rm_io29_pwm1_ch0 >,
<&rm_io24_spi1_clk &rm_io25_spi1_mosi &rm_io26_spi1_miso &rm_io27_spi1_csn0>,
<&rm_io19_can0_tx &rm_io20_can0_rx>
;
amp-cpu-aff-maskbits = /bits/ 64 <0x0 0x1 0x1 0x2 0x2 0x4>;
amp-irqs = /bits/ 64 <
/* GPIO EXT */
GIC_AMP_IRQ_CFG_ROUTE(36, 0x80, CPU_GET_AFFINITY(0, 2)) //GPIO 1
GIC_AMP_IRQ_CFG_ROUTE(32, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(40, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(44, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(48, 0xd0, CPU_GET_AFFINITY(0, 2))
/* GMAC0 */
GIC_AMP_IRQ_CFG_ROUTE(98, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(99, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(100, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(101, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(178, 0xd0, CPU_GET_AFFINITY(0, 2))
/* SARADC */
GIC_AMP_IRQ_CFG_ROUTE(89, 0xd0, CPU_GET_AFFINITY(0, 2))
/* I2C2 */
GIC_AMP_IRQ_CFG_ROUTE(74, 0xd0, CPU_GET_AFFINITY(0, 2))
/* CAN0 */
GIC_AMP_IRQ_CFG_ROUTE(77, 0xd0, CPU_GET_AFFINITY(0, 2))
/* TIME6 */
GIC_AMP_IRQ_CFG_ROUTE(132, 0xd0, CPU_GET_AFFINITY(0, 2))
/* TIME7 */
GIC_AMP_IRQ_CFG_ROUTE(133, 0x80, CPU_GET_AFFINITY(0, 2))
/* TIME8 */
GIC_AMP_IRQ_CFG_ROUTE(134, 0xd0, CPU_GET_AFFINITY(0, 2))
/* TIME9 */
GIC_AMP_IRQ_CFG_ROUTE(135, 0xd0, CPU_GET_AFFINITY(0, 2))
/* TIME10 */
GIC_AMP_IRQ_CFG_ROUTE(136, 0xd0, CPU_GET_AFFINITY(0, 2))
/* SPI1 */
GIC_AMP_IRQ_CFG_ROUTE(76, 0xd0, CPU_GET_AFFINITY(0, 2))
/* PWM1_CH0 */
GIC_AMP_IRQ_CFG_ROUTE(58, 0xd0, CPU_GET_AFFINITY(0, 2))
/* PWM1_CH1 */
GIC_AMP_IRQ_CFG_ROUTE(59, 0xd0, CPU_GET_AFFINITY(0, 2))
/* UART2 */
GIC_AMP_IRQ_CFG_ROUTE(68, 0xd0, CPU_GET_AFFINITY(0, 2))
/* MAILBOX */
GIC_AMP_IRQ_CFG_ROUTE(176, 0xd0, CPU_GET_AFFINITY(0, 2))>;
status = "okay";
};
这是Rockchip平台对于AMP的核心配置,关于时钟,引脚,中断的配置,将所需要的时钟,引脚,中断的控制权从Linux中移交到CPU2中。目的是为了将运行Linux的CPU0、CPU1与CPU2进行资源上面的隔离,对外设、时钟、引脚、中断资源进行划分。
(1). 节点基础配置
rockchip_amp: rockchip-amp {
compatible = "rockchip,amp";
...
status = "okay";
}; amp-irqs = /bits/ 64 <
/* GPIO EXT */
GIC_AMP_IRQ_CFG_ROUTE(36, 0x80, CPU_GET_AFFINITY(0, 2)) //GPIO 1
GIC_AMP_IRQ_CFG_ROUTE(32, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(40, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(44, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(48, 0xd0, CPU_GET_AFFINITY(0, 2))
/* GMAC0 */
GIC_AMP_IRQ_CFG_ROUTE(98, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(99, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(100, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(101, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(178, 0xd0, CPU_GET_AFFINITY(0, 2))
/* SARADC */
GIC_AMP_IRQ_CFG_ROUTE(89, 0xd0, CPU_GET_AFFINITY(0, 2))
/* I2C2 */
GIC_AMP_IRQ_CFG_ROUTE(74, 0xd0, CPU_GET_AFFINITY(0, 2))
/* CAN0 */
GIC_AMP_IRQ_CFG_ROUTE(77, 0xd0, CPU_GET_AFFINITY(0, 2))
/* TIME6 */
GIC_AMP_IRQ_CFG_ROUTE(132, 0xd0, CPU_GET_AFFINITY(0, 2))
/* TIME7 */
GIC_AMP_IRQ_CFG_ROUTE(133, 0x80, CPU_GET_AFFINITY(0, 2))
/* TIME8 */
GIC_AMP_IRQ_CFG_ROUTE(134, 0xd0, CPU_GET_AFFINITY(0, 2))
/* TIME9 */
GIC_AMP_IRQ_CFG_ROUTE(135, 0xd0, CPU_GET_AFFINITY(0, 2))
/* TIME10 */
GIC_AMP_IRQ_CFG_ROUTE(136, 0xd0, CPU_GET_AFFINITY(0, 2))
/* SPI1 */
GIC_AMP_IRQ_CFG_ROUTE(76, 0xd0, CPU_GET_AFFINITY(0, 2))
/* PWM1_CH0 */
GIC_AMP_IRQ_CFG_ROUTE(58, 0xd0, CPU_GET_AFFINITY(0, 2))
/* PWM1_CH1 */
GIC_AMP_IRQ_CFG_ROUTE(59, 0xd0, CPU_GET_AFFINITY(0, 2))
/* UART2 */
GIC_AMP_IRQ_CFG_ROUTE(68, 0xd0, CPU_GET_AFFINITY(0, 2))
/* MAILBOX */
GIC_AMP_IRQ_CFG_ROUTE(176, 0xd0, CPU_GET_AFFINITY(0, 2))>;
compatible加载驱动节点的专用驱动rockchip、amp ,并将节点状态配置为okay,配置节点有效。
(2). 时钟资源配置
clocks = <&cru HCLK_M0>, <&cru STCLK_M0>,
<&cru SCLK_UART2>, <&cru PCLK_UART2>,
<&cru PCLK_GPIO1>, <&cru DBCLK_GPIO1>, //GPIO1
<&cru CLK_I2C2>, <&cru PCLK_I2C2>, //I2C2
<&cru CLK_SARADC>, <&cru PCLK_SARADC>,
<&cru CLK_SPI1>, <&cru PCLK_SPI1>,
<&cru CLK_PWM1>, <&cru PCLK_PWM1>,
<&cru CLK_CAN0>, <&cru HCLK_CAN0>,
<&cru PCLK_TIMER>, <&cru CLK_TIMER0_CH5>, <&cru CLK_TIMER0_CH2>,
<&cru CLK_MAC0>, <&cru CLK_MAC0_PTP>,
<&cru PCLK_MAC0>, <&cru ACLK_MAC0>;
<&phandle clock_id>:&cru 是时钟控制器节点的标签,后面的 HCLK_M0, PCLK_UART2 等是具体的时钟。
通过配置始终资源,声明在CPU2中所需要的时钟资源,因为Linux 内核的电源管理子系统在检测到某个外设“空闲”时,会将其时钟关闭,从而导致CPU2中的系统崩溃,声明时钟资源可以避免这种情况,Linux将不再管理这些时钟,将由CPU2进行管理。
(3). 引脚控制组
pinctrl-names = "default";
pinctrl-0 = <&rm_io2_uart2_tx>, <&rm_io0_uart2_rx>,
<&rm_io28_pwm1_ch1 &rm_io29_pwm1_ch0 >,
<&rm_io24_spi1_clk &rm_io25_spi1_mosi &rm_io26_spi1_miso &rm_io27_spi1_csn0>,
<&rm_io19_can0_tx &rm_io20_can0_rx>
;声明在CPU2中所使用的引脚复用,RMIO(Rockchip Matrix IO)是Rockchip中的特色功能,及可以将98个功能映射随便到32个RMIO引脚上,而这里的rm_io28_pwm1_ch1 表示rm_io28引脚将复用为pwm1的ch1功能,以此类推。
(4).中断路由配置
#define CPU_GET_AFFINITY(cluster, cpu) (cpu)
amp-irqs = /bits/ 64 <
/* GPIO EXT */
GIC_AMP_IRQ_CFG_ROUTE(36, 0x80, CPU_GET_AFFINITY(0, 2)) //GPIO 1
GIC_AMP_IRQ_CFG_ROUTE(32, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(40, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(44, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(48, 0xd0, CPU_GET_AFFINITY(0, 2))
/* GMAC0 */
GIC_AMP_IRQ_CFG_ROUTE(98, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(99, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(100, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(101, 0xd0, CPU_GET_AFFINITY(0, 2))
GIC_AMP_IRQ_CFG_ROUTE(178, 0xd0, CPU_GET_AFFINITY(0, 2))
/* SARADC */
GIC_AMP_IRQ_CFG_ROUTE(89, 0xd0, CPU_GET_AFFINITY(0, 2))
/* I2C2 */
GIC_AMP_IRQ_CFG_ROUTE(74, 0xd0, CPU_GET_AFFINITY(0, 2))
/* CAN0 */
GIC_AMP_IRQ_CFG_ROUTE(77, 0xd0, CPU_GET_AFFINITY(0, 2))
/* TIME6 */
GIC_AMP_IRQ_CFG_ROUTE(132, 0xd0, CPU_GET_AFFINITY(0, 2))
/* TIME7 */
GIC_AMP_IRQ_CFG_ROUTE(133, 0x80, CPU_GET_AFFINITY(0, 2))
/* TIME8 */
GIC_AMP_IRQ_CFG_ROUTE(134, 0xd0, CPU_GET_AFFINITY(0, 2))
/* TIME9 */
GIC_AMP_IRQ_CFG_ROUTE(135, 0xd0, CPU_GET_AFFINITY(0, 2))
/* TIME10 */
GIC_AMP_IRQ_CFG_ROUTE(136, 0xd0, CPU_GET_AFFINITY(0, 2))
/* SPI1 */
GIC_AMP_IRQ_CFG_ROUTE(76, 0xd0, CPU_GET_AFFINITY(0, 2))
/* PWM1_CH0 */
GIC_AMP_IRQ_CFG_ROUTE(58, 0xd0, CPU_GET_AFFINITY(0, 2))
/* PWM1_CH1 */
GIC_AMP_IRQ_CFG_ROUTE(59, 0xd0, CPU_GET_AFFINITY(0, 2))
/* UART2 */
GIC_AMP_IRQ_CFG_ROUTE(68, 0xd0, CPU_GET_AFFINITY(0, 2))
/* MAILBOX */
GIC_AMP_IRQ_CFG_ROUTE(176, 0xd0, CPU_GET_AFFINITY(0, 2))>;
将硬件中断路由绑定到CPU2中,所绑定的中断被触发时,将把中断信号直接发送给CPU2。
3. rpmsg
rpmsg: rpmsg@3c00000 {
compatible = "rockchip,rpmsg";
mbox-names = "rpmsg-rx", "rpmsg-tx";
mboxes = <&mailbox0 0 &mailbox2 0>;
rockchip,vdev-nums = <1>;
/* CPU2: link-id 0x02; */
rockchip,link-id = <0x02>;
reg = <0x3c00000 0x20000>;
memory-region = <&rpmsg_dma_reserved>;
status = "okay";
};设备树节点说明(SDK/kernel-6.1/Documentation/devicetree/bindings/rpmsg/rpmsg-rockchip.txt)如下:
* Rockchip RPMsg Platform Driver
The Rockchip RPMsg Platform Driver is used for Remote Processors Messaging.
Required Properties:
- compatible: should be one of the following.
"rockchip,rk3568-rpmsg" for rk3568 SoCs.
- mbox-names: mailbox name for "rpmsg-rx" or "rpmsg-tx".
- mboxes: mailbox channel for rpmsg.
- rockchip,vdev-nums: number of rpmsg instance.
- rockchip,link-id: link_id of rpmsg instance. 4bit for master cpu_id and 4bit
for remote cpu_id.
Optional Properties:
Example:
rpmsg: rpmsg {
compatible = "rockchip,rk3568-rpmsg";
mbox-names = "rpmsg-rx", "rpmsg-tx";
mboxes = <&mailbox 0 &mailbox 3>;
rockchip,vdev-nums = <1>;
rockchip,link-id = <0x03>;
reg = <0x0 0x7c00000 0x0 0x20000>;
memory-region = <&rpmsg_dma_reserved>;
status = "okay";
};
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
rpmsg_reserved: rpmsg@7c00000 {
reg = <0x0 0x7c00000 0x0 0x400000>;
no-map;
};
rpmsg_dma_reserved: rpmsg-dma@8000000 {
compatible = "shared-dma-pool";
reg = <0x0 0x8000000 0x0 0x100000>;
no-map;
};
};spmsg是实现核间通信(IPC)的重要关键。
mbos(Mailbox)是硬件邮箱通道,每个core有一个相应的32bit的Mailbox寄存器,每一位可被单独地设置或清零,任意core可直接通过其它core 的mailbox对其它core发出中断。当mailbox被置位时,相应core的中断寄存器也同时被置位,软件可实现其中断处理。
TODO:Mailbox的深入探究。
结合txt文档可知,mbox-names定义了两个通道,一个是rpmsg-rx接收通道,一个是rpmsg-tx发送通道。
已调通,待更新技术博客。。。。