STM32与MRAM组合实现工业级非易失存储与掉电保护方案
MRAM 这类器件在工业项目里属于典型的参数不起眼、用起来真香方案。MR25H40CDF 是一颗 4Mbit 的 SPI 接口 MRAM配合 STM32F413RH 这颗带 320KB SRAM 的 Cortex-M4F 芯片可以构建一套非常可靠的参数存储与日志记录通道。本篇文章我会从选型动机、硬件接线、SPI 时序、驱动代码到掉电保护和实测数据尽量把关键细节一次讲透覆盖掉那些 datasheet 里没写清楚的坑。1. 为什么工业设备里我会把 Flash 和 EEPROM 换成 MRAM1.1 Flash 在工业现场最让我头疼的三件事做嵌入式这几年我在设备维护、产线调试、故障追溯上踩过的坑有一大半跟数据存储有关。第一类是 Flash 的擦写寿命问题工业现场的变频器、伺服驱动器、仪器仪表这类设备一天下来参数存储频次可以高达几万次普通 SPI NOR Flash 的擦写寿命也就十万次级别看起来够用但日志密集型场景加上频繁上下电寿命消耗实际非常快。第二类是掉电丢数据很多系统对 3.3V 跌落时间的容忍度很低代码刚写完 Flash 的 page program电源就断了现场排查起来极其痛苦。第三类是 EEPROM 容量太小、写得太慢常见的 24Cxx 系列也就 256 字节到 64KB扩展外置 EEPROM 还要占 I2C 总线和引脚读写速度在高速数据采集场景下完全不够用。1.2 MR25H40CDF 到底解决了什么问题MR25H40CDF 是一颗 4Mbit512KB的 SPI 接口 MRAM由 Everspin 出品工作电压 2.7~3.6V支持 SPI Mode 0 和 Mode 3最高时钟 40MHz。MRAM 的核心存储单元是磁隧道结MTJ通过磁化方向而不是电荷来保存数据所以它天然具备了两个让嵌入式工程师眼前一亮的特点无限次擦写以及掉电后数据不丢失。没有擦除周期概念也不需要页擦除、扇区擦除这种操作写操作一进去就生效真正做到了类 SRAM 的使用体验。从数据手册指标看MR25H40CDF 的写入时间远低于传统 NOR Flash 的 page program 时间后者的页编程通常要几十微秒到几毫秒而 MRAM 的写周期基本等同于一次普通 SPI 写命令的时序开销。数据保持能力官方标称为 20 年以上相比 SRAM电池后备方案彻底摆脱了电池维护问题。温度范围也覆盖了工业级常见的 -40℃ 到 105℃对于户外机柜、高温车间这类场景非常合适。1.3 一句话总结选型思路如果系统里需要频繁写入参数、记录事件日志、防止掉电丢数据而且容量需求在几 KB 到 512KB 之间MR25H40CDF 就是一个非常自然的中间选择。它比 EEPROM 容量大、速度快比 NOR Flash 写入简单、不需要擦写均衡和坏块管理比 SRAM后备电池维护成本低。配合 STM32F413RH 的高速 SPI 接口可以做到上电即读、随时可写、断电无忧的效果。2. MR25H40CDF 的数据手册细节接线前必须搞懂的引脚与时序2.1 引脚定义与硬件接线方案MR25H40CDF 的封装是 SOP-8引脚不多典型引脚包括 SI串行输入、SO串行输出、SCK时钟、CS片选、WP写保护、HOLD保持。和普通 SPI Flash 的引脚定义几乎一致区别主要在于 WP 和 HOLD 这两个脚在 MRAM 上的逻辑作用更加明确。我常用的接线方案如下表所示STM32F413RH 引脚MR25H40CDF 引脚说明PB3SPI1_SCKSCKSPI 时钟PB4SPI1_MISOSO从机输出PB5SPI1_MOSISI从机输入PA4GPIO 推挽输出CS软件片选控制3.3V 通过 10kΩ 上拉WP禁止写保护有效3.3V 通过 10kΩ 上拉HOLD禁止保持功能触发3.3VVDD电源GNDGND地WP 和 HOLD 这两个脚在大部分应用里都要接死到高电平。WP 拉高才能保证写保护功能关闭HOLD 拉高才能保证 SPI 通信不会被意外暂停。如果这两个脚悬空现场强干扰环境下很容易出现总线挂死、命令异常的情况这个后面我在实测部分会专门讲。2.2 SPI 命令集与状态寄存器的工作逻辑MR25H40CDF 的命令集非常精简核心命令就是下面这几个命令opcode说明WREN0x06写使能WRDI0x04写禁止RDSR0x05读取状态寄存器WRSR0x01写状态寄存器READ0x03读数据WRITE0x02写数据和普通 SPI NOR Flash 最大的区别是它没有 0xD8扇区擦除、0xC7芯片擦除这类命令。需要覆盖写时直接发送 WRITE 命令即可不需要先擦除。状态寄存器的低两位中包括我们最关心的 BUSY 位但 MRAM 的 BUSY 窗口通常极短甚至可以不用轮询不过为了时序严谨驱动里我还是保留了忙检查逻辑。地址是 24 位格式芯片总容量 512KB实际有效地址位是 A18~A0高 5 位地址线可以视为忽略位或必须为 0。发送 READ 或 WRITE 命令时先发 opcode再发 3 字节地址紧接着传数据。读和写的基本时间序列如下CS 拉低 → 发送 0x03 → 发送 24bit 地址 → 连续读取数据 → CS 拉高 CS 拉低 → 发送 0x02 → 发送 24bit 地址 → 连续写入数据 → CS 拉高2.3 模/数混合环境中的去耦与布局建议工业板卡上极少只有一颗 MCU 和一颗 MRAM大概率还有继电器、电机驱动、开关电源模块。MRAM 虽然抗干扰能力不错但 SPI 总线属于高速数字信号电源噪声过大依然会导致读写错误。我的经验是在 MR25H40CDF 的 VDD 引脚旁边放置一个 0.1μF 陶瓷电容并且在稍远位置并联一个 10μF 钽电容或陶瓷电容用于低频去耦MRAM 尽量靠近 MCU缩短 SCK 和 MOSI/MISO 走线长度如果 PCB 空间允许SPI 信号线做等长处理时钟线尽量不穿过大电流走线区域。HOLD 和 WP 的上拉电阻靠近 MRAM 引脚端放置而不是靠近 MCU 端这样能最大程度避免引脚拾取噪声。3. STM32F413RH 上 SPI 外设的工程化配置3.1 选 SPI1 还是 SPI2以及分频系数怎么算STM32F413RH 内部有多个 SPI 外设SPI1 挂在 APB2 总线上SPI2/SPI3 挂在 APB1 总线上。我选择 SPI1是因为 APB2 的时钟频率更高可以给 SPI 留出更高分频上限。STM32F413 的主频最高可以跑到 100MHzAPB2 外设时钟也基本能到 100MHz。MR25H40CDF 最高支持 40MHz 时钟但 STM32F4 系列的 SPI 预分频器只有 2、4、8、16、32、64、128、256 这几个档位100MHz 除以 2 等于 50MHz已经超出 MRAM 的额定值除以 4 等于 25MHz是稳定且留有余量的选择。25MHz 的时钟频率意味着每秒钟最多可以搬移约 3MB 数据对于 512KB 容量的器件来说读写完整片不到 200 毫秒实际场景足够用。这里顺带提一句不要为了追求 40MHz 极限去把 SPI 配在 50MHz超规格运行带来的误码隐患在工业现场会被无限放大。3.2 SPI1 的初始化代码与 GPIO 复用配置下面这段代码基于 HAL 库实际工程中可以直接整理成mx_spi1_init()函数。GPIO 复用模式需要打开 SPI1 的 SCK/MOSI/MISO片选 CS 用普通推挽输出即可。static void MX_SPI1_Init(void) { hspi1.Instance SPI1; hspi1.Init.Mode SPI_MODE_MASTER; hspi1.Init.Direction SPI_DIRECTION_2LINES; hspi1.Init.DataSize SPI_DATASIZE_8BIT; hspi1.Init.CLKPolarity SPI_POLARITY_LOW; hspi1.Init.CLKPhase SPI_PHASE_1EDGE; hspi1.Init.NSS SPI_NSS_SOFT; hspi1.Init.BaudRatePrescaler SPI_BAUDRATEPRESCALER_4; hspi1.Init.FirstBit SPI_FIRSTBIT_MSB; hspi1.Init.TIMode SPI_TIMODE_DISABLE; hspi1.Init.CRCCalculation SPI_CRCCALCULATION_DISABLE; hspi1.Init.CRCPolynomial 7; HAL_SPI_Init(hspi1); } static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct {0}; __HAL_RCC_SPI1_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5; GPIO_InitStruct.Mode GPIO_MODE_AF_PP; GPIO_InitStruct.Pull GPIO_NOPULL; GPIO_InitStruct.Speed GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate GPIO_AF5_SPI1; HAL_GPIO_Init(GPIOB, GPIO_InitStruct); GPIO_InitStruct.Pin GPIO_PIN_4; GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull GPIO_PULLUP; GPIO_InitStruct.Speed GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, GPIO_InitStruct); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); }从 STM32F413 的数据手册看PB3、PB4、PB5 的复用功能编号是 AF5对应 SPI1_SCK、SPI1_MISO、SPI1_MOSI。复用函数设置错误是最容易踩的坑我见过不少人把 pin 分配到了 AF 其他编号然后 SPI 怎么调都不通。3.3 SPI 模式选择Mode 0 与 Mode 3 都能用吗MR25H40CDF 数据手册明确支持 Mode 0 和 Mode 3。SPI Mode 0 对应 CPOL0、CPHA0数据在时钟上升沿采样SPI Mode 3 对应 CPOL1、CPHA1数据在时钟上升沿采样。两者在空闲状态的电平不同但采样沿一致。实际工程中我习惯使用 Mode 0理由很简单大多数 SPI 外设和逻辑分析仪默认分析 Mode 0 或 Mode 0/3排查波形时少一层换算。HAL 库初始化代码里CLKPolarity SPI_POLARITY_LOW、CLKPhase SPI_PHASE_1EDGE就是 Mode 0 的配置。如果换用其他 MRAM 型号比如 MR25H40MDF 这类后缀不同的型号仍然建议先确认数据手册的时序图不要默认沿用上一颗芯片的 SPI 模式配置。4. 驱动代码实现从轮询到 DMA 的完整落地4.1 基础读写函数与片选控制整个 MRAM 驱动可以拆成三层片选控制、命令发送、数据读写。片选由 GPIO 手动控制这是绝大多数 SPI 从机设备的通用做法软件控制的时间点最灵活。#define MRAM_CS_LOW() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET) #define MRAM_CS_HIGH() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET) #define MRAM_CMD_WREN 0x06 #define MRAM_CMD_WRDI 0x04 #define MRAM_CMD_RDSR 0x05 #define MRAM_CMD_READ 0x03 #define MRAM_CMD_WRITE 0x02这里有一个很关键的细节每次操作完成之后CS 必须拉高。SPI 从机通过 CS 的上升沿来判断命令结束和完成内部状态更新。如果 CS 一直拉低下一次操作发送的 opcode 会被当成上一段数据流的延续命令解析必定错乱。4.2 写使能与状态轮询MRAM 的写操作之前需要发送 WREN 命令将状态寄存器里的写使能锁存位置位。从数据手册时序角度看WREN 完成后紧接着就可以发 WRITE 命令但稳妥起见我在代码里加入了读取状态寄存器进行确认的步骤用于调试阶段快速定位问题。static void mram_write_enable(void) { uint8_t cmd MRAM_CMD_WREN; MRAM_CS_LOW(); HAL_SPI_Transmit(hspi1, cmd, 1, HAL_MAX_DELAY); MRAM_CS_HIGH(); } static uint8_t mram_read_status(void) { uint8_t cmd MRAM_CMD_RDSR; uint8_t sr 0xFF; MRAM_CS_LOW(); HAL_SPI_Transmit(hspi1, cmd, 1, HAL_MAX_DELAY); HAL_SPI_Receive(hspi1, sr, 1, HAL_MAX_DELAY); MRAM_CS_HIGH(); return sr; } static void mram_wait_ready(void) { while ((mram_read_status() 0x01) ! 0) { /* busy 等待MRAM 通常极快此循环一般只会进入一次 */ } }状态寄存器的 bit0 是 BUSY 位。对 MRAM 来说这个位可能短到观察不到高电平但保留轮询逻辑可以在市场批次差异、温度变化时提供保护。对于性能敏感的场景可以在轮询条件里加超时计数避免由于 SPI 线路异常导致 while 死循环。4.3 读取数据和写入数据的核心逻辑读操作的流程是片选拉低、发送 READ 命令、发送 3 字节地址、连续接收数据、片选拉高。写操作则是写使能、片选拉低、发送 WRITE 命令、发送地址、连续发送数据、片选拉高。void mram_read(uint32_t addr, uint8_t *buf, uint32_t len) { uint8_t hdr[4]; hdr[0] MRAM_CMD_READ; hdr[1] (addr 16) 0xFF; hdr[2] (addr 8) 0xFF; hdr[3] addr 0xFF; MRAM_CS_LOW(); HAL_SPI_Transmit(hspi1, hdr, 4, HAL_MAX_DELAY); HAL_SPI_Receive(hspi1, buf, len, HAL_MAX_DELAY); MRAM_CS_HIGH(); } void mram_write(uint32_t addr, const uint8_t *buf, uint32_t len) { uint8_t hdr[4]; hdr[0] MRAM_CMD_WRITE; hdr[1] (addr 16) 0xFF; hdr[2] (addr 8) 0xFF; hdr[3] addr 0xFF; mram_write_enable(); mram_wait_ready(); MRAM_CS_LOW(); HAL_SPI_Transmit(hspi1, hdr, 4, HAL_MAX_DELAY); HAL_SPI_Transmit(hspi1, (uint8_t *)buf, len, HAL_MAX_DELAY); MRAM_CS_HIGH(); }4.4 DMA 模式的改造与注意事项对于大批量日志写入轮询模式的效率瓶颈在于 CPU 每个字节都要参与。DMA 模式可以把 SPI 搬运任务的 CPU 占用率降下来。HAL 库下推荐使用HAL_SPI_Transmit_DMA和HAL_SPI_Receive_DMA但要注意全双工 SPI 在连续收发时需要同时启动收发通道否则接收端时钟缺失。这里给一个简单可靠的 DMA 读写方案void mram_write_dma(uint32_t addr, const uint8_t *buf, uint32_t len) { uint8_t hdr[4]; hdr[0] MRAM_CMD_WRITE; hdr[1] (addr 16) 0xFF; hdr[2] (addr 8) 0xFF; hdr[3] addr 0xFF; mram_write_enable(); mram_wait_ready(); MRAM_CS_LOW(); HAL_SPI_Transmit(hspi1, hdr, 4, HAL_MAX_DELAY); HAL_SPI_Transmit_DMA(hspi1, (uint8_t *)buf, len); /* 等待 DMA 传输完成中断或 HAL_SPI_GetState 回到 READY */ while (HAL_SPI_GetState(hspi1) ! HAL_SPI_STATE_READY) {} MRAM_CS_HIGH(); }DMA 方式下最容易忽略的问题是 CS 拉高的时机。HAL_SPI_Transmit_DMA 是非阻塞的如果不等 DMA 传输结束就把 CS 拉高从机会提前认为数据流结束导致最后一个字节甚至最后一段数据被截断。我一般会在传输完成中断回调里置一个标志位主流程轮询这个标志位或者在函数末尾等待HAL_SPI_GetState恢复 READY 状态。5. 掉电保存与数据完整性的设计思路5.1 用 STM32F413RH 的 PVD 检测电源跌落工业设备掉电不是瞬间从 3.3V 跳到 0V而是一个缓慢下降的过程。如果能在电源跌落到 MCU 最低工作电压之前把关键数据写进 MRAM就能避免现场数据丢失。STM32F413RH 内部集成了可编程电压检测器PVD可配置多个电压阈值。当 VDD 降到阈值以下时会产生 PVD 中断。实际项目中我通常把阈值配置在 2.9V 左右配合电源输入端的大容量电容可以在掉电中断触发后获得几十毫秒甚至上百毫秒的裕量这足够写完一条 4KB 的日志记录。PVD 初始化代码如下static void MX_PVD_Init(void) { PWR_PVDTypeDef sConfigPVD {0}; sConfigPVD.PVDLevel PWR_PVDLEVEL_7; /* 约 2.9V具体值参考芯片手册 */ sConfigPVD.Mode PWR_PVD_MODE_IT_RISING_FALLING; HAL_PWR_ConfigPVD(sConfigPVD); HAL_PWR_EnablePVD(); HAL_NVIC_SetPriority(PVD_IRQn, 15, 0); HAL_NVIC_EnableIRQ(PVD_IRQn); }5.2 写入流程中的防撕裂与先备份策略即使有 MRAM 的瞬时写入能力也不能认为掉电高枕无忧。一次写入如果横跨多个字节而掉电发生在写入过程中间可能会留下半条有效记录。MRAM 是字节级非易失写入掉电瞬间已经写入的字节会保留未写入的字节保持不变所以需要设计合理的记录格式来保证数据完整性。我常用的做法是双区交替写入 序号校验。每条记录头部放一个 magic number 和递增序号写入时交替写入 A 区和 B 区启动时读取两个区比较序号取序号连续且校验正确的一份。这样做的好处是即使某次写入只完成了一半另一份完整记录还在系统可以自动回退到最近一次有效状态。typedef struct __attribute__((packed)) { uint32_t magic; uint32_t seq; uint16_t crc16; uint8_t payload[256]; } log_record_t;CRC16 校验是必备的。MRAM 本身误码率很低但 SPI 总线噪声、外部干扰仍可能破坏数据加一层 CRC 能在读取失效时快速识别并进入恢复流程。5.3 上电恢复与坏区处理上电后第一步不是直接使用主存储区数据而是读取双区记录头比较 magic 和 seq。如果 A 区有效且比 B 区新就采用 A 区如果 B 区有效且比 A 区新则采用 B 区如果两份都无效则进入出厂默认配置。MRAM 没有坏块概念所以不需要像 NAND Flash 那样做坏块管理。但写入地址仍然存在边界问题读写跨 512KB 地址回绕时如果命令设置不当会从 0x00000 重新开始这一点在长数据连续读写时尤其要注意。6. 实测结果与现场踩过的坑6.1 25MHz 时钟下的实际吞吐表现我在自制测试板上用 STM32F413RH 100MHz、SPI1 25MHz、DMA 模式实测连续写入 4KB 缓存耗时大约 1.4ms连续读取 4KB 大约 1.2ms其中大部分开销在 SPI 时钟搬运。如果使用轮询模式读 4KB 大概要 2.2ms主要差在 HAL 层每次收发函数的调用开销。坦白说对于 512KB 的容量和 25MHz 的通信速率这个表现对大多数工业应用是绰绰有余的。真正该关注的是写循环效率比如每秒写入 100 条 60 字节的记录MRAM 可以轻松应付而同样的频率对 NOR Flash 会显著加速寿命衰减。6.2 坑HOLD 脚悬空导致的总线假死第一次打样时我把 HOLD 脚留了 NC结果系统运行一段时间后SPI 通信会偶发停止主控读回来的数据全部是 0xFF。逻辑分析仪抓波形发现SCK 和 MOSI 都有正常信号但 SO 一直是高电平。后来查资料才意识到HOLD 脚悬空时周围辐射噪声可能让该引脚瞬时落入低电平MRAM 进入 hold 状态忽略后续 SPI 输入直到 CS 重新拉低或者 HOLD 恢复高电平。解决办法就是一开始就接 10kΩ 上拉到 3.3V同时 HOLD 引脚走线远离继电器和大电流回路。此后再没有出现过类似假死问题。6.3 坑WP 脚没拉高导致写使能不生效另一个朋友调试时反馈写命令发下去后读回来的数据一直是 0xAA 的默认值WREN 也发了状态寄存器的写使能位就是不为 1。排查到最后发现 WP 脚接到了 MCU 的一个 GPIO而 GPIO 默认输出低电平导致硬件写保护一直使能。MR25H40CDF 的写保护优先级高于软件写使能这种情况下 WREN 无论如何都不会生效。这个问题在测试阶段很容易被忽略因为 MRAM 型号众多部分型号对 WP 的策略并不完全一致。我的建议是不需要动态切换保护时直接把 WP 接高电平别省这个电阻。6.4 坑自以为支持任意长度连续读写MR25H40CDF 确实支持突发模式连续读写但地址计数器走到 0x7FFFF 之后会回绕到 0x00000。如果上层协议没有留意长度计算写一条跨地址边界的日志会出现低地址段被覆盖的惨状。我的处理是所有跨区写入都按单次不超过 4KB 的数据块拆分并且强制从对齐地址开始写从根上规避回绕问题。6.5 给新项目的上手建议如果第一次在项目里用 MRAM建议先做四件事用逻辑分析仪抓一次 WREN 后状态寄存器的变化用固定 pattern如 0x55、0xAA写满前 16KB 再读回比对断电瞬间重复写擦测试 100 次确认 PVD 触发逻辑可靠将 SPI 时钟从 25MHz 降到 8MHz 跑一次长稳定性测试验证干扰环境下的边角时序。另外MR25H40CDF 的 READ/WRITE 命令时序简单在现有项目中甚至可以直接替换部分 NOR Flash 芯片只需把擦除命令去掉、删除写入前的擦除流程即可硬件改动非常小。这也是我后来在多个项目里快速铺开 MRAM 的核心原因。

