嵌入式ARM64 基于RK3588原生SDK添加用戶配置選項./build lunch debian

1 背景

????????在我們正常拿到SDK后會有一些配置選項,在使用./build.sh lunch之后會輸出一些defautconfig讓我們選擇,瑞芯微的原廠sdk會提供一些主板的配置選項,但是我們的如果是一塊新的主板就需要添加自己的配置選項,本文就討論如何來添加自己的板卡配置選項。

2 配置介紹

????????正常我們配置一套linux系統需要配的目標有uboot,Linux,rootfs,一般情況uboot我們不需要去管,這都是sdk里面做好的,不需要怎么修改。我們需要配的是Liunx的內核和rootfs這兩部分。

????????以我使用的rk3588_linux6.1_release_v1.2.0_20241220這套sdk為例,使用./build lunch會出現下列選項:

./build.sh lunch
Pick a defconfig:1. rockchip_defconfig
2. rockchip_rk3588_evb1_lp4_v10_defconfig
3. rockchip_rk3588_evb7_v11_defconfig
4. rockchip_rk3588_ipc_evb1_v10_defconfig
5. rockchip_rk3588_multi_ipc_evb1_v10_defconfig
6. rockchip_rk3588s_evb1_lp4x_v10_defconfig
Which would you like? [1]: 

這些選項都是瑞芯微官方主板的一些配置,如果我們直接在這些官方配置里面去改回比較亂,很容易搞混,目標是添加自己的配置又不想去修改原本的。想做到這一點是需要我們去搞懂他這個sdk自動化編譯的邏輯。

????????在Rockchip提供的Android/LinuxSDK里,頂層通常有一個build.sh腳本,用來封裝編譯流程,類似于AndroidAOSP的lunch+make。它的主要功能包括:設置環境變量、調用lunch(選擇目標平臺/產品/編譯模式)、調用make或m執行編譯、打包生成最終的固件(boot.img,system.img,update.img等)。

????????但是我們打開build.sh查看后發現沒有lunch這個函數,實際上現在都是通過build-hook機制,在main()有一句run_build_hooks init $OPTIONS實際執行的相當于是run_build_hooks init lunch,然后執行run_hooks "$RK_BUILD_HOOK_DIR" init lunch,這里RK_BUILD_HOOK_DIR=device/rockchip/common/build-hooks相當于run_hooks對這個目錄下的所有腳本進行遍歷,對所有的腳本執行hook_check看是否支持init lunch命令

run_hooks()
{DIR="$1"shift   # 參數變成:init lunch# Prefer chips' hooks than the common onesfor dir in "$RK_CHIP_DIR/$(basename "$DIR")/" "$DIR"; do[ -d "$dir" ] || continuefor hook in $(find "$dir" -maxdepth 1 -name "*.sh" | sort); do# Ignore unrelated hookshook_check "$hook" "$1" "$2" || continueif ! "$hook" $@; then...fidonedone
}hook_check()
{case "$2" ininit | pre-build | build | post-build) ;;*) return 0 ;;esacCMDS="$(sed -n \"s@^RK_${2//-/_}_CMDS[^ ]*\(.*\)\" # $(realpath "$1")\$@\1@ip" \"$RK_PARSED_CMDS")"if echo "$CMDS" | grep -wq default; thenreturn 0fioption_check "$CMDS" "$3"
}

hook_check()這里關鍵在 $RK_PARSED_CMDS,它是 output/.parsed_cmds 文件,里面記錄了哪些 hook 腳本支持哪些命令。比如 mk-config.sh 里聲明了INIT_CMDS="chip defconfig lunch [^:]*_defconfig ..."?這會被解析進 $RK_PARSED_CMDS,最后 hook_check()去執行:device/rockchip/common/scripts/mk-config.sh init lunch ,在mk-config.sh的末尾有init_hook $@,相當于執行?init_hook?init lunch,在init_hook里面有lunch|defconfig) shift; choose_defconfig $@ ;; 相當于執行choose_defconfig lunch這就進入了選擇defconfig菜單。

