Hello, 又来饮茶哈

加张台啊!

【Zephyr】Windows 下部署

环境 系统:Windows 10 终端:MSYS2 使用对应的 Windwos 安装包安装相关软件: 不要使用 MSYS2 的 pacman 命令安装 Python 当前使用的版本是 3.12.5 环境变量 PATH 里面包含有:C:\Program Files (x86)\Python\Python312(以实际安装路径为准) Git 当前使用的版本是 2.44.0 环境变量 PATH 里面包含有:D:\Program Files\Git\cmd(以实际安装路径为准) 7-Zip 当前使用的版本是 23.01 环境变量 PATH 里面包含有:C:\Program Files\7-Zip(以实际安装路径为准) CMake 当前使用的版本是 4.3.3 环境变量 PATH 里面包含有:C:\Program Files\CMake\bin(以实际安装路径为准) Ninja 当前使用的版本是 1.13.1 将解压得到的 ninja.exe 放到 C:\Program Files\CMake\bin 里面。 west 工具 Zephyr 使用 west 这个元工具(meta-tool)来管理其多个子仓库。 类似于 Repo + Git 的组合 west 这个工具使用 python 编写的,所以我们可以通过 pip 来安装它。 创建 Zephyr 目录 ...

June 13, 2026 · 3 min · 624 words

【ESP32】创建一个 HTTP 服务器

测试环境 芯片:ESP32-S3 ESP-IDF:v5.5.2 一、HTTP 服务器说明 访问 HTTP 服务器的方法: 当 ESP32 连上 WIFI 后,路由器会给 ESP32 分配一个 IP 地址,那么只要和这个 IP 地址位于同一个网段内的设备都可以通过 http://<ip>:<port> 来访问 ESP32 的 HTTP 服务器。 当 ESP32 开启 AP 后,当设备连上该 AP 后,ESP32 会给该设备分配一个 IP 地址(当前 ESP-IDF 默认使用的网段是 192.168.4),该设备可以通过 http://192.168.4.1:<port> 来访问 ESP32 的 HTTP 服务器。 当 HTTP 服务器收到请求后,可以: 返回静态网站的文件内容。 如果一个静态网站有三个文件:index.html,index.css,index.png,那么浏览器会发送三个请求,HTTP 服务器只需要读取文件内容并返回给浏览器,浏览器会自动渲染该静态网站。 返回特定的数据。 如果该 uri 的目的是获取设备当前的温度,那么则直接返回设备当前的温度。 二、示例 HTTPD,即 http daemon。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 #include "esp_err.h" #include "esp_log.h" #include "esp_http_server.h" static const char *TAG = "httpd"; static esp_err_t priv_uri_index_handle(httpd_req_t *req); /* http server 服务器句柄 */ static httpd_handle_t s_httpd_handle = NULL; static const httpd_uri_t s_index_uri = { .uri = "/index", /* uri 是 "/index" */ .method = HTTP_GET, /* uri 仅支持 GET 方法 */ .handler = priv_uri_index_handle, /* uri 的回调函数 */ .user_ctx = NULL, /* 用户上下文 */ }; static esp_err_t priv_uri_index_handle(httpd_req_t *req) { esp_err_t err = ESP_OK; /* 传入的 uri,这里打印的是 /uri */ ESP_LOGI(TAG, "uri: %s", req->uri); /* 触发该 uri 回调的方法, 这里打印的是 HTTP_GET */ ESP_LOGI(TAG, "method: %d", req->method); /* 此时 HTTP 服务器已经收到了 HTTP Header, 这里尝试接收 HTTP Body */ int ret = 0; char recv_buf[4096] = {0}; ret = httpd_req_recv(req, recv_buf, 4096); if (ret <= 0) { return ESP_FAIL; } /* 处理 recv_buf */ ... /* 配置响应的状态码 */ httpd_resp_set_status(req, HTTPD_200); /* 配置响应的数据类型 */ httpd_resp_set_type(req, "application/json"); /* 发送 HTTP 响应 */ char *send_buf = "{\"code\": 0}" err = httpd_resp_send(req, send_buf, strlen(send_buf)); if (err != ESP_OK) { return ESP_FAIL; } /* 当返回值不是 ESP_OK 时, httpd 会自动断开当前的连接 */ return ESP_OK; } int httpd_init(void) { esp_err_t err = ESP_OK; /* http 服务器配置初始化 */ httpd_config_t config = HTTPD_DEFAULT_CONFIG(); /* http 服务器配置 */ config.lru_purge_enable = true; /* 开启 LRU 功能 */ config.max_uri_handlers = 15; /* 支持 uri 的数量上限是 15 */ config.server_port = 80 /* 端口号是 80 */ config.stack_size = 20 * 1024; /* http 服务区任务的栈空间是 20 KB */ /* 启动 HTTP 服务器 */ err = httpd_start(&s_httpd_handle, &config); if (err != ESP_OK) { ESP_LOGE(TAG, "start http server failed: %s", esp_err_to_name(err)); return -1; } /* 注册 URI: http://<local_host>/index */ err = httpd_register_uri_handler(s_httpd_handle, &s_index_uri); if (err != ESP_OK) { ESP_LOGE(TAG, "register http uri failed: %s", esp_err_to_name(err)); } return 0; } 三、其他功能 1. 通配符 在上面的示例可以发现,每创建一个 uri 就要注册一个回调函数。数量少还好,一旦数量多了,就要频繁注册。 ...

