D133物联网电子秤项目
项目开始日期:2025,2,28
需求
硬件采购需求:
3.5寸RGB屏幕(目前已适配4.3寸(480x272)RGB565屏幕)
语音播报(语音模块+喇叭)
软件需求:
- lvgl用户交互界面
- 处理电子称串口数据
- 语音播报消息
- wifi上传到服务器
作用:
RGB屏幕实现电子秤输入,同时语音播报。
数据上传服务器
技术细节疑惑:
电子秤菜单串口是否输出计算结果,还是由D133计算?
等待中流程:
采购:屏幕,语音播报模块+喇叭
技术:串口包数据包格式,WiFi上传格式
拆分任务:
- 实现串口收发(解析)
- 移植RGB屏幕
- 移植LVGL
- 初步实现UI界面交互
- 实现wifi上传数据到服务器
- 增加语音播报
目前加急任务:
- 移植屏幕+lvgl
- 串口处理数据包
- WiFi上传数据
期限:三月末
要求:需要有初步结果:lvgl+屏幕+WiFi上传数据包到服务器
拉取SDK
- git clone --depth=1 https://gitee.com/lcsc/luban-lite.git
复制代码 git代码管理
- git remote add origin https://gitee.com/sword-level_0/digital-scale-d133.git
- git push -u origin "master"
复制代码 移植UART
串口0为Debug调试打印接口
使用
在user_uart3.c文件中将函数导出为命令,可以在终端开启串口- // 导出函数为命令
- MSH_CMD_EXPORT(uart3_test_on, Test transmission and reception using UART3 serial port);
复制代码 在终端开启
发送接受串口数据
移植外设
外设框架- [/code][size=4]移植0.96IIC[/size]
- 复制驱动文件夹至路径
- [indent][b]application\rt-thread\helloworld\user_bsp\0-96-iic-single-screen[/b]
- [/indent]在上层路径Kconfig添加
- 在配置中,配置开启
- 需要将冲突配置取消:
- LVGL相关和数字视频接口
- [code]Application options --->
- [*] LVGL (official): powerful and easy-to-use embedded GUI library ----
- [*] ArtInChip LVGL demo ----
- Board options --->
- [*] Using DVP
复制代码
外设路径
外设上层路径
- test_0_96_iic_single_screen
复制代码 进程间通信(消息队列)
消息队列的使用
发送- /* 格式化时间字符串 */
- snprintf(msg_buf, sizeof(msg_buf), "time=%d", time); // 使用snprintf函数将时间变量格式化为字符串,存储在msg_buf中
-
- /* 发送消息到队列 */
- result = rt_mq_send(mq, msg_buf, sizeof(msg_buf)); // 调用rt_mq_send函数将msg_buf中的消息发送到队列mq中
- if (result != RT_EOK) // 如果发送失败
- {
- rt_kprintf("Failed to send message\n"); // 打印错误信息
- }
复制代码 接收- char msg_buf[16]; // 定义一个字符数组,用于存储接收到的消息,数组大小为16字节
- rt_err_t result; // 定义一个变量result,用于存储函数返回的错误码
- while (1) // 无限循环,程序将一直执行这个循环体
- {
- /* 阻塞等待消息 */
- result = rt_mq_recv(mq, msg_buf, sizeof(msg_buf), RT_WAITING_FOREVER); // 调用rt_mq_recv函数从消息队列mq中接收消息
- if (result == RT_EOK)
- rt_kprintf("Received: %s\n", msg_buf);
- else
- rt_kprintf("Recv failed: %d\n", result);
- }
复制代码 同一文件- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <getopt.h>
- #include <sys/time.h>
- #include <rtthread.h>
- #include "rtdevice.h"
- #include "aic_core.h"
- #include "aic_hal_gpio.h"
- #define RT_USING_OVERFLOW_CHECK
- static rt_mq_t mq = RT_NULL; // 消息队列句柄
- /* 消息队列初始化 */
- static int msg_queue_init(void)
- {
- /* 创建消息队列:名称、消息大小、队列容量、队列模式 */
- mq = rt_mq_create("time_mq", 20, 10, RT_IPC_FLAG_FIFO);
- if (mq == RT_NULL)
- {
- rt_kprintf("Failed to create message queue\n");
- return -1;
- }
- return 0;
- }
- INIT_APP_EXPORT(msg_queue_init); // 系统启动时自动初始化
- /* 线程1:发送时间信息 */
- static rt_thread_t user_app_thread = RT_NULL;
- static void user_APP_thread_entry(void *param)
- {
- int time = 0;
- int count = 0;
- char msg_buf[20];
- rt_err_t result;
- while (1)
- {
- /* 格式化时间字符串 */
- snprintf(msg_buf, sizeof(msg_buf), "time=%d", time);
-
- /* 发送消息到队列 */
- result = rt_mq_send(mq, msg_buf, sizeof(msg_buf));
- if (result != RT_EOK)
- {
- rt_kprintf("Failed to send message\n");
- }
- /* 每两次发送(1秒)增加时间 */
- if (++count % 2 == 0)
- time++;
- rt_thread_mdelay(500); // 500ms间隔
- }
- }
- /* 启动线程1的命令 */
- static void usr_APP_run(int argc, char **argv)
- {
- // 修改线程创建时的栈大小参数(原512改为2048)
- user_app_thread = rt_thread_create(
- "user_app_thread",
- user_APP_thread_entry, RT_NULL,
- 2048, // 修改点:栈大小增加到2048字节
- 25, 5);
- if (user_app_thread)
- rt_thread_startup(user_app_thread);
- else
- rt_kprintf("Create thread1 failed\n");
- }
- MSH_CMD_EXPORT(usr_APP_run, "Start time sender thread");
- /* 线程2:接收并打印信息 */
- static rt_thread_t user_app2_thread = RT_NULL;
- static void user_APP2_thread_entry(void *param)
- {
- char msg_buf[16]; // 原20改为16("time=2147483647"仅需14字节)
- rt_err_t result;
- while (1)
- {
- /* 阻塞等待消息 */
- result = rt_mq_recv(mq, msg_buf, sizeof(msg_buf), RT_WAITING_FOREVER);
- if (result == RT_EOK)
- rt_kprintf("Received: %s\n", msg_buf);
- else
- rt_kprintf("Recv failed: %d\n", result);
- }
- }
- /* 启动线程2的命令 */
- static void usr_APP2_run(int argc, char **argv)
- {
- // 修改线程创建时的栈大小参数(原512改为2048)
- user_app2_thread = rt_thread_create(
- "user_app2_thread",
- user_APP2_thread_entry, RT_NULL,
- 2048, // 修改点:栈大小增加到2048字节
- 25, 5);
- if (user_app2_thread)
- rt_thread_startup(user_app2_thread);
- else
- rt_kprintf("Create thread2 failed\n");
- }
- MSH_CMD_EXPORT(usr_APP2_run, "Start message receiver thread");
复制代码 不同文件- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <getopt.h>
- #include <sys/time.h>
- #include <rtthread.h>
- #include "rtdevice.h"
- #include "aic_core.h"
- #include "aic_hal_gpio.h"
- extern rt_mq_t mq; // 消息队列句柄
- /* 外部线程:接收并打印信息 */
- static rt_thread_t user_External_app_thread = RT_NULL;
- static void user_External_app_thread_entry(void *param)
- {
- char msg_buf[16]; // 原20改为16("time=2147483647"仅需14字节)
- rt_err_t result;
- while (1)
- {
- /* 阻塞等待消息 */
- result = rt_mq_recv(mq, msg_buf, sizeof(msg_buf), RT_WAITING_FOREVER);
- if (result == RT_EOK)
- rt_kprintf("Received: %s\n", msg_buf);
- else
- rt_kprintf("Recv failed: %d\n", result);
- }
- }
- /* 启动线程的命令 */
- static void usr_External_app_run(int argc, char **argv)
- {
- // 修改线程创建时的栈大小参数(原512改为2048)
- user_External_app_thread = rt_thread_create(
- "usr_External_app_thread", // 线程名
- user_External_app_thread_entry, RT_NULL,
- 2048, // 修改点:栈大小增加到2048字节
- 25, 5);
- if (user_External_app_thread)
- rt_thread_startup(user_External_app_thread);
- else
- rt_kprintf("Create _External——thread failed\n");
- }
- MSH_CMD_EXPORT(usr_External_app_run, "Start message receiver thread");
复制代码 改动
在声明句柄的文件中:
- static rt_mq_t mq = RT_NULL; // 消息队列句柄
复制代码 去掉改成- rt_mq_t mq = RT_NULL; // 消息队列句柄
复制代码 在外部文件中- extern rt_mq_t mq; // 声明引用外部消息队列句柄
复制代码 终端命令
- 发送消息队列
- usr_APP_run
- 接收消息队列,打印
- usr_APP2_run
- oled显示+接收消息队列
- test_0_96_iic_single_screen
复制代码 网路(2.4GWIFI)
终端
扫描WIFI连接wifi:
输入名称,密码- wlan wifi_connect SSID PASSWORD
复制代码- wlan wifi_connect jianzhiji 8765432111
复制代码 开启网卡查看ip
例程分析
例程结构
网络概念解析
LwIP(Light Weight IP)是一个小型开源的TCP/IP协议栈,由瑞典计算机科学院(SICS)的Adam Dunkels开发。它的设计初衷是用少量的资源消耗(尤其是RAM)实现一个较为完整的TCP/IP协议栈,其中“完整”主要指的是TCP协议的完整性。
DNS域名解析
当在浏览器中输入 www.baidu.com 并解析时,整个过程涉及多个步骤和技术协议,最终目的是将域名转换为服务器IP地址并完成网页加载。以下是解析的主要流程及相关技术细节:
1. DNS域名解析
DNS(Domain Name System)负责将域名转换为对应的IP地址,具体步骤如下:
- 本地缓存查询
- 浏览器首先检查自身缓存(如Chrome的DNS缓存)中是否有该域名的IP记录214。
- 若无,则查询操作系统缓存(如Windows的hosts文件)和本地DNS缓存14。
- 本地DNS服务器查询
- 若本地缓存未命中,请求会发送至用户配置的本地DNS服务器(如运营商提供的114.114.114.114)414。
- 本地DNS服务器若缓存了域名记录,直接返回IP;否则进入递归查询流程14。
- 递归查询与根域名服务器
- 本地DNS服务器依次向根域名服务器、顶级域名服务器(.com)、权威域名服务器(百度注册的DNS服务器)发起迭代查询,最终获取www.baidu.com的IP地址714。
- 返回IP地址
- 查询结果逐级返回至浏览器,例如常见的百度IP地址可能为 220.181.111.147 或 202.108.22.5(实际IP可能因负载均衡而变化)27。
相关命令:
- 使用 nslookup www.baidu.com 或 ping www.baidu.com 可直接查看解析后的IP地址3。
2. 建立TCP连接
获取IP地址后,浏览器通过TCP协议与服务器建立连接:
- 三次握手
- 客户端发送SYN包,服务器返回SYN-ACK包,客户端再发送ACK包确认,完成可靠连接的建立27。
- 端口与协议
- 服务器默认监听80端口(HTTP)或443端口(HTTPS)212。
3. 发起HTTP请求与响应
- HTTP请求
- 浏览器发送HTTP GET请求,包含请求头(如User-Agent、Cookie等)和请求路径(如/表示首页)712。
- 服务器处理
- 百度服务器根据请求生成响应,可能涉及负载均衡、动态内容生成或静态资源返回1213。
- HTTP响应
- 服务器返回状态码(如200 OK)、响应头(如Content-Type)及HTML内容27。
4. 浏览器渲染页面
- 解析HTML与资源加载
- 浏览器解析HTML代码,并加载其中的CSS、JavaScript、图片等资源,可能触发多次HTTP请求212。
- 渲染引擎处理
- 构建DOM树、CSSOM树,合并为渲染树,最终布局和绘制页面712。
5. 连接释放
技术协议总结
协议层级协议与作用应用层HTTP(传输网页)、DNS(域名解析)2传输层TCP(可靠连接)、UDP(DNS查询)27网络层IP(路由选择)、ARP(IP转MAC地址)47链路层以太网帧(物理传输)4以下是关于 lwIP 的线程堆栈大小、MQTT/HTTP 协议使用、DHCP 服务器配置以及调试选项的详细说明:
1. lwIP 线程堆栈大小
作用:
lwIP 在多线程环境下运行时,每个网络线程(如 TCP/IP 主线程、协议处理线程等)需要分配足够的堆栈空间。堆栈大小不足会导致栈溢出、系统崩溃或数据损坏。
配置方法:
- 默认值:
lwIP 默认堆栈大小取决于移植的平台(如 FreeRTOS、裸机等),通常在 lwipopts.h 或平台配置文件中定义。
例如,在 FreeRTOS 中,TCP/IP 线程堆栈可能默认为 1KB~4KB。
- 调整堆栈:
根据协议复杂度和数据量调整。例如:
- 简单应用(如 UDP Echo):1KB~2KB
- 复杂应用(如 HTTP 文件传输):4KB~8KB
- MQTT/HTTP + TLS:可能需要 8KB~16KB(加密算法占用更多栈空间)
在 FreeRTOS 中修改示例:- // FreeRTOS 任务创建时指定堆栈大小
- xTaskCreate(tcpip_thread, "lwIP", 4096, NULL, 2, NULL);
复制代码 - 检测方法:
使用工具(如 FreeRTOS 的堆栈溢出检测钩子函数 vApplicationStackOverflowHook)或手动填充魔法值检查溢出。
2. 使用 MQTT 协议
实现步骤:
- 启用 lwIP MQTT 模块:
在 lwipopts.h 中启用 MQTT 支持: - 集成 MQTT 客户端:
lwIP 提供轻量级 MQTT 客户端,需包含头文件: - 连接与通信示例:
- // MQTT 连接配置
- struct mqtt_connect_client_info_t ci;
- memset(&ci, 0, sizeof(ci));
- ci.client_id = "client_id";
- // 连接到 Broker
- mqtt_client_t *client = mqtt_client_new();
- mqtt_connect(client, &ip_addr, 1883, mqtt_connection_cb, NULL, &ci);
- // 发布消息
- const char *message = "Hello MQTT";
- mqtt_publish(client, "topic", message, strlen(message), MQTT_QOS_0, 0, NULL);
复制代码 3. 使用 HTTP 协议
实现步骤:
- 启用 HTTP 服务器:
在 lwipopts.h 中启用 HTTP 支持:- #define LWIP_HTTPD 1
- #define LWIP_HTTPD_SSI 1 // 可选:支持 SSI
- #define LWIP_HTTPD_CGI 1 // 可选:支持 CGI
复制代码 - 实现 HTTP 回调函数:
定义页面处理和 CGI 函数:- // 处理 HTTP 请求
- const char *http_response = "<html><body>Hello HTTP</body></html>";
- err_t http_req_handler(struct pbuf *p, struct tcp_pcb *pcb) {
- tcp_write(pcb, http_response, strlen(http_response), TCP_WRITE_FLAG_COPY);
- tcp_close(pcb);
- return ERR_OK;
- }
- // 注册 HTTP 路径
- http_set_cgi_handlers(http_cgi_handlers, LWIP_ARRAYSIZE(http_cgi_handlers));
复制代码 - 启动 HTTP 服务器:
4. 使用 DHCP 服务器
配置方法:
- 启用 DHCP 服务器功能:
在 lwipopts.h 中启用:- #define LWIP_DHCP 1 // 启用 DHCP 客户端
- #define LWIP_DHCPS 1 // 启用 DHCP 服务器
复制代码 - 设置地址池:
在代码中配置 DHCP 地址池:- ip4_addr_t dhcp_start, dhcp_end;
- IP4_ADDR(&dhcp_start, 192, 168, 1, 100);
- IP4_ADDR(&dhcp_end, 192, 168, 1, 200);
- dhcp_server_init(netif_default, &dhcp_start, &dhcp_end);
复制代码 - 处理 DHCP 请求:
lwIP 自动处理客户端请求,分配 IP 并管理租期。
5. 启用 lwIP 调试选项
作用:
调试选项用于输出网络状态、协议解析细节和错误信息,帮助定位连接问题、内存泄漏或协议错误。
启用方法:
- 全局调试开关:
在 lwipopts.h 中设置:- #define LWIP_DEBUG 1 // 启用调试
- #define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL // 输出所有级别日志
复制代码 - 模块级调试:
按需启用特定模块的调试:- #define DHCP_DEBUG LWIP_DBG_ON // DHCP 调试
- #define TCP_DEBUG LWIP_DBG_ON // TCP 调试
- #define HTTP_DEBUG LWIP_DBG_ON // HTTP 调试
复制代码 - 输出调试信息:
实现 lwip_log 函数或重定向到串口:- void lwip_log(const char *fmt, ...) {
- va_list args;
- va_start(args, fmt);
- vprintf(fmt, args); // 输出到控制台或串口
- va_end(args);
- }
复制代码 典型调试场景:
- 内存泄漏:启用 MEM_DEBUG 和 MEMP_DEBUG。
- TCP 重传:启用 TCP_CWND_DEBUG 查看拥塞窗口变化。
- HTTP 请求解析:启用 HTTP_DEBUG 跟踪请求处理。
总结
- 堆栈大小:根据协议复杂度和线程任务调整,避免溢出。
- 协议支持:通过 lwipopts.h 启用 MQTT/HTTP/DHCP,并实现回调函数。
- 调试:启用调试宏并实现日志输出,快速定位问题。
建议结合具体平台(如 FreeRTOS、Linux 等)和硬件资源(内存、CPU)进行参数调优。
开启网络
help
以下是 RT-Thread Shell 命令的中文翻译:
RT-Thread Shell 命令列表
命令功能描述list_fd列出文件描述符sensor传感器测试功能sensor_polling传感器轮询模式测试功能sensor_int传感器中断模式测试功能sensor_fifo传感器 FIFO 模式测试功能free显示系统内存使用情况ps列出系统中的线程help显示 RT-Thread Shell 帮助list列出系统对象list_device列出系统中的设备list_timer列出系统中的定时器list_mempool列出内存池list_memheap列出内存堆list_msgqueue列出消息队列list_mailbox列出邮箱list_mutex列出互斥锁list_event列出事件list_sem列出信号量list_thread列出线程version显示 RT-Thread 版本信息clear清空终端屏幕tail输出文件的最后 N 行数据echo将字符串写入文件df显示磁盘剩余空间umount从文件系统卸载设备mount挂载设备到文件系统:mount mkfs格式化磁盘为指定文件系统mkdir创建目录pwd显示当前工作目录路径cd切换工作目录rm删除文件cat查看文件内容mv重命名文件或移动文件cp复制文件ls列出目录或文件信息ulog_filter显示 ulog 日志过滤设置ulog_kw设置 ulog 全局关键字过滤ulog_tag设置 ulog 全局标签过滤ulog_lvl设置 ulog 全局日志级别过滤ulog_tag_lvl按标签设置 ulog 日志级别过滤ulog_be_lvl按后端设置 ulog 日志级别过滤f运行一个函数m修改内存值p打印内存值meminfo显示内存信息run_in_loop_thre在循环线程中运行命令run_in_thread在线程中运行命令reboot重启系统reset重置设备模块list_pinmux列出引脚功能配置arecord录制音频为 WAV 文件aplay播放 WAV 文件test_clock测试时钟模块(CMU CLK)test_dma_memset测试 DMA 内存填充(参数:值 长度)test_dma_memcpy测试 DMA 内存复制(参数:长度)test_dvp测试 DVP 和摄像头模块test_gpai测试 GPAI 设备test_gpio测试 GPIO 设备test_eth网络回环测试iperf网络性能测试(-s 为服务端/-c 为客户端)sfSPI Flash 操作falFAL(Flash 抽象层)操作test_tsen温度传感器(TSen)测试top显示 CPU 使用率dhcpc启动/停止 DHCP 客户端(动态主机配置协议),自动分配IP、子网掩码、网关和DNS,这样用户就不用手动配置了ifconfig显示或配置网络信息ping网络连通性测试(输入 ping help 查看帮助)test_0_96_iic_si测试 0.96 英寸 IIC 屏幕usr_APP2_run启动消息接收线程usr_APP_run启动时间发送线程usr_External_app启动外部应用线程(消息接收)send_demoData发送测试数据dma_dump显示 DMA 寄存器(参数:通道号)efuse操作 EFUSEepwm_status显示 EPWM 状态mtop测试 mtop 功能pwm_set_tb设置 PWM 时基pwm_status显示 PWM 状态tsen_status显示温度传感器状态wdt_status显示看门狗状态list_irq列出系统中断canstat显示 CAN 设备状态adcADC 操作(输入 adc help 查看选项)pin引脚操作(输入 pin help 查看选项)pwmPWM 操作(输入 pwm help 查看选项)lptimer_dump显示低功耗定时器(LPTimer)信息pm_dump显示电源管理状态pm_run切换电源管理模式pm_module_delay设置模块延迟休眠请求pm_module_reques请求模块电源管理模式pm_module_releas释放模块电源管理模式计数pm_module_releas释放模块电源模式pm_request请求电源管理模式pm_release_all释放所有电源管理模式计数pm_release释放电源管理模式list_alarm列出闹钟信息date获取/设置日期和时间(本地时区):date [年 月 日 时 分 秒]player_demo播放器演示audio_player_dem音频播放器演示wlanWiFi 操作(输入 wlan help 查看子命令)使用说明
- 格式:命令 [参数],例如 ping 192.168.1.1。
- 帮助:输入 命令 help 查看详细用法(如 ping help)。
- 硬件相关命令(如 test_gpio, pwm)需确保硬件支持。
网络相关概念
DHCP
''(Dynamic Host Configuration Protocol,动态主机配置协议)是一种网络协议,用于自动分配和管理网络设备的IP地址及相关配置参数,从而简化网络配置并避免手动操作带来的错误。
一、核心功能
- IP地址自动分配
- 动态分配:从地址池中临时分配IP(有租期限制)
- 静态绑定:为特定设备(如服务器)固定分配IP
lwIP
(Lightweight IP) 是一个轻量化的开源 TCP/IP 协议栈,专为资源受限的嵌入式系统设计。它由瑞典计算机科学研究院的 Adam Dunkels 开发,广泛应用于物联网设备、工业控制、传感器网络等场景。
- 模块化架构
- 支持按需裁剪功能模块(如 DHCP、DNS、IPv6),开发者可灵活配置协议栈功能。
- 多协议支持
- 包含完整的 TCP/IP 协议族:
- 网络层:IPv4、IPv6、ICMP、IGMP
- 传输层:TCP、UDP
- 应用层:HTTP、SNMP、MQTT(需扩展实现)
lwIP 的典型应用场景
场景说明物联网设备智能家居设备(如 Wi-Fi 插座、传感器)通过 lwIP 实现网络通信。工业控制PLC、工业网关使用 lwIP 接入以太网,支持 Modbus TCP 等协议。嵌入式 Web 服务器通过 lwIP 的 HTTP 模块,在设备上运行轻量级 Web 页面(如配置界面)。低功耗设备结合低功耗无线技术(如 LoRa、BLE),实现电池供电设备的间歇性网络通信。
iperf
iperf 是一款开源的网络性能测试工具,主要用于测量 TCP/UDP 带宽、延迟、抖动和丢包率等网络性能指标。它通过在客户端和服务器之间发送数据流,评估网络的吞吐量和稳定性,是网络工程师和开发者的常用工具。
一、核心功能
功能说明带宽测试测量网络最大传输速率(如测出实际带宽是否达标)协议支持支持 TCP、UDP、SCTP 协议多线程测试可并行多连接测试(模拟多用户场景)数据方向控制支持上行(客户端→服务器)、下行(服务器→客户端)、双向测试统计报告实时输出带宽、抖动(Jitter)、丢包率(Loss%)等详细指标SDMC
通常指 同步数字主控制器(Synchronous Digital Master Controller),是一种用于协调多设备同步操作的高精度时序控制核心模块,尤其在高速数字系统、通信设备和复杂嵌入式系统中广泛应用。
WLAN连接
wifi(RTL8189FTV-WIFI模块2.4GHz,SDIO接口)
扫描wifi
连接wifi (输入名称,密码)
- wlan wifi_connect SSID PASSWORD
复制代码- wlan wifi_connect jianzhiji 8765432111
复制代码- wlan wifi_connect jianzhiji 8765432111
复制代码 需出现IP地址才算链接成功
可以 通过ping ip来再次确认是否连接到互联网还是内网:- ping www.baidu.com
- //DNS解码的百度ip地址
- ping 183.2.172.177
复制代码
无线网络
本章节讲解如何在 Luban-Lite 系统中配置 SDIO 接口的无线网络,需要配置的主要有以下几部分:
- 配置 SDMC 接口;
- 配置 WiFi 模组;
- 配置 lwIP 协议栈;
- 配置内核;
配置 SDMC 接口和 WiFi 模组
使用 SDMC 接口前,需将对应 SDMC 接口选中,以 D133CBV-QFN88 开发板为例,使用 scons --menuconfig 命令进行配置:- Board options
- [ * ] Using SDMC0 # 硬件连接哪个 SDMC 接口,选择哪个SDMC
- [ * ] Enable the interrupt of sdmc
- [ * ] Using Wireless lan --->
- [ * ] Using Realtek wlan driver --->
- Select Realtek wlan0 modul (rtl8189)--- > # 以 RTL8189 为例
- Realtek wlan0 paramete --->
- (PC.7) realtek wlan0 power on gpio
- (192.168.3.20) wlan0 ip addr
- (192.168.3.1) wlan0 gateway addr
- (255.255.255.0) wlan0 netmask
- [*] Enable Realtek driver debug information
复制代码 使用RTL8189FTV--WIFI模块该选
例程地址:packages -> third-party -> webclient ->samples
配置 lwIP
使用 scons --menuconfig 命令进入配置页面,配置如下:- Local packages options --->
- Third-party packages options --->
- LwIP: light weight TCP/IP stack
- [*] LwIP Examples --->
- [*] Using net tools
- [*] Enable DNS for name resolution
- [*] Enable alloc ip address through DHCP
- [*] Enable ping features --->
复制代码 配置内核
- Rt-Thread options --->
- RT-Thread Kernel --->
- (4) The priority level value of timer thread
- (4096) The stack size of timer thread
- RT-Thread Components --->
- Device Drivers --->
- (4096) The stack size for sdio irq thread
- (5) The priority level value of sdio irq thread
复制代码
WLAN基础管理命令
以下是这些 wlan 相关命令的详细功能解析和用法说明(按用途分类整理):
一、WiFi基础管理命令
1. 网络开关
命令功能示例wifi_on启动WiFi模块wifi_onwifi_off关闭WiFi模块wifi_off2. 连接管理
命令功能参数说明示例wifi_connect通过SSID和密码连接网络 wifi_connect MyWiFi 12345678wifi_connect_bssid指定BSSID连接(防AP同名欺骗) wifi_connect_bssid MyWiFi 1234 AA:BB:CC D:EE:FFwifi_disconnect断开当前连接无wifi_disconnect二、网络扫描与诊断
1. 扫描相关
命令功能参数说明示例wifi_scan执行全频段WiFi扫描无wifi_scanwifi_reoder_scan按信号强度排序扫描结果无wifi_reoder_scanwifi_scan_with_ssid扫描指定SSID是否存在wifi_scan_with_ssid MyWiFiwifi_scan_with_multissid批量扫描多个SSID ...wifi_scan_with_multissid Home Office2. 诊断工具
命令功能参数说明示例ping网络连通性测试 [-t] [-n count]ping 192.168.1.1 -n 5get_auto_chl获取自动信道选择结果无get_auto_chl三、高级调试与监控
1. 混杂模式(抓包)
命令功能参数说明示例wifi_promisc开启混杂模式监听原始数据包wifi_promisc enablerawdata_enable启用原始数据捕获无rawdata_enablerawdata_disable禁用原始数据捕获无rawdata_disablerawdata_send发送原始数据帧(需指定格式)rawdata_send 00AAFF...2. 调试接口
命令功能参数说明示例iwpriv设置/读取私有驱动参数 [值]iwpriv set_power 10wifi_debug开启调试日志(级别可调)wifi_debug 3四、AP模式操作
命令功能参数说明示例wifi_ap启动SoftAP热点模式 [channel]wifi_ap MyHotspot 12345678 6五、系统信息与退出
命令功能参数说明示例wifi_info显示当前连接状态(IP/RSSI/BSSID等)无wifi_infoexit退出命令行界面无exithelp显示命令帮助无help常见问题处理指南
1. 连接失败
- # 检查驱动状态
- wifi_info
- # 扫描确认AP存在
- wifi_scan_with_ssid MyWiFi
- # 尝试指定BSSID连接
- wifi_connect_bssid MyWiFi password AA:BB:CC:DD:EE:FF
复制代码 2. 网络延迟高
- # 持续ping测试
- ping 192.168.1.1 -t
- # 查看当前信道质量
- iwpriv get_rssi
复制代码 3. 抓包分析
- wifi_promisc enable
- rawdata_enable
- # 此时数据会输出到指定接口(需配合tcpdump或wireshark)
复制代码 参数顺序规则(重要!)
- 对于ping命令,选项顺序影响参数有效性:
- # 正确:发送5次请求
- ping 192.168.1.1 -n 5
- # 错误:-t出现在-n之后会被忽略
- ping 192.168.1.1 -n 5 -t # 实际只执行5次
复制代码 调试日志级别说明
级别日志详细程度0关闭所有调试输出1关键错误信息2基本连接状态变更3协议交互过程(推荐调试级别)4详细数据包跟踪5底层寄存器操作(开发者用)建议调试时先设置 wifi_debug 3 查看关键交互信息。
HTTP
[单片机] → (连接Wi-Fi) → [TCP握手] → [发送HTTP请求] → [接收响应] → [处理数据]
E:\D133EBS\WIFI\luban-lite\kernel\rt-thread\components\net\lwip\lwip-2.1.2\src\apps\http\http_client.c
E:\D133EBS\WIFI\luban-lite\packages\third-party\lwip\src\apps\http\http_client.c
- 1. 包含头文件**: 在你的源文件中包含 `http_client.h` 头文件,以便使用 HTTP 客户端的接口和数据结构。
- \#include "lwip/apps/http_client.h"
- 2. **配置 HTTP 客户端连接**: 配置 `httpc_connection_t` 结构体,设置代理地址、端口和回调函数等。
- *httpc_connection_t* settings;
- *memset*(&*settings*, 0, sizeof(settings));
- settings.result_fn = my_result_callback;
- settings.headers_done_fn = my_headers_done_callback;
- 3. **定义回调函数**: 实现 HTTP 客户端的回调函数,用于处理 HTTP 请求的结果和接收的头部信息。
- void *my_result_callback*(void **arg*, *httpc_result_t* *httpc_result*, *u32_t* *rx_content_len*, *u32_t* *srv_res*, *err_t* *err*) {
- *// 处理 HTTP 请求结果*
- }
- *err_t* *my_headers_done_callback*(*httpc_state_t* **connection*, void **arg*, struct pbuf **hdr*, *u16_t* *hdr_len*, *u32_t* *content_len*) {
- *// 处理接收到的 HTTP 头部信息*
- return ERR_OK;
- }
- 4. **发起 HTTP 请求**: 使用 `httpc_get_file` 或 `httpc_get_file_dns` 函数发起 HTTP 请求。
- *ip_addr_t* server_addr;
- *IP4_ADDR*(&*server_addr*, 192, 168, 1, 1); *// 设置服务器 IP 地址*
- const char *uri = "/path/to/resource";
- *httpc_state_t* *connection;
- *err_t* err = *httpc_get_file*(&*server_addr*, HTTP_DEFAULT_PORT, uri, &*settings*, my_recv_callback, NULL, &*connection*);
- if (err != ERR_OK) {
- *// 处理错误*
- }
- 5. **接收数据回调函数**: 实现数据接收回调函数,用于处理接收到的数据。
- *err_t* *my_recv_callback*(void **arg*, struct altcp_pcb **pcb*, struct pbuf **p*, *err_t* *err*) {
- if (p != NULL) {
- *// 处理接收到的数据*
- *altcp_recved*(pcb, p->tot_len);
- *pbuf_free*(p);
- }
- return ERR_OK;
- }
- 通过上述步骤,你可以使用 [http_client.c](vscode-file://vscode-app/d:/VS Code/resources/app/out/vs/code/electron-sandbox/workbench/workbench.html) 文件中的 HTTP 客户端功能发起 HTTP 请求并处理响应。确保在你的项目中正确配置 lwIP 库,并根据需要调整回调函数的实现。
复制代码 menuconig开启http
例程路径
- luban-lite\packages\third-party\webclient\samples
复制代码 例程运行逻辑:
终端执行:
tab提示命令:
使用例程:
先连接WIFI
- wlan wifi_connect jianzhiji 8765432111
复制代码 检查是否分配ip地址请求:webclient_get_sample:
运行命令:
请求网站并返回数据
作用:
演示如何使用 WebClient 软件包发送 HTTP GET 请求并接收响应数据。文件中的代码展示了如何创建 WebClient 会话、发送 GET 请求、接收响应数据并处理内存分配错误等操作。
例程实现的功能
- HTTP GET请求发送
- 支持向指定URI(如 http://www.rt-thread.com/service/rt-thread.txt)发送GET请求。
- 可处理 普通请求(分块传输或固定长度)和 简化请求(短数据场景)。
- 响应数据处理
- 接收服务器返回的响应数据,并打印输出到终端。
- 自动处理 分块传输编码(Chunked Transfer Encoding) 和 固定内容长度(Content-Length) 两种HTTP响应格式。
- 命令行交互支持
- 通过RT-Thread的 FINSH/MSH 命令行接口,提供用户可配置的测试命令,支持自定义URI和请求模式。
终端输出结果:
使用函数命令,访问
例如访问官方测试网站- web_get_test http://www.rt-thread.com/service/rt-thread.txt
复制代码 终端返回的结果
网站内容:
内容可以对应上,证明成功请求网站并返回了内容
自定义URI——访问个人网站- web_get_test https://www.cnblogs.com/tianwuyvlianshui
复制代码 该问题表示未启用https,确实如其言,我们只开启了http,后续开启https再尝试
测试其他http网站- # 测试 GET 请求
- curl http://httpbin.org/get
- # 测试 POST 请求
- curl -X POST http://httpbin.org/post -d "key=value"
- # 返回指定状态码(如 404)
- curl http://httpbin.org/status/404
复制代码 1、测试 GET 请求- web_get_test http://httpbin.org/get
复制代码 httpbin.org
- 用途:最全面的 HTTP 测试服务,支持 GET/POST/PUT/DELETE 等方法,可返回请求头、IP、状态码等。
该网站是测试网站,用于测试 HTTP 请求的公共服务,它会将你的请求信息原样返回。
测试带参数请求- web_get_test http://httpbin.org/get?name=RT-Thread&id=123
复制代码
成功添加访问参数- "name": "RT-Thread",
- "id": "123"
复制代码 测试html网站- web_get_test http://example.com
复制代码
成功返回该静态网站的html文件
将返回的html保存打开就是该网站
测试 返回指定状态码(如 404)- web_get_test http://httpbin.org/status/404
复制代码
webclient_post_sample:
运行命令:
- web_post_test http://www.rt-thread.com/service/echo
复制代码 作用:
演示如何使用 WebClient 软件包发送 HTTP POST 请求并接收响应数据。文件中的代码展示了如何创建 WebClient 会话、发送 POST 请求、接收响应数据并处理内存分配错误等操作。
实现了如何使用 WebClient 软件包发送 HTTP POST 请求并接收响应数据。具体实现了以下功能:
- 定义常量和变量:定义了响应缓冲区大小、请求头缓冲区大小和默认的 POST 请求 URI。
- 发送普通 POST 请求:
- 函数 webclient_post_comm 创建 WebClient 会话,构建请求头,发送 POST 请求,并接收和打印响应数据。
- 发送简化 POST 请求:
- 函数 webclient_post_smpl 创建请求头,发送 POST 请求,并接收和打印响应数据。
- 测试函数:
- 函数 webclient_post_test 根据命令行参数选择发送普通 POST 请求或简化 POST 请求,并处理 URI 内存分配和释放。
- 命令行集成:
- 使用 FinSH 命令行系统集成测试命令 web_post_test,可以在命令行中执行 POST 请求测试。
终端输出结果:
webclient_shard_download_sample:
运行命令:
作用:
演示如何使用 WebClient 软件包进行分片下载。文件中的代码展示了如何发送 HTTP GET 请求并分片接收响应数据,以及如何处理和打印接收到的数据。
终端输出结果:
测试http pose:
如果服务器是回显服务(如 http://www.rt-thread.com/service/echo),响应内容应与发送的 post_data 完全一致
终端测试命令:- web_post_test http://www.rt-thread.com/service/echo
复制代码 pose发送内容:
终端打印pose响应
响应内容应与发送的 post_data 完全一致
D133 ping 电脑
电脑与板子同连手机热点
电脑ip
板卡ip
可以看到在同一局域网192.168.106.xxx
理论上可以ping通,实际则可能不行,原因是电脑防护墙阻挡
关闭则可以ping通(测试完记得重新开启)
抓包
- web_post_test http://192.168.106.31:8080
复制代码 带参数- web_post_test http://192.168.106.31:8080?a=1&b=2&c=3
复制代码 测试单片机http pose请求
使用python搭建内网服务器
- from http.server import BaseHTTPRequestHandler, HTTPServer # 从http.server模块导入BaseHTTPRequestHandler和HTTPServer类
- import time # 导入time模块,用于处理时间相关功能
- host_ip = "0.0.0.0" # 监听所有IP地址,表示服务器将接受来自任何IP的请求
- port = 8080 # 端口号
- class RequestHandler(BaseHTTPRequestHandler):
- # 定义一个处理POST请求的方法
- def do_POST(self):
- # 从请求头中获取Content-Length字段,该字段表示请求体的长度
- content_length = int(self.headers['Content-Length'])
- # 读取请求体数据,长度为content_length,并将其解码为utf-8字符串
- post_data = self.rfile.read(content_length).decode('utf-8')
- # 打印接收到的POST数据
- print(f"Received POST data: {post_data}")
- # 发送HTTP响应状态码200,表示请求成功
- self.send_response(200)
- # 发送响应头,设置Content-type为text/plain,表示响应体是纯文本
- self.send_header('Content-type', 'text/plain')
- # 结束响应头
- self.end_headers()
- # 向客户端发送响应体数据"OK",表示处理成功
- self.wfile.write(b"OK")
- server = HTTPServer((host_ip, port), RequestHandler)
- print(f"Server running at http://{host_ip}:{port}")
- server.serve_forever()
复制代码 D133端(客户端,发送端,发送HTTP POST请求到服务器(内网)):
请求的数据(默认POST请求数据)
将数据通过http post 发送到服务器
命令(命令+网址):- web_post_test http://192.168.106.31:8080
复制代码
在PC
PC端(内网服务器,服务端,作接收端)
数据上报对接api
URL头部URL头部+api- web_post_test http://xxx/api/yyy
复制代码 Postman
Postman 是一款广泛应用于 API 开发与测试 的协作工具,旨在简化 API 的生命周期管理(设计、开发、测试、部署、监控等)。
主要功能
- API 请求测试与调试
- 支持发送 HTTP/HTTPS 请求(GET、POST、PUT、DELETE 等)。
- 可自定义请求头(Headers)、参数(Params)、身份验证(OAuth、JWT 等)和请求体(Body)。
- 直观的界面帮助快速调试 API,查看响应状态码、响应时间和返回数据(JSON、XML 等)。
- 自动化测试
- 使用 JavaScript 编写测试脚本,验证 API 响应是否符合预期。
- 支持断言(Assertions)、动态变量和环境变量,提升测试灵活性。
- 集成 CI/CD 工具(如 Jenkins、GitHub Actions)通过 Newman 命令行工具运行自动化测试。
- 协作与文档
- 团队可共享 API 集合(Collections) 和环境配置,提升协作效率。
- 自动生成 API 文档,支持一键发布,便于前后端开发者或第三方调用者查阅。
- Mock 服务器
- 创建虚拟 API 端点,模拟真实响应,支持前端开发与后端 API 并行工作。
- 监控与性能测试
- 定期运行 API 测试,监控服务可用性与性能,生成报告分析潜在问题。
适用场景
- 开发者:快速调试接口,验证功能逻辑。
- 测试工程师:设计自动化测试用例,确保 API 稳定性。
- 团队协作:统一管理 API 资产,减少沟通成本。
- 文档编写:自动生成易读的 API 文档,替代手动维护。
版本与平台
- 免费版:满足个人基础需求(请求测试、简单自动化)。
- 付费版(Pro/Enterprise):解锁团队协作、高级监控、私有 API 文档等功能。
- 跨平台支持:提供 Windows、macOS、Linux 客户端及网页版。
优势
- 用户友好:图形化操作降低学习成本,替代命令行工具(如 cURL)。
- 生态丰富:支持 OpenAPI 规范、WebSocket 测试、GraphQL 等扩展场景。
- 云端同步:数据云端存储,多设备无缝切换。
简单示例
- 在 Postman 中新建请求,输入 API 地址。
- 设置请求方法(如 POST),添加 JSON 格式的请求体。
- 添加测试脚本验证响应状态码是否为 200。
- 保存到集合,分享给团队成员或生成文档。
无论是独立开发还是团队协作,Postman 都能显著提升 API 开发效率,是现代软件工程中不可或缺的工具之一。
API文档解析与使用
api接口网址涉及实际产品,略
Postman测试应用
api接口网址时间戳转换网站- https://tool.lu/timestamp/
复制代码 网站头URL使用方式:网站头URL+API尾部
例如
则使用该api的URL为添加CJSON解析库
在串口终端控制HTTP_API访问服务器
[code]/*演示如何使用 WebClient 软件包发送 HTTP POST 请求并接收响应数据。文件中的代码展示了如何创建 WebClient 会话、发送 POST 请求、接收响应数据并处理内存分配错误等操作。*/#include #include #include #include // 定义POST请求响应缓冲区的大小为1024字节#define POST_RESP_BUFSZ 1024// 定义POST请求头部缓冲区的大小为1024字节#define POST_HEADER_BUFSZ 1024**涉及实际产品,略**typedef enum { API_GET_BALANCE_NO, // 远程编码 API_LOAD_KEY, // 获取密钥 **涉及实际产品,略**} API_TYPE;// API地址映射表static const char* API_URI_MAP[] = { [API_GET_BALANCE_NO] = "**涉及实际产品,略**", .......};// 获取API地址的宏#define GET_API_URI(api_type) (API_URI_MAP[(api_type)])/* 静态函数获取URI */static inline const char* get_api_uri(API_TYPE type) { return API_URI_MAP[type];}// /* 函数调用初始化 */// const char* POST_LOCAL_URI = NULL;// void post_api_uris(char str) {// POST_LOCAL_URI = get_api_uri(str);// }// 获取时间戳函数(get)// 定义一个静态函数get_timestamp,用于获取时间戳并存储在buffer中static int get_timestamp(char *buffer, size_t buffer_size){ // 定义一个指向webclient_session结构体的指针session,并初始化为RT_NULL struct webclient_session *session = RT_NULL; // 定义一个指向字符数组的指针response_buf,用于存储HTTP响应,并初始化为RT_NULL char *response_buf = RT_NULL; // 定义一个整型变量ret,用于存储函数返回值,并初始化为RT_EOK(表示成功) int ret = RT_EOK; // 定义一个常量字符串url,指向获取时间戳的URL const char *url = "http://acs.m.taobao.com/gw/mtop.common.getTimestamp/"; // 创建一个webclient会话,缓冲区大小为512字节 session = webclient_session_create(512); // 如果会话创建失败,打印错误信息并返回内存不足错误码 if (!session) { rt_kprintf("[ERROR] Create session failed\n"); return -RT_ENOMEM; } // 使用webclient发送GET请求,如果返回值不是200(HTTP OK),打印错误信息并设置返回值为错误码 if ((ret = webclient_get(session, url)) != 200) { rt_kprintf("[ERROR] GET failed (%d)\n", ret); ret = -RT_ERROR; // 跳转到退出标签,进行资源释放 goto __exit; } // 分配256字节的内存用于存储HTTP响应 response_buf = web_malloc(256); // 如果内存分配失败,设置返回值为内存不足错误码并跳转到退出标签 if (!response_buf) { ret = -RT_ENOMEM; goto __exit; } // 从webclient会话中读取响应数据到response_buf,最多读取256字节 int total_read = webclient_read(session, response_buf, 256); // 如果读取失败或没有读取到数据,设置返回值为错误码并跳转到退出标签 if (total_read |