rockchip_defconfigs()
{cd "$RK_CHIP_DIR"ls rockchip_defconfig 2>/dev/null || truels *_defconfig | grep -v rockchip_defconfig || true
}choose_defconfig()
{DEFCONFIG_ARRAY=( $(rockchip_defconfigs | grep "$1" || true) )DEFCONFIG_ARRAY_LEN=${#DEFCONFIG_ARRAY[@]}case $DEFCONFIG_ARRAY_LEN in0)error "No available defconfigs${1:+" for: $1"}"return 1;;1)	DEFCONFIG=${DEFCONFIG_ARRAY[0]} ;;*)if [ "$1" = ${DEFCONFIG_ARRAY[0]} ]; then# Prefer exact-matchDEFCONFIG="$1"elsemessage "Pick a defconfig:\n"echo ${DEFCONFIG_ARRAY[@]} | xargs -n 1 | \sed "=" | sed "N;s/\n/. /"local INDEXread -p "Which would you like? [1]: " INDEXINDEX=$((${INDEX:-1} - 1))DEFCONFIG="${DEFCONFIG_ARRAY[$INDEX]}"fi;;esacswitch_defconfig $DEFCONFIG
}INIT_CMDS="chip defconfig lunch [^:]*_defconfig olddefconfig savedefconfig menuconfig config default"
init_hook()
{case "${1:-default}" inchip) shift; choose_chip $@ ;;lunch|defconfig) shift; choose_defconfig $@ ;;*_defconfig) switch_defconfig "$1" ;;olddefconfig | savedefconfig | menuconfig)prepare_configmake $1;;config)prepare_configmake menuconfigmake savedefconfig;;default) prepare_config ;; # End of init*) usage ;;esac
}source "${RK_BUILD_HELPER:-$(dirname "$(realpath "$0")")/../build-hooks/build-helper}"init_hook $@

choose_defconfig()會通過rockchip_defconfigs()搜集.chip目錄下后綴為_defconfig的文件放到DEFCONFIG_ARRAY數組,然后打印出來,當我們選擇之后會通過switch_defconfig()函數將配置文件保存到output/.config里面。

3 增加配置

? ? ? ? 我們先查看一下.chip下面有什么文件,我們先用ls -la命令查看一下device/rockchip下面有哪些目錄:

$ ls device/rockchip/ -la
total 24
drwxrwxr-x  5 lubancat lubancat 4096 Sep  5 02:31 .
drwxrwxr-x  3 lubancat lubancat 4096 Sep  3 04:10 ..
lrwxrwxrwx  1 lubancat lubancat   13 Sep  5 02:31 .chip -> .chips/rk3588
drwxrwxr-x  3 lubancat lubancat 4096 Sep  3 04:10 .chips
drwxrwxr-x 13 lubancat lubancat 4096 Sep  3 04:10 common
drwxrwxr-x  2 lubancat lubancat 4096 Sep  3 04:10 .git
-rw-rw-r--  1 lubancat lubancat   24 Sep  3 04:10 .gitignore
lrwxrwxrwx  1 lubancat lubancat   13 Sep  5 02:31 rk3588 -> .chips/rk3588

經過查看發現.chip和rk3588這兩個目錄都是鏈接到.chips/rk3588里面的,所以我們真正需要關注是.chips/rk3588目錄:

