ARM裸机开发-点亮LED灯
目录背景介绍底板原理图一.引脚复用功能引脚电气属性IOMUXC 32)1.IOMUXC_SW_MUX_CTL_PAD:引脚复用功能2.IOMUXC_SW_PAD_CTL_PAD:电气属性3.代码二.GPIO模块(GPIO 28)1.DR2.GDIR3.PSR4.ICR与EDGE5.IMR6.ISR7.总结8.代码三.时钟模块CCM 18)1.简介2.代码四.全局代码五.环境搭建1.安装FileZilla与SSH服务器2.Ubuntu3.编译4.烧录背景介绍本文开始在VScode上使用IMX6ULL以真机进行学习注意创建的.S文件在本篇学习时注意大写在编译时会进行部分预处理操作小写则.s文件会跳过预处理阶段。芯片原理图参考如下。其中SOC IMX6ULL NXP核心处理器这是整块板子的“大脑”。NXP恩智浦的 IMX6ULL 基于ARM Cortex-A7架构主频通常在 528MHz 或 800MHz。DDR3 512MB运行内存 / RAM相当于电脑的内存条。它是掉电丢失的。当 Linux 系统启动时内核kernel会被加载到这块 DDR3 里运行它负责临时存放程序运行时产生的大量数据。EMMC nand flash 8GB存储 / ROM相当于电脑的硬盘。它是掉电不丢失的。用来永久存放系统镜像uboot、kernel、设备树、rootfs文件系统和用户程序。蜂鸣器贴纸有“”号表示有源蜂鸣器上电即可工作左下角BOOT拨码开关设置启动模式将17位拉高则开机。底板原理图其中两列引脚通过板子的两列白色插座接入核心板故核心板自然会将插座的引脚接入SOC内部该芯片GPIO分为5组GPIO1、GPIO2、GPIO3、GPIO4、GPIO5.若为图中LED0所在的GPIO 3则表示默认为GPIO1组注意中间有空格其中DCDC表示直流供电LED1是物理设备编号LED0则是引脚工作名称由原理图可知被接入到GPIO1组的03号引脚显然右边接入高电平控制LED0输出低电平则灯亮故本文后续点灯操作将围绕此展开。一.引脚复用功能引脚电气属性IOMUXC 32)点灯第一步先配置引脚复用功能以及电气属性1.IOMUXC_SW_MUX_CTL_PAD:引脚复用功能SION为控制输入功能1开启0关闭。而当采用GPIO1_IO03功能时输入输出默认打开而当采用其他七种模式时默认关闭MUX_MODE为引脚复用的功能易知共有八种模式而该引脚默认为0101即GPIO1_IO03功能2.IOMUXC_SW_PAD_CTL_PAD:电气属性HYS:仅输入功能使用用于过滤波形整形。(点灯为输出功能故暂不使用PUS:仅输入可用控制上拉下拉电阻。PUE:仅输入可用,控制引脚使用上拉还是保持电压PKE:打开PUE的开关为1表示PUE上拉保持功能开ODE:控制输出模式默认为0即推挽输出。漏级开漏输出引脚是高阻态可以输出低电平但无法输出高电平除非外部接入上拉电阻推挽输出驱动能力强既可输出高电平也可输出低电平SPEED:控制输出速度合适即可高速EMI电磁干扰会增加功耗DSE:驱动能力表示驱动多强的外部设备电阻越小电流越大驱动变强但同时功耗变大芯片发烫。给高电平有效对点灯无用默认即可SRE:从低电平变为高电平需要时间压摆率越高曲线越陡适用高速设备USBCAN网口对于点灯而言电气属性设置为默认值即可由图易知默认值0X10B0配置之后该引脚则为GPIO功能。3.代码_led_init: // 配置引脚复用功能:GPIO1_IO03 ldr r0, 0x020E0068 mov r1, #0x05 str r1, [r0] // 配置引脚电气属性:默认属性(0x10B0) ldr r0, 0x020E02F4 ldr r1, 0x10B0 str r1, [r0]二.GPIO模块(GPIO 28)1.DRGPIOx_DR:控制第几组的GPIO引脚DR控制引脚高低电平例如本篇要点亮的LED灯为GPIO1组的IO03引脚则让bit3置0灯亮2.GDIRGDIR(GPIO direction register)GPIO方向寄存器即控制输入/输出模式对应LED,GPIO_03显然该寄存器应置13.PSRPSR:只读读取引脚电平1为高0为低电平同时DR也可读4.ICR与EDGEICR1:配置引脚中断方式的寄存器从0-31一共32位每两位控制一个引脚的中断触发方式寄存器编号即引脚编号显然要配置GPIO03号引脚则应配置6.7位.对应具体设置位依次为低电平触发高电平触发上升沿触发下降沿触发。ICR1为0-15位引脚ICP2为16-31位引脚。ICR2原理同上此外EDGE寄存器则可控制为双边沿触发5.IMRIMR:控制中断是否屏蔽显然要将LED灯对应的bit3为置1表示开中断6.ISRISR查询引脚是否产生中断1表示产生中断7.总结GPIOx_DR:向GPIOx组某个引脚写0或1(低电平/高电平)GPIOx_GDIR:设置GPIOx组某个引脚方向(输入0和输出1)GPIOx_PSR(只读):读取GPIOx组某个引脚的状态GPIOxICR:设置GPIOx组某个引脚中断触发方式(低电平、高电平、下降沿、上升沿)GPIOx_IMR:设置GPIOx组某个引脚中断屏蔽/允许GPIOx_ISR:用来查询GPIOx组某个引脚是否产生中断GPIOx_EDGE_SEL:设置中断触发方式为双边沿触发以上则为GPIO模块的相关寄存器解析对于点灯功能而言无需中断此处了解即可后续开发将会详细介绍。点灯仅需设置GPIOx_DR与GPIOx_GDIR寄存器将引脚置低电平且设置为输出方向。8.代码_led_init: // 配置引脚方向(GDIR)输出模式 ldr r0, 0x0209C004 ldr r1, [r0] orr r1, r1, #(1 3) str r1, [r0] bx lr _led_on: //给DR bit3位低电平 ldr r0, 0x0209C000 ldr r1, [r0] bic r1, r1, #(1 3) str r1, [r0] bx lr三.时钟模块CCM 18)1.简介外设工作需要时钟不同外设工作频率不同需要的时钟频率则也不同故点灯则也需设置对应时钟频率。右侧为外设cgclock gate为控制外设开关ARM处理器中为了保证低功耗每个外设门都是关闭的要实现点灯则首先打开对应的cg开关。CCGRx即为控制外设cg的寄存器每两位控制一个外设置11即为开启。为方便后续开发将CCM_CCGR0-CCM_CCGR6都置为全1即0xFFFF FFFF表示打开所有外设时钟门。2.代码_enable_clocks: // CCM_CCGR0 clock enable ldr r0, 0x020C4068 ldr r1, 0xFFFFFFFF str r1, [r0] // CCM_CCGR1 clock enable ldr r0, 0x020C406C str r1, [r0] // CCM_CCGR2 clock enable ldr r0, 0x020C4070 str r1, [r0] // CCM_CCGR3 clock enable ldr r0, 0x020C4074 str r1, [r0] // CCM_CCGR4 clock enable ldr r0, 0x020C4078 str r1, [r0] // CCM_CCGR5 clock enable ldr r0, 0x020C407C str r1, [r0] // CCM_CCGR6 clock enable ldr r0, 0x020C4080 str r1, [r0] bx lr四.全局代码系统初次复位时在SVC模式复位异常位于0x00地址此时若执行一条跳转指令到复位异常函数处则可完成一些初始化工作。此外SVC模式仅在刚复位时使用此后大多时候在system进行工作故再不做过多阐述。可参考上篇启动代码的学习异常复位函数.global _start _start: ldr pc, _reset_handler ldr pc, _undefine_handler ldr pc, _software_handler ldr pc, _prefetch_abort_handler ldr pc, _data_abort_handler ldr pc, _reserved_handler ldr pc, _irq_handler ldr pc, _fiq_handler _fiq_handler: ldr pc, _fiq_handler _irq_handler: ldr pc, _irq_handler _reserved_handler: ldr pc, _reserved_handler _data_abort_handler: ldr pc, _data_abort_handler _prefetch_abort_handler: ldr pc, _prefetch_abort_handler _software_handler: ldr pc, _software_handler _undefine_handler: ldr pc, _undefine_handler finished: b finished复位函数其中 _enable_clocks_led_init _led_on函数均以在上述中实现。_reset_handler: // 设置irq模式 mrs r0, cpsr bic r0, r0, #0x1F orr r0, r0, #0x12 msr cpsr, r0 // 设置irq模式下的栈(32M) ldr sp, 0x86000000 // 设置system模式相比user模式多了特权模式 mrs r0, cpsr bic r0, r0, #0x1F orr r0, r0, #0x1F msr cpsr, r0 // 设置system模式下的栈 ldr sp, 0x84000000 // 打开所有外设时钟门 bl _enable_clocks // 初始化led bl _led_init // led亮 bl _led_on b finished上篇由于是仿真学习使用的是芯片内部的RAM而本芯片SOC内部的RAM不允使用故使用DDR3的内存而该芯片规定该内存起始地址为0X8000 0000,大小512MB即到0XA000 0000在这中间可自行根据七种异常栈分配内存。五.环境搭建1.安装FileZilla与SSH服务器由于在Ubuntu中运行VScode比较卡顿故选择在Windows上的VScode进行代码编写再将代码工程传输到Ubuntu中进行编译下载。首先为了方便从Windows和Ubuntu之间的文件传输我们需要在Windows下安装FileZilla该软件下载地址如下https://www.filezilla.cn/download。 FileZilla作为客户端Ubuntu作为服务端。该软件底层通过采用应用层的FTP协议实现文件传输。操作过程如下此外还需要在Ubuntu下安装SSH服务器sudo apt-get install vsftpd并配置文件 sudo vi/etc/vsftpd.conf 。使能本地功能和写入功能最后执行 sudo /etc/init.d/vsftpd restart刷新使配置文件生效2.Ubuntu1.设置NAT模式分配了虚拟IP,只要Windows能上网Ubuntu就能上网sudo /etc/init.d/networking restart //执行此代码重启网络桥接模式虚拟机就像你家里的另一台独立电脑。它和你的 Windows 宿主机平起平坐共用同一个真实路由器你之前连的手机热点。NAT模式虚拟机就像一个住在你 Windows 宿主机里面的“租客”。它通过宿主机代理上网外部网络手机热点根本看不见它。对比维度桥接模式VMnet0NAT模式VMnet8IP地址来源由外部路由器分配你之前是手机热点给的10.138.48.x由VMware虚拟路由器分配现在是192.168.85.x网络地位和宿主机Windows是平等的同学是宿主机的下属宿主机通信直接通过局域网通信但受限于外部路由器通过宿主机虚拟网卡192.168.85.1通信外网通信直接暴露在局域网中占用一个外部IP经过宿主机 NAT网络地址转换转发共用宿主机IP外部设备访问虚拟机能如果局域网没做隔离比如你之前手机热点的问题不能直接访问除非在VMware里设置端口转发虚拟机访问宿主机能但需要依赖外部路由器的配置能直接 ping192.168.85.1即可2.安装ARM编译器由于Ubuntu位X86架构gcc为对应的编译指令而要在ARM芯片上运行则需要安装对应ARM架构的编译器 。将该编译器拷贝至Ubuntu的家目录下再切换至根目录的/usr/local目录下创建arm文件夹再将家目录的编译器安装包复制于当前arm文件夹sudo mv ~/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz .再解压压缩包 sudo tar -xvf gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz。解压后会产生对应文件夹进入其中的bin目录其中为arm编译的工具链pwd打印出当前目录路径复制保存再sudo vim ~/.bashrc进入配置文件配置刚才复制的路径如下最后sudo reboot重启虚拟机即可最后arm-linux-gnueabihf-gcc -v查看安装编译器版本3.编译家目录下创建imx6ull/led_asm对应的芯片文件夹保存编译文件,通过FileZilla上传VScode上写的start.S文件至此编译三步骤编译arm-linux-gnueabihf-gcc -g -c start.S -o start.o其中“-g”选项是产生调试信息GDB 能够使用这些调试信息进行代码调试。“-c”选项是编译源文件但是不链接。“-o”选项是指定编译产生的文件名字这里我们指定 start.s 编译完成以后的文件名字为start.o。执行上述命令以后就会编译生成一个start.o 文件链接arm-linux-gnueabihf-ld -Ttext 0X87800000start.o -ostart.elf本次课程中我们所有的裸机例程都是烧写到 SD 卡中上电以后 I.MX6U 的内部 boot rom 程 序会将可执 行文件拷贝 到链接地址 处这个链 接地址可以 在 I.MX6U 的内部 128KBRAM 中 (0X900000~0X91FFFF)也可以在外部的 DDR 中。本次课程中所有裸机例程的链接地址都在 DDR中链 接起始地址为 0X87800000。I.MX6U-ALPHA 开发板的 DDR 容量有两种512MB 和256MB起始地址都为 0X80000000只不过 512MB 的终止地址为0X9FFFFFFF而 256MB 容量的终止地址为 0X8FFFFFFF。之所以选择 0X87800000 这个地址是因为后面要讲的 Uboot 其链接地址就是 0X87800000 这样我们统一使用 0X87800000 这个链接地址不容易记混。格式转换arm-linux-gnueabihf-objcopy -O binary -S -g start.elf start.bin我们需要用它将 start.elf 文件转换为start.bin 文件。上述命令中“-O”选项指定以什么格式输出后面的“binary”表示以二进制格式输出选项“-S”表示不要复制源文件中的重定位信息和符号信息“-g”表示不复制源文件中的调试信息。上述命令执行完成以后就会在工程目录下多一个 start.bin 文件。至此我们终于等到了想要的东西—start.bin 文件反汇编arm-linux-gnueabihf-objdump -D led.elf led.dis可不用大多数情况下我们都是用 C 语言写试验例程的有时候需要查看其汇编代码来调试代码因此就需要进行反汇编当然这个工作目前对于我们不是必须的。一般来说可以将 elf 文件反汇编。上述代码中的“-D”选项表示反汇编所有的段反汇编完成以后就会在当前目录下出现一个名为 start.dis 文件。我们可以打开这个文件查看其中的内容可以发 现这里面都是汇编代码。注意通过 start.dis 这个反汇编文件可以明显的看出我们的代码已经链接到了以​​​​0X87800000 为起始地址的区域。4.烧录装入SD卡插入读卡器连接到虚拟机ls /dev/sd*查看已有设备例如我这里看到的结果是/dev/sda /dev/sda1 /dev/sda2 /dev/sda3 四个文件分别代 表Ubuntu下的磁盘和三个分区然后将imxdownload文件上传至led_asm,执行chmod 0777 imxdownload给予权限使用命令./imxdownload start.bin /dev/sdb烧录注意不要写为./imxdownload led.bin /dev/sda,sda是系统磁盘会造成Ubuntu损坏.当出现此界面时下载成功注意下载速度为KB/S若为MB/S单位则下载失败拔卡重启虚拟机再插卡注意保证读卡器没有损坏部分廉价读卡器在插入时易因为静电烧坏。若是插入新读卡器则可能会出现自动挂载情况输入lsblk查看例如sdb挂载到boot与rootfs文件。执行下面指令卸载挂载因为 Linux 系统为了安全不允许对已经挂载的分区进行dd裸写入。如果不卸载你执行烧录会直接报Device or resource busy错误。sudo umount /dev/sdb1 sudo umount /dev/sdb2 //或者一句 sudo umount /dev/sdb*最后再进行烧录看到进度条跑完、提示烧录成功后。然后安全弹出读卡器把 SD 卡插回 i.MX6ULL 开发板拨到 SD 卡启动模式上电sudo ./imxdownload start.bin /dev/sdb至此灯亮了路也就清晰了前路漫漫亦灿灿与所有在嵌入式路上摸黑前行的朋友共勉。

相关新闻

Flutter三方库鸿蒙适配实战:giturl链接解析与资产路由搭建

Flutter三方库鸿蒙适配实战:giturl链接解析与资产路由搭建

最近我把一个 Flutter 项目从 Android 往 OpenHarmony 上迁移,最先卡住我的不是渲染性能,也不是状态管理,而是一个看起来毫不起眼的三方库:giturl。它专门做代码仓链接解析,能把 GitHub、GitLab、Bitbucket 以及各类自…

2026/10/3 15:40:08 阅读更多 →
HyperFrames2026终极指南-第11章第1节-商业变现实战-自由职业接单指南AI视频技能如何定价和获客

HyperFrames2026终极指南-第11章第1节-商业变现实战-自由职业接单指南AI视频技能如何定价和获客

自由职业接单指南:AI 视频技能如何定价和获客HyperFrames 2026 终极指南 第11章第1节 前几章我们把 HyperFrames 的核心能力摸了个遍,从模板开发到渲染优化,从 API 对接到自动化流水线。但说实话,技术再牛,不能变现就…

2026/10/3 14:39:04 阅读更多 →
GHelper 完整指南:华硕笔记本性能模式、风扇曲线与显卡模式一个工具全搞定

GHelper 完整指南:华硕笔记本性能模式、风扇曲线与显卡模式一个工具全搞定

GHelper 完整指南:华硕笔记本性能模式、风扇曲线与显卡模式一个工具全搞定 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, Vi…

2026/10/4 8:28:44 阅读更多 →

最新新闻

Webots R2023b 版本深度解析:Pose 节点迁移、VacuumGripper 真空吸盘与外置控制器启动器实战

Webots R2023b 版本深度解析:Pose 节点迁移、VacuumGripper 真空吸盘与外置控制器启动器实战

科研自动驾驶物理引擎 【免费下载链接】webots Webots Robot Simulator 项目地址: https://gitcode.com/gh_mirrors/web/webots 点击查看 免费下载 Webots R2023b 是 Cyberbotics 于 2023 年 6 月 28 日发布的重大版本更新,本篇文章以官方发布文档 docs…

2026/10/4 9:04:12 阅读更多 →
国庆七天搭建飞书企微自动化工作流:WorkBuddy实战指南

国庆七天搭建飞书企微自动化工作流:WorkBuddy实战指南

1. 为什么我要在国庆七天折腾这套自动化工作流国庆七天假,说长不长说短不短。出门堵在高速上看车尾灯,不如在家把一直想搭但没时间搭的自动化工作流给落地了。我平时的工作状态是这样的:飞书里堆着各种需求文档和表格,企微里是团队…

2026/10/4 9:04:12 阅读更多 →
VFH避障算法原理与调参实战:从向量场直方图到机器人局部路径规划

VFH避障算法原理与调参实战:从向量场直方图到机器人局部路径规划

做机器人避障和局部路径规划的人,应该没有一个没听说过VFH。VFH算法全称是Vector Field Histogram(向量场直方图),它解决的是移动机器人在未知环境下,如何根据传感器信息实时避开障碍物并朝目标方向运动的问题。市面上…

2026/10/4 9:04:12 阅读更多 →
IT爱学堂-普通人玩转 Vibe Coding 实战课,Vibe Coding全栈开发实战课(完结)

IT爱学堂-普通人玩转 Vibe Coding 实战课,Vibe Coding全栈开发实战课(完结)

一句话生成项目:从自然语言到可运行系统的技术链路 普通人玩转 Vibe Coding,第一步不是让 AI 立刻写代码,而是学会把一句话变成可执行的规格。所谓一句话生成项目,背后并不是魔法,而是一条技术链路:意图澄清…

2026/10/4 9:04:12 阅读更多 →
Hey压测公共服务:压别人家API时的法律红线与礼仪规范

Hey压测公共服务:压别人家API时的法律红线与礼仪规范

Hey压测公共服务:压别人家API时的法律红线与礼仪规范 【免费下载链接】hey HTTP load generator, ApacheBench (ab) replacement 项目地址: https://gitcode.com/GitHub_Trending/he/hey Hey 是一个用 Go 编写的轻量级 HTTP 压测工具(ApacheBench…

2026/10/4 9:04:12 阅读更多 →
宿舍楼局域网组网实战:从拓扑选型到VLAN划分的完整方案

宿舍楼局域网组网实战:从拓扑选型到VLAN划分的完整方案

简介:一份面向网络工程、计算机及相关专业学生的完整课程设计文档,以大学学生宿舍楼为场景,系统梳理局域网从规划到运维的闭环流程。文档主体为1个doc文件,压缩包约2.26MB,内容围绕网络规划、网络设计、网络实施、测试…

2026/10/4 9:03:12 阅读更多 →

日新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/4 1:00:58 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/4 1:00:58 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/4 1:00:58 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/4 1:00:58 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/4 1:00:58 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/4 1:00:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/2 10:36:31 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/3 9:42:35 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/3 9:42:36 阅读更多 →