小芯片部署模型后升级前先测什么
小芯片部署模型后升级前先测什么
边缘模型和固件一起升级时,先看静态内存布局、运行期分配和故障捕获是否仍能覆盖目标板。
先确定验证对象
先区分主机侧可重复的检查和目标板上的实际行为。板型、编译选项、内存布局和外设状态都应记录;缺少这些前提,任何容量或性能结论都只能算示例。
需要留下的证据
比较符号表差异、栈高水位、分配失败与异常寄存器;具体阈值由芯片内存图和任务预算决定。
代码片段说明
下列原有片段用于展示检查方法,其中的地址、大小和循环次数不是推荐配置。接入设备前请以链接脚本、数据手册和现场采样结果为准。
$ arm-none-eabi-size --format=berkeley build/firmware_v2.0.elf text data bss dec hex filename 1542104 12480 3840296 5394880 5251c0 build/firmware_v2.0.elf $ arm-none-eabi-readelf -s build/firmware_v2.0.elf | grep -E "kv_cache_pool|scratch_buffer" 548: 20004000 1048576 OBJECT GLOBAL DEFAULT 10 kv_cache_pool 912: 20104000 524288 OBJECT GLOBAL DEFAULT 10 scratch_buffer#include <stdio.h> #include <stdint.h> #include <stdbool.h> #include "rtos_wrapper.h" #define MAX_EVAL_TOKENS 256 #define STACK_CANARY_PATTERN 0xDEADBEEF extern uint32_t _estack; extern uint32_t _sstack; // 动态填充 Stack 哨兵值 void FillStackCanary(void) { uint32_t *p = (uint32_t*)&_sstack; while (p < (uint32_t*)&_estack) { *p++ = STACK_CANARY_PATTERN; } } // 检查最高 Stack 消耗(高水位线) size_t MeasureStackHighWatermark(void) { uint32_t *p = (uint32_t*)&_sstack; size_t unused = 0; while (p < (uint32_t*)&_estack && *p == STACK_CANARY_PATTERN) { unused += sizeof(uint32_t); p++; } return ((size_t)&_estack - (size_t)&_sstack) - unused; } bool RunLLMUpgradeStressTest(void) { printf("[STRESS_TEST] Starting KV Cache Allocation Test...\n"); FillStackCanary(); for (int token_idx = 0; token_idx < MAX_EVAL_TOKENS; token_idx++) { // 模拟调用新版推理 API int status = LLM_Engine_Forward_Token(token_idx); if (status != 0) { printf("[ERROR] Engine Forward failed at Token %d, Heap Fragmented!\n", token_idx); return false; } size_t current_stack_used = MeasureStackHighWatermark(); if (current_stack_used > 60 * 1024) { // 限制 60KB 警戒线 printf("[WARNING] Stack high watermark exceeded threshold: %zu bytes\n", current_stack_used); return false; } } printf("[SUCCESS] All Tokens Evaluated. Peak Stack Used: %zu bytes\n", MeasureStackHighWatermark()); return true; }$ gdb-multiarch -batch \ -ex "target remote localhost:3333" \ -ex "monitor reset halt" \ -ex "load build/firmware_v2.0.elf" \ -ex "break HardFault_Handler" \ -ex "continue" \ -ex "info registers" \ -ex "bt"Program received signal SIGTRAP, Trace/breakpoint trap. HardFault_Handler () at Core/Src/stm32h7xx_it.c:98 #0 HardFault_Handler () at Core/Src/stm32h7xx_it.c:98 #1 <signal handler called> #2 quantize_row_q4_0_arm (src=0x20015003, dst=0x20016000, k=128) at llm_quant_arm.c:45收尾
先把可复查的输入与输出留好,再讨论调优。嵌入式问题往往卡在边界条件,日志和波形比一句“已验证”更有用。
