STM32F407 FLASH读写保护实战:RDP/WRP配置与量产避坑指南

简介:这份资源面向使用STM32F407进行嵌入式开发的工程师与学习者,聚焦FLASH读写保护与解除这一安全配置主题。STM32F407基于ARM Cortex-M4内核,其FLASH存储程序代码与配置数据,读保护可防止敏感信息被非法读取,写保护则阻止代码被篡改或擦除,二者均通过选项字节与特定寄存器序列实现。资源包共129个文件,以58个h头文件与49个c源文件为主体,另含12个s汇编启动文件及uvprojx、uvoptx等Keil工程文件,压缩包约771KB,可直接导入工程编译调试。内容围绕HAL与LL库函数展开,涵盖解锁FLASH控制器、配置保护等级、查询FLASH_OBSTAT状态位以及选项字节设置等关键环节,并给出完整的设置与解除流程示例。已有1176人学习下载,适合希望掌握固件安全机制、提升项目可靠性的开发者参考实践。

1. 从一次量产翻车说起:STM32F407 固件库下的 FLASH 读写保护到底在防谁

某次小批量试产,两百块板子烧完程序发到现场,三个月后陆续回来十几块,症状出奇一致:程序跑飞、参数区数据被改得面目全非。拆机读回 FLASH,发现是现场调试口被误接、上位机误发擦写指令,把参数区整段抹了。事后复盘,问题不在代码逻辑,而在没人给 FLASH 上锁。STM32F407 固件库这套东西,读写保护(RDP/WRP)就是干这个的——它不解决你代码写得对不对,它解决的是"别人能不能动你的 FLASH"。这篇笔记讲的就是用标准外设库把 F407 的读保护、写保护配起来,以及怎么在需要升级时安全解除。适合正在做量产固件、需要防抄板防误擦、或者被现场返修折腾过的嵌入式工程师。下面所有操作基于 STM32F4xx 标准外设库(StdPeriph Lib),HAL 库思路一致但寄存器封装不同,我会在关键处点出来。

2. FLASH 读写保护的寄存器模型:先搞懂 RDP 和 WRP 在保护什么

动手之前必须把概念钉死,否则后面解除保护时一个选项字节写错,芯片直接锁死,那才是真的血泪经验。F407 的 FLASH 保护分两层,作用对象完全不同,很多人混着用,结果该保护的没保护住。

2.1 读保护 RDP:保护的是整片 FLASH 的读出通道

读保护(Read Protection)作用在整片主 FLASH 上,它不阻止你写,它阻止的是通过调试口(JTAG/SWD)或从 RAM 启动的代码去读 FLASH 内容。RDP 有三个等级:

等级选项字节值行为
Level 00xAA无保护,调试口可读可写
Level 1非 0xAA(常见 0x00)调试口无法读 FLASH,从 RAM 启动的代码也读不到,但用户程序自己可以正常读写
Level 20xCC永久保护,调试口彻底禁用,且不可逆

关键点:Level 1 下,你的应用程序自己访问 FLASH 是完全正常的,被挡住的只有外部调试通道和从 RAM 运行的代码。这就是为什么量产固件一般设 Level 1——现场能跑,但别人接上仿真器读不出你的固件。Level 2 是单向门,设了就回不来,除非换芯片,量产慎用。

2.2 写保护 WRP:保护的是指定扇区的写入和擦除

写保护(Write Protection)按扇区粒度生效,F407 主 FLASH 有 12 个扇区(0~11),每个扇区对应选项字节里的一个 bit。被写保护的扇区,擦除和编程操作会被硬件拒绝,FLASH_SR 寄存器里的 WRPERR 位置位。注意它只防写防擦,不防读——读保护才防读。

F407 的扇区划分和 WRP 位对应关系如下:

