尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
全志T113-S3点亮ST7789V SPI屏:设备树与内核配置全流程
做嵌入式Linux这几年屏幕点亮这种事永远是新板卡bring-up的第一道门槛。尤其是SPI接口的小屏原理上就那么几根线可真到设备树、内核、驱动一层层往下翻的时候细节多到足够熬一个通宵。这次完整记录一下我为100ASK T113-S3核心板点亮一块ST7789V SPI屏的过程从硬件接线、设备树写法、内核配置到最后的fb-test验证整条链路走一遍方便以后少踩坑。板子用的是百问网那套100ASK T113-S3核心板加底板核心是全志T113-S3双核Cortex-A7配一颗RISC-V协处理器带64MB DDR3跑Linux很典型的低成本方案。屏是常见的中景圆1.3寸240x320 ST7789V IPS小板四线SPI接口。这套组合在工业屏显、智能家居面板、仪表盘项目里出镜率很高。这篇文章适合手里正好有T113-S3、或者在做类似全志平台SPI屏bring-up的朋友就算你用的不是这块屏只要驱动IC是ST7789、ILI9341、ST7735这些思路一模一样。1. 项目背景与硬件准备1.1 T113-S3核心板与SPI屏选型先简单交代一下硬件平台。全志T113-S3是一颗内置DDR3L的异构SoC双核ARM Cortex-A7频率最高到1.2GHz外加一颗主频200MHz的RISC-V核主要用于跑E907 RTOS做实时控制。整个CPU封装里直接集成了内存做核心板能把板子面积压得很小集成度高的同时成本也低所以很多百元级Linux Linux开发板、串口屏、HMI都选这颗料。100ASK T113-S3核心板把电源、DDR、Flash都做好了通过邮票孔引出一堆IO外接底板扩展。我这里用的是他们配套的独立底板板上引出了多路SPI、I2C、UART等接口。屏选的是ST7789V驱动的1.3寸IPS屏分辨率240x320四线SPI协议模块上自带LDO稳压、SD卡槽不用、3.3V电平转换。SPI屏的好处就是IO占用少CLK、MOSI、CS、DC、RESET、BL加起来六根线对于核心板引线紧张的场景非常友好。1.2 硬件接线与电平检查拿到屏先不要急着通电把模块原理图和数据手册的接线表抄下来确认每个引脚的意义。ST7789V模块常见引脚包括VCC、GND、SCL即SCK、SDA即MOSI、CS、DC也叫RS、RESET、BL。我这次接线按以下表格来屏模块引脚连接位置说明VCC底板3.3VST7789V供电模块上通常有稳压GND底板GND共地SCLT113-S3 SPI1_CLKSPI时钟SDAT113-S3 SPI1_MOSISPI主机输出CST113-S3 SPI1_CS0片选低有效DC任意GPIO我这里用PE4命令/数据切换必须由GPIO控制RESET任意GPIO我这里用PE5复位引脚低有效BL背光或用GPIO我直接用了一个GPIO加三极管驱动这里要特别提醒一句DC引脚千万不能图省事接到GND或VCC上。ST7789V在四线SPI模式下没有单独的地址线主控是用DC引脚的电平来区分当前发送的是命令还是显存数据。DC为低表示这个字节是命令DC为高表示这个字节是数据。如果DC处理不对驱动发的初始化命令和数据全乱套屏要么白屏要么花屏。另外RESET引脚建议接一个真正的GPIO而不是直接接上拉因为驱动在初始化前需要给一个完整的低脉冲时序很多屏就是因为硬件复位时序不对后面初始化指令怎么发都白搭。接线完成后先检查一遍电压用万用表确认屏模块VCC对GND是3.3V左右再把背光引脚临时接3.3V如果模块好背光应该能亮起来这时候屏是白屏是正常的因为还没初始化。这个步骤能提前排除掉模块本身坏掉或者供电不足的问题。1.3 初上电验证与SDK准备硬件确认正常后准备好Ubuntu下的交叉编译环境。T113-S3的Linux SDK通常有三种获取方式百问网的资料包、全志公开的Tina SDK、或者用Buildroot从源码构建。我这边用的是SDK自带的Buildroot环境交叉编译器用的是ARM Cortex-A7通用的arm-linux-gnueabihf-。如果是从零开始建议先把SDK解压出来跑一遍官方的环境初始化脚本。确认环境变量ARCHarm、CROSS_COMPILEarm-linux-gnueabihf-已经export然后进到kernel/目录先编一次出厂默认配置确认SDK本身没问题。这一步虽然耗时但能确保后面报错的时候不是因为你环境坏了而是因为你自己改动引入的问题。2. 驱动框架选型与内核配置2.1 fbtft还是DRM panelLinux内核里驱动SPI屏目前能看到两条路线。一条是老的fbtft框架对应的内核配置项是CONFIG_FB_TFT_ST7789V注册出来的节点直接就是/dev/fbN用起来很直接fb-test、fbset这些工具开箱即用。另一条是DRM框架下的panel驱动对应配置项是CONFIG_DRM_PANEL_SITRONIX_ST7789V走的是drm_paneldrm_connector这套标准流程同时通过DRM的fbdev仿真层也能生成/dev/fb0。那到底选哪个我的建议是新内核、新SDK直接用DRM panel。原因有三个第一fbtft内核维护者已经很少更新在5.10以上的内核里很多功能有明显的滞后感第二DRM panel是显示子系统未来的标准后面如果要把这个屏和RGB屏做多屏、叠加、旋转这些高级操作DRM支持得更好第三T113-S3自带的显示引擎默认就和DRM接轨走DRM驱动可以减少很多冲突。唯一的小麻烦是DRM框架概念多一些需要理解panel和connector的关系。如果你的SDK内核版本还停留在4.9、5.4这种老内核而且你只是想快速出图走fbtft也不是不行设备树写法差不多只是最终节点不依赖DRM。这篇文章后续以DRM panel为主线来写。2.2 内核配置项逐条说明确认使用DRM panel之后在内核源码目录运行make menuconfig把下面几个关键项配置好CONFIG_DRMy或者CONFIG_DRMmDRM核心框架必须开CONFIG_DRM_PANELypanel框架层的总开关CONFIG_DRM_PANEL_SITRONIX_ST7789Vy这是ST7789V的panel驱动如果驱动IC是ILI9341则选对应的CONFIG_DRM_PANEL_ILITEK_ILI9341CONFIG_DRM_FBDEV_EMULATIONy这个非常关键不开的话DRM框架不会生成/dev/fb0后续fb-test就没法用CONFIG_FByfbdev基础框架配合DRM emulation使用CONFIG_BACKLIGHT_CLASS_DEVICEy背光设备class框架如果背光走GPIO或PWM都需要依赖它CONFIG_BACKLIGHT_PWMy仅当使用PWM背光时开配置路径大概在Device Drivers - Graphics support - DRM - Panel drivers - Sitronix ST7789V panel driver。菜单里不一定能看到中文但英文名字就是上面这些。如果使用make t113_100ask_defconfig这种SDK默认配置一般DRM框架默认已经打开了你只需要确认panel驱动和fbdev emulation有没有被选上。配置的时候顺便看一眼有没有把多个panel驱动都编进内核。比如你内核默认带了RGB屏的驱动可能影响DRM device的创建顺序带来莫名的问题。我这里关闭了不需要的显示控制器相关驱动减少变量。2.3 交叉编译环境验证在Ubuntu上编译内核前先检查交叉编译工具链是否可用。比较稳的命令source /your/sdk/path/build/envsetup.sh export ARCHarm export CROSS_COMPILEarm-linux-gnueabihf- arm-linux-gnueabihf-gcc -v看到版本信息后进入kernel/目录先编译一次原来的配置确保链路是通的make t113_100ask_defconfig make -j$(nproc)这一步能过说明你的工具链和SDK源码基本没有大问题。如果我按官方教程第一次编译就卡在头文件缺失、找不到lib等报错优先检查是不是SDK里带了固定的toolchain路径别自己乱装了一个新工具链就硬编。很多“最坑”的编译错误其实都是交叉编译器版本和老内核头文件不匹配导致的。3. 设备树配置详解3.1 SPI控制器与pinctrl配置设备树是整个SPI屏bring-up的核心环节。T113-S3内部有多个SPI控制器具体哪个可以用要看SoC的引脚复用关系。我这边选用了SPI1对应设备树节点为spi1。在设备树里做两件事一是打开SPI控制器二是设置引脚复用为SPI功能。引脚复用由pinctrl子系统完成。需要根据原理图确认CLK、MOSI、CS这块实际连到T113-S3的哪个pad我这里是PE0-PE3四根线。设备树中先定义一组pinctrlpio { spi1_pins: spi1-pins { pins PE0, PE1, PE2, PE3; function spi1; bias-pull-up; }; };然后SPI控制器节点改成这样spi1 { pinctrl-names default; pinctrl-0 spi1_pins; status okay; };为什么必须写pinctrl-names和pinctrl-0因为Linux驱动在probe阶段会主动去解析这两个属性主动把引脚复用切到spi1功能。如果只写了status okay而没配pinctrl默认引脚可能还是GPIO输入模式时钟和数据信号完全出不去屏怎么都不可能亮。注意如果SPI控制器挂的是Nor Flash而不是屏不要再往同一个控制器下面加panel节点片选和内容会冲突。T113-S3的SPI0在很多板卡上被系统Flash占用所以SPI屏尽量挂在SPI1上这是一个很实用的经验。3.2 SPI屏panel节点配置在spi1节点下添加一个panel子节点。ST7789V DRM面板驱动的绑定说明compatible字符串应该写成sitronix,st7789v。完整写法如下spi1 { pinctrl-names default; pinctrl-0 spi1_pins; status okay; st7789v_panel: st7789v0 { compatible sitronix,st7789v; reg 0; spi-max-frequency 20000000; rotate 90; rgb-order rgb; fps 30; reset-gpios pio PE 5 GPIO_ACTIVE_LOW; dc-gpios pio PE 4 GPIO_ACTIVE_LOW; backlight backlight; status okay; }; };逐个属性说清楚reg 0对应接在SPI控制器的CS0上也就是硬件上片选线连的引脚。如果接CS1这里写成1。spi-max-frequency是软件告诉Linux SPI主控制器给这个设备发送数据时的最高时钟。ST7789V手册标称四线SPI最高到32MHz但实际用杜邦线连接时我一般都先降到20MHz等确认没问题再往上提。为什么因为杜邦线、排针的寄生电容和串扰很大高频下波形明显畸变信号质量差到一定程度就会出现花屏而且这个花屏还是偶发的排查起来非常折磨人。rotate是驱动支持的面板旋转角度可选0/90/180/270。如果你的屏画面上下面倒置不要急着在应用层翻转直接把这里改成90或者270就行驱动会通过MADCTL寄存器把扫描方向调对。rgb-order控制颜色分量是RGB还是BGR。有些屏模块的像素排布就是BGR如果这里配置错画面颜色会偏红蓝互换。reset-gpios配PE5低有效驱动在初始化前会先拉低再拉高完成硬件复位。dc-gpios配PE4低有效这个说法容易误解实际DC引脚是“低命令、高数据”属性里的GPIO_ACTIVE_LOW仅表示驱动框架如何逻辑取反最关键的是这个引脚必须确实被面板驱动控制才能正确发送命令/数据。3.3 背光节点配置背光有两条路PWM背光和GPIO背光。PWM效果细腻亮度可调但需要额外确认T113-S3的PWM控制器配置。GPIO背光简单粗暴一个GPIO就能决定亮灭非常适合先把屏点亮这个阶段。我这里先用GPIO背光设备树顶层节点这样写/ { backlight: gpio-backlight { compatible gpio-backlight; gpios pio PE 6 GPIO_ACTIVE_HIGH; default-on; status okay; }; };然后在panel节点里已经用backlight backlight挂上了这个背光设备。这样做的意义在于用户空间可以通过标准的/sys/class/backlight/gpio-backlight/brightness接口直接开关背光驱动也会在probe后自动把背光设备enable起来。如果你确定要用PWM背光节点改成这样/ { backlight: pwm-backlight { compatible pwm-backlight; pwms pwm 0 5000000 0; brightness-levels 0 10 20 30 50 70 90 255; default-brightness-level 7; }; };这里pwms里的5000000单位是纳秒对应200Hz的PWM频率屏幕背光在200Hz以上基本看不到闪烁。还是那句话先把GPIO背光跑通后面再换PWM不迟。3.4 设备树编译与检查设备树写好后不能直接在源码目录里肉眼检查就完事要编译成dtb再逆编译验证。命令如下make dtbs如果有语法错误编译过程会直接报错。编译通过后用dtc工具把dtb转回dts看看内容dtc -I dtb -O dts arch/arm/boot/dts/sun8i-t113s3-100ask.dtb | grep -A 20 st7789v确认面板节点、背光节点都在。这个步骤很值得做因为设备树编译有时候会把不合法属性默默地丢掉或者被__overrides__机制改了肉眼看不出来逆编译之后能看到真实生效的树结构。如果板子已经能启动也可以启动后在板子端用ls /proc/device-tree/st7789v0确认设备树有没有加载到内核里。不过这一步通常等烧录后再说。4. 内核编译与烧录启动4.1 menuconfig开启选项进入内核源码目录执行make menuconfig逐项确认Device Drivers - Graphics support - * DRM driver support for Allwinner SoCs [*] Enable legacy fbdev support * Panel driver - Sitronix ST7789V panel driver Device Drivers - Backlight LCD device support - * Lowlevel Backlight controls * GPIO Backlight Driver如果SDK默认CONFIG_DRM_*已经开了但panel驱动没开这里手动选上就行。选完保存退出最好diff一下.config确认改动的位置。这一步我建议每次改配置前备份.config因为make的时候偶尔会静默地把一些依赖项改掉出问题回溯很麻烦。4.2 编译内核并生成boot镜像配置完成后开始编译make zImage -j8 make dtbszImage生成位置在arch/arm/boot/zImage设备树文件在arch/arm/boot/dts/。如果需要打包成Android风格的boot.img可以用SDK自带的mkbootimg工具mkbootimg --kernel arch/arm/boot/zImage \ --dtb arch/arm/boot/dts/sun8i-t113s3-100ask.dtb \ --output boot.img如果直接使用Buildroot整包编译一般make之后会在output/images里生成完整的烧录镜像。我觉得SPI屏调试阶段最好别每次烧整个系统镜像太慢了。直接把boot.img单独打包替换启动分区启动链路不变调试循环会快非常多。4.3 烧录启动并盯dmesg烧录方式取决于你的板卡支持SD卡启动还是EMMC写入。100ASK T113-S3底板一般提供PhoenixUSB烧录口用PhoenixSuit软件可以直接烧录整个镜像如果只是更新内核也可以接SD卡启动把boot.img放到SD卡对应分区。烧录后上电立刻在串口终端盯内核日志重点关注两行dmesg | grep -i st7789 dmesg | grep -i panel正常情况下能看到类似st7789v spi1.0: probed panel-st7789v spi1.0: fb0: ST7789V frame buffer device如果只看到设备被注册但报failed to get GPIO之类说明设备树里的reset-gpios、dc-gpios引脚的宏写错了回去翻include/dt-bindings/gpio/gpio.h确认GPIO_ACTIVE_LOW宏的数值和含义。再把/sys/class/drm/目录列出来ls /sys/class/drm/能看到card0-DSI-1或者card0-DPANEL-1这种节点说明DRM面板已经注册成功。到这里内核侧基本就结束了剩下就是应用层测试。5. fb-test测试与显示验证5.1 确认framebuffer设备前面开了DRM fbdev emulation启动后查看ls -l /dev/fb* cat /proc/fb如果看到0 st7789v或者0 panel-uixxxxx说明fb0已经属于这块屏了。/proc/fb输出第一列数字就是fb设备编号后面的名字是驱动identify里注册的。假如fb0被其他显示设备抢占了你得去查有没有多个DRM设备或者把不需要的显示控制器在内核里关掉。查看分辨率信息fbset -fb /dev/fb0 -xres 240 -yres 320 -vxres 240 -vyres 320 -depth 16 fbset -fb /dev/fb0-depth 16是ST7789V最常见也是驱动默认的RGB565格式每个像素16bit高5位红、中间6位绿、低5位蓝。如果你的屏是18bit RGB666某些场景下颜色饱和度和条纹问题会比较明显先不管16bit足够测试。5.2 fb-test工具基本用法fb-test是一个专门用来做framebuffer显示测试的小工具在Buildroot里直接勾选fb-test或者Ubuntu下apt install fb-test交叉编译。如果SDK没有带这个包源码也就几百行手动编译也不难。板子端运行fb-test屏幕上会依次呈现纯红、绿、蓝、白、黑等画面和一些条纹按键切换。命令本身的参数不多支持-r红色、-g绿色、-b蓝色、-w白色等fb-test -r fb-test -g fb-test -w如果你只是要快速验证framer不改fbset分辨率直接跑fb-test画面可能只占了屏幕一角或者显示错乱。所以先跑一遍fbset把分辨率设对再跑fb-test。很多朋友第一次测屏发现显示不全问题就出在这。5.3 不依赖工具直接写像素验证有时候设备上没装fb-test或者你更想验证自己在用户空间操作framebuffer的能力。可以写一个超级简单的C程序往fb0里填纯色#include stdio.h #include fcntl.h #include sys/mman.h #include sys/ioctl.h #include linux/fb.h int main(void) { int fd open(/dev/fb0, O_RDWR); if (fd 0) { perror(open /dev/fb0); return -1; } struct fb_var_screeninfo vinfo; ioctl(fd, FBIOGET_VSCREENINFO, vinfo); unsigned short *fbp mmap(NULL, vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (fbp MAP_FAILED) { perror(mmap); return -1; } unsigned short red 0xf800; /* RGB565 红色 */ unsigned short green 0x07e0; /* RGB565 绿色 */ unsigned short blue 0x001f; /* RGB565 蓝色 */ for (int i 0; i vinfo.xres * vinfo.yres; i) { if (i vinfo.xres * vinfo.yres / 3) fbp[i] red; else if (i vinfo.xres * vinfo.yres * 2 / 3) fbp[i] green; else fbp[i] blue; } munmap(fbp, vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8); close(fd); return 0; }交叉编译后拷到板子运行arm-linux-gnueabihf-gcc -o fbcolor fbcolor.c adb push fbcolor /tmp/ chmod x /tmp/fbcolor /tmp/fbcolor如果横屏竖屏切换不对可以顺便把设备树里rotate属性改一下重新编译。这个写像素的过程比单纯看fb-test画面更能确认颜色排布是否正确RGB565的高低字节顺序对不对实测很管用。还有一个更省事的方式直接dd写一段数据到fb0效果也很直观dd if/dev/urandom of/dev/fb0 bs1024 count50看到雪花状的花屏说明DMA路径和内存访问都正常只是数据没有意义看到纯色说明framebuffer确实被映射到了屏上。如果你连这一步都没有任何显示变化说明framebuffer数据根本没到屏上问题多半在内核panel驱动或SPI通信而不是用户空间。6. 常见问题排查与避坑实录6.1 白屏/黑屏问题白屏在SPI屏调试里是最经典的现象。白屏说明背光和供电没问题但panel没有接收到有效初始化命令或者初始化过程中途失败了。排查顺序先看dmesg有没有st7789v的probe日志。如果没有设备树compatible没对上或者panel节点没挂进SPI总线检查reg和status。如果有probe日志但白屏重点查reset时序。驱动拉低reset引脚后必须保持足够时间再拉高有些屏模块的复位引脚接了个大电容延时不够会复位不彻底可以试试把驱动里reset delay调长或者硬件上手动短接一下RESET到地再松开看屏是否出了初始化效果。检查DC引脚。DC接错会导致所有命令被当成数据送到显存看起来就是屏白得发光。用万用表量一下驱动probe期间DC引脚有没有电平变化。检查SPI时钟。把spi-max-frequency降到8MHz排除信号完整性导致的初始化命令被误码。6.2 花屏/颜色不对问题花屏分两种画面有内容但错乱和颜色整体偏色。画面错乱一般是分辨率、扫描方向或SPI时序问题。先在设备树里把rotate调整一遍常见是0和90的差异。如果旋转属性改完还是花把spi-max-frequency降下来再测。为什么高频会花ST7789V对SPI时序要求其实不高但杜邦线连接时寄生电容会把上升沿拉慢在高bitrate下一个bit的建立时间都不够数据就采错了。工业底板如果走线短而均匀上到30MHz都不一定有问题调试期先用10-20MHz是稳的办法。颜色偏色主要是rgb-order配置错误把rgb改成bgr重新编译设备树就好。注意DRM panel驱动的rgb-order属性不是所有内核版本都支持如果你内核较老可能需要在内核的驱动源码里直接改panel-rgb_order这个不太优雅但能解决问题。6.3 /dev/fb0未生成/dev/fb0不存在多半不是panel驱动问题而是fbdev仿真层没开。确认内核配置里CONFIG_DRM_FBDEV_EMULATIONy、CONFIG_FBy。有时候虽然编译进去了但fbdev emulation要求在用户空间有/dev/dri/card0权限跑fb-test时如果是root用户一般没问题如果用的是普通用户要先chmod 777 /dev/dri/card0或者使用udev规则。也可能系统里存在多个显示设备如RGB LCD、HDMI同时注册fb0被非SPI屏占用。此时先用cat /proc/fb看清楚哪个fb是ST7789V如果是fb1之类直接fbset -fb /dev/fb1来测试。真正常用的办法还是在设备树里只保留SPI panel把用不到的显示控制器全部disable这样fb0一定是你的屏。6.4 背光不亮问题背光不亮有两种情况一是背光控制的GPIO没有正确配置二是背光设备树节点没被panel引用。如果用的是gpio-backlight启动后执行cat /sys/class/backlight/gpio-backlight/brightness默认应该是255如果不是手动写一下echo 255 /sys/class/backlight/gpio-backlight/brightness如果手动写完背光亮了说明硬件通路没问题是设备树里default-on属性没生效或者驱动probe失败。还有种情况最常见屏模块的背光引脚直接接GPIO但模块上背光串阻很大导致电流不足这时候量一下背光引脚电压如果驱动能力不够用一个三极管或者MOS管做开关控制背光不要直接让GPIO去推。6.5 一个实操汇总表把我在这个项目里遇到的关键问题整理成速查表现象优先怀疑项排查命令/操作完全白屏设备树没生效或reset时序dmesg抓st7789v日志白屏且dmesg无日志compatible不匹配dtc逆编译查看dtb花屏乱码SPI频率太高或rotate不对降频率到8MHz、改rotate颜色红蓝互换rgb-order配置错误设备树改为bgr/dev/fb0不存在DRM fbdev emulation没开查CONFIG_DRM_FBDEV_EMULATION背光不亮背光GPIO或PWM配置错误cat /sys/class/backlight/*/brightness画面只有一角fbset分辨率不对fbset -fb /dev/fb0 -xres 240 -yres 320调试的时候我习惯每改一次设备树就把dtb逆编译一次对比差异确认改动真的进了二进制镜像。这个方法虽然土但在多个overlay叠加、SDK自动处理设备树的地方能避免很多“明明改了却不生效”的诡异问题。这次点亮过程中我最大一个体会是SPI屏bring-up八成的坑不是驱动代码本身而是硬件信号、引脚复用、设备树属性这些“看起来没技术含量”的地方。特别是GPIO背光和DC引脚就两个电平的事搞错了能折腾你一晚上。先把频率压低、把引脚核对清楚、把dmesg每一行都看明白剩下的事情水到渠成。另外一个建议是调试阶段尽量用相同品牌、相同接口的屏做替换验证排除屏个体差异很多花屏问题换一块屏就好了别死磕代码。如果后面想做亮度调节、睡眠唤醒、局部刷新这些高级功能只要这次设备树框架搭对了都是顺水推舟的事。
RELATED

