首页/新闻资讯/正文详情

Jetson Orin Nano 内核编译与驱动打包全流程实战指南

发布时间:2026/9/28 1:49:59 来源:云帆数科 栏目:资讯中心
Jetson Orin Nano 内核编译与驱动打包全流程实战指南
1. 为什么要在 Jetson Orin Nano 上折腾内核编译拿到 Jetson Orin Nano 的第一天大多数人都是插上电源、烧录官方镜像、跑通 Hello AI World然后心满意足地收工。但只要你打算接一个官方 BSP 里没带驱动的外设——比如某款特定的网卡、CAN 收发器、工业相机或者自定义的 GPIO 扩展板——很快就会撞上那堵墙驱动源码编译通过了insmod却报invalid module format或者干脆在dmesg里看到一堆Unknown symbol。这不是你代码写错了而是内核模块与运行中的内核版本、配置、符号表不匹配。Jetson Orin Nano 跑的是 NVIDIA 定制的 Linux 内核基于 5.10 或 5.15 系列具体取决于 JetPack 版本它和你在 Ubuntu 主机上apt install linux-headers-$(uname -r)拿到的那套东西完全是两码事。NVIDIA 对内核做了大量下游修改尤其是 Tegra 平台相关的驱动、设备树和内存管理部分。你从 kernel.org 拉一个 vanilla 内核编译出来的模块几乎不可能直接加载到 Orin Nano 上。所以要加驱动就得编译和板子上运行的内核完全同源的那份源码。这件事的难点不在于编译本身——make谁都会敲——而在于整条链路上有太多容易踩的坑源码版本对不上、交叉编译工具链选错、localversion没设置导致模块路径错位、Module.symvers缺失、设备树没同步更新、打包时--append-to-version用错……任何一个环节出问题你拿到的就是一堆废铁。我前后在 Orin Nano 上完整走过五六遍这个流程从 JetPack 5.1 到 6.x踩过的坑足够写一本小册子。这篇就把整条链路拆开从依赖安装一直讲到驱动打包把每个环节的为什么和怎么做都讲透。适合读这篇的人手里有 Orin Nano 开发板、需要编译自定义内核模块或修改内核配置的嵌入式工程师正在做边缘 AI 设备驱动适配的开发者以及任何被invalid module format折磨过、想搞清楚背后原理的人。不需要你是内核专家但得会用 Linux 命令行、看得懂 Makefile。2. 编译前的环境盘点主机、工具链与源码版本的三方对齐2.1 主机环境的选择与最小依赖清单编译 Jetson 内核主机建议用 Ubuntu 20.04 或 22.04 的 x86_64 机器。为什么强调这个因为 NVIDIA 官方文档里给的依赖包列表和构建脚本都是在这两个版本上验证过的。你用 Ubuntu 24.04 或者别的发行版大概率会在某个apt install步骤卡住或者遇到 GCC 版本不兼容的问题。我试过在 Fedora 上跑光是libncurses和libssl的包名差异就折腾了半天不划算。依赖安装这一步很多人直接复制官方文档的一条命令就完事但实际执行时经常报无法定位软件包。原因通常是apt源没更新或者某些包在新版本里改了名字。下面是我在 Ubuntu 22.04 上实测可用的完整依赖清单sudo apt update sudo apt install -y \ build-essential \ bc \ flex \ bison \ libssl-dev \ libncurses5-dev \ libncursesw5-dev \ libelf-dev \ dwarves \ python3 \ python3-pip \ device-tree-compiler \ rsync \ cpio \ kmod \ git \ wget \ curl \ zstd \ liblz4-tool这里有几个包值得单独说。dwarves提供pahole工具内核编译开启DEBUG_INFO_BTF时需要它生成 BTF 信息缺了会直接编译失败。device-tree-compiler提供dtc处理设备树必备。libssl-dev是内核模块签名和证书处理需要的。zstd和liblz4-tool则是内核镜像压缩格式的支持——Orin Nano 的默认配置可能用 zstd 压缩主机上没有对应工具就会在压缩阶段报错。提示如果你在虚拟机里编译确保磁盘空间至少留 50GB。内核源码本身约 1.5GB编译产物加上中间文件轻松超过 20GB再加上交叉工具链和后续打包空间不够会在链接阶段莫名其妙失败。2.2 交叉编译工具链用官方的还是自己装Orin Nano 是 aarch64 架构主机是 x86_64所以必须用交叉编译工具链。这里有个分岔路一是用 NVIDIA 官方 JetPack 里自带的工具链二是用 Ubuntu 源里的gcc-aarch64-linux-gnu。我的建议是优先用官方工具链。原因很直接NVIDIA 的内核源码是用他们自己的工具链验证的GCC 版本、binutils 版本都经过匹配测试。Ubuntu 源里的交叉编译器版本可能偏新或偏旧编译 Tegra 特定代码时偶尔会触发一些奇怪的警告甚至错误。官方工具链通常在你安装 JetPack 的主机上位于/usr/bin/aarch64-linux-gnu-*或者通过 NVIDIA 的 SDK Manager 安装后放在~/nvidia/nvidia_sdk/下面。如果你手头没有官方工具链用 Ubuntu 源的也能跑通但要确认版本sudo apt install -y gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu aarch64-linux-gnu-gcc --version记下这个版本号后面配置内核时CROSS_COMPILE前缀要和它对应。工具链的路径一定要加到PATH里或者在内核make时用绝对路径指定否则会出现command not found或者更隐蔽的——找到了错误的编译器。2.3 源码版本必须和板子上的内核严格一致这是整个流程里最关键、也最容易翻车的一步。你怎么知道板子上跑的内核是什么版本在 Orin Nano 上执行uname -r你会看到类似5.10.104-tegra或5.15.136-tegra的输出。这个字符串由三部分组成上游内核版本号5.10.104、localversion-tegra、以及可能的构建后缀。你编译时用的源码必须能生成完全相同的版本字符串否则模块加载时内核会直接拒绝。源码从哪来两个途径JetPack 自带的 kernel 源码通过 SDK Manager 安装 JetPack 时如果勾选了 Jetson Linux 或源码组件会在~/nvidia/nvidia_sdk/JetPack_*/Linux_for_Tegra/source/下找到kernel_src.tbz2之类的压缩包。这是最稳妥的来源。NVIDIA 官方 Git 仓库在https://github.com/NVIDIA/linux或 NVIDIA 的公开源码站点上按 JetPack 版本找对应的分支比如jetson-linux-r35对应 JetPack 5.x。用 Git 的好处是方便切换版本和查看提交历史。拿到源码后第一件事是确认它的版本号。解压后进入源码根目录看Makefile顶部的VERSION 5 PATCHLEVEL 10 SUBLEVEL 104 EXTRAVERSION 如果这里的版本和板子上uname -r的前三段对不上后面全白搭。EXTRAVERSION通常是空的-tegra这个后缀是通过内核配置里的CONFIG_LOCALVERSION加进去的这个后面会细说。注意不要试图用uname -r的完整字符串去反推源码版本然后随便下载一个看起来差不多的内核。Tegra 的下游补丁差异很大5.10.104 和 5.10.120 之间的 Tegra 驱动代码可能完全不同。版本对不上编译出来的模块符号表就对不上加载必失败。3. 内核配置从 defconfig 到 localversion 的每一个关键开关3.1 选对 defconfig 并理解它的来源Jetson 内核的配置不是从零开始make menuconfig一项项选的而是基于 NVIDIA 提供的 defconfig 文件。在源码目录下执行ls arch/arm64/configs/ | grep tegra你会看到类似defconfig、tegra_defconfig这样的文件。对于 Orin Nano通常用defconfig即可它已经包含了 Tegra 平台所需的全部基础配置。但要注意不同 JetPack 版本的 defconfig 名字可能不同有的版本里叫jetson_defconfig。以实际源码里的文件为准。配置命令export CROSS_COMPILEaarch64-linux-gnu- export ARCHarm64 make defconfig这里的ARCHarm64必须设置否则内核会按主机的 x86 架构去解析配置直接报错。CROSS_COMPILE的前缀要和你的工具链名字匹配如果你用的是官方工具链可能是aarch64-linux-gnu-或者aarch64-none-linux-gnu-用ls看一下工具链目录里的文件名前缀就知道了。3.2 localversion 设置决定模块能不能被加载的隐藏开关这是最容易被忽略、但后果最严重的一个配置项。前面说过板子上uname -r输出的是5.10.104-tegra这个-tegra就是CONFIG_LOCALVERSION的值。如果你编译时没有设置它生成的内核版本就是5.10.104模块会被安装到/lib/modules/5.10.104/下而板子上的内核去/lib/modules/5.10.104-tegra/找模块——路径对不上加载失败。设置方法有两种。一是在make menuconfig里找到General setup→Local version - append to kernel release填入-tegra。二是直接改.config文件CONFIG_LOCALVERSION-tegra改完之后验证一下最终版本字符串make kernelrelease这个命令会输出编译后将生成的内核版本。它必须和板子上uname -r的输出完全一致一个字符都不能差。如果板子上是5.10.104-tegra你输出的是5.10.104-tegra-custom那也不行。有些 JetPack 版本的 localversion 可能更复杂比如带构建日期或配置后缀这时候你得从板子上/proc/version或者/lib/modules/$(uname -r)/build/Makefile里反查出准确的值。提示如果板子上有/lib/modules/$(uname -r)/build这个符号链接指向内核源码目录那说明板子本身带了编译环境你可以直接在板子上编译模块省去交叉编译的麻烦。但 Orin Nano 的 eMMC 或 SD 卡空间通常紧张而且板子上编译速度慢所以大多数情况下还是主机交叉编译更实际。3.3 必须确认的几个内核选项除了 localversion还有几个配置项直接影响模块加载和设备驱动工作配置项推荐值作用CONFIG_MODULESy启用模块支持不开启无法加载任何 .koCONFIG_MODULE_SIG按需模块签名验证开启后未签名模块会被拒绝CONFIG_MODULE_SIG_FORCEn强制签名设为 y 则只加载已签名模块CONFIG_MODVERSIONSy启用模块版本控制影响符号 CRC 校验CONFIG_DEBUG_INFO_BTFy生成 BTF 信息eBPF 相关工具需要CONFIG_MODULE_SIG_FORCE这个尤其要注意。有些安全加固的内核配置会把它设为y这时候你编译的未签名模块根本加载不了dmesg里会看到module verification failed: signature and/or required key missing。如果你只是做开发调试把它设为n最省事。如果必须开启签名那就得生成密钥对、编译时签名、并把公钥烧到板子的内核密钥环里流程复杂得多。CONFIG_MODVERSIONS开启后内核会为每个导出符号生成 CRC 校验值模块加载时校验。这本来是好事能防止版本不匹配的模块被加载。但如果你编译模块时用的Module.symvers和板子内核的不一致就会报disagrees about version of symbol错误。所以编译完内核后一定要把生成的Module.symvers保留好编译外部模块时要用到它。4. 编译与模块打包从 make 到 .ko 的完整链路4.1 编译内核镜像与模块的正确姿势配置确认无误后就可以开始编译了。命令本身很简单make -j$(nproc) Image modules dtbs但这里有几个细节值得展开。Image是 aarch64 架构的内核镜像格式不是 x86 的bzImagemodules编译所有配置为模块的驱动dtbs编译设备树二进制文件。三个目标可以一起编也可以分开编。-j$(nproc)用满所有 CPU 核心加速编译。但如果你主机内存不足比如只有 8GB并行度太高会导致 OOM。这时候把-j的值降到核心数的一半或-j4。我在一台 16GB 内存的机器上用-j16编译大概 15-20 分钟能完成内存小的机器可能要半小时以上。编译过程中如果报错最常见的原因是依赖缺失。比如HOSTCC scripts/dtc/dtc.o /bin/sh: 1: flex: not found这就是flex没装。或者*** No rule to make target debian/canonical-certs.pem这是 Ubuntu 内核源码里常见的证书路径问题在 Jetson 源码里一般不会遇到但如果遇到了检查.config里CONFIG_SYSTEM_TRUSTED_KEYS和CONFIG_SYSTEM_REVOCATION_KEYS是否指向了不存在的文件把它们清空即可。编译完成后检查关键产物ls arch/arm64/boot/Image ls arch/arm64/boot/dts/nvidia/*.dtb find . -name *.ko | head -20Image是内核镜像.dtb是设备树.ko是内核模块。三者缺一不可。4.2 外部模块的编译Makefile 怎么写才不出错如果你只是要编译一个外部驱动模块比如自己写的字符设备驱动不需要重新编译整个内核但需要内核源码目录里已经完成过一次完整编译生成了Module.symvers和配置好的构建环境。外部模块的 Makefile 典型写法obj-m my_driver.o my_driver-objs : main.o helper.o KDIR : /path/to/kernel/source PWD : $(shell pwd) all: $(MAKE) -C $(KDIR) M$(PWD) ARCHarm64 CROSS_COMPILEaarch64-linux-gnu- modules clean: $(MAKE) -C $(KDIR) M$(PWD) clean关键点是-C $(KDIR)指定内核源码路径M$(PWD)指定模块源码路径ARCH和CROSS_COMPILE必须和编译内核时一致。编译成功后当前目录下会生成my_driver.ko。这里有个坑KDIR指向的源码目录必须是已经编译过的里面要有.config、Module.symvers、include/generated/等生成文件。如果你拿一份刚解压、没编译过的源码去编译外部模块会报Module.symvers not found或者include/config/auto.conf not found。解决办法就是先在KDIR里跑一遍make defconfig make modules_preparemodules_prepare会生成编译外部模块所需的最小环境。4.3 模块安装路径与 depmod 的配合编译出来的.ko文件需要放到板子上的正确位置。标准路径是/lib/modules/$(uname -r)/kernel/drivers/子系统/比如一个网络驱动放在kernel/drivers/net/下一个字符设备驱动放在kernel/drivers/char/下。放好之后在板子上执行sudo depmod -adepmod会扫描/lib/modules/$(uname -r)/下的所有模块解析它们之间的依赖关系生成modules.dep和modules.alias等文件。没有这一步modprobe找不到模块只能手动insmod并自己解决依赖顺序。如果你在主机上交叉编译可以用INSTALL_MOD_PATH指定安装根目录把模块安装到一个临时目录再整体拷贝到板子上make INSTALL_MOD_PATH/tmp/jetson_modules modules_install这样模块会安装到/tmp/jetson_modules/lib/modules/5.10.104-tegra/下保持目录结构完整。然后用scp或读卡器拷贝到板子的/lib/modules/下再在板子上跑depmod。注意modules_install默认会尝试更新主机上的/lib/modules/如果你不加INSTALL_MOD_PATH可能把交叉编译的 aarch64 模块装到 x86 主机上造成混乱。养成加INSTALL_MOD_PATH的习惯。5. 驱动打包与部署让模块在板子上真正跑起来5.1 打包成 deb 包比手动拷贝更靠谱的方式手动拷贝.ko文件到板子上虽然简单但有几个问题容易漏文件、权限可能不对、升级和卸载麻烦。更工程化的做法是打成.deb包用dpkg安装和管理。NVIDIA 的源码树里通常带了打包脚本在debian/或scripts/目录下找找。如果没有可以自己写一个简单的打包流程# 创建包目录结构 mkdir -p my-module/DEBIAN mkdir -p my-module/lib/modules/5.10.104-tegra/kernel/drivers/misc # 拷贝模块 cp my_driver.ko my-module/lib/modules/5.10.104-tegra/kernel/drivers/misc/ # 写控制文件 cat my-module/DEBIAN/control EOF Package: my-driver Version: 1.0.0 Architecture: arm64 Maintainer: your_name Description: Custom driver for Jetson Orin Nano EOF # 写 postinst 脚本安装后自动 depmod cat my-module/DEBIAN/postinst EOF #!/bin/sh depmod -a modprobe my_driver exit 0 EOF chmod x my-module/DEBIAN/postinst # 打包 dpkg-deb --build my-module my-driver_1.0.0_arm64.deb这个.deb包拷到板子上dpkg -i安装postinst脚本会自动跑depmod并加载模块。卸载时dpkg -r my-driver也能干净地移除文件。比手动rm靠谱得多。5.2 设备树同步驱动能加载不等于硬件能用很多驱动除了.ko文件还需要设备树里对应的节点描述。比如你接了一个 I2C 设备驱动加载了但设备树里没有这个 I2C 设备的节点驱动就找不到硬件probe函数根本不会被调用。设备树的修改流程在源码的arch/arm64/boot/dts/nvidia/下找到对应板子的.dts文件Orin Nano 通常是tegra234-p3767-0000-p3768-0000-a0.dts之类的名字在里面添加或修改节点。改完后重新编译dtbsmake dtbs生成的.dtb文件需要放到板子的/boot/目录下并确保引导配置extlinux.conf或 UEFI 配置指向了正确的.dtb。这一步如果搞错板子可能直接黑屏起不来——这也是热词里Jetson Orin Nano 启动后黑屏的常见原因之一。提示修改设备树之前先把原始的.dtb备份一份。如果新设备树导致无法启动可以通过串口或恢复模式把备份的.dtb刷回去。Orin Nano 的恢复模式进入方法是按住 Force Recovery 按钮再上电然后用主机上的flash.sh或 SDK Manager 重新烧录。5.3 验证模块加载从 dmesg 到 lsmod 的排查链路模块部署到板子上后加载并验证sudo modprobe my_driver lsmod | grep my_driver dmesg | tail -30lsmod显示模块已加载说明insmod成功了。但加载成功不等于工作正常。真正的验证要看dmesg里驱动probe函数的输出以及设备节点是否创建ls /dev/my_device如果probe失败dmesg里会有详细错误信息。常见的几类Unknown symbol in module模块依赖的符号在内核里找不到。检查Module.symvers是否匹配或者依赖的模块是否已加载。invalid module format版本字符串不匹配回到第 3.2 节检查localversion。disagrees about version of symbolCONFIG_MODVERSIONS的 CRC 校验失败说明编译模块时用的内核源码和板子上的内核不是同一份。probe failed with error -ENODEV设备树里没有对应节点或者硬件没接好。排查的时候dmesg -w实时看日志最方便一边插拔硬件一边观察输出。6. 那些年我踩过的坑从依赖缺失到启动黑屏的完整复盘6.1 依赖包缺失导致的编译中断第一次编译时我在make modules阶段遇到pahole not found。当时不知道dwarves包提供这个工具在网上搜了半天有人说是内核版本太新、有人说是 GCC 问题绕了一大圈才定位到就是一个包没装。后来我养成了一个习惯编译前先跑一遍make defconfig make prepare看它报什么错缺什么装什么比对着文档一条条核对快得多。另一个坑是libssl-dev的版本问题。Ubuntu 22.04 默认的 OpenSSL 3.0 和某些老版本内核的签名脚本不兼容会报openssl: error while loading shared libraries。解决办法是装libssl-dev的同时确保openssl命令行工具也是匹配的版本或者在内核配置里关掉模块签名相关选项。6.2 localversion 不一致引发的模块加载失败这个坑我踩了两次。第一次是忘了设CONFIG_LOCALVERSION编译出来的模块版本是5.10.104板子上是5.10.104-tegrainsmod直接报invalid module format。第二次是设了-tegra但板子上的实际版本是5.10.104-tegra后面还跟了一个构建后缀某些 JetPack 版本会有还是对不上。后来我学乖了编译前先在板子上执行cat /proc/version把完整的版本字符串记下来然后在主机上make kernelrelease对比。两者完全一致才继续编译。这个检查花不了 10 秒钟但能省掉后面半小时的排查。6.3 设备树改错导致的黑屏有一次我为了加一个 SPI 设备在设备树里改了一个引脚复用配置结果板子启动到一半就黑屏了。串口日志显示内核在初始化某个时钟时卡死。原因是那个引脚被其他外设占用了我改的配置产生了冲突。教训是改设备树之前先搞清楚每个引脚、每个时钟、每个电源域的归属。Tegra 的引脚复用和时钟树非常复杂一个引脚可能同时被多个控制器引用。改之前用dtc把原始设备树反编译成.dts搜索相关节点看清楚有没有冲突。改完之后如果条件允许先用fdtdump或dtc验证新设备树的语法正确性再刷到板子上。如果已经黑屏了别慌。Orin Nano 可以通过恢复模式重新烧录。按住 Force Recovery 按钮上电主机上lsusb能看到 NVIDIA 的设备然后用 SDK Manager 或flash.sh重新刷入官方镜像即可。数据会丢但板子能救回来。6.4 Module.symvers 丢失导致的符号校验失败编译外部模块时如果KDIR指向的内核源码目录里没有Module.symvers编译会报一堆undefined符号警告生成的.ko加载时也会失败。Module.symvers是内核编译过程中生成的记录了所有导出符号的 CRC 值。如果你把内核源码清理过make clean或make mrproper这个文件就没了。解决办法编译完内核后把Module.symvers单独备份一份。编译外部模块时确保KDIR目录里有这个文件。如果没有重新编译一次内核的modules目标即可生成。7. 把流程固化成脚本一次编写多次复用7.1 编译脚本的骨架设计每次手动敲一堆命令容易出错我把整个流程写成了一个 shell 脚本放在主机上需要时改几个变量就能跑。脚本的核心结构#!/bin/bash set -e # 可配置变量 KERNEL_SRC/path/to/kernel/source CROSS_COMPILEaarch64-linux-gnu- ARCHarm64 LOCALVERSION-tegra INSTALL_PATH/tmp/jetson_modules JOBS$(nproc) # 进入源码目录 cd ${KERNEL_SRC} # 配置 export ARCH CROSS_COMPILE make defconfig sed -i s/^CONFIG_LOCALVERSION.*/CONFIG_LOCALVERSION\${LOCALVERSION}\/ .config # 验证版本 EXPECTED_VERSION$(make kernelrelease) echo Kernel release will be: ${EXPECTED_VERSION} read -p Does this match the board? (y/n) confirm if [ ${confirm} ! y ]; then echo Version mismatch, aborting. exit 1 fi # 编译 make -j${JOBS} Image modules dtbs # 安装模块到临时目录 make INSTALL_MOD_PATH${INSTALL_PATH} modules_install echo Build complete. Modules at ${INSTALL_PATH}这个脚本的关键点是set -e任何命令失败就退出和版本验证环节人工确认后再继续。read -p那一步虽然看起来笨但能有效防止版本不匹配的模块被编译出来。7.2 部署脚本与板端验证主机上编译完成后用scp或rsync把模块目录同步到板子上rsync -avz /tmp/jetson_modules/lib/modules/5.10.104-tegra/ \ jetsonboard_ip:/lib/modules/5.10.104-tegra/然后在板子上执行sudo depmod -a sudo modprobe my_driver dmesg | tail -20如果一切正常dmesg里会看到驱动的初始化日志。如果失败根据错误信息回到前面的章节排查。提示板子上的/lib/modules/目录可能需要 root 权限才能写入。用rsync时加--rsync-pathsudo rsync或者先同步到用户目录再sudo cp。7.3 版本管理与回滚策略内核和模块的版本管理很重要。我的做法是每次编译成功后把Image、.dtb、Module.symvers和模块目录一起打包用版本号命名比如jetson_kernel_5.10.104-tegra_20240115.tar.gz。板子上保留最近两三个版本出问题可以快速回滚。回滚时把旧的Image和.dtb放回/boot/旧的模块目录放回/lib/modules/重启即可。注意extlinux.conf里的内核和设备树路径要对应修改否则引导的还是新版本。这套流程跑熟之后从修改代码到板子上验证大概 20-30 分钟能完成一轮。比起第一次折腾时花了一整天效率提升非常明显。核心就是把每个环节的为什么搞清楚然后固化成脚本减少人为失误。

