首页/新闻资讯/正文详情

STM32移植cJSON解析JSON字符串实战:内存配置、解析避坑与压测验证

发布时间:2026/11/4 3:38:29 来源:云帆数科 栏目:资讯中心
STM32移植cJSON解析JSON字符串实战:内存配置、解析避坑与压测验证
简介这份资源面向使用STM32进行嵌入式开发的工程师与学习者聚焦于在单片机环境中解析和生成JSON格式数据这一常见需求。包内提供经过工程验证的cJSON移植与调用示例可直接嵌入实际项目帮助读者解决设备与上位机、云平台之间轻量级数据交换的问题。压缩包共133个文件约1.76MB以31个c源文件和31个h头文件为核心涵盖STM32标准外设库与cJSON实现同时包含o、d、crf等编译中间文件s启动文件、uvprojx与uvoptx工程配置以及map、lst、axf等构建产物并附readme说明便于快速导入Keil环境复现。目前已有3250人学习下载说明该方案在社区中具备一定参考价值。读者可从中获得cJSON在STM32上的集成方式、内存配置与序列化/反序列化调用思路适合作为项目开发中的基础组件与排错参照。1. 串口收到一包 JSONSTM32 该怎么把它拆开调试一块 STM32 板子时串口或无线模块吐上来一包{temp:25.6,hum:60,ok:1}很多人第一反应是strstr找冒号、atoi转数字字段一多、嵌套一深代码立刻变成一坨没法维护的字符串手术。这份stm32使用cjson解析json字符串.zip就是冲着这个场景来的把 cJSON 这套轻量 JSON 解析库移植进 STM32 工程让单片机像上位机一样按 key 取值、按数组下标遍历而不是靠手写偏移量硬啃字符串。它适合正在做物联网节点、设备上报、上位机协议对接的嵌入式开发者尤其是 RAM 只有几十 KB、又不想自己造解析轮子的那批人。下面按「库怎么进工程 → 怎么解析 → 怎么避坑 → 怎么验证」走一遍能直接抄。2. 把 cJSON 塞进 Keil 工程文件、内存与编译选项cJSON 的全部实现就两个文件cJSON.c和cJSON.h纯 C89 风格不依赖操作系统也不依赖标准库里的浮点格式化之外的东西。这意味着它在 STM32 上落地的主要工作量不在「能不能编译」而在「内存从哪来、编译选项怎么配、浮点会不会把 Flash 撑爆」。先把这三件事定下来后面解析代码才有意义。2.1 源码文件清单与目录组织拿到压缩包后先别急着全丢进工程。cJSON 官方仓库里还有 test、fuzzing 之类的目录那些跟单片机无关进工程只会拖慢编译、增加误包含风险。我一般只保留核心两个文件按下面结构放YourProject/ ├── Core/ │ └── Src/ │ └── main.c ├── Drivers/ ├── Middlewares/ │ └── Third_Party/ │ └── cJSON/ │ ├── cJSON.c │ └── cJSON.h └── MDK-ARM/ └── YourProject.uvprojx放好之后在 Keil 里做两件事一是把cJSON.c加入对应分组比如新建一个Middlewares/cJSON组二是在Options for Target → C/C → Include Paths里把Middlewares/Third_Party/cJSON加进去。头文件包含路径这一步漏了编译会报cannot open source input file cJSON.h这是最高频的低级翻车点跟库本身没关系。提示不要图省事把cJSON.c直接拖进main.c所在目录再#include cJSON.c。这种写法在单文件 demo 里能跑一旦工程里有两个 .c 都包含它链接期就是一堆重复符号。2.2 内存钩子让 cJSON 用你自己的堆cJSON 默认用malloc/free分配节点。STM32 上如果启用了标准库的malloc它背后是_sbrk那套堆大小由启动文件里的Heap_Size决定默认往往只有 0x200 到 0x400 字节。解析一个稍大的 JSON节点一多就返回 NULL现象是「解析函数不报错但取不到值」非常隐蔽。稳妥做法是给 cJSON 挂自定义内存钩子把它指到自己的内存池或者 RTOS 的堆上。cJSON 提供了cJSON_InitHooks#include cJSON.h /* 假设工程里已有一个静态内存池或 RTOS 的 pvPortMalloc */ extern void *my_pool_malloc(size_t size); extern void my_pool_free(void *ptr); static cJSON_Hooks g_json_hooks { .malloc_fn my_pool_malloc, .free_fn my_pool_free, }; void json_lib_init(void) { /* 必须在任何 cJSON_Parse 之前调用且只调一次 */ cJSON_InitHooks(g_json_hooks); }malloc_fn的签名是void *(size_t)free_fn是void (void *)和标准库一致所以裸机下直接传malloc/free也能编过但那就失去了控制堆的意义。参数上唯一要注意的是钩子必须在第一次解析前设置中途改钩子会导致「这块内存是用 A 分配的、却用 B 释放」轻则内存池错乱重则 HardFault。我一般把json_lib_init()放在main里外设初始化之后、进主循环之前位置固定不给自己留后悔药。2.3 编译选项浮点、栈与-lmcJSON 解析带小数的字段时会走strtod格式化输出时会走sprintf的浮点分支。如果你的 JSON 里全是整数和字符串可以把CJSON_NESTING_LIMIT之外的浮点相关裁剪掉但只要有一个temp:25.6就得保证工具链的浮点支持是开的。Keil ARMCC/ARMCLANG 下常见配置选项建议值原因Floating Point Hardware按芯片选 Single Precision有 FPU 的 F4/F7 打开解析浮点更快C99 Mode勾选cJSON 里用了//注释和部分 C99 写法Optimization-O1 或 -O2-O0 下 cJSON 代码体积偏大但调试期可先用 -O0Use MicroLIB视情况MicroLIB 的malloc更省但和自定义钩子二选一如果链接阶段报undefined symbol strtod或浮点相关符号多半是没把数学库带上。GCC 工具链加-lmKeil 一般在Options → Target → Floating Point Hardware配好即可。还有一个容易忽略的点cJSON 解析是递归下降嵌套层数受栈深度限制。默认启动文件里Stack_Size常常是 0x400解析三四层嵌套没问题但如果你的协议里有深层数组套对象建议把栈加到 0x800 以上否则现象是「解析到一半跑飞」用调试器看调用栈才发现是栈溢出。3. 解析实战从cJSON_Parse到按 key 取值库进工程只是第一步真正决定代码好不好维护的是解析流程的组织方式。cJSON 的 API 是「解析成树 → 在树上找节点 → 取值 → 释放整棵树」这个顺序不能乱尤其是释放漏一次就是内存泄漏跑几百次解析后堆就空了。下面按一个典型的设备上报报文把完整链路走一遍。3.1 解析入口与根节点校验假设串口收到这样一包数据已去掉帧头帧尾只留 JSON 正文{dev:node01,temp:25.6,hum:60,alarm:{code:3,msg:overheat},ch:[1,2,3]}解析代码#include cJSON.h #include string.h /* 返回值0 成功-1 失败调用方负责在合适时机释放 root */ int parse_report(const char *json_str, float *temp, int *hum) { cJSON *root cJSON_Parse(json_str); if (root NULL) { /* 拿错误位置定位是哪个字符开始不合法 */ const char *err cJSON_GetErrorPtr(); if (err ! NULL) { /* 实际项目里可把 err 前后若干字节打印出来 */ printf(json parse error near: %.20s\r\n, err); } return -1; } cJSON *item_temp cJSON_GetObjectItemCaseSensitive(root, temp); cJSON *item_hum cJSON_GetObjectItemCaseSensitive(root, hum); if (cJSON_IsNumber(item_temp)) { *temp (float)item_temp-valuedouble; } if (cJSON_IsNumber(item_hum)) { *hum item_hum-valueint; } cJSON_Delete(root); /* 整棵树一次性释放 */ return 0; }逻辑上分四步cJSON_Parse把字符串建成树失败时用cJSON_GetErrorPtr拿到出错位置cJSON_GetObjectItemCaseSensitive按 key 精确匹配大小写敏感协议里 key 大小写不一致时用它别用不区分大小写的版本否则Temp和temp会被当成同一个取值前必须用cJSON_IsNumber之类的类型判断直接读valueint而不判类型遇到字符串字段会读到 0属于「不崩但错」的典型最后cJSON_Delete(root)释放整棵树子节点不用单独释放。参数上要留意valuedouble和valueint的区别cJSON 内部所有数字都存成 doublevalueint是解析时顺手截断的 int。取小数用valuedouble取整数用valueint更省事但前提是确认字段确实是整数否则25.6用valueint取出来是 25这种精度丢失在温度、电压场景里会直接导致业务判断出错。3.2 嵌套对象与数组的遍历上面那包数据里alarm是嵌套对象ch是数组。嵌套对象用cJSON_GetObjectItemCaseSensitive逐层往下取数组则用cJSON_GetArraySize配cJSON_GetArrayItem或者用 cJSON 提供的遍历宏/* 取嵌套对象字段 */ cJSON *alarm cJSON_GetObjectItemCaseSensitive(root, alarm); if (cJSON_IsObject(alarm)) { cJSON *code cJSON_GetObjectItemCaseSensitive(alarm, code); cJSON *msg cJSON_GetObjectItemCaseSensitive(alarm, msg); if (cJSON_IsNumber(code)) { printf(alarm code%d\r\n, code-valueint); } if (cJSON_IsString(msg) msg-valuestring ! NULL) { printf(alarm msg%s\r\n, msg-valuestring); } } /* 遍历数组 */ cJSON *ch cJSON_GetObjectItemCaseSensitive(root, ch); if (cJSON_IsArray(ch)) { int n cJSON_GetArraySize(ch); for (int i 0; i n; i) { cJSON *elem cJSON_GetArrayItem(ch, i); if (cJSON_IsNumber(elem)) { printf(ch[%d]%d\r\n, i, elem-valueint); } } }这里的关键判断是cJSON_IsObject和cJSON_IsArray。很多翻车案例是「协议里alarm有时是对象、有时是 null」代码不判类型直接往下取cJSON_GetObjectItemCaseSensitive(NULL, ...)返回 NULL再对 NULL 取valueint就是空指针解引用。cJSON 对 NULL 入参有一定容错多数 Get 系列函数遇到 NULL 返回 NULL但-valueint这种直接解引用没有保护必须自己判。数组遍历还有一个边界cJSON_GetArraySize返回的是当前节点数遍历过程中不要对数组做增删否则下标会错位。解析场景一般只读不写问题不大但如果你的代码在同一棵树上既解析又修改建议先取值到本地结构体再统一处理别在树上边遍历边改。3.3 构造 JSON设备上报的另一半解析是收构造是发。设备上报时经常要把本地结构体拼成 JSON 字符串再走串口或无线发出去cJSON 的构造 API 是cJSON_CreateObject起头cJSON_AddXxxToObject挂字段最后cJSON_PrintUnformatted序列化char *build_report(float temp, int hum) { cJSON *root cJSON_CreateObject(); if (root NULL) { return NULL; } cJSON_AddStringToObject(root, dev, node01); cJSON_AddNumberToObject(root, temp, temp); cJSON_AddNumberToObject(root, hum, hum); cJSON *alarm cJSON_AddObjectToObject(root, alarm); if (alarm ! NULL) { cJSON_AddNumberToObject(alarm, code, 0); cJSON_AddStringToObject(alarm, msg, ok); } /* PrintUnformatted 不带缩进和换行适合串口/无线传输 */ char *out cJSON_PrintUnformatted(root); cJSON_Delete(root); /* 树释放后 out 仍然有效需调用方 free */ return out; }两个参数细节值得说。第一cJSON_PrintUnformatted返回的字符串是 cJSON 用钩子里的malloc_fn分配的调用方用完必须free或对应的my_pool_free否则每发一包泄漏一次。第二cJSON_AddNumberToObject对浮点的默认格式化位数有限温度25.6没问题但如果你的业务要求两位小数25.60默认输出可能是25.6需要自己用sprintf拼字符串字段或者接受这个精度。我一般对精度敏感的字段直接cJSON_AddStringToObject传格式化后的字符串接收端再转省得两边对小数位数的预期不一致。4. 避坑清单五个让解析「不崩但错」的现场cJSON 本身不复杂真正耗时间的是那些不报错、但结果不对的场景。下面五条是我在 STM32 上实际踩过的按「现象 → 原因 → 解决」记遇到同类问题可以直接对号。4.1 解析成功但取值为 0现象cJSON_Parse返回非 NULLcJSON_GetObjectItemCaseSensitive也能拿到节点但valueint读出来是 0而报文里明明是hum:60。原因key 大小写或前后有空格不匹配函数返回了 NULL代码没判 NULL 就直接读-valueint对 NULL 解引用在部分编译器下读到 0 而不崩。另一种是字段类型是字符串60用cJSON_IsNumber判断为假代码走了默认分支留下 0。解决所有GetObjectItem的返回值先判 NULL再判类型取值前打印一次 key 和类型确认匹配上了再读。协议对接初期我会在解析函数里加一行printf(key%s type%d\r\n, key, item ? item-type : -1)跑通再删。4.2 跑几十次后cJSON_Parse开始返回 NULL现象上电初期解析正常设备跑几分钟或解析几十包后cJSON_Parse突然一直返回 NULL复位后恢复。原因某条错误分支提前return漏了cJSON_Delete(root)每包泄漏几十到几百字节堆耗尽后malloc返回 NULLcJSON 建树失败。解决解析函数统一用「单入口单出口」结构所有分支汇到末尾统一cJSON_Delete或者用goto cleanup模式。更稳的做法是把解析封装成一个函数函数内保证「只要 Parse 成功就一定 Delete」调用方只拿值不碰树。4.3 浮点字段解析出来是 0 或乱值现象整数字段正常temp:25.6解析后valuedouble是 0 或者一个极大值。原因工具链没开浮点支持strtod链接到了精简版实现或者printf浮点格式化被裁掉导致调试输出误导。也有可能是报文里小数点用了中文全角字符strtod解析到非法字符就停。解决确认编译选项里浮点硬件和库都开了用十六进制打印valuedouble的内存表示排除是显示问题还是解析问题抓原始字节确认小数点、负号是 ASCII。串口收到的数据先做一次字符集检查全角字符在嵌入式协议里是纯灾难。4.4 嵌套深了直接 HardFault现象解析扁平 JSON 正常遇到三四层嵌套的报文程序跑飞进 HardFault。原因cJSON 递归下降解析每层嵌套消耗栈帧默认Stack_Size太小栈溢出踩到了其他内存区。解决把启动文件里的Stack_Size从 0x400 加到 0x800 或 0x1000同时在链接脚本里确认栈区没和堆区重叠。更根本的做法是协议设计阶段就限制嵌套层数设备间通信没必要套五层扁平化对双方都友好。4.5cJSON_Print返回的字符串用free释放报错现象构造 JSON 后调用cJSON_PrintUnformatted用完free(out)偶尔进 HardFault 或堆断言。原因设置了自定义malloc_fn/free_fn但释放时用了标准库free分配器和释放器不匹配。解决谁分配谁释放。用了钩子就用钩子对应的释放函数裸机下如果钩子就是标准malloc/free那free没问题一旦换成内存池释放也必须走内存池。这条和 2.2 节是同一个坑的两面写代码时把「分配器」当成一个全局约定别在某个文件里图方便混用。5. 验证与压测怎么确认这套解析在板子上真的稳代码编过、单包解析对不等于能在设备上长期跑。JSON 解析的稳定性问题大多是「跑久了才暴露」所以验证环节要专门设计不能只靠手动发几条报文看看串口打印。下面这套流程是我现在每次移植第三方解析库都会走一遍的成本不高但能提前把内存和边界问题逼出来。5.1 用固定用例做回归先准备一组覆盖边界的 JSON 字符串放在一个数组里上电后自动跑一遍比对预期值typedef struct { const char *json; int expect_ret; /* 0 成功-1 失败 */ float expect_temp; } json_case_t; static const json_case_t g_cases[] { {{\temp\:25.6,\hum\:60}, 0, 25.6f}, {{\temp\:-10.5,\hum\:0}, 0, -10.5f}, {{\temp\:25.6}, 0, 25.6f}, {{\temp\:\25.6\}, 0, 0.0f}, /* 类型不符取默认 */ {{\temp\:25.6,}, 0, 25.6f}, /* 尾逗号看库容错 */ {{\temp\:25.6, -1, 0.0f}, /* 缺右括号 */ {not a json, -1, 0.0f}, {, -1, 0.0f}, }; void json_regression_run(void) { for (int i 0; i (int)(sizeof(g_cases)/sizeof(g_cases[0])); i) { float temp 0.0f; int hum 0; int ret parse_report(g_cases[i].json, temp, hum); if (ret ! g_cases[i].expect_ret) { printf(case %d ret mismatch: got %d\r\n, i, ret); } if (ret 0 temp ! g_cases[i].expect_temp) { printf(case %d temp mismatch: got %.2f\r\n, i, temp); } } }这套用例的价值在于把「我以为库会怎么处理」变成可执行的断言。比如尾逗号那条不同版本的 cJSON 容错行为可能不同跑一遍就知道你手上这份是宽松还是严格协议对接时心里有数。类型不符那条用来确认你的解析函数在字段类型变化时是走默认值还是报错这直接决定上层业务逻辑要不要额外兜底。5.2 长时间循环压测看堆水位单包正确之后做一轮循环压测把同一包报文连续解析一万次每次解析后记录当前堆剩余用xPortGetFreeHeapSize或自己内存池的剩余量观察曲线是否单调下降。正常情况应该是锯齿状、整体持平如果持续下降就是 4.2 那条泄漏。void json_stress_test(const char *json, int times) { for (int i 0; i times; i) { float temp; int hum; parse_report(json, temp, hum); if ((i % 1000) 0) { printf(iter%d free_heap%u\r\n, i, (unsigned)get_free_heap()); } } }参数上times取一万起步堆小的板子取五千也行关键是看趋势而不是绝对值。压测期间别开太多其他动态分配的任务否则堆水位波动会掩盖泄漏信号。我一般会在压测前后各打印一次堆总量差值超过单包节点大小的量级就值得查。5.3 边界与异常输入的取舍最后一层验证是异常输入超长字符串、深层嵌套、非法 UTF-8、数字溢出。cJSON 对超长字符串没有硬上限取决于你的堆深层嵌套受栈限制数字溢出会走strtod的饱和行为。这些不需要全部在设备上处理但协议层要定好规矩单包最大长度、最大嵌套层数、字段类型白名单。设备端解析函数在入口处先做长度检查超过阈值直接丢弃并回错误码比让 cJSON 去啃一个畸形报文安全得多。从那以后我每次往 STM32 工程里塞第三方解析库都强制先跑一遍回归用例加一万次循环压测堆水位曲线不平就不往下写业务代码。这套习惯帮我省掉了好几次「现场跑三天才复现」的排查。希望帮到你。本文还有配套的精品资源点击获取

