完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
用esp32实现httpOTA,用到webclient,包括论坛里面其它AT模块用到webclient的,webclient与at是怎么交互衔接的?能指教下吗,谢谢 |
|
相关推荐
9个回答
|
|
|
|http_ota_fw_download
|—> webclient_read |——> wbclient_recv |———> recv |————> sal_recvfrom |—————> at_recvfrom (位于af_inet_at.c) |
|
|
|
|
|
我这板子同时启用了以太网卡(LWIP进行modbusTCP)和esp32的WiFi无线网卡(HTTP OTA),那进行http ota怎么就确定webclient最终调用的是esp32的网卡而不是以太网卡?
|
|
|
|
|
|
在af_inet_lwip.c中,有sal_socket_ops变量的赋值,同理,在af_inet_at.c中也有该变量的赋值。这两个变量都是static,仅在本文件域内有效。当然,rtt中都是这么个逻辑。
在sal层,会使用SAL_NETDEV_SOCKETOPS_VALID判断网卡的状态,然后进行通信,比如pf->skt_ops->recvfrom。 你的系统中有多张网卡,在进行具体通信时,可以使用netdev_set_default确定默认网卡。 |
|
|
|
|
|
在哪设置调用,能给个demo示例吗?如果不指定按照你上面说的是不是也不会找错?
|
|
|
|
|
|
以前写得玩儿的一段代码,在官方bing_test上做了一个简单修改,有两张网卡,esp32和sim7600。所以下方的代码中,都是使用AF_AT协议栈。你的是LwIP和AT,则需要分别对应AF_INET和AF_AT。
#include #include #define SERVER_HOST "xx.xx.xx.xx" #define SERVER_PORT (xxxx) static int bing_test(int argc, char **argv) { struct sockaddr_in client_addr; struct sockaddr_in server_addr; struct netdev *netdev = RT_NULL; int sock_esp32 = -1; int sock_sim7600 = -1; struct in_addr esp32_addr; struct in_addr sim7600ce_addr; if (argc != 2) { rt_kprintf("bind_test [netdev_name] --bind network interface device by name.n"); return -RT_ERROR; } /* 通过名称获取 netdev 网卡对象 */ netdev = netdev_get_by_name("esp32"); if (netdev == RT_NULL) { rt_kprintf("get network interface device(%s) failed.n", argv[1]); return -RT_ERROR; } /* 设置默认网卡对象 */ netdev_set_default(netdev); if ((sock_esp32 = socket(AF_AT, SOCK_STREAM, 0)) < 0) { rt_kprintf("Socket create failed.n"); return -RT_ERROR; } esp32_addr.s_addr = netdev->ip_addr.addr; /* 初始化需要绑定的客户端地址 */ client_addr.sin_family = AF_AT; client_addr.sin_port = htons(8080); /* 获取网卡对象中 IP 地址信息 */ client_addr.sin_addr.s_addr = esp32_addr.s_addr; rt_memset(&(client_addr.sin_zero), 0, sizeof(client_addr.sin_zero)); if (bind(sock_esp32, (struct sockaddr *)&client_addr, sizeof(struct sockaddr)) < 0) { rt_kprintf("socket bind failed.n"); closesocket(sock_esp32); return -RT_ERROR; } rt_kprintf("socket bind network interface device(%s) success!n", netdev->name); netdev = netdev_get_by_name("sim7600ce"); if (netdev == RT_NULL) { rt_kprintf("get network interface device(%s) failed.n", argv[1]); return -RT_ERROR; } /* 设置默认网卡对象 */ netdev_set_default(netdev); if ((sock_sim7600 = socket(AF_AT, SOCK_STREAM, 0)) < 0) { rt_kprintf("Socket create failed.n"); return -RT_ERROR; } sim7600ce_addr.s_addr = netdev->ip_addr.addr; /* 初始化需要绑定的客户端地址 */ client_addr.sin_family = AF_AT; client_addr.sin_port = htons(8080); /* 获取网卡对象中 IP 地址信息 */ client_addr.sin_addr.s_addr = sim7600ce_addr.s_addr; rt_memset(&(client_addr.sin_zero), 0, sizeof(client_addr.sin_zero)); if (bind(sock_sim7600, (struct sockaddr *)&client_addr, sizeof(struct sockaddr)) < 0) { rt_kprintf("socket bind failed.n"); closesocket(sock_sim7600); return -RT_ERROR; } rt_kprintf("socket bind network interface device(%s) success!n", netdev->name); /* 初始化预连接的服务端地址 */ server_addr.sin_family = AF_AT; server_addr.sin_port = htons(SERVER_PORT); server_addr.sin_addr.s_addr = inet_addr(SERVER_HOST); rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); /* 连接到服务端 */ if (connect(sock_esp32, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0) { rt_kprintf("socket connect failed!n"); closesocket(sock_esp32); return -RT_ERROR; } else { rt_kprintf("socket connect success!n"); } /* 连接到服务端 */ if (connect(sock_sim7600, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0) { rt_kprintf("socket connect failed!n"); closesocket(sock_sim7600); return -RT_ERROR; } else { rt_kprintf("socket connect success!n"); } /* 关闭连接 */ if (closesocket(sock_esp32) < 0 ) { rt_kprintf("socket close failed!n"); } else { rt_kprintf("socket close success!n"); } /* 关闭连接 */ if (closesocket(sock_sim7600) < 0 ) { rt_kprintf("socket close failed!n"); } else { rt_kprintf("socket close success!n"); } return RT_EOK; } #ifdef FINSH_USING_MSH #include MSH_CMD_EXPORT(bing_test, bind network interface device test); #endif /* FINSH_USING_MSH */ 你也可以根据自己的实际需求,在论坛/百度搜索RT-Thread 多网卡,会有很多解决方案的。祝顺利! |
|
|
|
|
|
今天试了,在AT全部初始化完成直接HTTP OTA会提示202错误;但若此时拔掉网线,提示emac linkdown,此时再http ota则成功进行了升级,从现象上来看就是webclient对应的网卡弄错了,你觉得呢?我觉得是不是最好直接修改源码调用的地方去分别设置缺省网卡?
|
|
|
|
|
|
你在开始http_ota之前,调用netdev_set_default设置默认网卡为ESP32,然后再升级,应该不会有问题的。
一般在OTA过程中,其他线程,如LWIP传输等应该停下来。这样就不涉及到多张网卡在数据处理过程中乱套了。 在日常的业务过程中,是通过socket套接字来进行数据交互的。在bind之前,先切换默认网卡,bind后会有socket编号返回的,通过socket来connect和send数据,不会引起数据乱套。我试过两张AT网卡连不同的MQTT Broker,没有问题。 |
|
|
|
|
|
关于第二点,其实自己也想如此,但因为1 很多线程都是软件包自己创建的线程,比如就LWIP来说自身创建的线程2~4个,直接根据IPC通讯信息去源码上挂起,删除线程,这样魔改不太合适。2 同时RTT又说不能在A线程中直接挂起或删除B线程(即使A的优先级比B高,因为A不知道B线程现在的状态(是否有关联的其它内核资源)),那么这种情况下该怎么处理呢?syswatch看说明是系统监护线程,在这上面有法解决在一个重要操作时其它线程都关闭的操作吗?
|
|
|
|
|
|
你可以关调度器呀,让当前OTA线程全占CPU即可。
|
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
1033 浏览 0 评论
2877 浏览 0 评论
图腾柱PFC无法上升至400V,且电感电流为正弦波形,但是幅值极小
9386 浏览 0 评论
飞凌嵌入式ElfBoard-Vim编辑器之静态链接和动态链接
2898 浏览 0 评论
使用 LinkBoy 将程序导出为 C 语言代码并烧录至 Arduino ESP32 开发板
2302 浏览 1 评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-2 02:34 , Processed in 0.675028 second(s), Total 58, Slave 51 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
2576