相关推荐

Java汽车销售管理系统课程设计:事务、锁与状态机实战
Java汽车销售管理系统课程设计:事务、锁与状态机实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/28 1:49:59

RTL8201F百兆以太网PHY电路设计避坑实战指南
RTL8201F百兆以太网PHY电路设计避坑实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/28 1:49:59

特斯拉Optimus人形机器人硬件拆解:28个关节、空心杯电机与MCU控制链路
特斯拉Optimus人形机器人硬件拆解:28个关节、空心杯电机与MCU控制链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/28 1:49:59

Python搭建QQ聊天机器人极简教程
Python搭建QQ聊天机器人极简教程

随着QQ粉丝群管理需求的不断增长,简单的群管工具难以满足复杂的信息响应和自动化需求。现有的自动回复机器人虽然功能强大,但其高昂的年费成为不少用户的顾虑。因此,通过搭建一个自定义机器人来实现自动回复,成为解决这一问题的有效途径。 基于此需求,本文介绍了使用go-c… · 2026/9/28 2:14:08

Python整理百度云盘文件大量重复无用文件
Python整理百度云盘文件大量重复无用文件

百度云盘容量有限,当文件数量逐渐增多,空间很容易被填满。删除重复文件可以帮助释放大量空间。通过获取云盘缓存目录并使用Python脚本来整理数据,可以高效识别重复文件并避免手动操作的繁琐。 此方法基于 sqlite3 和 pandas 进行数据处理,简单快捷。 文章目录 云盘数据整理… · 2026/9/28 2:14:07