扇区起始地址大小对应 WRP 位
Sector 00x0800000016KBWRP0 bit0
Sector 10x0800400016KBWRP0 bit1
Sector 20x0800800016KBWRP0 bit2
Sector 30x0800C00016KBWRP0 bit3
Sector 40x0801000064KBWRP0 bit4
Sector 50x08020000128KBWRP0 bit5
............
Sector 110x080E0000128KBWRP1 bit3

典型做法:Bootloader 放 Sector 0~3,参数区放 Sector 4,应用程序放 Sector 5 以后。写保护只保护 Bootloader 和参数区,应用程序区留空以便 OTA 升级。这个划分不是拍脑袋,是让"不该被改的"和"需要被改的"物理隔离。

2.3 选项字节:所有保护的唯一入口

RDP 和 WRP 都写在选项字节(Option Bytes)里,不是普通 FLASH 地址。F407 的选项字节结构里,RDP 是一个字节,WRP 是 WRP0~WRP3 四个字节,还有 BOR、用户字节等。修改选项字节必须走解锁→擦除→编程→重载的固定流程,任何一步顺序错了都会失败。标准库把这套流程封装在 FLASH_OB_* 系列函数里,但底层时序还是得自己盯。

3. 用标准库设置读保护:从解锁到生效的完整代码

这一章给可直接抄的代码。环境是 STM32F407 + StdPeriph Lib,工程里已经包含 stm32f4xx_flash.c。设置读保护的核心是 FLASH_OB_RDPConfig,但前面必须解锁 FLASH 和选项字节,后面必须触发选项字节重载。

3.1 设置 RDP Level 1 的完整函数

#include "stm32f4xx_flash.h" /* 设置读保护为 Level 1,返回 0 成功,非 0 失败 */ uint8_t FLASH_SetReadProtection(void) { FLASH_Status status; /* 1. 解锁 FLASH 控制器,否则后续所有操作被拒 */ FLASH_Unlock(); /* 2. 解锁选项字节控制寄存器,这一步容易被漏掉 */ FLASH_OB_Unlock(); /* 3. 等待上一次操作彻底结束,BUSY 位不清零就动手必翻车 */ status = FLASH_WaitForLastOperation(); if (status != FLASH_COMPLETE) { FLASH_OB_Lock(); FLASH_Lock(); return 1; } /* 4. 写入 RDP Level 1,标准库用 NewRDPLevel 参数 */ status = FLASH_OB_RDPConfig(OB_RDP_Level_1); if (status != FLASH_COMPLETE) { FLASH_OB_Lock(); FLASH_Lock(); return 2; } /* 5. 触发选项字节重载,让新配置立即生效 */ FLASH_OB_Launch(); /* 6. 重新上锁,生产代码不要长期保持解锁状态 */ FLASH_OB_Lock(); FLASH_Lock(); return 0; }

逻辑说明:第 1、2 步是两个独立的解锁,FLASH_Unlock 管主 FLASH 编程,FLASH_OB_Unlock 管选项字节,少一个都会返回错误。第 3 步的 FLASH_WaitForLastOperation 是保险,如果上电后有过未完成的擦写,直接写选项字节会失败。第 4 步 OB_RDP_Level_1 是标准库定义的宏,对应写入非 0xAA 值。第 5 步 FLASH_OB_Launch 会触发一次系统复位级别的重载,执行到这里芯片行为会短暂异常,不要在中断上下文里调用。

参数说明:OB_RDP_Level_1 是标准库枚举,不要自己填 0x00,不同库版本对 Level 1 的具体值定义可能不同,用宏最稳。如果你要设 Level 0(解除保护),传 OB_RDP_Level_0。

3.2 验证读保护是否真的生效

设完不能只看返回值,得实际验证。最直接的方法是用调试器读 FLASH 首地址:

/* 在调试器里执行,或写进测试代码 */ volatile uint32_t *pFlash = (volatile uint32_t *)0x08000000; uint32_t val = *pFlash; /* Level 1 生效时,调试器读这里会报错或返回全 0 */