相关新闻

ABAQUS地应力平衡三大路径与K₀/NLGEOM关键参数解析

ABAQUS地应力平衡三大路径与K₀/NLGEOM关键参数解析

/* 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:14:09 阅读更多 →
有限元剪切锁死原理与工程解决方案

有限元剪切锁死原理与工程解决方案

/* 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:14:09 阅读更多 →
AB脉冲原理与应用:编码器、PLC与上位机全链路解析

AB脉冲原理与应用:编码器、PLC与上位机全链路解析

/* 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:14:09 阅读更多 →

最新新闻

24天16万行代码:用Claude Code从零构建K12教育产品的实战工作流

24天16万行代码:用Claude Code从零构建K12教育产品的实战工作流

1. 先聊聊这个项目到底在做什么24 天,630 次提交,16 万行代码。这三个数字放在一起,任何一个写过代码的人都会先愣一下——平均每天 26 次提交、6600 多行代码产出,而且是在不到一个月的时间里从零搭出一个 K12 教育产品。如果这是…

2026/10/4 7:33:03 阅读更多 →
Codex++卡顿排查与提速:六个亲测有效的性能优化方案

Codex++卡顿排查与提速:六个亲测有效的性能优化方案

1. 卡顿先别急着换工具,先搞清楚Codex到底卡在哪我用Codex做日常开发也有小半年了,这工具的补全和对话能力都相当能打,尤其是结合多文件上下文理解之后,改起老项目来确实顺手。但最近这阵子,明显感觉到它变“钝”了&am…

2026/10/4 7:33:03 阅读更多 →
OpenRig:基于Node.js与tmux的Codex CLI本地化封装方案

OpenRig:基于Node.js与tmux的Codex CLI本地化封装方案

1. OpenRig 是什么:一个被误读但极具潜力的开发者工具链OpenRig 这个名字最近在开发者社区里频繁出现,但它既不是某个新发布的 AI 框架,也不是某家大厂推出的闭源 SDK。我第一次在 GitLab CI 日志里看到openrig被当作服务名调用时&#xff0c…

2026/10/4 7:33:03 阅读更多 →
别急着做完整SaaS:用AI Agent快速验证产品需求

别急着做完整SaaS:用AI Agent快速验证产品需求

1. 为什么“先做完整 SaaS”正在变成一条弯路过去几年,做产品的默认路径几乎是固定的:先想清楚需求,画原型,搭后端,做权限,接支付,再一点点把功能堆成一个完整的 SaaS。这套打法在移动互联网时代…

2026/10/4 7:33:03 阅读更多 →
openrig:统一管理Claude Code与Codex的YAML配置编排工具

openrig:统一管理Claude Code与Codex的YAML配置编排工具

1. openrig 到底在解决什么问题第一次看到 openrig 这个名字,很多人会以为是某个硬件机架项目,或者跟 rigging 动画绑定有关。但结合它周边的关键词——claude code、codex、yaml、node.js——基本可以判断,这是一个围绕 AI 编程助手做配置编…

2026/10/4 7:33:03 阅读更多 →
两千元预算本地部署Qwen3-27B:V100实战280 tok/s推理

两千元预算本地部署Qwen3-27B:V100实战280 tok/s推理

1. 两千块预算的本地AI部署,到底能跑出什么水平先说结论:两千多块钱,在二手市场上凑一套能跑Qwen3-27B级别模型、推理速度稳定超过280 tok/s的平台,这件事在2025年是完全可行的。我自己前前后后折腾了大概三周,从选卡、…

2026/10/4 7:32:02 阅读更多 →

日新闻

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 阅读更多 →