Python实现将图片转化为具有视觉震撼效果的字符图
Python实现将图片转化为具有视觉震撼效果的字符图

字符画是一种将图片转化为字符的艺术表现形式,它通过字符的密度和排列来模拟图片的色彩和形状效果。这种技术不仅在视觉上充满了创造力,还在文字处理领域展示了字符的丰富表现力。通过Python,可以将图片转换为字符画,生成具有视觉冲击力的字符艺术。 本文将通过具体步骤和… · 2026/9/28 2:13:48

Python实现将目录下的图片合并成PDF文件
Python实现将目录下的图片合并成PDF文件

在图像处理和文档管理中,经常需要将一系列图片文件合并为PDF格式,以便于传输、存档和阅读。Python凭借其丰富的第三方库,为图像处理和PDF操作提供了便捷的解决方案。 本文将详细介绍如何通过Python脚本,将目录中的所有图片合并为一个PDF文件,内容包括从基础环境配置到代码… · 2026/9/28 2:13:48

Python实现文件移动到指定文件夹
Python实现文件移动到指定文件夹

在编程过程中,经常需要对文件进行整理和管理,将不同类型的文件分类存放在指定文件夹中。Python提供了强大的文件操作模块,使得文件的移动操作变得简单高效。这篇教程将详细讲解如何使用Python实现将文件移动到指定文件夹的功能,帮助理解并掌握文件操作的基本方法和常见应用… · 2026/9/28 2:13:47

