Category: 每周学习摘要

  • 关于瑞芯微的一些image

    以下所有的操作基于“
    kernel下面生成的boot.imgRKIMG(RKIMG is a format customized by Rockchip from Android boot image)的镜像,因为u-boot里面用的命令是android_boot(之前不知道这个东西是用安卓启动的方式启动linux内核的,误解成是bootrkp)
    然后FIT镜像是uboot.itb,在uboot目录下的fit,可以用dumpimage -l uboot.itb查看.
    TSPI的原厂固件boot.img,recovery.img也是一个FIT镜像
    所以镜像分两种,一个是uboot FIT一个是android镜像

    分区信息可以在执行完./make.sh orangepi-3b-rk3566后看见fit/u-boot.its

    
    /*
     * Copyright (C) 2020 Rockchip Electronic Co.,Ltd
     *
     * Simple U-boot fit source file containing ATF/OP-TEE/U-Boot/dtb/MCU
     */
    
    /dts-v1/;
    
    / {
        description = "FIT Image with ATF/OP-TEE/U-Boot/MCU";
        #address-cells = <1>;
    
        images {
    
            uboot {
                description = "U-Boot";
                data = /incbin/("u-boot-nodtb.bin");
                type = "standalone";
                arch = "arm64";
                os = "U-Boot";
                compression = "none";
                load = <0x00a00000>;
                hash {
                    algo = "sha256";
                };
            };
            atf-1 {
                description = "ARM Trusted Firmware";
                data = /incbin/("./bl31_0x00040000.bin");
                type = "firmware";
                arch = "arm64";
                os = "arm-trusted-firmware";
                compression = "none";
                load = <0x00040000>;
                hash {
                    algo = "sha256";
                };
            };
            atf-2 {
                description = "ARM Trusted Firmware";
                data = /incbin/("./bl31_0xfdcc1000.bin");
                type = "firmware";
                arch = "arm64";
                os = "arm-trusted-firmware";
                compression = "none";
                load = <0xfdcc1000>;
                hash {
                    algo = "sha256";
                };
            };
            atf-3 {
                description = "ARM Trusted Firmware";
                data = /incbin/("./bl31_0x0006b000.bin");
                type = "firmware";
                arch = "arm64";
                os = "arm-trusted-firmware";
                compression = "none";
                load = <0x0006b000>;
                hash {
                    algo = "sha256";
                };
            };
            atf-4 {
                description = "ARM Trusted Firmware";
                data = /incbin/("./bl31_0xfdcd0000.bin");
                type = "firmware";
                arch = "arm64";
                os = "arm-trusted-firmware";
                compression = "none";
                load = <0xfdcd0000>;
                hash {
                    algo = "sha256";
                };
            };
            atf-5 {
                description = "ARM Trusted Firmware";
                data = /incbin/("./bl31_0xfdcce000.bin");
                type = "firmware";
                arch = "arm64";
                os = "arm-trusted-firmware";
                compression = "none";
                load = <0xfdcce000>;
                hash {
                    algo = "sha256";
                };
            };
            atf-6 {
                description = "ARM Trusted Firmware";
                data = /incbin/("./bl31_0x00069000.bin");
                type = "firmware";
                arch = "arm64";
                os = "arm-trusted-firmware";
                compression = "none";
                load = <0x00069000>;
                hash {
                    algo = "sha256";
                };
            };
            fdt {
                description = "U-Boot dtb";
                data = /incbin/("./u-boot.dtb");
                type = "flat_dt";
                arch = "arm64";
                compression = "none";
                hash {
                    algo = "sha256";
                };
            };
        };
    
        configurations {
            default = "conf";
            conf {
                description = "rk3566-orangepi-3b";
                rollback-index = <0x0>;
                firmware = "atf-1";
                loadables = "uboot", "atf-2", "atf-3", "atf-4", "atf-5", "atf-6";
    
                fdt = "fdt";
                signature {
                    algo = "sha256,rsa2048";
    
                    key-name-hint = "dev";
                    sign-images = "fdt", "firmware", "loadables";
                };
            };
        };
    };
    

    如何pack idblock(idbloader)?

    在u-boot下面进行

    ./make.sh --idblock

    shell源码:

    function pack_idblock()
    {
        INI=${INI_LOADER}
        if [ ! -f ${INI} ]; then
            echo "ERROR: No ${INI}"
            exit 1
        fi
    
        # chip
        COMMON_H=`grep "_common.h:" include/autoconf.mk.dep | awk -F "/" '{ printf $3 }'`
        PLAT=${COMMON_H%_*}
    
        # file
        SPL_BIN=${RKBIN}/`filt_val "FlashBoot" ${INI}`
        TPL_BIN=${RKBIN}/`filt_val "FlashData" ${INI}`
        if [ ! -z "${ARG_SPL_BIN}" ]; then
            SPL_BIN=${ARG_SPL_BIN}
        fi
        if [ ! -z "${ARG_TPL_BIN}" ]; then
            TPL_BIN=${ARG_TPL_BIN}
        fi
    
        # pack
        rm idblock.bin -f
        ./tools/mkimage -n ${PLAT} -T rksd -d ${TPL_BIN}:${SPL_BIN} idblock.bin
        echo "Input:"
        echo "    ${INI}"
        echo "    ${TPL_BIN}"
        echo "    ${SPL_BIN}"
        echo
        echo "Pack ${PLAT} idblock.bin okay!"
        echo
    }

    运行后终端提示:

    (py2) ➜  u-boot-orangepi git:(v2017.09-rk3588) ./make.sh --idblock         
    Image Type:   Rockchip RK35 boot image
    Init Data Size: 55296 bytes
    Boot Data Size: 241664 bytes
    Input:
        /home/ztn/Embedded/RK/rkbin/RKBOOT/RK3566MINIALL.ini
        /home/ztn/Embedded/RK/rkbin/bin/rk35/rk3566_ddr_1056MHz_v1.18.bin
        /home/ztn/Embedded/RK/rkbin/bin/rk35/rk356x_spl_v1.12.bin
    
    Pack rk3568 idblock.bin okay!

    在运行./make.sh xxx时候INI_LOADER如何被选中?

    看源码make.sh, 是从当前目录下的.config中寻找CONFIG_LOADER_INI

    function select_ini_file()
    {
        # default
        INI_LOADER=${RKBIN}/RKBOOT/${RKCHIP_LOADER}MINIALL.ini
        if [ "${ARM64_TRUSTZONE}" == "y" ]; then
            INI_TRUST=${RKBIN}/RKTRUST/${RKCHIP_TRUST}TRUST.ini
        else
            INI_TRUST=${RKBIN}/RKTRUST/${RKCHIP_TRUST}TOS.ini
        fi
    
        # defconfig
        NAME=`filt_val "CONFIG_LOADER_INI" .config`
        if [ ! -z "${NAME}" ]; then
            INI_LOADER=${RKBIN}/RKBOOT/${NAME}
        fi
        NAME=`filt_val "CONFIG_TRUST_INI" .config`
        if [ ! -z "${NAME}" ]; then
            INI_TRUST=${RKBIN}/RKTRUST/${NAME}
        fi
    
        # args
        if [ ! -z "${ARG_INI_TRUST}" ]; then
            INI_TRUST=${ARG_INI_TRUST}
        fi
        if [ ! -z "${ARG_INI_LOADER}" ]; then
            INI_LOADER=${ARG_INI_LOADER}
        fi
    }

    小勘误

    rockchip wiki上面是这样从bin 制作img的(img烧录到sd卡中)

    tools/mkimage -n rkxxxx -T rksd -d rkxx_ddr_vx.xx.bin idbloader.img
    cat rkxx_miniloader_vx.xx.bin >> idbloader.img

    但是这样会有问题(提示文件过大)
    然后用make.sh里面的方法:

    ./tools/mkimage -n ${PLAT} -T rksd -d ${TPL_BIN}:${SPL_BIN} idblock.bin
  • 【每周学习摘要01(25/01/23-25/01/29)】

    Rk3566 OV2640调试记录

    参考文献

    camera调试:RK3588 MIPI/DVP camera关键配置
    基于瑞芯微平台cif接口dvp相机的视频接入(ov2640、rv1126为例)
    (BT656)rk3568制冷项目驱动开发流程汇总(只适用于部分模块CIF DVP等,自用)
    瑞芯微摄像头移植流程和注意事项
    (全志平台,仅供参考)MQ-r T113 ov2640驱动

    订阅了个博客,可以当做文档?

    https://blog.csdn.net/weixin_35723192/category_11824879_3.html

    Rk3566 VI version 2.1 能力

    其中注意瑞芯微rk3566/68平台的VICAP(rkcif)和ISP是两个不同的IP核,两个IP核都能进行capture.
    其中rk3566的ISP21是lite版本,看描述是不支持HDR
    rk3566/3568没有ispp这个东西,只有rv1126/rv1109/rk3588有(可能是因为VI 3.0才有这个)

    详见ISP21/Rockchip_Driver_Guide_VI_CN_v1.1.3.pdf

    GPIO/GRF/GRF_SYS

    ➜  ~ cd /sys/class/gpio
    ➜  gpio cd gpio144
    ➜  gpio144 echo 0 > value 
    ➜  gpio144 cd ../145
    cd: no such file or directory: ../145
    ➜  gpio144 echo 0 > value
    ➜  gpio144 cd../g
    ➜  gpio144 cd ../gpio145
    ➜  gpio145 echo 0 > value
    ➜  gpio145 echo 1 > value
    ➜  gpio145 cd ../gpio144
    ➜  gpio144 echo 1 > value
    ➜  gpio144 devmem2 0xFDC60070 w 0x00FF0011
    /dev/mem opened.
    Memory mapped at address 0x7fb954d000.
    Value at address 0xFDC60070 (0x7fb954d070): 0x0
    Written 0xFF0011; readback 0x11

    GRF 是 General Register File 的意思,其中有IOMUX的作用.
    其中的SYS_GRF掌管了GPIO的IOMUX工作

    我们可以通过devmem2 0xFDC60070 w 0x00FF0011来改变GPIO4_C bank 的复用,其中一个pin 4bit,高16位是用来做mask的.

    GPIO 复用/linux pinctrl

    比如dts长这样

    device {
            pinctrl-names = "active", "idle";
            pinctrl-0 = <&state_0_node_a>;
            pinctrl-1 = <&state_1_node_a>, <&state_1_node_b>;
        };

    然后active对应pinctrl-0.

    #define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default"
    gc4c33->pins_default = pinctrl_lookup_state(gc4c33->pinctrl, OF_CAMERA_PINCTRL_STATE_DEFAULT);
    pinctrl_select_state(gc4c33->pinctrl, gc4c33->pins_default);

    当然这里的names可以是任何名字, 然后每个组内可以有多个pins.
    对于标有defaultpinstate, 驱动会默认进行pinctrl_select, 不需要在像i2c这种设备的源码里面手动再mux一遍. source:
    The pin control core will automatically claim the default pinctrl state for us when the device is probed. If one defines an init state, the pinctrl core will automatically set pinctrl to this state before the probe() function, and then switch to the default state after probe() (unless the driver explicitly changed states already).

    GPIO 复用查看

    cat /sys/kernel/debug/pinctrl/pinctrl-rockchip-pinctrl/pinmux-pins

    系统时钟树信息查看

    ➜  / cd /sys/kernel/debug/clk/clk_cif_out
    ➜  clk_cif_out cat clk_enable_count 
    4

    可以看到clock被开启了4次, 位于gc1054.c的测试代码:

    
    // should enable 4 times
        ret = __gc1054_power_on(gc1054);
        ret = __gc1054_power_on(gc1054);
        ret = __gc1054_power_on(gc1054);
        ret = __gc1054_power_on(gc1054);

    驱动c源码

    需要在g_mbus_config中设置V4L2_MBUS_BT656, PARALLEL是给BT601用的

    Linux 源码查看当前版本

    找根目录Makefile前几行

    25/01/23


    可以看到pinmux 还没mux上去.可能mux工作是在rkcif_dvp驱动里面做的,但是i2c摄像头节点没有注册成功?(但是需要开起来).

    [    8.849418] rkcif_dvp: get_remote_sensor: remote pad is null

    看了下源码, pinmux在userspace不能通过sysfs改变, 只能查看. 然后根据迅为电子的教程看到改pinmux用到了这个函数:pinctrl_select_state, 于是查看了driver/media/i2c下面的调用, 发现改pinmux是在i2c driver里面做的,然后从linux4.19搬过来的gc1054驱动没有调用这个函数.

    现在尝试把这个加进powerup函数里面

    25/01/25

    现在发现之前无法读取ov2640,第一个是因为CLK_CIF_OUT并非开启,然而IOMUX和clock确实都是开过的.后来用电压表量了一下,发现是clk在设备probe失败后自动关闭了,即使我在i2c设备内注释了所有关闭clock的函数.(可能是i2c驱动的上级驱动帮忙关闭的). 当我在开启clock后,关闭probe结束前加入一段很长的delay, 这样示波器能观察到稳定的波形。 delay 代码如下

        dev_info(&client->dev, "[debug] ov2640 xvclk start extreme long sleep(5s) - trial 1!");
        usleep_range(5 * 1000000, 6 * 1000000); // sleep 10s
        dev_info(&client->dev, "[debug] ov2640 xvclk stop extreme long sleep(5s) - trial 1!");
        i2c_smbus_write_byte_data(client, BANK_SEL, BANK_SEL_SENS);
        pid  = i2c_smbus_read_byte_data(client, PID);
        ver  = i2c_smbus_read_byte_data(client, VER);
        midh = i2c_smbus_read_byte_data(client, MIDH);
        midl = i2c_smbus_read_byte_data(client, MIDL);

    然后发现OV2640的i2c地址(ID地址)是0x30. 然后现在dmesg信息如下, 看描述是因为ov2640这个驱动是主线的驱动(linux 5.10.160),并非能在rockchip那套平台(rkcif/rkisp)下面正常工作,因为rkcif(rkcif_dvp)会通过设备树里的endpoint链接,从而获取i2c v4l2subdev的信息,并且通过一些函数进行对应操作。
    例如v4l2_subdev_video_ops里面缺乏.g_frame_interval, 然后v4l2_subdev_pad_ops里面缺乏.get_mbus_config,该函数是rkcif判断该摄像头是否为BT656/BT1120还是BT601,亦或是CSI2等类型,所以必须得有.可能在别的platform下面这个函数并非必须的.
    还有一个很严重的误解, 才发现有外同步信号的叫BT.601/PARALLEL, 然后BT656没有外同步(HS,VS), 27MHz 的一般是BT656

    [    5.273685] i2c /dev entries driver
    [    5.276240] fan53555-regulator 0-001c: FAN53555 Option[12] Rev[15] Detected!
    [    5.278280] vdd_cpu: supplied by vcc5v0_sys
    [    5.288395] ov2640 2-0030: [debug] ov2640 xvclk start extreme long sleep(5s) - trial 1!
    [   10.290330] ov2640 2-0030: [debug] ov2640 xvclk stop extreme long sleep(5s) - trial 1!
    [   10.292579] ov2640 2-0030: ov2640 Product ID 26:42 Manufacturer ID 7f:a2
    [   10.292613] ov2640 2-0030: [debug] ov2640 xvclk start extreme long sleep(5s) - trial 2!
    [   15.320326] ov2640 2-0030: [debug] ov2640 xvclk stop extreme long sleep(5s) - trial 2!
    [   15.320357] i2c i2c-2: OV2640 Probed
    [   15.321788] rkcifhw fdfe0000.rkcif: Adding to iommu group 7
    [   15.322363] rkcifhw fdfe0000.rkcif: can't request region for resource [mem 0xfdfe0000-0xfdfe7fff]
    [   15.322494] rkcifhw fdfe0000.rkcif: No reserved memory region assign to CIF
    [   15.322720] rkcif rkcif_dvp: rkcif driver version: v00.02.00
    [   15.322880] rkcif rkcif_dvp: attach to cif hw node
    [   15.322898] rkcif rkcif_dvp: rkcif wait line 0
    [   15.322913] : terminal subdev does not exist
    [   15.322925] : terminal subdev does not exist
    [   15.322935] : terminal subdev does not exist
    [   15.322946] : terminal subdev does not exist
    [   15.324769] ov2640 2-0030: Async registered subdev
    [   15.324792] rkcif_dvp: get mbus config failed for linking
    [   15.324809] rkcif rkcif_dvp: Entity type for entity rkcif-dvp-sof was not initialized!
    [   15.325155] rkcif_dvp: rkcif_update_sensor_info: get terminal ov2640 2-0030 g_frame_interval failed!
    [   15.325182] rkcif_dvp: input mbus_code 0x2006, can't transform to RG10
    [   15.325196] rkcif_dvp: input mbus_code 0x2006, can't transform to RG10
    [   15.325208] rkcif_dvp: input mbus_code 0x2006, can't transform to RG10
    [   15.325220] rkcif_dvp: input mbus_code 0x2006, can't transform to RG10
    [   15.325241] rkcif_dvp: Async subdev notifier completed
    [   15.325264] rkcif_dvp: rkcif_update_sensor_info: get terminal ov2640 2-0030 g_frame_interval failed!
    [   15.325283] rkcif_dvp: There is not terminal subdev, not synchronized with ISP
    [   15.325483] rkcif rkcif_dvp: No memory-region-thunderboot specified
    [   15.327104] rockchip-mipi-csi2-hw fdfb0000.mipi-csi2-hw: enter mipi csi2 hw probe!
    [   15.327343] rockchip-mipi-csi2-hw fdfb0000.mipi-csi2-hw: probe success, v4l2_dev:mipi-csi2-hw!
    [   15.329032] rkisp_hw fdff0000.rkisp: Adding to iommu group 8
    [   15.329287] rkisp_hw fdff0000.rkisp: is_thunderboot: 0
    [   15.329330] rkisp_hw fdff0000.rkisp: can't request region for resource [mem 0xfdff0000-0xfdffffff]
    [   15.329370] rkisp_hw fdff0000.rkisp: max input:0x0@0fps
    [   15.329601] rkisp_hw fdff0000.rkisp: no find phandle sram
    [   15.330220] rkisp rkisp-vir0: rkisp driver version: v02.03.00
    [   15.330429] rkisp rkisp-vir0: No memory-region-thunderboot specified
    [   15.330706] rkisp rkisp-vir0: Entity type for entity rkisp-isp-subdev was not initialized!
    [   15.330738] rkisp rkisp-vir0: Entity type for entity rkisp-csi-subdev was not initialized!
    [   15.334198] usbcore: registered new interface driver uvcvideo
    [   15.334221] USB Video Class driver (1.1.1)
    [   15.336410] Bluetooth: HCI UART driver ver 2.3
    [   15.336436] Bluetooth: HCI UART protocol H4 registered
    [   15.336447] Bluetooth: HCI UART protocol ATH3K registered

    待做事项

    现在可以直接参考gc2145的文档,因为这个是BT-601 YUV(外同步)来移植OV2640
    也可以参考这个全志平台的移植MQ-r T113 ov2640驱动 因为都是MEDIA_BUS_FMT_UYUV8_2X8. 有些驱动是1X12,但我的硬件做的是2X8(8根CIF数据线). 所以只能看gc2145的代码和全志的这个(gc1054的驱动是MEDIA_BUS_FMT_SRGGB10_1X10, bayer RGB) 关于一个摄像头驱动用的哪种格式读取图像信息直接搜索关键词MEDIA_BUS_FMT. 然后RK的框架/硬件貌似不支持RGB565,见附录B MEDIA_BUS_FMT表,因为在整个文档都没搜到
    这里说的RAW RGB 就是Bayer RAW RGB的意思.然后还有个RAW BW
    主线的摄像头驱动貌似支持多种MEDIA_BUS_FMT, 详见ov2640/ov5640,不过一般在probe的时候都会选一个default类型.
    基本上rk的摄像头只支持了一种特定的camera output数据格式,毕竟没必要写那么多别output format支持,主打一个能用就行.
    gc2145用的是MEDIA_BUS_FMT_UYVY8_2X8,主线ov2640的default也是MEDIA_BUS_FMT_UYVY8_2X8
    接下来的工作是照着这些资料完善主线ov2640的一些函数,基本上只要上报正确信息就好
    注意gc2145 的vsync是low active,(见手册 7.1. Timing), 而ov2640的vsync是high active(待确认?,因为那个全志的人写的是high active但是我看手册确实是low active,可以看到gc1054也是vsync low active,凭逻辑判断也是这样,不放心多看几个V4L2_MBUS_PARALLEL的驱动,看了七八个都是这样的估计全志那个人写错了)但是hsync(href)都是high active,然后pclk_sample 基本上都是rising

    设备树哪些必须要配置

    关于ar0230为什么vs hs 都是高有效?

    ar0230是一个桥接芯片并不是camera, 见手册第23页

    当rkcif_dvp 成功链接后media拓扑长啥样?

    这里的source(虽然是BT656的):rk3568制冷项目驱动开发流程汇总(只适用于部分模块CIF DVP等,自用)

    第二个参考,虽然是rv1126的,但完整的展现了既有rkcif又有isp的情况下的拓扑(主要是知道哪个video设备是哪个产生的,哪个是裸的,哪个是经过处理的)
    media-ctl 工具打印media control框架下media设备节点拓扑结构
    第三个参考:

    第四个参考:
    (Rk的wiki,虽然是ISPv1)Rockchip-isp1

    24/01/26

    subdev-formats大全-kernel.org

    最后发现是同步信号反了,改了下就能capture了.

    摄像出现问题

    当摄像头频率上去后出现条纹

    考虑可能是供电不足,原因参考
    OV2640图像出现细小条纹问题

    拍照偏绿

    capture过快,自动白平衡还没适应过来.
    [讨论] OV2640 拍照偏绿的问题 请求帮助

    RTSP推流参考 以及rknpu等等

    RTSP 推流
    mpp,编码这些还有推理这些之后再研究了

  • 【每周学习摘要20(24/07/25-24/07/31)】

    在新的buildroot(2302)上面交叉编译Mplayer-1.5

    ./configure --cc=arm-rockchip830-linux-uclibcgnueabihf-gcc --enable-cross-compile --strip=arm-rockchip830-linux-uclibcgnueabihf-strip --target=arm-linux --enable-alsa --enable-fbdev --prefix=/home/ztn/Embedded/RK/luckfox-pico/sysdrv/source/buildroot/buildroot-2023.02.6/output/target/usr --extra-ldflags=-L/home/ztn/Embedded/RK/luckfox-pico/sysdrv/source/buildroot/buildroot-2023.02.6/output/host/arm-buildroot-linux-uclibcgnueabihf/sysroot/usr/lib --extra-cflags=-I/home/ztn/Embedded/RK/luckfox-pico/sysdrv/source/buildroot/buildroot-2023.02.6/output/host/arm-buildroot-linux-uclibcgnueabihf/sysroot/usr/include

    然后

    make -j && make install

    buildroot的output下面的host/sysroot 是包含include和lib的sysroot,全部由交叉编译器生成,所以不用担心和ubuntu-base的一样,生成的binary(例如glibc)源头的编译器和目前使用的编译器不一致.
    我觉得有必要学习LFS(Linux from scratch), 这样就能知道glibc或ulibc怎么编译的,包括核心组件比如ls, pwd这些,看8. Chapter 5: Compiling a Cross-Toolchain – How to build Linux From Scratch (LFS) 12.1 Tutorial

    conda更新后crash

    C:\Users\tz61>conda activate
    Traceback (most recent call last):
      File "D:\miniconda3\Lib\site-packages\conda\exception_handler.py", line 18, in __call__
        return func(*args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^
      File "D:\miniconda3\Lib\site-packages\conda\cli\main.py", line 96, in main_sourced
        from ..base.context import context
      File "D:\miniconda3\Lib\site-packages\conda\base\context.py", line 31, in <module>
        from ..common._os.linux import linux_get_libc_version
      File "D:\miniconda3\Lib\site-packages\conda\common\_os\__init__.py", line 8, in <module>
        from .windows import get_free_space_on_windows as get_free_space
      File "D:\miniconda3\Lib\site-packages\conda\common\_os\windows.py", line 11, in <module>
        from ctypes import (
      File "D:\miniconda3\Lib\ctypes\__init__.py", line 8, in <module>
        from _ctypes import Union, Structure, Array
    ImportError: DLL load failed while importing _ctypes: 找不到指定的模块。
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "D:\miniconda3\Scripts\conda-script.py", line 12, in <module>
        sys.exit(main())
                 ^^^^^^
      File "D:\miniconda3\Lib\site-packages\conda\cli\main.py", line 128, in main
        return conda_exception_handler(main, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "D:\miniconda3\Lib\site-packages\conda\exception_handler.py", line 388, in conda_exception_handler
        return_value = exception_handler(func, *args, **kwargs)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "D:\miniconda3\Lib\site-packages\conda\exception_handler.py", line 21, in __call__
        return self.handle_exception(exc_val, exc_tb)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "D:\miniconda3\Lib\site-packages\conda\exception_handler.py", line 52, in handle_exception
        from .exceptions import (
      File "D:\miniconda3\Lib\site-packages\conda\exceptions.py", line 31, in <module>
        from .models.channel import Channel
      File "D:\miniconda3\Lib\site-packages\conda\models\channel.py", line 23, in <module>
        from ..base.context import Context, context
      File "D:\miniconda3\Lib\site-packages\conda\base\context.py", line 31, in <module>
        from ..common._os.linux import linux_get_libc_version
      File "D:\miniconda3\Lib\site-packages\conda\common\_os\__init__.py", line 8, in <module>
        from .windows import get_free_space_on_windows as get_free_space
      File "D:\miniconda3\Lib\site-packages\conda\common\_os\windows.py", line 11, in <module>
        from ctypes import (
      File "D:\miniconda3\Lib\ctypes\__init__.py", line 8, in <module>
        from _ctypes import Union, Structure, Array
    ImportError: DLL load failed while importing _ctypes: 找不到指定的模块。

    解决方法
    ImportError: DLL load failed while importing _ctypes: Can’t find specified module.
    我从python3.9的Library/bin下面拷贝了ffi.dll ffi-7.dll到miniconda3下面的Library/Bin就好了,不知道有没有什么别的隐患

    Allegro 关于via 和焊盘未连接抑制

    1. 检查pad有没有勾选
    2. 检查cross-section Editor(Ctrl-2)有没有勾选 Unused pin suppression, unused Via suppression, 还有底下的Dynamic unused pads suppression
    3. 检查Hole 到Shape的规则,有可能比Shape到Pad的距离还大(

      Rv1106画板心得

      一定要检查这个从PADS转Allegro 或者是从嘉立创封装转AD转Allegro 它的焊盘有没有paste和solder层,以及PADS转过来的pads默认是bb via,然后嘉立创焊盘有时候抽风,阻焊层会很大,注意一下
      Allegro pcb文件大小和设计的画布大小有关系,所以尽量缩小否则文件会上几百兆 source:Allegro brd文件大小优化方向参考

  • 【每周学习摘要19(24/06/29-24/07/06)】

    瑞芯微相关调试

    DVP摄像头(RK CIF)

    直接看 Rockchip_Driver_Guide_VI_CN_v1.1.3(Driver)文档和Rockchip_Development_Guide_ISP21_CN_v2.1.1(Application)
    注意mipi_csi2里面的2指的并非有两个设备而是这个设备就叫这个名字.
    然后关于数据链路,mipi csi摄像头可以经过dphy直接进入isp(绕过rkcif)(参考tspi-rk3566)
    rk3568mipi摄像头调试(gc2385 + gc2053)
    Rockchip-isp1(仅供参考,老ISP平台)
    Rockchip Image Signal Processor (rkisp1)(仅供参考,老ISP平台)
    基于瑞芯微平台cif接口dvp相机的视频接入(ov2640、rv1126为例)
    瑞芯微RK3588驱动配置之DVP并口摄像头1

    蓝牙模块(AP6212 Bluetooth4.0+wifi4.0)/(AP6256 BT5.0)

    7. Debian使用蓝牙(播放音乐)
    Rockchip RK3399 – WiFi AP6356驱动
    ap6212中串口蓝牙在linux下的使用记录
    使用AP6210B蓝牙模块记录(2016-02-18)
    郁闷,没有搞定 Ubuntu下用btstack协议栈驱动 RTL8723BS
    救命!linux平台的蓝牙驱动怎么搞?AP6212的
    WIFI / BT 驱动之—设备树配置
    [Linux驱动炼成记] 06-博通WIFI模组AP6212配置
    23. 板载蓝牙

    红外 NEC格式 IR

    RK3399教程:PWM之IR调试
    RK3568平台 (input篇)IR红外遥控器

    RV1103 开启framebuffer console

    先去Devices drivers -> Character devices->Virtual terminal 开启
    然后Devices drivers -> Graphics support -> Console display driver support 开启

    linux终端反选字符

    echo -e "\033[7mABCD\033[0m" > /dev/tty0
    控制台\033方式设置字体颜色

    Linux SPI 驱动下的Chip Select以及reg的问题

    硬件SPI控制器

    即SoC(例如RV1106)上面有这个SPI 控制器外设,那么平台设备驱动加载到对应的地址
    此时该节点下的spi设备的reg 0即为默认的cs0,reg 1 即为默认的cs1
    如果指定了cs-gpio,意思是可以用GPIO管脚扩充该spi控制器的cs引脚

    cs-gpios:
        description: |
          GPIOs used as chip selects.
          If that property is used, the number of chip selects will be
          increased automatically with max(cs-gpios, hardware chip selects).
    
          So if, for example, the controller has 4 CS lines, and the
          cs-gpios looks like this
            cs-gpios = <&gpio1 0 0>, <0>, <&gpio1 1 0>, <&gpio1 2 0>;
    
          Then it should be configured so that num_chipselect = 4, with
          the following mapping
            cs0 : &gpio1 0 0
            cs1 : native
            cs2 : &gpio1 1 0
            cs3 : &gpio1 2 0

    source
    这种情况下,cs-gpio的field中<0>代表原生的cs0,那么对应的reg要根据其在cs-gpio的顺序确定

    软件SPI控制器

    即为mosi miso cs 都为gpio控制

    Example:
    
        spi {
            compatible = "spi-gpio";
            #address-cells = <0x1>;
            ranges;
    
            sck-gpios = <&gpio 95 0>;
            miso-gpios = <&gpio 98 0>;
            mosi-gpios = <&gpio 97 0>;
            cs-gpios = <&gpio 125 0>;
            num-chipselects = <1>;
    
            /* clients */
        };
    

    source

  • 【每周学习摘要18(24/06/22-24/06/28)】

    关于UEFI-EDK

    现代 64 位操作系统开发(一):Cmake 构建、UEFI 启动、GRUB 引导、frame buffer 文字绘制

    接网线

    参考:
    Understanding Ethernet Patch Cords in Modern Networks
    Fiber Optic Cabling Solutions
    See also
    Video【科普】T568a vs T568b
    Can you use a straight-through cable to connect two computers?
    百兆100Base-TX只需要用到12,36
    不管是交叉线(一边568A一边568B)和直通线(两边都是568A或568B),45和78的线序都不会变
    以前有人说两个电脑直连必须交叉线,现在看样子好像也不用.
    然后是,如果距离短,甚至不用管线序,两边一样就行,但这样干扰大(打个比方RX和TX互为双绞线那就很糟了)
    中心抽头接100nF,然后内部高压接电容接地

    BusyBox Init

    kernel启动完毕后会调用busybox的/sbin/init, 然后读取/etc/inittab/etc/init.d/执行所有文件

    关于设备树device tree 里reg 以及@是什么

    Linux DTS(Device Tree Source)设备树详解之一(背景基础知识篇)

    RKNN同时跑两个模型

    [C++ API] 如何使用rknn_init初始化多个模型

    Luckfox-pico

    spi启动的镜像和sd启动的镜像,启动参数不同,需要重新编译(env.img不同)

    pinctrl-0 -1的意思

    Pinctrl子系统之一了解基础概念

    pinctrl-0 pinctrl-1 pinctrl-2 .....表示了该设备的一个个状态,这里我们定义了三个pinctrl-0 pinctrl-1 pinctrl-2,
    数字0、1、2就是pinctrl-names中对应的字符串数组的index。其中pinctrl-0就是“sleep”状态,
    pinctrl-1就是“default”状态,pinctrl-2就是“idle”状态。
    而xxx_state_sleep,xxx_state_default,xxx_state_idel就是驱动具体的pin配置项了,需要在pinctrl设备节点处定义

    VM-ware和hyper-V共存办法

    喜大普奔!Hyper-V 和 VMWare 终于可以无缝共存、同时运行了!

    WSA安装

    Install Windows Subsystem for Android on Windows 11 non Insider

  • 【每周学习摘要17(23/02/19-24/02/25)】

    Windows原生编译openssl 脚本

    :: must be executed at the same directory as root of this project
    :: need to install StrawBerry Perl and NASM, then fill in those two environment variables.
    set StrawBerry=D:\Strawberry
    set NASM_dir=D:\NASM
    set JOM_dir=D:\Qt\jom
    :: below no need to read
    set StrawBerry_dir=%StrawBerry%\c\bin;%StrawBerry%\perl\bin;%StrawBerry%\perl\site\bin
    set PATH=%NASM_dir%;%StrawBerry_dir%;%JOM_dir%;%PATH%
    :: Refer to https://stackoverflow.com/questions/75869012/unable-to-build-my-c-project-with-jom-qmake-problem
    :: Compiler said "If several cl.exe write in the same file .PDB, use /FS"
    set CFLAGS=/FS 
    set CXXFLAGS=/FS
    :: use call otherwise the below commands will not be executed
    call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" x64 10.0.18362.0 -vcvars_ver=14.0
    perl Configure --prefix=%cd%\openssl_build_output
    jom -j32
    jom test -j32
    :: I don't know why but jom can't read the prefix 
    nmake install -j32

    Reference

    How to Build OpenSSL, zlib, and cURL libraries on Windows
    Notes for Windows platforms – openssl

    Windows下编译ffmpeg(Msvc+msys2)

    时效性声明

    本文使用的版本为ffmpeg n6.1.1, vcvarsall.bat 来源于Visual Studio2022,
    编译器为msvc v140

    具体步骤

    先随便打开一个cmd
    -vcvars_ver=14.0 是为了用msvc v140(VS2015)编译
    -use-full-path 是为了继承cmd里的环境变量到msys2 console里

    "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" x64 -vcvars_ver=14.0
    D:\msys64\msys2_shell.cmd -use-full-path

    到了msys2后安装git cmp make nasm

    pacman -S git diffutils make nasm pkg-config

    因为msys2自带的link和msvc里的link会冲突,所以修改原来的link名称

    mv /usr/bin/link /usr/bin/lin

    反正这个link基本用不到(msys2环境是隔离的,生成的库不能直接被msvc链接,还不如mingw64环境,那个至少还能生成可被msvc链接的东西)
    然后克隆和配置,默认安装到/usr/local/ffmpeg-v6.1.1

    git clone https://github.com/FFmpeg/FFmpeg.git --depth 1 -b n6.1.1 ffmpeg-v6.1.1
    cd ffmpeg-v6.1.1
    ./configure --toolchain=msvc --prefix=/usr/local/ffmpeg-v6.1.1

    warning C4828: 文件包含在偏移 0x1d9 处开始的字符,该字 符在当前源字符集中无效(代码页 65001)。make: *** Deleting file ‘libavcodec/msvideo1enc.o’

    可能会遇到编译器信息导致的编码错误(有些人cmd打开默认code page是936)
    直接随便改一下或者根据cl.exe给出的,编辑config.h

    #define CC_IDENT "用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.00.24247.2 版"

    最后

    make -j32
    make install

    Reference

    Windows + MSVC环境编译ffmpeg – 罗均 – 知乎
    FFmpeg wiki:CompilationGuide/MSVC

    关于一直说的MSVC CRT是个什么东西

    https://learn.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=msvc-170

    Orcad Capture CIS

    调整原理图页面默认字体,以及模板默认字体

    Mingw-w64下链接动态库的细节

    比如我想链接一个库-lA,在windows下有import library和static libraray之分,其中import library在mingw下通常以dll.a结尾,而statlic library则直接以.a结尾

    打个比方usb-1.0,

    libusb-1.0.a  libusb-1.0.dll.a

    那么如果-L库路径包含了两个相同的会如何呢
    请阅读binutils关于Win32的官方文档
    这里面说了
    For instance, when ld is called with the argument ‘-lxxx’ it will attempt to find, in the first directory of its search path,

    libxxx.dll.a
    xxx.dll.a
    libxxx.a
    xxx.lib
    libxxx.lib
    cygxxx.dll (*)
    libxxx.dll
    xxx.dll

    所以是默认先找动态库的导入库进行链接的
    其中还有有趣的 direct linking to a dll, 这是说不需要导入库,ld直接连接到一个dll上

    如何让CMake找到QT

    source
    For find_package to be successful, CMake must find the Qt installation in one of the following ways:

    • Set your CMAKE_PREFIX_PATH environment variable to the Qt 5 installation prefix. This is the recommended way.
    • Set the Qt5_DIR in the CMake cache to the location of the Qt5Config.cmake file.
      但是下面那种办法只能找到qt core
      还需要设置一堆比如

      所以说, recommended approach is to set the CMake cache variable CMAKE_PREFIX_PATH to include the Qt 6 installation prefix

      cmake -GNinja -B build -DCMAKE_PREFIX_PATH=
      /Users/tz61/Qt/6.5.3/macos

      更快地编译QT6

      QT在6以后可以用cmake编译源码了,source

      Windows下CMake可以默认从C:/Qt下找到Qt各个版本

      在linux交叉编译openocd参考

      source

      MSVC BuildTools 老版本下载

      更新:MSVC老编译器可以从VS2022里面下载,没必要单独再搞个BuildTools
      2017: https://aka.ms/vs/15/release/vs_buildtools.exe
      2019: https://aka.ms/vs/16/release/vs_buildtools.exe
      2022: https://aka.ms/vs/17/release/vs_buildtools.exe
      source
      MSVC 14.16 是runtime 版本,10.0.17763.0是Windows SDK版本,19.16.27051是Compiler版本

  • 【每周学习摘要16(23/01/20-24/01/26)】

    QT

    把AUTOUIC开启后
    cmake通过add进executable的file中的include 语句判断ui文件
    其中在include同级目录或者CMAKE_AUTOUIC_SEARCH_PATHS变量下寻找该ui文件
    具体见https://cmake.org/cmake/help/latest/variable/CMAKE_AUTOUIC_SEARCH_PATHS.html#variable:CMAKE_AUTOUIC_SEARCH_PATHS

    Vscode 调试Makefile

    第一个方式,直接修改launch.json

    这个文件从ece220/mps/mp10/.vscode/.launch.json

    "configurations": [
            {
                "name": "(gdb) Launch",
                "type": "cppdbg",
                "request": "launch",
                "program": "${workspaceFolder}/mp10",
                "args": [
                    "graph",
                    "requests",
                    "0"
                ],
                "stopAtEntry": false,
                "cwd": "${fileDirname}",
                "environment": [],
                "externalConsole": false,
                "MIMode": "gdb",
                "setupCommands": [
                    {
                        "description": "Enable pretty-printing for gdb",
                        "text": "-enable-pretty-printing",
                        "ignoreFailures": true
                    },
                    {
                        "description": "Set Disassembly Flavor to Intel",
                        "text": "-gdb-set disassembly-flavor intel",
                        "ignoreFailures": true
                    }
                ]
            }
        ]

    第二个方式,通过Makefile插件

    然后打开workspacesettings.json,修改makefile.launchConfigurations

    {
        "makefile.launchConfigurations": [
            {
                "cwd": "/home/ztn/Documents/cs225sp24/lab_debug",
                "binaryPath": "/home/ztn/Documents/cs225sp24/lab_debug/sketchify",
                "binaryArgs": ["in_111","sddsd"]
            }
        ]
    }

    stm32重定向printf

    需要修改fputc,或者write, 因为不同库实现不一样,而且gcc的newlib版本不同,新版本需要修改write

  • 【每周学习摘要15(23/12/30-24/01/05)】

    ubuntu-base 不能获取串口的原因

    卡在serial getty’
    原因:没有安装udev
    source

    mplayer 播放

    mplayer -vo fbdev2:/dev/fb1 -vf scale=240:135 -geometry 0:50 -fps 30 -ao alsa:device=hw=0.0 badapple.mp4
    alsa那里 hw=0.0 可以用aplay -l 查看card:device
    如果是用drm产生的fb需要用fbdev2:/dev/fb0,其他比如fbtft的就用fbdev:/dev/fb0

    mpg123使用

    mpg123 -o alsa:hw:0,0 mican*\ -\ Deadline.mp3
    同理

    ubuntu-base移植libmali

    参考仓库mirror
    其中我看到官方rk的buildroot镜像里面,libEGL,libgbm的大小都是一样的里面有libmali_hook.so.1的调用关系
    现在知道libmali_hook怎么生成(在刚才那个仓库的hook文件夹下),
    然后libegl,libgbm什么的大小竟然都一样

    (base) ➜  lib ls -l libgbm.so.1 libEGL.so.1 libGLESv1_CM.so.1 libGLESv2.so.2 
    -rwxr-xr-x 1 root root 5784  9月 14 17:01 libEGL.so.1
    -rwxr-xr-x 1 root root 5784  9月 14 17:01 libgbm.so.1
    -rwxr-xr-x 1 root root 5784  9月 14 17:01 libGLESv1_CM.so.1
    -rwxr-xr-x 1 root root 5784  9月 14 17:01 libGLESv2.so.2
    (base) ➜  

    补充:这些libegl,libgbm什么的都是一些wrapper库,具体创建过程在这个脚本里
    meson.build
    我到时候解读一下然后换成用普通命令创建,不用meson

  • 【每周学习摘要14(23/12/23-23/12/29)】

    手动编译最新版本的rockchip bsp linux

    CrossCompile Toolchain

    首先交叉编译工具链可以从linaro下载,这个无所谓

    boot.img

    boot.img是rockchip专有镜像格式 ,需要使用他们kernel仓库的Makefile里面的命令进行打包,具体原理暂时不清楚。
    先把泰山派的设备树拷贝到kernel/arch/arm64/dts/rockchip/下面

    export PATH="$PATH:/home/ztn/Embedded/Allwinner/Allwinner-H616/toolchains/bin"
    ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu- make tspi-rk3566-user-v10-linux.img -j32

    然后可以得到boot.img,这个文件里面包含了内核镜像文件和设备树tspi-rk3566-user-v10-linux.dtb

    u-boot.itb

    这个文件是一个复合体
    需要py2环境
    然后利用rkdeveloptool,先加载bootloader到内存,然后烧录,然后再烧录boot.img,u-boot.itb

    ZYNQ EBAZ4205

    为什么正点原子的镜像启动不了,我猜是启动参数(比如DDR配置不一样)所以说开不起来。已经改了电阻了也不行。
    别慌,明天自己编译一遍

  • 【每周学习摘要13(23/12/16-23/12/22)】

    RK3566 Drm Panel 驱动配置

    1.dt-binding解读-2022-03-24 RK3566 MIPI屏 调试记录,panel-init-sequence 命令格式介绍
    2.配置生成工具-original_mipi_init_sequence-to-rk_dts_panel_init_sequence-convert Public
    panel节点是挂载在dsi0节点下面,如果对应spi屏幕的drm驱动,则是将panel节点挂载在spi0节点下面,参考嵌入式Linux使用TFT屏幕:使用树莓派4B的MIPI-DSI接口点亮ST7701S屏幕

    关于怎么解读屏幕参数和时序,然后填写dts,参考RK3588-MIPI屏幕调试笔记:RK3588-MIPI-DSI之屏参配置
    再具体的话,可以参考rockchip官方bsp仓库-drivers/gpu/drm/panel/panel-simple.c
    arch/arm64/boot/dts/rockchip

    eDP屏幕相关

    RK3568 EDP接口调试

    RockChip编译教程

    其实可以单独下载github上rockchip-linux的官方bsp linux,u-boot仓库单独编译
    也可以设置上次那个H616里面的工具链
    但是在make.sh的第273行需要把none加进去
    然后需要clone rkbin到同级目录

    CROSS_COMPILE_ARM64=$(cd `dirname ${CROSS_COMPILE_ARM64}`; pwd)"/aarch64-none-linux-gnu-"

    具体操作可以看toybrick的仓库里面的make.sh,也可以使用官方推荐的
    比如
    软件开发/U-Boot

    具体编译

    Rockchip-linux kernel-5.10

    git clone https://github.com/rockchip-linux/kernel.git -b develop-5.10 --depth 1
    cd kernel
    ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu- make rockchip_linux_defconfig
    ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu- make -j32

    Rockchip-linux uboot

    直接根据toybrick的进行编译,clone 他们自己的编译工具链后然后照做

    ./make.sh rk3566

    rkdevelop-tool

    需要切换到gcc-7/g++-7编译
    具体操作自己看rkdeveloptool

    在rk3566上编译taisei-v1.3

    没什么好说的,甚至可以用自带的SDL
    之前我以为自带的SDL有bug,其实是因为可能在mingw上面编译的缘故,编译完了有些东西针对mingw平台的没开,然后就启动不了窗口,只能通过pacman安装
    想不到1G内存+tf卡这种丐版配置都能编译SDL2+taiseiv1.3
    但是taisei和extreme-tux-tracer这两个游戏,以及glxinfo监测的时候都只察觉到了llvmpipe 这个软件渲染器。
    但是glmark2-es2就可以完美利用GLES2
    后来我才知道原来GLES2 API不一定需要EGL作为后端,也可以在GLX上面使用,然后glmark2-es2就是在X11上面通过GLX使用了GLES2的API
    taisei和etr估计在链接的时候就用的是gl的API,所以fallback了到llvmpipe上面的api(mesa库提供的)
    然后他们在运行的时候会显示

    libGL error: unable to load driver: rockchip_dri.so
    libGL error: driver pointer missing
    libGL error: failed to load driver: rockchip

    但是跑glmark2-es2就不会出现这些
    根据那个Richardn2002兄弟的在stm32MP157上的源码STM32MP157F-DK2/blob/main/src/gl-test.c
    可以知道,程序链接时需要链接GLESv2库而非GL,然后gl头文件需要用GLES2/gl2.h而非GL/gl.h
    看SDL2的做法好像是用他们自己的头文件套了一层?这个有待研究。先准备math241 mid3先
    然后找到的Xorg加载GLX的流程:Firefly3568-libGL error: failed to load driver: rockchip
    3588上运行qt报错,请指教
    GPU/Driver/libGL error on Rock 4C plus on Debian

    GL4ES

    将gl call 转换成gles call,且自己创建一个context。
    用的时候把编译产生的libGL.so.1放到LD_LIBRARY_PATH就行。
    然后只能运行gles2.0
    然后可以玩etr但是很鬼畜,玩不了taisei

    查看GPU使用率

    RK查看gpu占用率方法

    cat /sys/devices/platform/fde60000.gpu/devfreq/fde60000.gpu/load

    转接板

    st7701的屏幕:(0.5mm pitch),fl7703np(0.3mm pitch)

    fl7703np转接板

    排线 31pin 0.3mm 3块钱一根
    31pin 0.3mm 排座 0.3一个,要两个
    然后是3.3V转1.8V点LDO芯片,芯片准备用ME6206A18XG,输出电压1.8V,那个屏幕没说需要多大电流,然后SOT23-3封装最大功率300mW,所以没关系的。主要这个也便宜
    这个转接板成本加起来可能就5块钱,所以还好
    注意转接板要连接
    泰山派上面的屏幕背光驱动芯片是SY7201,电流计算公式是I=0.2V/R
    所以说驱动st7701s 20mA需要200mV/20mA=10Ohm作为反馈电阻,可以买两个20欧的电阻并联或者直接一个10欧电阻