Android Framework 常见解决方案(03)android系统 资源文件添加:TaoToken 统一 Key 通道下的编译验证 发布时间:2026/11/1 6:38:28 1. 从一次 system.img 里找不到资源文件说起Android Framework 开发里有个很典型的场景你往frameworks/base/data/etc/放了一个资源文件Android.mk也照着模板改了单模块编译mmm能过out/target/product/xxx/system/etc/下确实能看到文件。可一旦跑整编make -j刷进设备后adb shell ls /system/etc/就是找不到它。这个问题在 Android 系统源码资源文件添加、Android.mk 参与系统编译的链路里非常高频尤其是 Android O 之后PRODUCT_PACKAGES和PRODUCT_COPY_FILES两套机制并存很容易只做了一半。这篇聚焦的就是这条完整链路资源文件res/、assets/、data/etc/下的预置文件怎么通过Android.mk进入系统编译怎么被PRODUCT_PACKAGES或PRODUCT_COPY_FILES收进system.img以及编译完成后怎么验证它真的打进去了。同时因为现在做 Framework 开发经常要多个工具协作——本地编译、远程构建机、代码助手、模型对话——鉴权配置如果每个工具一套 Key管理起来很乱。我会顺带说明怎么用 TaoToken 统一 Key/API 通道把这些工具的鉴权收敛到一处让编译验证和工具调用不互相干扰。适合谁看正在改 Android 系统源码、需要往 system 分区加资源文件的 Framework 工程师被「单编能过、整编丢失」坑过的同学以及想把手上一堆 AI 编码工具鉴权统一管理的开发者。下面所有命令和 mk 片段都可以直接复制改路径使用。2. TaoToken 统一 Key 通道多工具协作时的鉴权前置做 Android 系统编译验证时工具链往往不止一个。你可能本地用 Claude Code 或 Cline 读代码、远程构建机上跑make、再用某个模型对话工具查报错。如果每个工具都单独配一套 API Key切换环境时很容易搞混尤其是构建机是共享的Key 散落在各个配置文件里不好管。TaoToken 在这里的作用是把这些工具的鉴权收敛到一个统一通道。它的 API 入口是https://taotoken.net/api你只需要在 TaoToken 控制台生成一个 Key然后让各个工具都指向这个 Base URL 和同一个 Key。这样本地、构建机、代码助手用的是同一套凭证换机器时只改一处。具体操作上先去控制台创建 Keyhttps://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentconsole创建完在 API Keys 页面复制出来https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi-keys拿到 Key 之后不同工具的接入方式略有差异但核心三件套是一样的Base URL、Key、Model ID。以 Claude Code 这类工具为例配置里需要写全这三项缺一个都会在请求时报鉴权或模型找不到的错。如果你用的是 Coding Plan 做长期编码任务可以在https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentcoding-plan查看套餐和接入说明。需要验证某个模型是否可用时直接用模型对话页面测一条请求最省事https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmodel-chat这里要强调一点TaoToken 是统一鉴权通道不是让你绕过任何本地编译流程。Android 系统编译该跑的source build/envsetup.sh、lunch、make一步都不能少它只是让你在调用外部工具时不用维护多套 Key。接入文档在https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc把 Key 配好之后回到正题——资源文件怎么进 system.img。这两件事是并行的鉴权通道解决工具协作Android.mk 解决编译产物。3. 可复制的 Android.mk 与 PRODUCT 配置片段这一节是核心直接给可复制的配置。以在系统中构建一个新资源system/etc/cursor.png为例路径和原文保持一致。第一步创建资源文件本身frameworks/base/data/etc/cursor.png第二步修改同目录下的frameworks/base/data/etc/Android.mk。在文件末尾追加一段BUILD_PREBUILT模块定义######################## include $(CLEAR_VARS) LOCAL_MODULE : cursor.png LOCAL_MODULE_CLASS : ETC LOCAL_MODULE_PATH : $(TARGET_OUT_ETC) LOCAL_SRC_FILES : $(LOCAL_MODULE) include $(BUILD_PREBUILT)这里几个变量的含义要清楚LOCAL_MODULE_CLASS : ETC决定它归到 etc 类LOCAL_MODULE_PATH : $(TARGET_OUT_ETC)决定最终落到system/etc/LOCAL_SRC_FILES指向同目录的文件。改完这一步单模块编译mmm frameworks/base/data/etc/就能在 out 目录看到产物。但整编时它不会自动进 system.img因为整编走的是 product 的包列表。所以第三步在build/make/target/product/base.mk的PRODUCT_PACKAGES里加上模块名PRODUCT_PACKAGES \ netd \ ping \ ping6 \ cursor.png \ platform.xml \ privapp-permissions-platform.xml \ pppd第四步如果这个资源还需要通过拷贝方式进镜像比如某些 sdk_base 场景在build/make/target/product/sdk_base.mk的PRODUCT_COPY_FILES里补一行PRODUCT_COPY_FILES : \ frameworks/native/data/etc/android.hardware.fingerprint.xml:system/etc/permissions/android.hardware.fingerprint.xml \ frameworks/native/data/etc/android.software.autofill.xml:system/etc/permissions/android.software.autofill.xml \ frameworks/av/media/libeffects/data/audio_effects.conf:system/etc/audio_effects.conf \ device/generic/goldfish/audio_policy.conf:system/etc/audio_policy.conf \ frameworks/base/data/etc/cursor.png:system/etc/cursor.pngPRODUCT_PACKAGES和PRODUCT_COPY_FILES的区别值得记一下前者是「编译出一个模块再装进镜像」后者是「直接把源文件拷到目标路径」不经过模块系统。预置二进制、配置类文件常用 COPY_FILES需要走模块依赖或带 class 的用 PACKAGES。两者可以同时存在但别对同一个文件重复配置否则可能出现覆盖顺序问题。如果你在工具协作时用到了 Cline MCP 或 Codex 的auth.json记得把 Base URL、Key、Model ID 三件套写全。Codex 的auth.json里字段名和 Claude Code 不同但语义一致缺 Model ID 会在请求阶段直接报模型不存在。Cline 的 MCP 配置同理Base URL 指向https://taotoken.net/apiKey 用控制台生成的那一个。配置改完编译命令按标准流程走source build/envsetup.sh lunch aosp_arm64-userdebug make -j$(nproc) systemimage只想快速验证资源模块可以先单编mmm frameworks/base/data/etc/单编通过后再整编能省不少时间。4. 验证资源是否成功打入 system.img编译过了不等于打进镜像了这一步必须实测。有三种验证方式从快到慢。第一种直接看 out 目录的中间产物。整编完成后ls -l out/target/product/device/system/etc/cursor.png如果这里没有说明PRODUCT_PACKAGES或PRODUCT_COPY_FILES没生效回到第 3 节检查拼写和路径。注意device换成你lunch时选的 target。第二种检查 system.img 内部。用simg2img把稀疏镜像转成 raw再挂载或解包simg2img out/target/product/device/system.img system_raw.img mkdir -p /mnt/sysimg sudo mount -o loop system_raw.img /mnt/sysimg ls -l /mnt/sysimg/system/etc/cursor.png sudo umount /mnt/sysimg如果挂载不方便也可以用debugfs直接读debugfs -R ls -l /system/etc system_raw.img第三种刷机后真机验证这是最可靠的adb root adb remount adb shell ls -l /system/etc/cursor.png adb shell md5sum /system/etc/cursor.png把设备上的 md5 和源文件对比md5sum frameworks/base/data/etc/cursor.png两个值一致说明文件完整打进去了。我试过在整编后只做第一种检查就以为万事大吉结果刷机发现文件是旧版本——因为增量编译缓存了旧的 system.img 片段。所以真机 md5 对比这一步别省。如果验证时发现文件存在但内容不对多半是PRODUCT_COPY_FILES的源路径写错或者有另一个模块覆盖了同一目标路径。用grep -rn cursor.png build/ frameworks/base/全局搜一下看有没有重复定义。5. 本篇常见报错与排查对照这一节列真实会遇到的报错对照着查。报错一build/make/core/main.mk:xxx: *** PRODUCT_PACKAGES: cursor.png not found这是模块名没被模块系统识别。原因通常是Android.mk没被 include 进当前 product 的模块扫描路径或者LOCAL_MODULE拼写和PRODUCT_PACKAGES里的不一致。检查frameworks/base/data/etc/Android.mk是否在build/make/target/product/的扫描范围内以及模块名大小写。Android 模块名区分大小写。报错二单编能过整编后 out 目录没有文件典型的两套机制只做了一半。Android.mk定义了模块但PRODUCT_PACKAGES没加整编就不会把它装进镜像。回到base.mk补上模块名。反过来如果只加了PRODUCT_COPY_FILES没定义模块拷贝能生效但模块依赖链里没有它某些场景会丢。报错三401 Unauthorized或local proxy failed这类是工具鉴权问题和编译无关。如果你在编译过程中调用了外部代码助手或模型工具报 401 说明 Key 没配或过期local proxy failed说明 Base URL 指向不对。检查三件套Base URL 是否为https://taotoken.net/api、Key 是否从控制台正确复制、Model ID 是否填了有效值。三个都对了还报错去接入文档核对字段名https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc报错四reading choices相关解析错误这通常出现在模型返回内容解析阶段工具拿到的响应格式和预期不符。先确认 Model ID 和工具要求的模型类型匹配再确认 Base URL 没有多余路径。有些工具会在 Base URL 后自动拼/v1/chat/completions如果你填的 URL 已经带了路径就会重复拼接。报错五OAuth 相关失败部分工具用 OAuth 流程而非直接 Key。这种情况下仍然需要把 Base URL 指向统一通道OAuth 的 token 获取地址和 API 地址要分开配。如果工具只支持 Key 模式就退回 Key 方式别混用。报错六刷机后文件是旧版本增量编译缓存导致。执行make installclean或删掉out/target/product/device/system/下对应文件再整编。最稳的是make clean后全量编一次虽然慢但能排除缓存干扰。排查顺序建议先看编译日志有没有模块相关 warning再看 out 中间产物最后真机验证。三步定位比盲目重编快得多。6. 把鉴权通道和编译链路分开管回到开头那个问题资源文件进不了 system.img根因几乎都在PRODUCT_PACKAGES/PRODUCT_COPY_FILES这一层和工具鉴权是两件独立的事。我的做法是把它们彻底分开管——编译链路只关心 mk 配置和 product 包列表工具鉴权统一走 TaoToken 一个 Key。这样分工的好处是构建机上不用为每个工具维护不同凭证换人换机器只改一处 Base URL 和 Key。需要长期跑编码或 Agent 任务时用 Coding Plan 的接入方式https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentcoding-plan临时验证模型或查报错直接开模型对话测一条https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmodel-chatKey 管理和文档入口固定在这两个地方收藏一下省得每次翻https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi-keys https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc最后留一个实用习惯每次改完Android.mk和 product 配置先mmm单编确认模块能出再整编最后一定做一次真机 md5 对比。这三步做完资源文件进 system.img 这件事基本不会再翻车。编译验证和工具鉴权各管各的出问题时排查范围也清晰。 相关新闻 半边结构:多边形网格处理的核心数据结构 有些东西,你不亲手写一遍数据结构,真的很难体会它为什么要设计成那样。多边形网格处理这本书的前面几章看起来像是在“复习数学”,等翻到关于网格表示那一章,才开始真正进入几何处理的腹地。今天我用一整篇的篇幅,把这… 2026/11/1 1:50:15 JavaScript执行顺序深度解析:从执行上下文到事件循环 JS 的执行顺序,不是靠“从上到下读一遍”就能搞定的。我见过不少人写代码几年,遇到变量提升、闭包、定时器回调混在一起时,照样踩坑。有一次线上有个功能时好时坏,查到最后,问题出在一个var变量在函数声明之前被使用&a… 2026/10/31 13:53:48 Python局域网设备扫描:ARP缓存表原理与多线程实现 1. 从一个真实需求说起:为什么要自己写局域网设备检测很多人第一次接触"局域网设备检测"这个概念,是因为家里或者办公室里遇到了一个很具体的问题:路由器后台显示的已连接设备列表里,出现了几个自己完全不认识的设备名。… 2026/10/31 19:39:08 最新新闻 1.c++入门篇 1.c中的关键字asmdoifreturntrycontinueautodoubleinlineshorttypedefforbooldynamic_castintsignedtypeidpublicbreakelselongsizeoftypenamethrowcaseenummutablestaticunionwchar_tcatchexplicitnamespacestatic_castunsigneddefaultcharexportnewstructusingfriendclassext… 2026/11/1 2:02:05 《江灯合声》:有可行的分框版,也仍可以选择连续鸣谢 武汉江岸区栎坡合唱团在免费节目册《江灯合声》中,以表格集中鸣谢资助者。各家共同要求改为独立小框,团里仍想保留表格。现有全名与支持事项清楚可见,双方此前未承诺具体排版。我支持保留表格。补充的试排材料让选择更具体:分框能… 2026/11/1 2:02:05 关于“贾子猜想”的数学地位、结构特征与讨论边界 关于“贾子猜想”的数学地位、结构特征与讨论边界摘要 本文对“贾子猜想”进行基于公开表述与现有数学事实的分析。该猜想主张:当正整数 n3m>5(即 n6,9,12,15,…)时,方程x₁ⁿ x₂ⁿ ⋯ xₙⁿ yⁿ不存在正整数解。文章首先… 2026/11/1 2:02:05 启动报Port 8088 was already in use?先查是谁占的 启动报Port 8088 was already in use?先查是谁占的 项目启动报 Port 8088 was already in use,意思很直白:这个端口已经有人占了。 先说原理:端口是"门牌号",一间房只住一个进程 端口就是一台机器上的门牌号… 2026/11/1 2:02:05 担心文档上云?本地运行的办公AI才敢放心用 单位上周开了个会,主题是"AI 提效",散会时领导补了一句:涉及客户资料的文档,不许往云端传。这话一出,会议室里本来跃跃欲试的同事全蔫了——大家平时用的那些在线 AI,文档一上传就不知道存哪儿去… 2026/11/1 2:02:04 zk使用--api讲解 1.zookeeper_init ZOOAPI zhandle_t *zookeeper_init(const char *host, // 服务器地址列表(可含 chroot)watcher_fn fn, // 全局 watcher 回调int recv_timeout, // 期望的会话超时(毫秒)const cl… 2026/11/1 1:59:04 日新闻 DRV8818+MK20DX128步进电机驱动方案:从电路到固件实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … 2026/11/1 1:02:01 DRV8818PWPR+PIC18LF46K40双极步进电机驱动实战指南 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … 2026/11/1 1:02:01 DRV8818PWPR与MK20DX128VFM5工业级双极步进控制协同设计 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … 2026/11/1 1:02:01 周新闻 DRV8818+MK20DX128步进电机驱动方案:从电路到固件实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … 2026/11/1 1:02:01 DRV8818PWPR+PIC18LF46K40双极步进电机驱动实战指南 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … 2026/11/1 1:02:01 DRV8818PWPR与MK20DX128VFM5工业级双极步进控制协同设计 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … 2026/11/1 1:02:01 月新闻 DRV8818+MK20DX128步进电机驱动方案:从电路到固件实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … 2026/11/1 1:02:01 DRV8818PWPR+PIC18LF46K40双极步进电机驱动实战指南 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … 2026/11/1 1:02:01 DRV8818PWPR与MK20DX128VFM5工业级双极步进控制协同设计 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … 2026/11/1 1:02:01
半边结构:多边形网格处理的核心数据结构 有些东西,你不亲手写一遍数据结构,真的很难体会它为什么要设计成那样。多边形网格处理这本书的前面几章看起来像是在“复习数学”,等翻到关于网格表示那一章,才开始真正进入几何处理的腹地。今天我用一整篇的篇幅,把这… 2026/11/1 1:50:15
JavaScript执行顺序深度解析:从执行上下文到事件循环 JS 的执行顺序,不是靠“从上到下读一遍”就能搞定的。我见过不少人写代码几年,遇到变量提升、闭包、定时器回调混在一起时,照样踩坑。有一次线上有个功能时好时坏,查到最后,问题出在一个var变量在函数声明之前被使用&a… 2026/10/31 13:53:48
Python局域网设备扫描:ARP缓存表原理与多线程实现 1. 从一个真实需求说起:为什么要自己写局域网设备检测很多人第一次接触"局域网设备检测"这个概念,是因为家里或者办公室里遇到了一个很具体的问题:路由器后台显示的已连接设备列表里,出现了几个自己完全不认识的设备名。… 2026/10/31 19:39:08
1.c++入门篇 1.c中的关键字asmdoifreturntrycontinueautodoubleinlineshorttypedefforbooldynamic_castintsignedtypeidpublicbreakelselongsizeoftypenamethrowcaseenummutablestaticunionwchar_tcatchexplicitnamespacestatic_castunsigneddefaultcharexportnewstructusingfriendclassext… 2026/11/1 2:02:05
《江灯合声》:有可行的分框版,也仍可以选择连续鸣谢 武汉江岸区栎坡合唱团在免费节目册《江灯合声》中,以表格集中鸣谢资助者。各家共同要求改为独立小框,团里仍想保留表格。现有全名与支持事项清楚可见,双方此前未承诺具体排版。我支持保留表格。补充的试排材料让选择更具体:分框能… 2026/11/1 2:02:05
关于“贾子猜想”的数学地位、结构特征与讨论边界 关于“贾子猜想”的数学地位、结构特征与讨论边界摘要 本文对“贾子猜想”进行基于公开表述与现有数学事实的分析。该猜想主张:当正整数 n3m>5(即 n6,9,12,15,…)时,方程x₁ⁿ x₂ⁿ ⋯ xₙⁿ yⁿ不存在正整数解。文章首先… 2026/11/1 2:02:05
启动报Port 8088 was already in use?先查是谁占的 启动报Port 8088 was already in use?先查是谁占的 项目启动报 Port 8088 was already in use,意思很直白:这个端口已经有人占了。 先说原理:端口是"门牌号",一间房只住一个进程 端口就是一台机器上的门牌号… 2026/11/1 2:02:05
担心文档上云?本地运行的办公AI才敢放心用 单位上周开了个会,主题是"AI 提效",散会时领导补了一句:涉及客户资料的文档,不许往云端传。这话一出,会议室里本来跃跃欲试的同事全蔫了——大家平时用的那些在线 AI,文档一上传就不知道存哪儿去… 2026/11/1 2:02:04
zk使用--api讲解 1.zookeeper_init ZOOAPI zhandle_t *zookeeper_init(const char *host, // 服务器地址列表(可含 chroot)watcher_fn fn, // 全局 watcher 回调int recv_timeout, // 期望的会话超时(毫秒)const cl… 2026/11/1 1:59:04
DRV8818+MK20DX128步进电机驱动方案:从电路到固件实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … 2026/11/1 1:02:01
DRV8818PWPR+PIC18LF46K40双极步进电机驱动实战指南 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … 2026/11/1 1:02:01
DRV8818PWPR与MK20DX128VFM5工业级双极步进控制协同设计 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … 2026/11/1 1:02:01
DRV8818+MK20DX128步进电机驱动方案:从电路到固件实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … 2026/11/1 1:02:01
DRV8818PWPR+PIC18LF46K40双极步进电机驱动实战指南 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … 2026/11/1 1:02:01
DRV8818PWPR与MK20DX128VFM5工业级双极步进控制协同设计 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … 2026/11/1 1:02:01
DRV8818+MK20DX128步进电机驱动方案:从电路到固件实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … 2026/11/1 1:02:01
DRV8818PWPR+PIC18LF46K40双极步进电机驱动实战指南 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … 2026/11/1 1:02:01
DRV8818PWPR与MK20DX128VFM5工业级双极步进控制协同设计 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … 2026/11/1 1:02:01