$ ls device/rockchip/.chips/rk3588/ -l
total 48
-rw-rw-r-- 1 lubancat lubancat 1708 Sep  3 04:10 amp_linux.its
-rw-rw-r-- 1 lubancat lubancat 1365 Sep  3 04:10 amp_mcu.its
-rw-rw-r-- 1 lubancat lubancat 1673 Sep  3 04:10 boot4recovery.its
-rw-rw-r-- 1 lubancat lubancat 1430 Sep  3 04:10 boot.its
-rw-rw-r-- 1 lubancat lubancat  477 Sep  3 04:10 parameter-ab.txt
-rw-rw-r-- 1 lubancat lubancat  539 Sep  3 04:10 parameter.txt
lrwxrwxrwx 1 lubancat lubancat   34 Sep  3 04:10 rockchip_defconfig -> rockchip_rk3588_evb7_v11_defconfig
-rw-rw-r-- 1 lubancat lubancat   64 Sep  3 04:10 rockchip_rk3588_evb1_lp4_v10_defconfig
-rw-rw-r-- 1 lubancat lubancat   60 Sep  3 04:10 rockchip_rk3588_evb7_v11_defconfig
-rw-rw-r-- 1 lubancat lubancat  103 Sep  3 04:10 rockchip_rk3588_ipc_evb1_v10_defconfig
-rw-rw-r-- 1 lubancat lubancat  112 Sep  3 04:10 rockchip_rk3588_multi_ipc_evb1_v10_defconfig
-rw-rw-r-- 1 lubancat lubancat   66 Sep  3 04:10 rockchip_rk3588s_evb1_lp4x_v10_defconfig
-rw-rw-r-- 1 lubancat lubancat 1429 Sep  3 04:10 zboot.its

?這里有很多代_defconfig后綴的文件,我們打開一個看一下:

$ vi device/rockchip/.chips/rk3588/rockchip_rk3588_evb7_v11_defconfig 
RK_KERNEL_DTS_NAME="rk3588-evb7-v11-linux"
RK_USE_FIT_IMG=y

?這里其實很簡單就是指定了一個RK_KERNEL_DTS_NAME變量,這個變量表明了要編譯的內核配置文件。我們新建一個配置文件,將剛才的那個文件改個名字就行了,然后將RK_KERNEL_DTS_NAME改為"yz3588-aiot-v10"

$ cp device/rockchip/.chips/rk3588/rockchip_rk3588_evb7_v11_defconfig device/rockchip/.chips/rk3588/rockchip_rk3588_yeezi_v10_defconfig
$ vi device/rockchip/.chips/rk3588/yz3588_defconfig 
RK_KERNEL_DTS_NAME="yz3588-aiot-v10"
RK_USE_FIT_IMG=y

這個時候我們再執行./build.sh lunch會發現多了一個選項:

$ ./build.sh lunch
Log colors: message notice warning error fatalLog saved at /home/lubancat/rk3588/rk3588_linux6.1_release_v1.2.0_20241220/output/sessions/2025-09-05_02-51-27
Pick a defconfig:1. rockchip_defconfig
2. rockchip_rk3588_evb1_lp4_v10_defconfig
3. rockchip_rk3588_evb7_v11_defconfig
4. rockchip_rk3588_ipc_evb1_v10_defconfig
5. rockchip_rk3588_multi_ipc_evb1_v10_defconfig
6. rockchip_rk3588s_evb1_lp4x_v10_defconfig
7. rockchip_rk3588_yeezi_v10_defconfig
Which would you like? [1]: 

我們的初始配置已經添加成功。

3.1 Linux內核配置

????????現在說一下剛才RK_KERNEL_DTS_NAME這個文件的作用,在Linux內核配置中主要是通過dts文件去配置設備樹,通過設備樹去選擇哪些設備需要打開,哪些需要配什么功能。瑞芯微sdk的設備樹目錄是在kernel/arch/arm64/boot/dts/rockchip/這個目錄下,通過ls查看發現有很多rk3588開頭的dts和dtsi文件