如果 RDP Level 1 生效,通过 SWD 调试器读 0x08000000 会触发总线错误,或者读回全 0。注意:这个验证必须在"调试器连接"的场景下做,用户程序自己读是正常的。另一个验证点是看 FLASH_OB_GetRDP() 的返回值,标准库提供这个函数,返回 RESET 表示 Level 1 已生效。

3.3 设置写保护的代码与扇区掩码计算

写保护按扇区来,标准库用 FLASH_OB_WRPConfig 配置,参数是扇区号和使能状态。但 F407 的 WRP 是位掩码,标准库封装成了逐个扇区调用:

/* 保护 Sector 0~4,即 Bootloader 和参数区 */ uint8_t FLASH_SetWriteProtection(void) { FLASH_Status status; FLASH_Unlock(); FLASH_OB_Unlock(); /* 逐个扇区使能写保护,OB_WRP_Sector_0 到 OB_WRP_Sector_4 是库宏 */ status = FLASH_OB_WRPConfig(OB_WRP_Sector_0, ENABLE); if (status != FLASH_COMPLETE) goto fail; status = FLASH_OB_WRPConfig(OB_WRP_Sector_1, ENABLE); if (status != FLASH_COMPLETE) goto fail; status = FLASH_OB_WRPConfig(OB_WRP_Sector_2, ENABLE); if (status != FLASH_COMPLETE) goto fail; status = FLASH_OB_WRPConfig(OB_WRP_Sector_3, ENABLE); if (status != FLASH_COMPLETE) goto fail; status = FLASH_OB_WRPConfig(OB_WRP_Sector_4, ENABLE); if (status != FLASH_COMPLETE) goto fail; FLASH_OB_Launch(); FLASH_OB_Lock(); FLASH_Lock(); return 0; fail: FLASH_OB_Lock(); FLASH_Lock(); return 1; }

逻辑说明:每次 FLASH_OB_WRPConfig 调用都会改写选项字节,连续调用多次会反复擦写选项字节区。选项字节的擦写寿命有限(数据手册标称 10k 次左右),所以生产代码里不要频繁调用这个函数,一次配好就行。更稳妥的做法是先把所有扇区的掩码算好,用寄存器直接写一次,但标准库没提供批量接口,逐个调用是常见做法。

参数说明:OB_WRP_Sector_0 到 OB_WRP_Sector_11 是标准库宏,对应不同扇区。ENABLE/DISABLE 控制使能。注意 F407 的 WRP 位是"1 表示保护",和某些系列相反,标准库已经处理了这个映射,用宏就不会错。

4. 解除读写保护:升级和返修时怎么安全开锁

保护设上去容易,解除才是真正容易出事的地方。RDP 从 Level 1 降回 Level 0 会触发整片 FLASH 擦除,这是硬件行为,不是可选项。很多人不知道这一点,解除保护后程序没了,现场直接懵。这一章把解除流程和后果讲清楚。

4.1 解除读保护:整片擦除是硬性代价

/* 解除读保护,注意:此操作会擦除整片主 FLASH */ uint8_t FLASH_DisableReadProtection(void) { FLASH_Status status; FLASH_Unlock(); FLASH_OB_Unlock(); /* 写回 Level 0 */ status = FLASH_OB_RDPConfig(OB_RDP_Level_0); if (status != FLASH_COMPLETE) { FLASH_OB_Lock(); FLASH_Lock(); return 1; } /* 重载后芯片会执行整片擦除,耗时较长,不要在此期间断电 */ FLASH_OB_Launch(); FLASH_OB_Lock(); FLASH_Lock(); return 0; }

逻辑说明:FLASH_OB_RDPConfig(OB_RDP_Level_0) 写入后,FLASH_OB_Launch 触发的重载会启动整片擦除。这个擦除是硬件自动完成的,时间取决于芯片容量,F407 大容量型号可能几百毫秒到一秒。期间绝对不能断电,否则芯片可能进入不确定状态。擦除完成后,调试口恢复可读,但你的固件已经没了,需要重新烧录。

