STM32F103 CAN Bootloader远程升级方案:从Flash分区到量产部署
做嵌入式量产项目最怕的往往不是代码写不出来而是产品已经装到现场、封进机箱之后突然要改一个固件问题却没法把板子拆回来。干过几年嵌入式实战的人应该都有这个体会拆机升级一次的成本可能比写这段代码本身的成本还要高。所以当年我们团队给一批基于 STM32F103 的设备做量产时第一个坚持下来的决定就是——“必须带 CAN Bootloader 出厂”。这篇文章把整个项目从方案设计、源码划分、协议定义到产线批量部署的完整过程整理出来包括我踩过的坑和后来反复验证过的经验希望给正在做同类产品的朋友一个可以直接参考的底稿。1. 项目背景为什么非用 CAN Bootloader 不可1.1 远程升级的刚需场景当时这批设备用在工业现场节点分散在几十米甚至上百米的线路上设备之间只有两根 CAN 总线连在一起没有额外的调试接口。外观是密封壳开盖意味着破坏防拆标签用户根本不会同意你拿仿真器去现场。这种情况下固件升级只有两条路可选要么全部返厂要么走通信总线远程升级。既然是控制网络CAN 总线天然就是最合适的升级通道。另外一个现实原因是STM32F103 这类芯片虽然可以用串口 IAP但串口线在现场往往根本没有引出来而且工业环境下串口通信的抗干扰能力不如 CAN。CAN 的差分信号、错误重发、仲裁机制都更适合长距离、多节点、干扰重的工业现场。选 CAN Bootloader 并不是为了炫技而是从安装环境倒推回来的刚需。1.2 方案选型对比在做方案预研时我们对比了几条路线。一种是直接用 STM32 芯片内置的系统存储器 Bootloader也就是 ROM 里出厂自带的那段引导程序。它支持 USART、CAN 等接口但问题是它只能配合 ST 官方的升级工具使用帧格式、握手逻辑都不受我们控制也没法嵌入自定义的加密校验算法。对于追求“量产可控”的团队来说这只是救急方案不是工程方案。另一种是网上能找到的各种串口 IAP 例程改成 CAN 驱动。这条路跑通容易但很多例程只实现了“能写 Flash、能跳转”完全没有考虑量产时需要一拖多、需要版本核对、需要防掉电回滚。我们决定自己写基于 CAN 通信的 Bootloader把所有量产相关的机制直接做进去一次投入后面所有产品都复用。1.3 STM32F103 的 CAN 资源盘点STM32F103 内置的是 bxCAN 外设支持标准帧、扩展帧有 3 个发送邮箱和 2 个接收 FIFO报文的硬件滤波、FIFO 溢出检测这些都有。对 Bootloader 场景来说资源完全够用。这里只说一个容易忽略的点F103 的 CAN 外设挂载在 APB1 总线上APB1 时钟默认是 36MHz系统主频 72MHz 时。后面计算波特率、配置位时间都要基于 36MHz 这个数很多人 CAN 通信不稳定问题往往就出在这——拿 72MHz 直接套公式波特率全偏了。Flash 方面我们用的芯片是 STM32F103CBT6128KB Flash按项目需求把 Flash 拆成引导区、应用区、参数区三块。Flash 每页 1KB擦除按页操作写是按半字16 bit写的。这些基础特性直接决定了 Bootloader 的分区规划和写入策略下面详细说。2. Bootloader 整体架构设计2.1 Flash 分区规划分区是 Bootloader 设计的核心分区没划好后面写多少代码都难受。我们对 128KB Flash 做了如下划分区域地址范围大小用途Bootloader 区0x08000000 - 0x08007FFF32KB引导程序本体App 区0x08008000 - 0x0801FBFF约 95KB应用固件存储与运行区参数区0x0801FC00 - 0x0801FFFF1KB设备序号、版本信息、升级标志Bootloader 留 32KB看起来有点奢侈但考虑到后续可能增加协议类型、加密逻辑这个空间是值得的。App 区从 0x08008000 开始中断向量表也迁移到这个地方。参数区独立放在最后一页这样每次擦写 App 区时不会把设备信息和升级标志冲掉软件升级之后设备编号、产线记录都还在。为什么 App 区不能直接顶到 Flash 末尾我给的理由很简单升级标志位和回滚标记需要一个不随 App 擦除而消失的存放位置。如果把标志放 App 区内部每升一次级就要重新考虑标志的存活问题容易在异常掉电时产生逻辑漏洞。独立的参数页让整个状态管理变得清晰。2.2 升级协议设计Bootloader 和上位机之间的通信协议我用的是标准 CAN 帧ID 固定为 0x100 作为广播命令帧节点应答使用 0x200 节点号。数据域共 8 字节前 2 字节放命令字和块序号后 6 字节放有效数据。这样做的好处是协议实现简单、便于在中断里快速解析缺点是一次最多只能带 6 字节有效数据升级一个小 40KB 的固件大概需要 7000 帧在 250kbps 波特率下实测约 8 秒完全能接受。协议命令字定义如下命令值方向说明CMD_SYNC0x01主机→节点同步请求节点进入升级模式CMD_INFO0x02节点→主机返回设备信息、固件版本CMD_ADDR0x03主机→节点设置写入起始地址CMD_DATA0x04主机→节点携带 6 字节固件数据CMD_CRC0x05主机→节点发送整体校验码节点校验CMD_BOOT0x06主机→节点跳转命令回到 App 运行CMD_ERR0xFF节点→主机错误应答携带错误码协议有一个细节必须强调块序号是整个升级会话里唯一的节点端只要发现块序号不连续就立刻回 CMD_ERR上位机从这个序号开始重传。这个“不连续即报错”的机制看起来原始但它比任何超时重传都更可靠因为 CAN 本身的硬件错误重发机制已经保证了一帧数据要么完整到达要么报错重发应用层只需要关注顺序逻辑。2.3 App 端配合改动Bootloader 不是单独工作的App 侧必须做两件关键的事否则跳转过去一定会出问题。第一件事是设置中断向量表偏移。STM32F103 默认向量表在 0x08000000但我们的 App 在 0x08008000所以 App 的 main 函数最开始就要执行SCB-VTOR 0x08008000;这行代码必须在任何依赖中断的外设初始化之前执行。我见过有人把它放在 SystemInit 之后、外设初始化之前那是常规操作也有人放到 main 最后才想起来结果系统一进中断就跑飞了。第二件事是 App 里预留一个“远程升级回 Bootloader”的入口。正常工作时用户希望设备能通过 CAN 命令主动回去做升级。我们是在 App 里监听一个特定 ID 的报文收到后保存一个升级请求标志然后软复位。复位后 Bootloader 先检查参数区的升级标志如果有升级请求就停在 boot 模式等待主机连接如果没有直接跳转 App。这里有一个容易犯的错误软复位前没有把 CAN 外设和中断清理干净导致复位后 Bootloader 初始化 CAN 时被残留状态干扰。实际上 STM32 外设复位是由硬件保证的系统复位后外设寄存器回到默认值所以常规的 NVIC_SystemReset 是足够干净的但前提是你不要用软件里的看门狗把复位路径搞复杂了。3. Bootloader 核心代码实现3.1 CAN 外设初始化与波特率计算CAN 初始化的核心在于波特率。我们项目统一采用 250kbps这是工业 CAN 场景里比较通用的速率兼顾了距离和带宽。计算过程如下APB1 时钟 36MHz目标波特率 250kbps所以位时间总长度是 4 微秒。如果我们把每一个时间量子 TQ 设为 250ns那么一个位时间就是 16 个 TQ。Prescaler 分频值 36MHz / 4MHz 9。位时间的 16 个 TQ 分布为同步段 1 TQ传播段加相位段 1 共 11 TQ相位段 2 共 4 TQ采样点落在 75% 的位置。CubeMX 里对应配置就是 Prescaler9BS111TQBS24TQ。这里说个我自己的教训不要直接抄网上的例程参数不同主频、不同 APB 分频下同样的寄存器值对应的波特率可能相差很远。上产线之前用示波器测一下 CAN_H 和 CAN_L 之间的显性电平时间确认位宽是不是 4 微秒这比对着波特率计算器反复改参数要快得多。初始化代码示例void MX_CAN1_Init(void) { hcan1.Instance CAN1; hcan1.Init.Prescaler 9; hcan1.Init.Mode CAN_MODE_NORMAL; hcan1.Init.SyncJumpWidth CAN_SJW_1TQ; hcan1.Init.TimeSeg1 CAN_BS1_11TQ; hcan1.Init.TimeSeg2 CAN_BS2_4TQ; hcan1.Init.TimeTriggeredCommMode DISABLE; hcan1.Init.AutoBusOffManagement ENABLE; hcan1.Init.AutoWakeUp DISABLE; hcan1.Init.AutoRetransmission ENABLE; hcan1.Init.ReceiveFifoLocked DISABLE; hcan1.Init.TransmitFifoPriority DISABLE; hcan1.Init.NbrOfMailboxes 1; HAL_CAN_Init(hcan1); CAN_FilterTypeDef sFilterConfig {0}; sFilterConfig.FilterBank 0; sFilterConfig.FilterMode CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale CAN_FILTERSCALE_32BIT; sFilterConfig.FilterIdHigh 0x0000; sFilterConfig.FilterIdLow 0x0000; sFilterConfig.FilterMaskIdHigh 0x0000; sFilterConfig.FilterMaskIdLow 0x0000; sFilterConfig.FilterFIFOAssignment CAN_RX_FIFO0; sFilterConfig.FilterActivation ENABLE; HAL_CAN_ConfigFilter(hcan1, sFilterConfig); HAL_CAN_Start(hcan1); HAL_CAN_ActivateNotification(hcan1, CAN_IT_RX_FIFO0_MSG_PENDING); }滤波器这里配置成接收所有报文因为 Bootloader 在升级阶段要响应不同节点的地址如果在 Bootloader 里把滤波器收得太窄调试会非常痛苦。FilterMask 全 0 表示不屏蔽任何位所有 ID 都收。量产固件里你可以根据实际部署再收紧但开发调试阶段建议全收。3.2 接收中断与协议解析CAN 报文接收我们走中断加回调的方式。实际工程里我推荐中断里只做报文存取和最小解析把耗时的 Flash 操作放到主循环里处理。原因很简单Flash 擦写期间 CPU 会被阻塞如果这时候 CAN 中断还在嵌套往里进轻则丢帧重则把中断栈弄崩。中断接收代码void CAN1_RX0_IRQHandler(void) { HAL_CAN_IRQHandler(hcan1); } void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { CAN_RxHeaderTypeDef rxHeader; uint8_t rxData[8]; if (hcan-Instance CAN1) { HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, rxHeader, rxData); boot_frame_parse(rxHeader.IDE, rxHeader.StdId, rxData); } }boot_frame_parse 里只做三件事判断命令字、保存数据到缓冲区、置位对应的处理标志。真正调用 Flash 写入的函数放在主循环里用状态机来串。这里有一个我强烈推荐的写法——接收缓冲区和处理缓冲区分开收到一帧数据后先把数据拷到 pending buffer等主循环处理完再切换到下一个 buffer。这样即使写 Flash 期间来了新帧数据也不会被覆盖。3.3 Flash 擦写与跳转实现Flash 写入是所有 Bootloader 里最容易出 Bug 的部分。我们用的是标准库或 HAL 的 Flash 接口流程是先解锁再按页擦除然后按半字写入最后上锁。STM32F103 的 Flash 写入要求地址必须是半字对齐长度必须是偶数写奇数个字节时要自己在末尾补 0xFF。实际写入函数uint32_t boot_flash_write(uint32_t addr, uint8_t *buf, uint32_t len) { uint32_t i; uint32_t halfWord; if ((addr % 2) ! 0) return 0xFF; if ((len % 2) ! 0) len 1; FLASH_Unlock(); for (i 0; i len; i 2) { halfWord buf[i] | ((uint16_t)buf[i 1] 8); if (FLASH_FlashProgram(addr i, halfWord) ! FLASH_COMPLETE) { FLASH_Lock(); return 0xFF; } } FLASH_Lock(); return 0; }跳转函数是 Bootloader 的生命线写错一个字节整个产品变砖。核心逻辑是从 App 起始地址读取栈顶指针和复位向量然后检查栈顶指针是否落在 RAM 合法范围内确认无误后关中断、改向量表、跳转#define APP_START_ADDR 0x08008000 void boot_jump_to_app(void) { uint32_t app_sp *(volatile uint32_t *)APP_START_ADDR; uint32_t app_pc *(volatile uint32_t *)(APP_START_ADDR 4); if ((app_sp 0x2FFE0000) ! 0x20000000) { return; } HAL_CAN_Stop(hcan1); __disable_irq(); SCB-VTOR APP_START_ADDR; __set_MSP(app_sp); void (*jump)(void) (void (*)(void))app_pc; jump(); }这里有一点要专门说明跳转前一定要把 Bootloader 阶段打开的外设停掉尤其是 CAN 和定时器。如果带着 CAN 初始化状态直接跳进 AppApp 的 CAN 初始化可能因为外设状态不一致而表现怪异。__disable_irq() 保证跳转过程不被中断打扰App 初始化完成后会重新开全局中断。3.4 看门狗与超时保护Bootloader 和普通程序不一样它必须考虑“在升级中途卡死了怎么办”。我们的处理策略是Bootloader 阶段启用独立看门狗 IWDG喂狗逻辑放在主循环里。正常等待命令时周期性喂狗一旦开始接收大数据包每写一页 Flash 就喂一次。为什么擦写过程中要喂狗因为 F103 擦除一页 1KB Flash 大约耗时 20ms 左右如果看门狗超时设置太短擦除期间来不及喂狗就会复位。这里有一个进阶方案把升级流程拆成“擦除”和“写入”两步。收到 CMD_ADDR 后先只擦对应页再通过数据帧逐帧写入这样每帧之间的间隔可以控制看门狗不容易误触发。我们实际量产版本用的就是这个策略稳定性和可调试性都提升了。4. 从源码到量产部署的工程化落地4.1 上位机发送工具光有设备端 Bootloader 还不够量产部署需要一个趁手的上位机。我们用 Python 写了一个简单的命令行工具通过 CANable 或周立功的 USB-CAN 适配器发送升级包。工具的核心逻辑分四步解析 bin 文件、按每帧 6 字节分包、逐帧发送并等待应答、最后下发 CRC 校验和跳转命令。发送逻辑里有一个关键参数是帧间隔。CAN 250kbps 下一帧标准数据帧最长大概 130 bit算上填充位理论上 1ms 发一帧是绰绰有余的。但实测发现上位机通过 USB 转 CAN 适配器发送时如果发送太快适配器的驱动缓冲会溢出导致丢帧。我们最终把帧间隔设为 5ms升级一个 60KB 的固件大概 15 秒现场完全能接受。稳定大于速度这个原则在量产工具里永远适用。4.2 一拖多批量升级量产部署最花心思的是“一拖多”。产线上一根 CAN 总线下面通常挂着 10 到 20 块板子如果每块板子都手动连一次效率太低。我们的方案是先广播 CMD_SYNC让总线上所有节点都进入升级模式然后上位机逐个查询节点信息根据节点号逐一点名升级。这里有三个必须避免的坑。第一多节点同时应答会造成 CAN 总线仲裁混乱。所以广播同步之后所有节点进入静默监听状态只有被点名时才能应答。如果哪个节点在没被点名时抢答上位机立刻重发点名帧同时把总线上其他节点的应答屏蔽掉。第二节点号必须可以通过参数区独立配置不能写死在程序里。我们用产线工装上的拨码开关来设定节点号Bootloader 启动时读取参数区如果没有则读取 GPIO 电平组合。第三升级顺序上建议优先升级节点号小的设备并且每升级完一个节点就让它重新跳回 App 运行不要等全部升级完再批量跳转。这样即使某个节点升级失败也不影响其他节点的现场验证。4.3 产线流程与工装准备量产流程我们最终定成了五步贴片完成后的裸板先用 ST-Link 烧录 Bootloader烧录完成后立即打开读保护RDP 级别 1防止固件被读取。在产线测试工装上插入 USB-CAN 适配器连接待测板子上的 CAN 接口工装供电。上位机发送广播同步命令板子进入 Bootloader 模式回传固件版本和设备序号。上位机按节点号逐个下载 App 固件下载完成后进行 CRC 校验校验通过跳转 App。App 执行自检流程ADC 采样、继电器动作、CAN 回环测试等自检通过后上报产线系统包装入库。读保护这一步容易被人忽略。很多团队出厂时根本不设读保护Bootloader 和 App 固件完全裸露。等产品流出市场被人逆向程序被人抄走再后悔就来不及了。STM32F103 的选项字节可以设置 RDP设置之后通过调试接口读出的 Flash 内容全是 0xFF。注意设置 RDP 后如果想再次用仿真器调试必须做全片擦除会连带把 Bootloader 也擦掉。所以这道工序放在 Bootloader 烧录之后、App 升级之前刚好顺路。4.4 版本管理与防呆设计量产升级最怕“升错版本”。我们在 App 的固定地址放了一个版本结构体包含应用版本号、编译时间、固件大小。Bootloader 在收到 CMD_INFO 时把这个结构体原样返回给上位机上位机先核对版本需求再决定是否继续升级。这比“拿到文件就刷”要安全得多。另外在协议层做了一个简单的防呆每个数据包里的块序号必须连续如果上位机发的是旧包或者重复包节点直接报错上位机按错误码重新组织发送。这个机制曾经在一次产线误操作中救了我们操作员把旧版固件和升级脚本搭错了脚本一直发错包所有节点统一拒绝升级没有一块砖头。5. 常见问题与排查实录5.1 CAN 通信突然连不上这个现象在开发和产线调试里都遇到过太多次了。排查顺序我基本固定先看物理层再看波特率最后查软件状态。物理层最常见的有三种CAN_H 和 CAN_L 接反、总线缺少终端电阻、线缆过长导致信号衰减。CAN 总线两端必须有 120Ω 终端电阻如果只有一块板子和一个 USB-CAN 适配器那这两端就是适配器一端、板子一端。没有终端电阻的时候总线空闲电平不稳定通信时好时坏表现得“像接触不良”。波特率的问题则更隐蔽。我们遇到过两块板子明明配置一样但一个通信正常一个完全不通最后用示波器抓波形发现出问题的板子 APB1 分频被 CubeMX 配置成了 2 分频CAN 时钟实际是 36MHz 而不是预期的 36MHz——不对应该说系统时钟配置被改过APB1 是 36MHz但另一块板子因为代码分支问题跑在了 72MHz APB1 上两边的位时间差了一倍自然完全无法通信。5.2 升级中途断电升级过程最怕断电Flash 写到一半数据不完整设备直接变砖。我们的防护有三级。第一级是协议校验全部数据写完后主机下发整体 CRC32Bootloader 对 Flash 里已写入的数据做同样的 CRC32 计算不一致就报错等待重传。第二级是升级标志位参数区里维护一个“App 有效标志”。每次升级开始前先把标志清掉这时候即使断电Bootloader 启动时会发现 App 无效不会跳转而是乖乖停在 Bootloader 等重新升级。只有全部数据写完、CRC 校验通过才把有效标志置位。第三级是在擦除旧 App 之前把新固件先写入一个临时区域写完校验成功后再搬移到运行区这需要 Flash 够大。我们 128KB 的芯片里App 约 60KB临时区再占 60KB引导区 32KB刚好塞下。但对于 Flash 较小的型号这个方案不现实那就老老实实靠有效标志 重传机制兜底。我们最后量产用的就是第二级方案临时区方案留给了后续 512KB 的大容量型号。5.3 跳转后死机或跑飞跳转后最常见的两个问题我都替大家踩过了。第一个是 App 里没设置向量表偏移或者设置得太晚。表现是上电后直接跳 App一开始能跑但一进中断就死机。解决方法是把 SCB-VTOR 的赋值挪到 main 函数的第一行任何外设初始化之前。第二个是跳转前没有关中断或者关了中断之后 App 没有重新使能。表现是跳转过去后 App 的 SysTick 不跑、延时函数死等。解决方法是 Bootloader 里 __disable_irq()然后在 App 的 main 函数最开始调用 __enable_irq()。如果你的 App 里用了 FreeRTOS还要注意在启动调度器之前完成所有外设和中断初始化。5.4 常见错误码速查表错误码含义排查建议0x01块序号不连续检查上位机分包逻辑确认没有漏包乱序0x02Flash 写入失败检查地址对齐、Flash 是否解锁、是否越界0x03CRC 校验失败检查 bin 文件是否完整重新发送一次0x04命令超时确认波特率、终端电阻、节点地址是否匹配0x05跳转失败检查 App 起始地址的栈顶指针是否合法排查的时候记住一个原则先把上位机和单板直连排除总线多节点干扰再把示波器挂上确认波形正常最后才查软件逻辑。顺序反了会浪费大量时间。做这个项目的过程中我最深的体会是Bootloader 的代码量不大但它就像一个产品的“保险丝”平时不起眼关键时刻决定整个现场是顺利升级还是集体返厂。设计阶段多花一天考虑协议、分区、掉电保护能换来后面量产阶段少熬几个通宵。尤其是量产部署这一步很多人把 Bootloader 当成普通外设驱动来写写完能跳转就以为完事了结果一到产线上就暴露出节点配置、读保护、版本校验这些工程细节的缺失。最后再分享一个小技巧Bootloader 阶段把 CAN 发送做成“发送后等待应答超时重发”的机制上位机那端不要做任何重发逻辑把可靠性全部压在节点端这样即使换了不同的 USB-CAN 适配器升级流程依然稳定。这个设计让我们在后面多个项目里省了无数排查时间算是这个项目里最值得复用的一条经验。