June 8, 2026 · 4 min · 709 words

【RK3568】一、部署 Qwen 3.5 2B 模型:资源介绍

一、Qwen3.5-2B Hugging Face - Qwen3.5-2B。 参数:2B(2 Billion,20 亿)。 参数类型:F32(Float32)/ BF16(BFloat16) 二、TOPS TOPS,Tera Operations Per Second,每秒万亿次操作。 三、RK3568 芯片 RK3568 主要参数: CPU:Quad‑core Arm® Cortex®‑A55 (ARMv8) 64‑bit @ 2.0GHz GPU:Mali™ G52 GPU NPU:1TOPS @ INT8 开发板 Rock 3A 主要参数: DDR:4GB 32bits LPDDR4

June 1, 2026 · 1 min · 39 words

【ESP32】在 Linux 环境下运行应用程序

测试环境 Ubuntu 22.04 1 2 3 4 5 6 $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.5 LTS Release: 22.04 Codename: jammy 安装 ESP-IDF 安装 EIM(ESP-IDF 安装管理器) 1 2 3 4 5 6 7 # APT 源列表添加 EIM 仓库 $ echo "deb [trusted=yes] https://dl.espressif.com/dl/eim/apt/ stable main" | sudo tee /etc/apt/sources.list.d/espressif.list $ sudo apt update # 这里仅安装 CLI $ sudo apt install eim-cli 更新 EIM(可选) ...

May 30, 2026 · 2 min · 397 words

【Device】入网参数的保存