参数说明:解除读保护没有"部分解除"的说法,Level 1 到 Level 0 就是全擦。如果你只是想临时读一下固件,正确做法是在设保护之前就留好备份,而不是事后解除。

4.2 解除写保护:不擦除,但要注意扇区状态

写保护的解除比读保护温和,不会触发擦除:

/* 解除 Sector 0~4 的写保护 */ uint8_t FLASH_DisableWriteProtection(void) { FLASH_Status status; FLASH_Unlock(); FLASH_OB_Unlock(); status = FLASH_OB_WRPConfig(OB_WRP_Sector_0, DISABLE); if (status != FLASH_COMPLETE) goto fail; status = FLASH_OB_WRPConfig(OB_WRP_Sector_1, DISABLE); if (status != FLASH_COMPLETE) goto fail; status = FLASH_OB_WRPConfig(OB_WRP_Sector_2, DISABLE); if (status != FLASH_COMPLETE) goto fail; status = FLASH_OB_WRPConfig(OB_WRP_Sector_3, DISABLE); if (status != FLASH_COMPLETE) goto fail; status = FLASH_OB_WRPConfig(OB_WRP_Sector_4, DISABLE); if (status != FLASH_COMPLETE) goto fail; FLASH_OB_Launch(); FLASH_OB_Lock(); FLASH_Lock(); return 0; fail: FLASH_OB_Lock(); FLASH_Lock(); return 1; }

逻辑说明:解除写保护后,对应扇区恢复可擦写。但注意,如果之前扇区里有数据,解除保护不会动数据,只是允许你后续擦写。实际升级流程里,通常是先解除写保护,再擦除目标扇区,再写入新固件,最后重新设保护。

参数说明:DISABLE 对应清除 WRP 位。和设置时一样,逐个扇区调用会反复擦写选项字节,建议只在升级流程里做一次。

4.3 升级场景下的推荐顺序

把上面的操作串成一条升级流水线,顺序不能乱:

  1. 进入 Bootloader,确认当前 RDP 状态(FLASH_OB_GetRDP)
  2. 解除目标扇区的写保护(只解要升级的扇区,别全解)
  3. 擦除目标扇区
  4. 写入新固件数据
  5. 校验写入内容(读回比对)
  6. 重新使能写保护
  7. 跳转到应用程序

这个顺序里,第 2 步只解必要扇区是关键。如果全解再全设,选项字节被反复擦写,寿命消耗快,而且中间窗口期保护是空的。

5. 避坑与排查:选项字节操作里最容易翻车的五个点

这一章全是踩过的坑,每条按现象、原因、解决写。选项字节这东西,出错往往不是代码逻辑问题,而是时序、状态、硬件行为没对齐。

5.1 现象:FLASH_OB_RDPConfig 返回 FLASH_ERROR_PG,写不进去

原因:选项字节解锁没做,或者上一次操作还没完成就发起新操作。F407 的选项字节编程要求 FLASH_CR 的 OPTLOCK 位为 0,且 BSY 位为 0。很多人只调了 FLASH_Unlock,忘了 FLASH_OB_Unlock,或者连续调用两个 OB 函数中间没等 BUSY 清零。

解决:每次选项字节操作前,先 FLASH_OB_Unlock,再 FLASH_WaitForLastOperation 确认空闲。如果还失败,检查是不是在中断里调用了,选项字节操作不能被中断打断。

5.2 现象:设了写保护,但某个扇区还是能被擦除

原因:扇区号和 WRP 位映射搞错了。F407 的 WRP0 寄存器管 Sector 0~7,WRP1 管 Sector 8~11,但标准库的 OB_WRP_Sector_x 宏已经做了映射。如果你绕过标准库直接写寄存器,很容易把 Sector 5 的位写到 WRP0 的 bit5,而实际上 Sector 5 在 WRP0 里确实是 bit5,但 Sector 8 开始就跳到 WRP1 了。

