【ESP32】创建一个 HTTP 服务器
测试环境 芯片:ESP32-S3 ESP-IDF:v5.5.2 一、HTTP 服务器说明 访问 HTTP 服务器的方法: 当 ESP32 连上 WIFI 后,路由器会给 ESP32 分配一个 IP 地址,那么只要和这个 IP 地址位于同一个网段内的设备都可以通过 http://: 来访问 ESP32 的 HTTP 服务器。 当 ESP32 开启 AP 后,当设备连上该 AP 后,ESP32 会给该设备分配一个 IP 地址(当前 ESP-IDF 默认使用的网段是 192.168.4),该设备可以通过 http://192.168.4.1: 来访问 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 就要注册一个回调函数。数量少还好,一旦数量多了,就要频繁注册。 ...
【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
【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(可选) ...
【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 要预先配置的参数如下: ...
【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 ...
【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 分。 ...
【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 查看版本信息: ...
【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/ ...
【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 通信函数 单字节的写操作 ...
【Node】占空比机制
协议栈代码:LoRaMac-node v4.7.0 参考文档 《RP002-1.0.4 LoRaWAN® Regional Parameters》 《TS001-1.0.4 LoRaWAN® L2 1.0.4 Specification》 一、占空比 1. 区域和占空比 参考《RP002-1.0.4 LoRaWAN® Regional Parameters》1.3 Regional Parameters Summary Tables 有些 Region 是有占空比限制,有些 Region 是没有占空比限制的。 对于动态频点的 Region: 对于固定频点的 Region: 2. 占空比规则 参考《TS001-1.0.4 LoRaWAN® L2 1.0.4 Specification》7 Retransmissions Backoff 3. 占空比代码 占空比代码涉及到两个概念: 时间信用(Time Credit) 不同的时间段内,都有一个最大可花费的时间信用,每次发送数据都会消耗一笔时间信用,当时间信用不满足下一次发送的花费时,则不允许发送数据。 观察时间(Observation Time) 当出现当时间信用不满足下一次发送的花费这种情况时,则会计算到达下一个时间段的观察时间,在下一个时间段内所花费的时间信息会清零。 3.1. 占空比参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 /* src/mac/region/RegionCommon.c */ /* Duty Cycle 1% */ #define BACKOFF_DC_1_HOUR 100 #define BACKOFF_DUTY_CYCLE_1_HOUR_IN_S 3600 #define BACKOFF_DUTY_CYCLE_10_HOURS_IN_S (BACKOFF_DUTY_CYCLE_1_HOUR_IN_S + (BACKOFF_DUTY_CYCLE_1_HOUR_IN_S * 10)) #define BACKOFF_DUTY_CYCLE_24_HOURS_IN_S (BACKOFF_DUTY_CYCLE_10_HOURS_IN_S + (BACKOFF_DUTY_CYCLE_1_HOUR_IN_S * 24)) #define BACKOFF_24_HOURS_IN_S (BACKOFF_DUTY_CYCLE_1_HOUR_IN_S * 24) #ifndef DUTY_CYCLE_TIME_PERIOD /* Default duty cycle observation time period is 1 hour (3600000 ms) according to ETSI. */ #define DUTY_CYCLE_TIME_PERIOD 3600000 #endif #ifndef DUTY_CYCLE_TIME_PERIOD_JOIN_BACKOFF_24H /* Time credits for the join backoff algorithm for the 24H period. */ #define DUTY_CYCLE_TIME_PERIOD_JOIN_BACKOFF_24H 870000 #endif 3.2. 更新占空比最大值 更新时间信用和观察时间: ...