系统接口使用

RTC_SRAM存储OEM说明

OEM参数位置是eMMC的硬件boot1分区,进入kernel后挂载在/dev/mmcblk0boot1。MCU在fsbl阶段开始运行,需要OEM参数用于设置不同的board,A53和MCU不能同时访问eMMC,因此在FSBL加载MCU之前,先从eMMC的boot1分区读OEM参数到RTC_SRAM,然后MCU再去取参数。

RTC_SRAM起始地址:0x5200000,长度:0x8000(32K),预留RTC_SRAM最后256 byte用于存储OEM参数,OEM组成结构如下:

offset

name

description

0x00

SN0

chip sn

0x20

SN1

reserve for product or customer

0x40

MAC0

0x50

MAC1

0x60

PRODUCT_TYPE

0x70

MODULE_TYPE

0x80

INTERFACE_FLAG

0x81

AGING_FLAG

0x90

VENDER

0xa0

DTS_TYPE

0xc0

HW_VERSION

0xd0

PRODUCT

产品系列,例如: SE9

0xe0

CHIP

BM1688/CV186AH

保留

修改和读取SN和MAC地址

BM1688 的SN和MAC地址存放在MCU的EEPROM中,您可以通过如下方式进行修改和读取操作。

首先需要解锁mmcblk0boot1设备节点:

sudo -i
echo 0 > /sys/block/mmcblk0boot1/force_ro

写入SN:

echo "HQATEVBAIAIAI0001" > sn.txt
dd if=sn.txt of=/dev/mmcblk0boot1 count=17 bs=1
echo "HQATEVBAIAIAI0002" > sn.txt
dd if=sn.txt of=/dev/mmcblk0boot1 count=17 bs=1 seek=32

读取SN:

dd if=/dev/mmcblk0boot1 of=dump.bin count=17 bs=1
hexdump -C dump.bin | head

写入MAC(双网卡各有一个MAC):

echo "E0A509261417" > mac0.txt
xxd -p -u -r mac0.txt > mac0.bin
dd if=mac0.bin of=/dev/mmcblk0boot1 count=6 bs=1 seek=64
echo "E0A509261418" > mac1.txt
xxd -p -u -r mac1.txt > mac1.bin
dd if=mac1.bin of=/dev/mmcblk0boot1 count=6 bs=1 seek=80

读取MAC:

dd if=/dev/mmcblk0boot1 of=mac_dump.bin count=6 bs=1 skip=64
hexdump mac_dump.bin

最后重新对mmcblk0boot1设备节点加锁,以避免意外改写:

echo 1 > /sys/block/mmcblk0boot1/force_ro

新的MAC地址将在重启系统后生效。

读取BM1688芯片温度

命令:

cat /sys/class/thermal/thermal_zone0/temp

返回(单位为毫摄氏度):

38745

即38.745摄氏度。

Linux的thermal框架会使用这个温度做管理(需要加载soph_clock_cooling驱动):

  • 当温度升到110度时,TPU频率会降到450MHz,CPU降频到1GHz;

  • 当温度升高到120度时,TPU降频到100MHz,CPU降频到1GHz;

  • 当温度回落到100度时,TPU和CPU频率恢复额定值;

  • 当温度升高到125度时,系统关机。

另支持pwm控制风扇进行主动降温,默认策略为:

  • 温度在40度以下时,风扇不转;

  • 温度升高到40度时,风扇以100/255最大转速运行;

  • 温度升高到60度时,风扇以170/255最大转速运行;

  • 温度升高到80度时,风扇以最大转速运行。

注:可以通过设备树修改以上策略,在soph_base.dtsi文件中:

sophgo_cooling:sophgo-cooling {
        clocks = <&clk CV186X_AP_CPU_CLK>, <&clk CV186X_TPU_CLK_TPU>;
        clock-names = "clk_cpu", "clk_tpu_axi";
        dev-freqs = <1650000000 900000000>,
                <1000000000 450000000>,
                <1000000000 100000000>;
        compatible = "cvitek,cv186x-cooling";
        #cooling-cells = <2>;
};