解决:坚持用标准库宏,不要自己算位。如果必须直接操作寄存器,对照参考手册的 WRP 位映射表逐位核对。验证方法:设完保护后,写一段测试代码尝试擦除目标扇区,看 FLASH_SR 的 WRPERR 位是否置位。

5.3 现象:解除读保护后芯片不启动,或者调试器连不上

原因:解除 RDP 触发的整片擦除过程中断电了,或者擦除还没完成就复位。F407 在 RDP 降级时会进入一个特殊状态,擦除期间如果电源不稳,选项字节可能处于半写状态,芯片行为不确定。

解决:解除读保护的操作要放在电源稳定的环境里做,擦除期间不要按复位、不要断电。如果不幸已经出问题,尝试用 BOOT0 拉高从系统存储器启动,用内置 Bootloader 擦除整片,再重新配置。实在不行只能换芯片,这就是为什么 Level 2 要慎用。

5.4 现象:写保护生效后,自己的 Bootloader 也写不了参数区

原因:写保护是硬件级的,不区分"谁在写"。你把参数区设了写保护,Bootloader 自己调用 FLASH_Program 也会被拒。很多人以为写保护只防外部,其实它防所有写入。

解决:参数区的更新逻辑要设计成"先解保护→擦写→再设保护"的流程,而不是常驻保护状态下直接写。或者把参数区放在一个不设写保护的扇区,用读保护来防读,用软件校验来防误写。两种方案各有取舍,看你的安全等级要求。

5.5 现象:选项字节改完后,复位才能生效,但代码里没复位

原因:FLASH_OB_Launch 会触发选项字节重载,但某些情况下重载不等于完整复位,新配置可能要在下一次上电复位后才完全生效。尤其是 RDP 降级,必须等整片擦除完成。

解决:配置完选项字节后,主动调用 NVIC_SystemReset() 做一次软复位,确保所有状态干净。生产代码里,设置保护的操作通常放在首次烧录后的初始化流程里,配完就复位,不要指望"立即生效"。

6. 进阶:把保护配置做成可回滚的产线流程

前面讲的都是单次操作,实际产线要的是可重复、可验证、可回滚。我一般会把保护配置做成一个独立的配置区,用版本号管理,每次变更留记录。具体做法:在 FLASH 末尾留一个扇区存"保护配置版本",每次改选项字节前先写版本号,改完再写一次确认。这样即使中途出问题,也能从版本号判断当前处于哪个状态。

另一个技巧是写保护的分级策略。不要一刀切全保护或全不保护,按扇区功能分三级:Bootloader 区永久写保护(升级时才解)、参数区写保护但允许 Bootloader 解、应用程序区不设写保护但设读保护。这样既防了误擦,又留了升级通道。

验证环节我习惯用两个独立手段交叉确认:一是代码里读 FLASH_OB_GetWRP() 和 FLASH_OB_GetRDP() 的返回值,二是用调试器实际尝试读 FLASH 首地址和擦除目标扇区,看硬件是否真的拒绝。软件返回值和硬件行为对不上,说明选项字节没真正生效,这时候别急着量产,先查时序。

最后说个习惯:每次动选项字节之前,先把当前配置读出来打印一遍,存到日志里。选项字节这东西,改之前是什么状态、改之后是什么状态,中间差了什么,全靠这个日志回溯。我吃过一次亏,现场返修时忘了之前设过写保护,直接擦除失败,查了半天才发现是保护没解。从那以后,任何涉及选项字节的操作,第一步永远是读当前状态。希望帮到你。

本文还有配套的精品资源,点击获取

相关新闻

STM32F407 FLASH读写保护实战:从量产翻车到产线落地

STM32F407 FLASH读写保护实战:从量产翻车到产线落地