相关推荐

自动化数据分析流水线:智能体技术与工程实践
自动化数据分析流水线:智能体技术与工程实践

1. 项目背景与核心价值在数据驱动的决策时代,传统的数据分析流程往往需要人工介入多个环节——从数据清洗、特征工程到建模分析,再到最终的可视化呈现。这不仅效率低下,还容易因人为因素导致结果偏差。我们团队最近构建的这套自动化流水线&am… · 2026/11/4 3:38:29

音频驱动视频生成:稀疏帧如何让数字人实现无限长对话
音频驱动视频生成:稀疏帧如何让数字人实现无限长对话

打开一段语音,让数字人说出同样的话,30秒内不翻车容易,三分钟不翻车很难。我在本地搭音频驱动视频生成(audio-driven video generation)管线时定的验收线,就是这样一段三分钟连续口播。前30秒效果通常不错&… · 2026/11/4 3:38:29

财富创造的底层逻辑:三层套利模型解析
财富创造的底层逻辑:三层套利模型解析

1. 财富逻辑的底层架构解析财富创造的本质是价值交换过程中的套利行为。这种套利并非简单的投机取巧,而是基于信息差、资源差和能力差形成的系统性优势。我在金融行业从业十年间观察到一个现象:所有可持续的财富积累,本质上都是三层套利模型的… · 2026/11/4 3:38:29