...
-rw-rw-r--   24364 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5.dtsi
-rw-rw-r--     339 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10.dts
-rw-rw-r--    1886 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10-edp.dts
-rw-rw-r--    1890 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10-edp-linux.dts
-rw-rw-r--     337 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10-linux.dts
-rw-rw-r--    9586 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb4-lp4.dtsi
-rw-rw-r--     304 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb4-lp4-v10.dts
-rw-rw-r--     302 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb4-lp4-v10-linux.dts
-rw-rw-r--    5287 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb5-lp4.dtsi
-rw-rw-r--     304 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb5-lp4-v10.dts
-rw-rw-r--     302 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb5-lp4-v10-linux.dts
-rw-rw-r--    9554 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb6-lp4.dtsi
-rw-rw-r--     304 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb6-lp4-v10.dts
-rw-rw-r--     302 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb6-lp4-v10-linux.dts
-rw-rw-r--   21798 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-cam-8x.dtsi
-rw-rw-r--    2710 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-imx415.dtsi
-rw-rw-r--   17498 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-lp4.dtsi
-rw-rw-r--     339 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-lp4-v10.dts
-rw-rw-r--     337 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-lp4-v10-linux.dts
-rw-rw-r--    2038 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-lp4-v10-rk1608-ipc-8x-linux.dts
-rw-rw-r--     345 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-lp4-v11-linux-ipc.dts
-rw-rw-r--     335 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11.dts
-rw-rw-r--   19537 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11.dtsi
-rw-rw-r--    2710 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11-imx415.dtsi
-rw-rw-r--  287281 Sep  3 04:28 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11-linux.dtb
-rw-rw-r--     333 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11-linux.dts
-rw-rw-r--    3657 Sep  3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11-rk628-hdmi2csi.dts
...

通過前面的配置發現defconfig調用的是rk3588-evb7-v11-linux.dts文件,打開這個文件:

#include "rk3588-evb7-v11.dtsi"
#include "rk3588-evb7-v11-imx415.dtsi"
#include "rk3588-linux.dtsi"/ {model = "Rockchip RK3588 EVB7 V11 Board";compatible = "rockchip,rk3588-evb7-v11", "rockchip,rk3588";
};

這個文件調用了三個頭文件,其中rk3588-linux.dtsi是通用的頭文件不需要改,我們選擇rk3588-evb7-v11版本改為自己主板的名字,通過復制原有的配置來進行修改比較簡單,將rk3588-evb7-v11*開頭的文件復制一下得到3個文件,并修改yz3588-aiot-v10-linux.dts文件

$ ls kernel/arch/arm64/boot/dts/rockchip -l
-rw-rw-r-- 1 lubancat lubancat 19537 Sep  5 03:04 yz3588-aiot-v10.dtsi
-rw-rw-r-- 1 lubancat lubancat  2710 Sep  5 03:04 yz3588-aiot-v10-imx415.dtsi
-rw-rw-r-- 1 lubancat lubancat   321 Sep  5 03:12 yz3588-aiot-v10-linux.dts$ vi kernel/arch/arm64/boot/dts/rockchip/yz3588-aiot-v10-linux.dts 
#include "yz3588-aiot-v10.dtsi"
#include "yz3588-aiot-v10-imx415.dtsi"
#include "rk3588-linux.dtsi"/ {model = "Rockchip RK3588 EVB7 V11 Board";compatible = "rockchip,yz3588-aiot-v10", "rockchip,rk3588";
};

這個文件就是我們再defconfig中調用的文件

3.2 Debian配置

? ? ? ? 默認在執行build.sh不選擇系統的時候是指向的是buildroot,如果要改操作系統就需要更改配置,