简介:这份资源面向使用STM32F407进行嵌入式开发的工程师与学习者,聚焦FLASH读写保护与解除这一程序安全核心主题。STM32F407基于ARM Cortex-M4内核,其FLASH存储着代码、配置数据与启动代码,读保护可阻止敏感信息被非法读取&#x…

2026/10/20 10:01:43 阅读更多 →
64M轻量级语言模型:从零训练、可落地的LLM基座

64M轻量级语言模型:从零训练、可落地的LLM基座

1. 这不是“玩具模型”,而是可落地的轻量级语言能力基座“花3块钱、2小时,从零训练一个64M参数的大语言模型”——看到这个标题,我第一反应是点开链接前先截图发给团队群:“快看,有人把LLM训练成本干到奶茶价了。”不是…

2026/10/20 10:01:43 阅读更多 →
11维度交叉验证技术分析面板:从指标混乱到统一共识的实战框架

11维度交叉验证技术分析面板:从指标混乱到统一共识的实战框架

最近复盘一段时间的行情,发现一个挺有意思的现象:很多时候我们对走势的判断差之毫厘,但交易结果却谬以千里。根本原因往往不在于方向看没看对,而在于下单那一刻的犹豫和动摇。技术指标太多,信号相互打架,今…

2026/10/20 10:00:42 阅读更多 →

最新新闻

为什么一降重AI率就升高?手动降重越改越像AI,降重降AI一起做才是正解!

为什么一降重AI率就升高?手动降重越改越像AI,降重降AI一起做才是正解!

为什么一降重AI率就升高?手动降重越改越像AI,降重降AI一起做才是正解! 为什么一降重AI率就升高?不少同学都碰到过:查重报告上的红色总算改少了,再送去做AIGC检测,AI率反而比改之前还高。明明每…

2026/10/20 10:44:37 阅读更多 →
基于Springboot大学生就业服务平台【附源码+文档】

基于Springboot大学生就业服务平台【附源码+文档】

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

2026/10/20 10:44:37 阅读更多 →
Node.js部署实战:从环境配置、PM2进程守护到日志排错的完整指南

Node.js部署实战:从环境配置、PM2进程守护到日志排错的完整指南

开头:真香的是开发,想砸电脑的是部署我当初也是冲着 Node.js 那套开发体验去的,写接口、做工具脚本、甚至给团队搭个内部面板,简直行云流水。直到第一次正儿八经把服务部署到服务器上,才发现前端的爽和后端的痛之间&am…

2026/10/20 10:44:37 阅读更多 →
论文AI率和重复率怎么一起降下来?降重降AI几分钟就能一起完成!

论文AI率和重复率怎么一起降下来?降重降AI几分钟就能一起完成!

论文AI率和重复率怎么一起降下来?降重降AI几分钟就能一起完成! 论文AI率和重复率怎么一起降下来,是很多同学交稿前最头疼的事。论文AI率和重复率两个数字同时摆在报告上,先压哪个都不对:刚把AI率压下去,查…

2026/10/20 10:44:37 阅读更多 →
AgentScope实践:用标准化Msg协议搭建多智能体协作系统

AgentScope实践:用标准化Msg协议搭建多智能体协作系统

上周我在重构一个内部客服项目的时候,终于体会到“多智能体”和“多个会说话的模块”之间那条天堑。单机脚本里我写了三百多行状态机,让一个主管Agent给三个执行Agent派活,结果一个Agent因为提示词里写了句“你继续分析”,就带着上…

2026/10/20 10:44:37 阅读更多 →
如何 5 步把游戏手柄映射为键盘鼠标?AntiMicroX 完整指南

如何 5 步把游戏手柄映射为键盘鼠标?AntiMicroX 完整指南

如何 5 步把游戏手柄映射为键盘鼠标?AntiMicroX 完整指南 【免费下载链接】antimicrox Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support. 项目地址: https://gitcode.com/Gi…

2026/10/20 10:43:36 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

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

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

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

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

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

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 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/20 10:02:08 阅读更多 →
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/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练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/20 9:50:45 阅读更多 →