fan0: pwm-fan {
        compatible = "pwm-fan";
        #cooling-cells = <2>;
        pwms = <&pwm0 0 1000000 0>; // default pwm0, 1ms period, normal polarity
        cooling-levels = <1 100 170 255>; // max 255
};


thermal-zones {
        soc_thermal_0: soc_thermal_0 {
                polling-delay-passive = <1000>; /* milliseconds */
                polling-delay = <1000>; /* milliseconds */
                thermal-sensors = <&thermal 0>;

                trips {
                        soc_thermal_trip_0: soc_thermal_trip_0 {
                                temperature = <110000>; /* millicelsius */
                                hysteresis = <10000>; /* millicelsius */
                                type = "passive";
                        };

                        soc_thermal_trip_1: soc_thermal_trip_1 {
                                temperature = <120000>; /* millicelsius */
                                hysteresis = <20000>; /* millicelsius */
                                type = "passive";
                        };

                        soc_thermal_crtical_0: soc_thermal_crtical_0 {
                                temperature = <125000>; /* millicelsius */
                                hysteresis = <0>; /* millicelsius */
                                type = "critical";
                        };

                        soc_thermal_active_0: soc_thermal_active_0 {
                                temperature = <40000>; /* millicelsius */
                                hysteresis = <0>; /* millicelsius */
                                type = "active";
                        };

                        soc_thermal_active_1: soc_thermal_active_1 {
                                temperature = <60000>; /* millicelsius */
                                hysteresis = <0>; /* millicelsius */
                                type = "active";
                        };

                        soc_thermal_active_2: soc_thermal_active_2 {
                                temperature = <80000>; /* millicelsius */
                                hysteresis = <0>; /* millicelsius */
                                type = "active";
                        };
                };

                cooling-maps {
                        map0 {
                                trip = <&soc_thermal_trip_0>;
                                cooling-device = <&sophgo_cooling 1 1>;
                        };

                        map1 {
                                trip = <&soc_thermal_trip_1>;
                                cooling-device = <&sophgo_cooling 2 2>;
                        };

                        map2 {
                                trip = <&soc_thermal_active_0>;
                                cooling-device = <&fan0 1 1>;
                        };

                        map3 {
                                trip = <&soc_thermal_active_1>;
                                cooling-device = <&fan0 2 2>;
                        };

                        map4 {
                                trip = <&soc_thermal_active_2>;
                                cooling-device = <&fan0 3 3>;
                        };
                };
        };

修改以上设备树节点即可自定义温控策略(TPU分频只可整数倍),参考linux Documention相关设备树说明。

查询内存用量

BM1688 板载了16GB DDR,可以分为三类:

  1. kernel管理的部分,即可以用malloc、kmalloc等常规API分配出来使用。

  2. ION管理的部分,预留给TPU、VPU、VPP使用,需要使用ION的ionctl接口,或使用sophonSDK中bmlib库提供的接口分配出来使用。

  3. 预留给固件的部分,用户无法使用。

您可以使用如下方式检查各部分内存的用量:

  1. 查看系统内存

    linaro@bm1684:~$ free -h
                  total        used        free      shared  buff/cache   available
    Mem:          6.6Gi       230Mi       6.2Gi       1.0Mi       230Mi       6.3Gi
    Swap:            0B          0B          0B
    
  2. 查看ION内存

    sudo -i
    root@bm1684:~# cat /sys/kernel/debug/ion/cvi_npu_heap_dump/summary  | head -2
    Summary:
    [0] npu heap size:4141875200 bytes, used:0 bytes        usage rate:0%, memory usage peak
    0 bytes
    
    root@bm1684:~# cat /sys/kernel/debug/ion/cvi_vpp_heap_dump/summary  | head -2
    Summary:
    [2] vpu heap size:2147483648 bytes, used:0 bytes        usage rate:0%, memory usage peak
    0 bytes
    

    如上,通常会有2个ION heap(即两块预留的内存区域),如名字所示,分别供TPU、VPP使用。以上示例中只打印了每个heap使用信息的开头,如果完整地cat summary文件,可以看到其中分配的每块buffer的地址和大小信息。