WinForm核心技术解析与企业级应用实践
WinForm核心技术解析与企业级应用实践

1. WinForm的现状与生命力解析WinForm作为.NET框架下的老牌桌面应用开发技术,在WPF、MAUI等新技术的冲击下依然保持着惊人的生命力。根据2023年Stack Overflow开发者调查,仍有超过28%的.NET开发者在使用WinForm进行开发,特别是在企业级应用领… · 2026/11/4 4:16:38

SAP现金销售流程重构:绕过发出商品实现成本直结
SAP现金销售流程重构:绕过发出商品实现成本直结

简介:本资源是一份面向SAP财务与销售模块实施顾问、ERP运维人员及企业业务操作员的实操型流程指南,聚焦现金销售(Cash Sale)这一高频但易出错的特殊业务场景,系统解决手工记账效率低、清账环节冗余、系统配置不统一等痛… · 2026/11/4 4:16:38

AI编程工具三阶段进化:从提示驱动到系统协作者
AI编程工具三阶段进化:从提示驱动到系统协作者

1. 这不是工具测评,是一场开发者认知系统的迭代升级“AI编程工具大比拼:进化之路”——这个标题里藏着两个被多数人忽略的关键动词:“比拼”是表象,“进化”才是内核。我从2023年年初开始系统性地把AI编程工具嵌入日常开发流&… · 2026/11/4 4:16:38