相关推荐

用 Vega 绘制小提琴图(Violin Plot):KDE 核密度估计变换完整实战解析

用 Vega 绘制小提琴图(Violin Plot):KDE 核密度估计变换完整实战解析

数据可视化 【免费下载链接】vega A visualization grammar. 项目地址: https://gitcode.com/gh_mirrors/ve/vega 点击查看 免费下载 小提琴图(violin plot)把一组定量数据的分布可视化为概率密度函数的连续近似,是比箱线图信息量…

📅 2026/9/24 10:59:36
GB/T 27930-2015直流充电CAN报文交互详解:从握手到统计

GB/T 27930-2015直流充电CAN报文交互详解:从握手到统计

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

📅 2026/9/24 10:59:36
RootlessJamesDSP:安卓无Root全局音频DSP技术解析

RootlessJamesDSP:安卓无Root全局音频DSP技术解析

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

📅 2026/9/24 10:59:36
MORE NEWS

更多资讯

📰

把网络安全意识PPT变成可运行的代码和自动化脚本

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

📰

LRU 缓存算法详解

LRU 缓存算法 一、什么是 LRU LRU(Least Recently Used,最近最少使用)是一种常见的缓存淘汰策略。 核心思想:当缓存空间满了,优先淘汰"最久没有被访问过"的数据,因为我们认为"最近被访问过的…

📰

A2B数字麦克风从零跑通:AD2428主从配置与SigmaStudio实战

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

📰

科研AI工作台选型指南:Cursor、Codex、Papers AI、CoCalc与Deepnote实操对比

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

📰

STM32 VBAT电路设计避坑指南:从RTC失效到工业级可靠供电

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

📰

代理IP 接入决策树:按语言、并发、目标站三个条件选方案

选代理IP这件事,说简单也简单——无非是发请求时多填一个地址。说复杂也复杂——选错了类型,代码怎么写都跑不通;选错了轮换策略,跑了一半才发现IP大面积失效。大多数团队在选型时习惯直接问“哪家IP池大、哪家便宜”,…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