关于瑞芯微的一些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

【每周学习摘要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欧电阻