ESP32使用WIFI STA搭建TCP服务端并使用FreeRTOS_CLI制作简单命令终端
本文简单讲了如何缝合几个示例代码和第三方库来实现简单的telnet服务端和CLI.
WiFi STA:WiFi客户端(连WiFi热点的那个设备)
1 搭建telnet(TCP)服务器
由于telnet实际就是TCP流,上面无任何协议栈,所以只要搭建个TCP服务器就能用telnet。
连接WIFI(WIFI STA)
需要这堆头文件:
1 |
然后,写连接wifi的代码。
注:
- ESP32的射频校准信息等存储在NVS中,需要在分区表中预留NVS区。
- 关于RTOS事件组:https://www.freertos.org/zh-cn-cmn-s/event-groups-API.html
另外地:
ESP-NETIF 库有两个目的:
它为 TCP/IP 堆栈之上的应用程序提供了一个抽象层。这将允许应用程序将来在 IP 堆栈之间进行选择。
它提供的 API 是线程安全的,即使底层 TCP/IP 堆栈 API 不是。
ESP-IDF 目前仅针对 lwIP TCP/IP 堆栈实现 ESP-NETIF。但是,适配器本身与 TCP/IP 实现无关,并且可以使用不同的实现。
某些 ESP-NETIF API 函数旨在由应用程序代码调用,例如获取/设置接口 IP 地址、配置 DHCP。其他函数供网络驱动层内部 ESP-IDF 使用。
在很多情况下,应用不需要直接调用 ESP-NETIF API,因为它们是从默认的网络事件处理程序调用的。
以及:
事件循环库允许一个组件声明一个事件,该事件由其他组件注册事件处理程序,即这些事件发生时将执行的代码。这允许松散耦合的组件将所需的行为附加到其他组件来进行状态更改,而无需应用程序参与。例如,高级连接处理库可以直接订阅 Wi-Fi 子系统生成的事件并对这些事件进行操作。这通过将代码执行序列化和延迟到另一个上下文来简化事件处理。
代码实现:
1 | static const char *TAG = "example"; |
在WiFi基础上搭建TCP服务器
WiFi连接好后,WiFi物理层会连接到内置netif,netif来处理TCP/IP栈相关的东西,接下来只需要配置TCP相关的东西即可,而不用关心TCP层与IP、MAC层的通信(由TCP库自动配置)。
注:
setsockopt: 设置与某个套接字关联的选项。选项可能存在于多层协议中,它们总会出现在最上面的套接字层。当操作套接字选项时,选项位于的层和选项的名称必须给出。为了操作套接字层的选项,应该将层的值指定为SOL_SOCKET。为了操作其它层的选项,控制选项的合适协议号必须给出。例如,为了表示一个选项由TCP协议解析,层应该设定为协议号TCP
确切地说,close() 用来关闭套接字,将套接字描述符(或句柄)从内存清除,之后再也不能使用该套接字,与C语言中的 fclose() 类似。应用程序关闭套接字后,与该套接字相关的连接和缓存也失去了意义,TCP协议会自动触发关闭连接的操作。
shutdown() 用来关闭连接,而不是套接字,不管调用多少次 shutdown(),套接字依然存在,直到调用 close() 将套接字从内存清除。
调用 close()关闭套接字时,或调用 shutdown() 关闭输出流时,都会向对方发送 FIN 包。FIN 包表示数据传输完毕,计算机收到 FIN 包就知道不会再有数据传送过来了。
默认情况下,close()会立即向网络中发送FIN包,不管输出缓冲区中是否还有数据,而shutdown() 会等输出缓冲区中的数据传输完毕再发送FIN包。也就意味着,调用 close()将丢失输出缓冲区中的数据,而调用 shutdown() 不会。
accept()函数返回了一个new socket,这个socket从listen socket而来,是server专为listen到的client准备的一个socket,可以认为是为这一对通路单独服务的server端socket。我们先把它叫做专属socket。
accept()过程结束,返回的socket用于接下来的recv()。
代码实现:
1 | // TCP参数 |
TCP服务器搭建完成后,用telnet客户端连接ESP32获得的IP地址即可建立telnet连接
2 移植FreeRTOS_CLI
从https://www.freertos.org/zh-cn-cmn-s/a00104.html下载freertos官方插件包,拿到代码。
注:ESP32进临界区会崩溃,暂时去掉临界区,要求注册新命令时不能运行cli核心。
打开FreeRTOS_CLI.c,做如下更改:
1 | /* FreeRTOS includes. */ |
然后作为组件加载给ESP-IDF就行了。
3 制作简单命令终端
1 | //带分片的tcp socket发送 |
完整代码(tcp_server.c、FreeRTOS_CLI.c、FreeRTOS_CLI.h)请参见代码包LINK>>>。
参考
ESP32使用WIFI STA搭建TCP服务端并使用FreeRTOS_CLI制作简单命令终端