AI编程工具的进化之路:从补全到架构协作者
AI编程工具的进化之路:从补全到架构协作者

1. 这不是工具测评,而是一次真实开发者的“进化切片”记录我从2018年开始写代码,经历过手写jQuery、手动配Webpack、为一个CI失败熬夜三小时的年代。2023年夏天,我第一次用Copilot补全了一整段React状态管理逻辑——不是“它写了什么”&#… · 2026/11/4 4:16:38

Solax逆变器Modbus TCP寄存器深度解析:从地址映射到能量控制逻辑
Solax逆变器Modbus TCP寄存器深度解析:从地址映射到能量控制逻辑

简介:本资源是Solax SK-SU系列混合太阳能逆变器的官方Modbus TCP通信协议规范文档,面向光伏系统集成商、能源监控平台开发者、嵌入式工程师及工业自动化运维人员,用于实现对逆变器的远程读取、参数配置与状态监控。文档完整覆盖V1.0至V2.50共… · 2026/11/4 4:16:38

跨平台文件传输与AWS Glue ETL数据清洗实战指南
跨平台文件传输与AWS Glue ETL数据清洗实战指南

1. 跨平台文件传输与数据清洗的现代解决方案在移动互联网时代,我们面临着两个看似不相关却同样令人头疼的问题:不同操作系统间的文件传输障碍,以及海量数据的自动化处理需求。作为一名长期在技术一线工作的从业者,我经常需要同时处… · 2026/11/4 4:15:36

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

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

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

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

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

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

