From 87c8e019363ce2a7a401ce8f5bb177caf7004a5c Mon Sep 17 00:00:00 2001 From: wangfq Date: Thu, 13 Aug 2026 11:27:08 +0800 Subject: [PATCH] =?UTF-8?q?test(vd960DBN):=20SPI=E5=86=99=E5=AF=86?= =?UTF-8?q?=E5=BA=A6=E6=A8=A1=E6=8B=9F=E5=AE=9E=E9=AA=8C=20+=20factory?= =?UTF-8?q?=E5=86=99=E6=AD=A2=E8=A1=80=20=E2=80=94=20VDD=E8=B7=8C=E8=90=BD?= =?UTF-8?q?=E8=AF=8A=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - peripheral_main: sim_snap_spi 模拟快照落盘节奏 (20ms 64B页写 + 每64条切扇区擦除+头写) - cfig_flash: magic不匹配时跳过 factory SPI_Flash_Write, 用内存默认值继续 (SPI写触发硬件复位死循环止血: 参数区0x00写也崩, RST=0x00000000) - 诊断修正: CH32V208GBU6 QFN28 无 NRST 引脚, 共线假设作废; SPI写/擦除→电流尖峰→VDD跌落→内部POR/PDR(2.4V)复位; BLE射频+SPI电流叠加是头号嫌疑 --- .../OnlyUpdateApp_Peripheral/APP/cfig_flash.c | 55 +++++++++++++-- .../APP/peripheral_main.c | 70 +++++++++++++++++++ 2 files changed, 120 insertions(+), 5 deletions(-) diff --git a/vd960DBN/BLE/OnlyUpdateApp_Peripheral/APP/cfig_flash.c b/vd960DBN/BLE/OnlyUpdateApp_Peripheral/APP/cfig_flash.c index b51e291..889ceb4 100644 --- a/vd960DBN/BLE/OnlyUpdateApp_Peripheral/APP/cfig_flash.c +++ b/vd960DBN/BLE/OnlyUpdateApp_Peripheral/APP/cfig_flash.c @@ -241,11 +241,56 @@ void load_cfg_from_flash(void) if(strncmp(mBuff, DEV_USER_FLASH_MAGIC, sizeof(DEV_USER_FLASH_MAGIC)) != 0) { free(mBuff); - PRINT("Will_Factory_dev_____\n"); - - factory_dev_info(); - - NVIC_SystemReset(); + /* ===== 止血 (2026-08-13): factory SPI 写触发硬件复位死循环 ===== + 现场: SPI_Flash_Write(参数区 0x00, 512B) → RST=0x00000000 硬件复位 + → magic 写不进 → 无限复位循环。SPI 写触发硬件复位实锤(与快照区无关)。 + 临时方案: 不写 Flash, 用内存默认配置继续 (恢复原逻辑删本块即可) */ + PRINT("CFG: magic mismatch - MEMORY DEFAULTS (factory SPI write disabled)\n"); + memset(g_dev_number, 0, 6); + memcpy(g_dev_number, gMacAddr, 6); + sprintf(g_dev_number_str, "%02X%02X%02X%02X%02X%02X", + g_dev_number[0], g_dev_number[1], g_dev_number[2], + g_dev_number[3], g_dev_number[4], g_dev_number[5]); + g_sub_code_enable.code_set = 0x0001; + g_max_counter_bt_min = BT_DISABLE_IDLE_TIMEOUT; + g_max_counter_bt_timeout = g_max_counter_bt_min * 60 * 1000; + g_storage_uart_baud = UART_BAUD_DEFAULT_PORT_1; + g_storage_uart_baud_2 = UART_BAUD_DEFAULT_PORT_2; + memcpy(g_dev_password, "123456", 6); + memcpy(local_net_cfg.mac, g_dev_number, 6); + local_net_cfg.lip[0] = 192; local_net_cfg.lip[1] = 168; local_net_cfg.lip[2] = 1; local_net_cfg.lip[3] = 188; + local_net_cfg.sub[0] = 255; local_net_cfg.sub[1] = 255; local_net_cfg.sub[2] = 255; local_net_cfg.sub[3] = 0; + local_net_cfg.gw[0] = 192; local_net_cfg.gw[1] = 168; local_net_cfg.gw[2] = 1; local_net_cfg.gw[3] = 1; + local_net_cfg.dns[0] = 192; local_net_cfg.dns[1] = 168; local_net_cfg.dns[2] = 1; local_net_cfg.dns[3] = 1; + local_net_cfg.port_ssc_tcp = 5550; + local_net_cfg.port_ssc_udp = NET_REPORT_INTERVAL; + local_net_cfg.port_ssc_udp_message = 5505; + local_net_cfg.port_dev_tcp = 5550; + local_net_cfg.port_dev_udp = 4900; + net_center_info.lssc_ip[0] = 192; net_center_info.lssc_ip[1] = 168; net_center_info.lssc_ip[2] = 1; net_center_info.lssc_ip[3] = 222; + net_center_info.msg_port = 4999; + net_center_info.tcp_port = 5550; + net_center_info.udp_port = NET_REPORT_INTERVAL; + net_center_info.sw_ver[0] = 1; net_center_info.sw_ver[1] = 2; + memset(iot_net_info.remote_addr, 0, 64); + memcpy(iot_net_info.remote_addr, "121.37.20.199", 13); + iot_net_info.mqtt_port = 1883; + memset(iot_net_info.client_id, 0, 64); + memset(iot_net_info.username, 0, 64); memcpy(iot_net_info.username, "admin", 5); + memset(iot_net_info.password, 0, 32); memcpy(iot_net_info.password, "password", 8); + iot_net_info.mode = 0; + g_iot_topic.clientid_enable = 0; + memset(g_iot_topic.topic_pub, 0, 64); + memset(g_iot_topic.topic_sub, 0, 64); + g_sub_code_enable.net_enable = 1; + g_sub_code_enable.iot_enable = 0; + g_sub_code_enable.custom_enable = 0; + g_sub_code_enable.loop_enable = 0; + g_sub_code_enable.dgdus_enable = 0; + g_sub_code_enable.wbdus_enable = 0; + g_sub_code_enable.radar_enable = 0; + PRINT("CFG: memory defaults OK (no factory write)\n"); + return; } _offset = DEV_NUMER_ADDR_OFFSET; diff --git a/vd960DBN/BLE/OnlyUpdateApp_Peripheral/APP/peripheral_main.c b/vd960DBN/BLE/OnlyUpdateApp_Peripheral/APP/peripheral_main.c index 7945969..a6c8cdb 100644 --- a/vd960DBN/BLE/OnlyUpdateApp_Peripheral/APP/peripheral_main.c +++ b/vd960DBN/BLE/OnlyUpdateApp_Peripheral/APP/peripheral_main.c @@ -217,6 +217,75 @@ void key_event_srv(void){ } +/********************************************************************* + * @fn sim_snap_spi + * + * @brief 实验(2026-08-13 第一步): 模拟快照区 SPI 写密度 + * + * 当前固件: snap_init 已 #if 0 跳过 (纯读基座, 日志读写正常)。 + * 本函数恢复快照落盘的写节奏, 隔离"SPI 写频率" vs "快照逻辑 bug": + * - 每 20ms: 64B 页写 (SPI_Flash_Write_NoCheck, 模拟 snap_write_raw) + * - 每 64 条: 切扇区序列 (读首条 magic + 擦除 45ms + + * 头区 SPI_Flash_Write 读-改-写整扇区, 模拟 snap_flush_head) + * 复现复位 → SPI 高频写触发硬件问题 (PA7/NRST 共线怀疑坐实); + * 不复现 → 快照区有具体逻辑 bug, 转向代码审查。 + * 注意: 会覆盖快照区旧数据, 恢复快照功能前需 snap_clear。 + * + * @return none + */ +#define SIM_SNAP_HEAD_BASE 0x110000UL +#define SIM_SNAP_DATA_BASE 0x111000UL +#define SIM_SNAP_DATA_SIZE (4096UL * 751UL) /* 与 snapshot.c 数据扇区数一致 */ +static uint32_t _sim_snap_wr = SIM_SNAP_DATA_BASE; +static uint32_t _sim_snap_cnt = 0; +static uint32_t _sim_snap_last = 0; +void sim_snap_spi(void) +{ + uint32_t _now = mstick(); + + if ((uint32_t)(_now - _sim_snap_last) < 20) return; /* 20ms 节拍 = 50Hz 帧率 */ + _sim_snap_last = _now; + + /* 切扇区: 每 64 条 (4096/64) 一次, 与 snap_write_raw 同节奏 */ + if (_sim_snap_cnt > 0 && (_sim_snap_cnt & 63) == 0) + { + uint8_t _r[64]; + uint8_t _h[32]; + + /* 1) snap_sector_has_data: 读目标扇区首条 magic */ + SPI_Flash_Read(_r, _sim_snap_wr, 64); + + /* 2) SPI_Flash_Erase_Sector (~45ms) */ + SPI_Flash_Erase_Sector(_sim_snap_wr / 4096); + + /* 3) snap_flush_head: 头区读-改-写 (SPI_Flash_Write 内部 + 读4096 + 擦 + 写回4096, ~100ms) */ + memset(_h, 0xFF, sizeof(_h)); + _h[0] = 'S'; _h[1] = 'N'; _h[2] = 'P'; _h[3] = 'M'; + _h[8] = (uint8_t)(_sim_snap_cnt & 0xFF); + _h[9] = (uint8_t)((_sim_snap_cnt >> 8) & 0xFF); + _h[10] = (uint8_t)((_sim_snap_cnt >> 16) & 0xFF); + _h[11] = (uint8_t)((_sim_snap_cnt >> 24) & 0xFF); + SPI_Flash_Write(_h, SIM_SNAP_HEAD_BASE, 32); + } + + /* 模拟 snap_write_raw: 64B 页写 */ + { + static uint8_t _b[64]; + uint8_t _i; + for (_i = 0; _i < 64; _i++) _b[_i] = (uint8_t)(_sim_snap_cnt + _i); + _b[0] = 'S'; _b[1] = 'N'; _b[2] = 'P'; _b[3] = 'M'; + SPI_Flash_Write_NoCheck(_b, _sim_snap_wr, 64); + _sim_snap_wr += 64; + if (_sim_snap_wr >= SIM_SNAP_DATA_BASE + SIM_SNAP_DATA_SIZE) + _sim_snap_wr = SIM_SNAP_DATA_BASE; + _sim_snap_cnt++; + if ((_sim_snap_cnt & 0x3F) == 0) + PRINT("SIM: cnt=%lu wr=0x%08lx\n", + (unsigned long)_sim_snap_cnt, (unsigned long)_sim_snap_wr); + } +} + /********************************************************************* * @fn Main_Circulation * @@ -269,6 +338,7 @@ void Main_Circulation(void) uart_srv(); snap_flush(); /* 快照落盘: 无条件挂主循环 (原在 iot_enable 分支, TCP 模式不落盘) */ + sim_snap_spi(); /* 实验第一步(2026-08-13): 模拟快照区 SPI 写密度, 定位复位触发源 */ poll_dbn_ble();