$ vi device/rockchip/common/scripts/mk-rootfs.sh
build_hook()
{check_config RK_ROOTFS || falseif [ -z "$1" -o "$1" = rootfs ]; thenROOTFS=${RK_ROOTFS_SYSTEM:-buildroot}elseROOTFS=$1fi

我這里改為使用debian系統,所以就需要修改defconfig選項

$ vi device/rockchip/.chips/rk3588/rockchip_rk3588_yeezi_v10_defconfig 
RK_KERNEL_DTS_NAME="yz3588-aiot-linux"
RK_USE_FIT_IMG=y
RK_ROOTFS_SYSTEM_DEBIAN=y

添加RK_ROOTFS_SYSTEM_DEBIAN=y這就打開了debian系統,然后我們進行編譯測試,這里直接使用./build all就可以了,不用單獨選擇./build.sh debian

需要注意,我們在編譯debian的時候可能會報錯:

==========================================Start building rootfs(debian)
==========================================Your live-build doesn't support bookworm
Please replace it:
sudo apt-get remove live-build
git clone https://salsa.debian.org/live-team/live-build.git --depth 1 -b debian/1%20230131
cd live-build
rm -rf manpages/po/
sudo make install -j8

因為SDK的rootfs構建邏輯實際上是基于Debianlive-build來生成rootfs鏡像的,這里提示系統apt源里的live-build版本比較老,不支持DebianbookwormRockchip的mk-rootfs.sh或hook腳本默認使用bookworm來生成rootfs,所以就提示當前live-build版本太舊。

如果使用提示的方法很可能會連不上網,git不到,有一個辦法就是直接下載deb包來解決,注意不要使用太新的軟件包,否則會報extlinux錯誤,我們選擇23年的版本就好了,我在這里也折騰了很久,進入https://ftp.debian.org/debian/pool/main/l/live-build/選擇一個版本:

下載之后執行sudo dpkg -i live-build_20230502_all.deb || sudo apt-get -f install -y進行安裝

3.3 ./build.sh all

到這里所有的配置已經完成,只需要在./build.sh lunch選擇剛自定義的配置rockchip_rk3588_yeezi_v10_defconfig執行./build.sh all就會把所有的uboot linux debian編譯一遍然后自動打包到output/update/update.img

$ ./build.sh all
Using last kernel version(6.1)==========================================Final configs
==========================================
RK_BOOT_FIT_ITS=/home/lubancat/rk3588/rk3588_linux6.1_release_v1.2.0_20241220/device/rockchip/.chip/boot.its
RK_BOOT_IMG=boot.img
RK_BUILDROOT=y
RK_BUILDROOT_CFG=rockchip_rk3588
RK_CHIP=rk3588
RK_CHIP_FAMILY=rk3588
RK_DEBIAN=y
RK_DEBIAN_ARCH=arm64
RK_DEBIAN_BOOKWORM=y
RK_DEBIAN_MIRROR=mirrors.ustc.edu.cn
RK_DEBIAN_VERSION=bookworm
RK_DEFCONFIG=rockchip_rk3588_yeezi_v10_defconfig
RK_EXTRA_PARTITION_NUM=2
RK_EXTRA_PARTITION_STR=oem:oem:/oem:ext4:defaults:normal:auto:@userdata:userdata:/userdata:ext4:defaults:normal:auto:@@@
RK_KERNEL=y
RK_KERNEL_ARCH=arm64
RK_KERNEL_CFG=rockchip_linux_defconfig
RK_KERNEL_DTS=kernel/arch/arm64/boot/dts/rockchip/yz3588-aiot-v10-linux.dts
RK_KERNEL_IMG=kernel/arch/arm64/boot/Image
RK_KERNEL_VERSION=6.1
RK_KERNEL_VERSION_RAW=6.1
RK_LOADER=y
RK_MISC=y
RK_MISC_BLANK=y
RK_OVERLAY=y
RK_OWNER=lubancat
RK_OWNER_UID=1000
RK_PARAMETER=parameter.txt
RK_RECOVERY=y
RK_RECOVERY_CFG=rockchip_rk3588_recovery
RK_RECOVERY_CPIO_GZ=y
RK_RECOVERY_FIT_ITS=/home/lubancat/rk3588/rk3588_linux6.1_release_v1.2.0_20241220/device/rockchip/.chip/boot4recovery.its
RK_RECOVERY_INITRD_TYPE=cpio.gz
RK_ROOTFS=y
RK_ROOTFS_ASYNC_COMMIT=y
RK_ROOTFS_DEBUG_INFO=y
RK_ROOTFS_EXT4=y
RK_ROOTFS_FSTRIM=y
RK_ROOTFS_FSTRIM_INTERVAL=3600
RK_ROOTFS_GENERATE_LOGS=y
RK_ROOTFS_INPUT_EVENT_DAEMON=y
RK_ROOTFS_IRQBALANCE=y
RK_ROOTFS_LD_CACHE=y
RK_ROOTFS_LOG_GUARDIAN=y
RK_ROOTFS_LOG_GUARDIAN_INTERVAL=10m
RK_ROOTFS_LOG_GUARDIAN_LOG_DIRS=/var/log/,/tmp/
RK_ROOTFS_LOG_GUARDIAN_MIN_SIZE=100M
RK_ROOTFS_OVERLAY=y
RK_ROOTFS_STRIP_MODULES=y
RK_ROOTFS_SYSTEM=debian
RK_ROOTFS_TYPE=ext4
RK_ROOTFS_UDEV_RULES=y
RK_SAVE_TRACKED=y
RK_SESSION=2025-09-05_17-48-38
RK_UBOOT_ARCH=arm64
RK_UBOOT_CFG=rk3588
RK_UPDATE=y
RK_USB_ADBD=y
RK_USB_ADBD_SHELL=/bin/bash
RK_USB_ADBD_TCP_PORT=5555
RK_USB_FW_VER=0x0310
RK_USB_GADGET=y
RK_USB_MANUFACTURER=Rockchip
RK_USB_PRODUCT=rk3xxx
RK_USB_VID=0x2207
RK_USE_FIT_IMG=y
RK_WIFIBT=y
RK_WIFIBT_MODULES=ALL_AP
RK_WIFIBT_RTK_AP=y
RK_YOCTO=y
RK_YOCTO_CHROMIUM=y
RK_YOCTO_DISPLAY_PLATFORM=wayland
RK_YOCTO_MACHINE=rockchip-rk3588-evb
RK_YOCTO_USBMOUNT=y

可以看到

RK_DEFCONFIG=rockchip_rk3588_yeezi_v10_defconfig

RK_ROOTFS_SYSTEM=debian

Unpacking /home/lubancat/rk3588/rk3588_linux6.1_release_v1.2.0_20241220/output/linux-headers/linux-headers-aarch64.tar ...
Debian control file:
Package: linux-headers-6.1-arm64
Source: linux-rockchip (6.1)
Version: 6.1-rockchip
Architecture: aarch64
Section: kernel
Priority: optional
Multi-Arch: foreign
Maintainer: Tao Huang <huangtao@rock-chips.com>
Homepage: https://www.kernel.org/
Description: Kbuild and headers for Rockchip Linux 6.1 arm64 configuration
Packing linux-headers-6.1-arm64_aarch64.deb...
Running mk-kernel.sh - linux-headers-aarch64 succeeded.
Running mk-kernel.sh - linux-headers succeeded.
Running 99-all.sh - build_all succeeded.

最后編譯成功,第一次編譯需要很久,還有源要更換一下,我是用的是清華的源。這里我們只是把dts這些配置文件搭建出來,還沒有進行修改,后面會寫一些怎么配置內核的一些方法。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/98423.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/98423.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/98423.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

專為石油和天然氣檢測而開發的基于無人機的OGI相機

專為石油和天然氣檢測而開發的基于無人機的OGI相機基于無人機的 OGI 相機:&#xff08;Optical Gas Imaging&#xff0c;光學氣體成像&#xff09;其實是近幾年油氣、電力、化工等行業里非常熱門的應用方向。什么是 OGI 相機OGI&#xff08;Optical Gas Imaging&#xff09;&am…

iPhone17全系優缺點分析,加持遠程控制讓你的手機更好用!

知名數碼廠商蘋果&#xff0c;不久前已官宣將于北京時間9月10日凌晨1點開啟發布會&#xff0c;主打對于iPhone 17系列產品介紹&#xff0c;并且和以往不同的是&#xff0c;今年會在購物平臺上開啟線上直播&#xff0c;還是很有新意的。9.13全平臺渠道將開啟預售模式&#xff0c…

人工智能-python-深度學習-神經網絡VGG(詳解)

LeNet 系列之后 —— VGG&#xff08;詳解&#xff09;&#xff1a;從原理到 PyTorch 實現 文章目錄LeNet 系列之后 —— **VGG&#xff08;詳解&#xff09;**&#xff1a;從原理到 PyTorch 實現1. VGG 的發展歷史與意義&#xff08;一句話&#xff0b;背景&#xff09;2. VGG…

光伏運維迎來云端革命!AcrelCloud-1200如何破解分布式光伏四大痛點?

在國家“雙碳”目標推動下&#xff0c;分布式光伏正迎來爆發式增長&#x1f31e;。甘肅、吉林、云南等多地政策接連落地&#xff0c;整縣推進屋頂光伏試點如火如荼&#xff01;然而&#xff0c;快速發展的背后&#xff0c;你是否也遇到過這些“光伏運維之痛”&#xff1f;?【痛…

將 maven 集成到 idea 后出現 向項目創建模塊時出錯:null 的問題

1.出現的問題今天想將maven繼承到idea出現了一下問題&#xff1a;用生成器里面的也會報錯&#xff0c;找了找帖子并沒有哪位大佬出現類似錯誤&#xff0c;于是我解決完想分享一下&#xff0c;如果有不對&#xff0c;請指正。2.解決辦法很可能是java 的 版本 與 maven 版本有問題…

類似于 Progress Telerik Fiddler Classic 的 免費 或 開源 HTTP/HTTPS 抓包與調試工具推薦

以下是一些 類似于 Progress Telerik Fiddler Classic 的 免費 或 開源 HTTP/HTTPS 抓包與調試工具推薦&#xff1a;免費 / 開源替代工具推薦 1. Wireshark 免費且開源的網絡協議分析工具&#xff0c;支持 Windows、macOS、Linux 等平臺。可捕獲并深入分析網絡流量&#xff0c;…

7.0 熱電偶的工作原理

在工業生產過程中&#xff0c;溫度是需要測量和控制的重要參數之一。在溫度測量中&#xff0c;熱電偶的應用極為廣泛&#xff0c;它具有結構簡單、制造方便、測量范圍廣、精度高、慣性小和輸出信號便于遠傳等許多優點。另外&#xff0c;由于熱電偶是一種無源傳感器&#xff0c;…

commons-lang3

概述 提供了許多幫助程序實用程序&#xff0c;特別是字符串操作方法&#xff0c;基本數值方法&#xff0c;對象反射&#xff0c;并發&#xff0c;創建和序列化以及系統屬性。maven依賴<dependency><groupId>org.apache.commons</groupId><artifactId>c…

vue-amap組件呈現的效果圖如何截圖

我們用amap呈現了幾個圖層后&#xff0c;用戶覺得效果很好&#xff0c;想點個按鈕直接將這個畫面截圖下來。 首先我們用Canvas的toDataURL方法可以直接獲取圖像數據&#xff0c;但是實踐發現截圖后是空白的。 原因在警告中&#xff1a; 地圖的WebGL context 的preserveDrawin…

杰理燒錄ERROR: Data error after erasing, address = 0x430000

把CONFIG_BOARD_DEV_KIT關閉&#xff0c;打開CONFIG_BOARD_DEVELOP

超越自動化:為什么說供應鏈的終局是“AI + 人類專家”的混合智能?

摘要&#xff1a;當前&#xff0c;圍繞AI賦能供應鏈的討論&#xff0c;大多聚焦于“自動化”帶來的降本增效。然而&#xff0c;這僅僅是第一層。當我們的系統面對“黑天鵝”事件時&#xff0c;一個過度依賴自動化的“脆弱”系統可能會瞬間崩潰。本文旨在深入探討供應鏈演進的下…

Spine文件導入Unity流程

1、轉為Json文件導出 2、對文件進行處理 3、添加Spine的Package包 一、Spine文件導出設置 1、選擇Json文件 2、選擇導出所在路徑 3、點擊打包設置 更改圖集擴展名 二、文件導出后的設置 1、修改Json的Spine版本 這里必須是3.8 三、下載Unity支持包 1、鏈接 spine-unit…

Docker Compose healthcheck介紹(監控容器中服務的實際健康狀態)數據庫健康檢查pg_isready

文章目錄**功能概述****核心參數詳解****配置示例****1. 基礎用法****2. 使用數據庫健康檢查****3. 結合 depends_on 控制啟動順序****高級用法****1. 自定義健康檢查腳本****2. 多種健康檢查類型**- **HTTP 檢查**&#xff1a;- **TCP 端口檢查**&#xff1a;- **Redis 檢查**…

算法之雙指針

在算法設計中&#xff0c;雙指針是一種高效優化工具&#xff0c;主要用于線性數據結構&#xff08;如數組&#xff08;數組劃分和數組分塊常用&#xff09;、鏈表、字符串&#xff09;&#xff0c;通過控制兩個指針的移動軌跡&#xff0c;將原本需要 O (n) 時間復雜度的問題優化…

冪等性、順序性保障以及消息積壓

冪等性 概念 在應用程序中&#xff0c;冪等性就是指對一個系統進行重復調用&#xff08;相同參數&#xff09;&#xff0c;不論請求多少次&#xff0c;這些請求對系統的影響都是相同的效果. 比如數據庫的select操作.不同時間兩次查詢的結果可能不同&#xff0c;但是這個操作…

算法訓練營DAY58 第十一章:圖論part08

拓撲排序精講 卡碼網&#xff1a;117. 軟件構建(opens new window) 題目描述&#xff1a; 某個大型軟件項目的構建系統擁有 N 個文件&#xff0c;文件編號從 0 到 N - 1&#xff0c;在這些文件中&#xff0c;某些文件依賴于其他文件的內容&#xff0c;這意味著如果文件 A 依…

如何在Python中使用正則表達式?

在Python中使用正則表達式主要通過內置的re模塊實現。正則表達式用于匹配、查找、替換字符串中的特定模式&#xff0c;是處理文本的強大工具。以下是使用正則表達式的核心方法和示例&#xff1a; 一、基本用法步驟 導入re模塊&#xff1a;import re定義正則表達式模式&#xff…

用 Trae 玩轉 Bright Data MCP 集成

引言 在自動化與智能體浪潮中&#xff0c;Trae 以“開箱即用、所見即所得”的工具編排體驗&#xff0c;成為個人與團隊落地 AI 工作流的高效選擇。本篇將以 Trae 為主角&#xff0c;展示如何通過最少配置完成與 Bright Data MCP 的對接&#xff0c;并快速構建一個可用、可觀測…

大數據Spark(六十三):RDD-Resilient Distributed Dataset

文章目錄 RDD-Resilient Distributed Dataset 一、RDD五大特性 二、RDD創建方式 RDD-Resilient Distributed Dataset 在 Apache Spark 編程中&#xff0c;RDD&#xff08;Resilient Distributed Dataset&#xff0c;彈性分布式數據集&#xff09;是 Spark Core 中最基本的數…

java,通過SqlSessionFactory實現動態表明的插入和查詢(適用于一個版本一個表的場景)

1,測試實體類package org.springblade.sample.test;import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data;/*** Author: 肖揚* CreateTime: 2025-09-05* Description: SqlSessionFactoryTest測試* Version: 1.0*/ Data TableName("session_factory_…