ST 适配的 LoRaWAN 协议栈 stm32-mw-lorawan 当前版本:2.6.2 由于是 ST 适配过,所以和 Semtech 开源的 LoRaMac-node 协议栈还是有差别的 一、OTAA 1. 参数 OTAA 主要参数如下: DevAddr AppSKey NwkSKey NetworkActivation 2. 入网保存参数的流程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 /* Mac/LoRaMac.c */ static void ProcessRadioRxDone( void ) { ... switch( macHdr.Bits.MType ) { case FRAME_TYPE_JOIN_ACCEPT: { ... SecureElementGetJoinEui( joinEui ); /* 解密 */ macCryptoStatus = LoRaMacCryptoHandleJoinAccept( JOIN_REQ, joinEui, &macMsgJoinAccept ); ... ... /** * 更新设备地址 DevAddr * 1. Nvm.MacGroup2.DevAddr * 2. Nvm.SecureElement.SeNvmDevJoinKey.DevAddrOTAA */ Nvm.MacGroup2.DevAddr = macMsgJoinAccept.DevAddr; SecureElementSetDevAddr( ACTIVATION_TYPE_OTAA, Nvm.MacGroup2.DevAddr ); ... /* 更新激活状态 NetworkActivation */ Nvm.MacGroup2.NetworkActivation = ACTIVATION_TYPE_OTAA; ... ... break; } ... } ... } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 /* Mac/LoRaMacCrypto.c */ LoRaMacCryptoStatus_t LoRaMacCryptoHandleJoinAccept( JoinReqIdentifier_t joinReqType, uint8_t* joinEUI, LoRaMacMessageJoinAccept_t* macMsg ) { ... { ... /** * 生成密钥 AppSKey * 1. Nvm.SecureElement.KeyList[], 对应的 key id 是 APP_S_KEY */ retval = DeriveSessionKey10x( APP_S_KEY, currentJoinNonce, netID, nonce ); ... #if (defined( LORAMAC_VERSION ) && ( LORAMAC_VERSION == 0x01010100 )) ... #else /** * 生成密钥 NwKSKey * 1. Nvm.SecureElement.KeyList[], 对应的 key id 是 NWK_S_KEY */ retval = DeriveSessionKey10x( NWK_S_KEY, currentJoinNonce, netID, nonce ); #endif ... } ... /** * FCnt 相关统计清零 * CryptoNvm 指向的是 Nvm.Crypto, 实际是 * 1. Nvm.Crypto.FCntList.FCntUp * 2. Nvm.Crypto.FCntList.FCntDown * 3. Nvm.Crypto.FCntList.NFCntDown * 4. Nvm.Crypto.FCntList.AFCntDown */ CryptoNvm->FCntList.FCntUp = 0; CryptoNvm->FCntList.FCntDown = FCNT_DOWN_INITIAL_VALUE; CryptoNvm->FCntList.NFCntDown = FCNT_DOWN_INITIAL_VALUE; CryptoNvm->FCntList.AFCntDown = FCNT_DOWN_INITIAL_VALUE; return LORAMAC_CRYPTO_SUCCESS; } 二、ABP 1. 参数 ABP 要预先配置的参数如下: ...

January 25, 2026 · 11 min · 2329 words

【SonarQube】Cyclomatic Complexity 圈复杂度

Cyclomatic Complexity 来自 SonarQube 函数的复杂度是通过函数体中的逻辑运算符(&&、||)和条件控制语句(if、while、do-while、for、?:、catch、case、default)的数量来衡量的。 计算规则: 默认复杂度是 1,每遇到一次上述符号,复杂度增加 1。 复杂度在 1 到 10 之间的方法被认为是简单的,易于理解和测试。 复杂度在 10 到 20 之间的值表示代码更复杂,但仍然可以理解;然而,由于代码可能包含更多的分支,测试变得更加困难。 复杂度在 20 及以上是典型的具有大量潜在执行路径的代码,只有经过极大的困难和努力才能完全掌握和测试。 复杂度大于 50,肯定是不可维护的,或者说非常然维护的。 错误提示 The Cyclomatic Complexity of this function is 31 which is greater than 20 authorized. The Cyclomatic Complexity of this function is 23 which is greater than 20 authorized. 分析 其中: +1: function definition 表示定义函数时,复杂度默认为 1。 +1: if statement 表示识别到 if 语句,复杂度加 1。 +1: while loop ...

January 18, 2026 · 2 min · 358 words

【SonarQube】Cognitive Complexity 认知复杂度

Cognitive Complexity 来自 SonarQube 认知复杂度旨在弥补传统的圈复杂度在衡量代码可维护性方面的不足: 对于不同结构的代码,即使圈复杂度相同,但是理解难度可能差异很大。 不适合现代的编程语言结构。 计算规则: 忽略简化写法 不计算那些使代码更简洁、已读的结构。 结构增量(Structural Increment) for、while、do-while、if、?:、#if、#ifdef 会增加 1 分。 catch 语句会增加 1 分。 try 和 finally 则不会加入统计。 switch 语句会增加 1 分。 switch 里面的 case 语句则不会加入统计。 同类型的运算符会增加 1 分,但是不同类型的运算符会增加 n 分(n 取决于实际个数)。 if (a && b && c && d) 会增加 1 分,if (a || b || c || d) 会增加 1 分。 if (a && b || c) 会增加 2 分,if (a || (b && c) || d) 会增加 3 分。 ...

January 18, 2026 · 2 min · 338 words

【PyOCD】使用 Vscode 调试

一、安装 PyOCD OpenOCD,Open On-Chip Debugger,主要使用 C 编写。 PyOCD,Python On-Chip Debugger,主要使用 Python 编写。 当前最新版本的 PyOCD 是 v0.42,其依赖的 Python 版本是 >= 3.8.0。 1 2 3 4 5 $ python --version Python 3.12.5 $ pip --version pip 25.3 from C:\Users\Zeepunt\AppData\Roaming\Python\Python312\site-packages\pip (python 3.12) 这里我们使用 pip 工具安装即可。 1 2 3 4 5 6 7 8 $ python -mpip install -U pyocd ... Installing collected packages: pyocd Attempting uninstall: pyocd Found existing installation: pyocd 0.41.0 Uninstalling pyocd-0.41.0: Successfully uninstalled pyocd-0.41.0 Successfully installed pyocd-0.42.0 查看版本信息: ...

January 3, 2026 · 3 min · 506 words

【MT2500A】相关信息

一、产品信息 MT2500A 是金属外壳。 厂商:GL.iNet CPU:MediaTek MT7981B,Dual-core @ 1.3GHz ARMv8 Processor rev 4 Cortex-A53 内存:1GB DDR4 南亚 NT5AD512M16C4-JR 存储:8GB eMMC 三星 KLM8G1GETF-B041 供电:Type-C,5V / 2A PHY 芯片:MediaTek MT7981 内置 PHY 2.5G 芯片:MXL SLNW8 二、硬件引脚 版权声明 本文为「Zeepunt 日常随笔」的原创文章,遵循 CC BY-NC-ND 4.0 许可协议。允许在署名作者、注明原文链接且不作任何更改的前提下非商业性地分享本文。 原文链接:https://zeepunt.github.io/article/router/mt2500a%E7%9B%B8%E5%85%B3%E4%BF%A1%E6%81%AF/ ...

December 28, 2025 · 1 min · 41 words

【Gateway】射频芯片通信

芯片:ESP32-S3(v0.2) IDF 版本:ESP-IDF-v5.5.0 一、SX125x SX125x 指的是 SX1255 和 SX1257。 1. SPI 通信格式 在硬件上,SX125x 的 SPI 引脚连接的是 SX1302 Radio A/B 的 SPI 接口,所以主控是通过 SX1302 来控制 SX125x 的。 对于 SX1302 未提供。 对于 SX125x 1 2 3 4 5 6 7 8 9 10 11 12 13 NSS -----+ +----- | | +-----------------------------------------------------+ SCK ... MOSI +-----+-----------+-----------------+-----------------+-----+ | W/R | Addr[6:0] | Data Write[7:0] | Data Write[7:0] | ... | -----+-----+-----------+-----------------+-----------------+-----+----- MISO +-----------------+-----------------+-----------------+-----+ | xxx | Data Read[7:0] | Data Read[7:0] | ... | -----+-----------------+-----------------+-----------------+-----+----- 寄存器地址范围在 0x00 - 0x13 2. SPI 通信函数 单字节的写操作 ...

December 16, 2025 · 4 min · 849 words