【PyQt】PyQT6制作一个Django项目启动器
【PyQt】PyQT6制作一个Django项目启动器

在现代的桌面和Web应用开发中,Python以其简单高效的特点获得了广泛的应用。通过集成PyQt和Django框架,将桌面应用的便捷操作与Django项目的后端处理相结合,不仅能够提升用户体验,更能显著提高开发的便利性和效率。 本文将聚焦于如何构建一个基于PyQt的Django项目启动器,实… · 2026/9/28 2:13:40

MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现

简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01

汕头网站建设制作厂家避坑指南:5大注意事项救急
汕头网站建设制作厂家避坑指南:5大注意事项救急

汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01

多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习

简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01

制作网页比较方便的软件怎么选?一文搞懂避坑指南
制作网页比较方便的软件怎么选?一文搞懂避坑指南

制作网页比较方便的软件怎么选?一文搞懂避坑指南 很多老板一上来就问:做个网站多少钱?但我反问他:你的域名买了吗?服务器租了吗?他一脸懵。这就是典型的“域名服务器搞不懂”。别急,今天咱们不聊虚的,直接 一文搞懂 那些让你头秃的技术名词。… · 2026/9/28 0:00:06

婚恋网站实战案例:避开3个高价坑,省钱50%还能跑赢流量
婚恋网站实战案例:避开3个高价坑,省钱50%还能跑赢流量

婚恋网站实战案例:避开3个高价坑,省钱50%还能跑赢流量 找婚恋网站建站公司,最怕的就是被坑高价。很多同行跟我吐槽,报价单上写得模棱两可,功能栏里全是“高级定制”、“专属UI”,结果落地全是套壳。今天不聊虚的,直接甩几个我经手的 实战案例… · 2026/9/28 0:00:19

济南做网站多少钱:3个案例拆解,防黑源码下载全攻略
济南做网站多少钱:3个案例拆解,防黑源码下载全攻略

济南做网站多少钱:3个案例拆解,防黑源码下载全攻略 上周济南一个做建材的老板找我,脸都绿了。他的官网首页弹出了赌博广告,后台被植入了挖矿脚本。他慌得问我:“网站被黑挂马不知道怎么办?能不能直接找之前的外包公司要源码下载,看看哪里被动了手脚?… · 2026/9/28 0:00:25

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码