相关新闻

云游戏端到端延迟分解与终端适配实战指南

云游戏端到端延迟分解与终端适配实战指南

简介:本资源为《全球云游戏产业深度观察及趋势研判研究报告(2022年)》,由中国信息通信研究院与IDC咨询联合发布,面向游戏行业从业者、人工智能与云计算领域研究者、数字文娱产业政策制定者及高校相关专业师生&#xff…

2026/10/4 8:36:50 阅读更多 →
R绘图中文字体显示乱码?showtext跨平台配置终极解决方案

R绘图中文字体显示乱码?showtext跨平台配置终极解决方案

先说说这个经典的“方框问题”。我刚从 base 绘图转 ggplot2 的那阵子,几乎每个新手都会遇到:图能画出来,但所有中文全部变成一个个小方框,英文数字倒是好好的。有人管这叫“豆腐块”,也有人叫“乱码”,实际…

2026/10/4 8:36:50 阅读更多 →
Python工程化训练:从课后题到真实项目的能力跃迁

Python工程化训练:从课后题到真实项目的能力跃迁

/* 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 8:36:50 阅读更多 →

最新新闻

12个自动化浪费检测器:Token Optimizer如何揪出重试循环、模型错配与上下文臃肿

12个自动化浪费检测器:Token Optimizer如何揪出重试循环、模型错配与上下文臃肿

12个自动化浪费检测器:Token Optimizer如何揪出重试循环、模型错配与上下文臃肿 【免费下载链接】token-optimizer Find the ghost tokens. Fix them. Survive compaction. Avoid context quality decay. 项目地址: https://gitcode.com/gh_mirrors/toke/token-o…

2026/10/4 9:12:16 阅读更多 →
Bootstrap Icons 图标深度解析:diamond-half 半填充菱形的 SVG 源码、字体码点与实战使用

Bootstrap Icons 图标深度解析:diamond-half 半填充菱形的 SVG 源码、字体码点与实战使用

前端 【免费下载链接】icons Official open source SVG icon library for Bootstrap. 项目地址: https://gitcode.com/gh_mirrors/ic/icons 点击查看 免费下载 diamond-half 是 Bootstrap Icons 官方图标库中 Shapes(形状)分类下的一个基础几…

2026/10/4 9:12:16 阅读更多 →
cppcheck 无效迭代器解引用检查:derefInvalidIterator 与 derefInvalidIteratorRedundantCheck 原理与实战

cppcheck 无效迭代器解引用检查:derefInvalidIterator 与 derefInvalidIteratorRedundantCheck 原理与实战

开发工具静态分析代码质量质量保障 【免费下载链接】cppcheck static analysis of C/C code 项目地址: https://gitcode.com/gh_mirrors/cpp/cppcheck 点击查看 免费下载 本文围绕 cppcheck 的 STL 迭代器安全分析展开,深入解析 derefInvalidIterator&a…

2026/10/4 9:12:16 阅读更多 →
AI 时代程序员的 20 件事:从代码编写者到 AI 指挥官的思维与技术升级指南

AI 时代程序员的 20 件事:从代码编写者到 AI 指挥官的思维与技术升级指南

文档教程知识库人工智能 【免费下载链接】ai-guide 程序员鱼皮的 AI 资源大全 Vibe Coding 零基础教程,分享 OpenClaw 保姆级教程、大模型玩法(DeepSeek / GPT / Gemini / Claude / GLM)、最新 AI 资讯、Prompt 提示词大全、AI 知识百科&…

2026/10/4 9:12:16 阅读更多 →
从 PagerDuty 档案看 remoteintech 远程友好公司目录的数据模型与维护管线

从 PagerDuty 档案看 remoteintech 远程友好公司目录的数据模型与维护管线

数据集 【免费下载链接】remote-jobs Source for remoteintech.company — a community-maintained directory of remote-friendly tech companies 项目地址: https://gitcode.com/GitHub_Trending/re/remote-jobs 点击查看 免费下载 本篇文章以远程友好科技公司目…

2026/10/4 9:12:16 阅读更多 →
Meta开源Muse Gadgets,让全球开发者自己「造AI外设」

Meta开源Muse Gadgets,让全球开发者自己「造AI外设」

Muse刚火,Meta就让开发者自己造AI硬件! Meta 的 Muse 还在持续升温。 这款刚推出不久的个人 AI Agent,已经成为 Meta 今年 AI 战略中的重要产品。不同于传统聊天机器人,Muse 被设计为能够替用户执行任务的智能助手:处…

2026/10/4 9:11:15 阅读更多 →

日新闻

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