AI辅助技术栈评估:提升研发决策效率60%
AI辅助技术栈评估:提升研发决策效率60%

1. 项目背景与核心价值技术决策一直是研发团队面临的重大挑战。随着技术生态的快速演进,技术栈的选择、维护和迭代变得愈发复杂。我们团队在过去两年里,先后经历了三次重大技术栈迁移,每次都需要投入大量人力进行技术评估和风险分析。直到去年… · 2026/11/4 0:00:17

从生成Token到直接决策:Jev如何重塑AI Agent工程实践
从生成Token到直接决策:Jev如何重塑AI Agent工程实践

1. 从"生成文字"到"拍板决策":Jev 到底在解决什么问题大多数人第一次接触大模型,脑子里建立的模型是"输入问题、输出文字"。你问它今天天气怎么样,它给你一段描述;你让它写个周报,它给你… · 2026/11/4 0:00:17

32G统一内存跑大模型:内存账、TPS实测与端云分流
32G统一内存跑大模型:内存账、TPS实测与端云分流

想在一台 32G 统一内存的小主机上把大模型跑成"日常可用",这件事我前后折腾了小半年。标题里说的这台 Mac mini M6,是我们这次讨论的目标平台,具体到手规格以实物为准;但下面这套推算方法和实测思路,对任何统… · 2026/11/4 0:00:17

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

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

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

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

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

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

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码