1404|5

35

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

[FireBeetle 2 ESP32C6开发板] uart2tcp透传工具 [复制链接]

今天来设计和实现一个叫uart2tcp的透传小工具,名字里的"2"是"to"的意思。

 

uart2tcp是什么

此工具把esp32c6开发板上的uart传输都透传到tcp server上,板子会接入环境中的wifi AP,其它设备如PC机通过网络连接这个tcp server,读写socket就相当于读写esp32c6的uart。

 

为什么做uart2tcp

或者说应用场景是什么。现阶段串口是极佳的调试工具比如看log、输入命令等等,所以几乎每块板子都有串口针脚或者可以焊接针脚,然后和电脑的usb转串口连接起来。但有的场景接电脑并不方便,比如目标设备是移动机器人、扫地机,或者处于封闭空间或服务器机房等等,这时候这个工具就派上用场了,只要测试场所有wifi服务,工程师可以安安静静地坐在自己座位上调试,和把目标板放在身边一样方便。

 

怎么做uart2tcp

esp idf例子这么全,自己看懂后手搓一个,有句话怎么说来着自己动手丰衣足食。

 

先看看我们需要做哪些

第一,wifi连接AP;第二,实现一个tcp server;第三,uart读写。巧的是这三块esp idf都有例子代码,分别是examples/common_components/protocol_examples_common, examples/protocols/sockets/tcp_server/与examples/peripherals/uart/uart_events/。注意uart示例目录examples/peripherals/uart中有好几个,个人翻来覆去挑了挑还是觉得uart_events合适。

 

选谁为主模板

上面这三个各自独立,有自己的task和main函数,但以谁为主模板修改呢?笔者选择examples/protocols/sockets/tcp_server/,它和wifi示例examples/common_components/protocol_examples_common联系比较紧密,uart更独立一些,以tcp_server为主模板修改会更少。那么拷贝一份吧做工程模板吧:

cp -a examples/protocols/sockets/tcp_server/  examples/uart2tcp
mv examples/uart2tcp/main/tcp_server.c   examples/uart2tcp/main/uart2tcp.c

并修改下examples/uart2tcp/main/CMakeLists.txt为

idf_component_register(SRCS "uart2tcp.c"
                    INCLUDE_DIRS ".")

 

代码设计和实现

模板里的uart2tcp.c只创建了一个任务,就是监听并接收tcp连接,连接建立以后然后从客户端收数据再写回。我们要把它改成从客户端收数据再往uart写入,这里展示下核心代码:

static void do_retransmit(const int tsock)
{
        int len;
        char rx_buffer[128];

        do {
                len = recv(tsock, rx_buffer, sizeof(rx_buffer), 0);
                if (len < 0) {
                        ESP_LOGE(TAG, "Error occurred during receiving: errno %d", errno);
                } else if (len == 0) {
                        ESP_LOGW(TAG, "Connection closed");
                } else {
                        //ESP_LOGI(TAG, "Received %d bytes", len);
                        uart_write_bytes(EX_UART_NUM, rx_buffer, len);
                }
        } while (len > 0);
}

 

到此已经打通tcp socket收数据后写入uart的通路,还缺另一个方向的通路即从uart读并写入socket。创建一个FreeRTOS任务来完成这个通路。此任务主要就是监听uart什么时候有数据,监听uart通过uart event做到,examples/peripherals/uart/uart_events示例可以搬过来。一旦uart有数据调用uart_read_bytes()函数读取后再调用send()函数写入socket,关键代码片段如下:

                if(xQueueReceive(uart0_queue, (void *)&event, (TickType_t)portMAX_DELAY))
{
                        //ESP_LOGI(TAG, "uart[%d] event:", EX_UART_NUM);
                        switch(event.type) {
                                //Event of UART receving data
                        case UART_DATA:
                                //ESP_LOGI(TAG, "[UART DATA]: %d", event.size);
                                uart_read_bytes(EX_UART_NUM, data, event.size, portMAX_DELAY);
                                to_write = event.size;
                                while (to_write > 0) {
                                        int written = send(sock, data + (event.size - to_write), to_write, 0);
                                        if (written < 0) {
                                                ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno);
                                        }
                                        to_write -= written;
                                }

                                break;
                                //Event of HW FIFO overflow detected

其余uart event比如UART_FIFO_OVF, UART_BUFFER_FULL等等可以沿用examples/peripherals/uart/uart_events中的代码。

 

处理好初始化uart/wifi/tcp_server等小事

到此coding任务基本完成了,剩下即使uart、wifi和tcp servert初始化。因为沿用examples/protocols/sockets/tcp_server/为主模板,wifi和tcp server相应初始化代码可以沿用,我们需要把examples/peripherals/uart/uart_events中uart初始化代码搬运过来:

static void uart_init(void)
{
        uart_config_t uart_config = {
                .baud_rate = 115200,
                .data_bits = UART_DATA_8_BITS,
                .parity = UART_PARITY_DISABLE,
                .stop_bits = UART_STOP_BITS_1,
                .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
                .source_clk = UART_SCLK_DEFAULT,
        };
        //Install UART driver, and get the queue.
        uart_driver_install(EX_UART_NUM, BUF_SIZE * 2, BUF_SIZE * 2, 20, &uart0_queue, 0);
        uart_param_config(EX_UART_NUM, &uart_config);
        uart_set_pin(EX_UART_NUM, UART_TXD, UART_RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
}

 

对照原理图选合适的针脚作为uart的RX和TX

FireBeetle 2 ESP32C6开发板可用IO16与IO17两根引脚,并选用UART0。综合以上信息写入宏定义 :

#define EX_UART_NUM             UART_NUM_0
#define UART_TXD                GPIO_NUM_16
#define UART_RXD                GPIO_NUM_17

 

编译、烧录和测试

cd examples/uart2tcp
idf.py set-target esp32c6
idf.py menuconfig

menuconfig进如下界面

 

设置一下SSID和密码:

 

当然也可以从stdin动态输入,对于esp32c6就是由usb那个cdc串口输入

哪种方便自己选择

 

使用示例

连接FireBeetle 2 ESP32C6开发板的IO16、IO17和目标板串口,别忘记GND也要接上。假设esp32c6的ip地址为192.168.1.88 (获得方式:usb cdc串口会打印,也可通过wifi ap查询), 那么如下命令就可以和目标板串口交互了,和用串口助手、minicom、putty基本一样

nc 192.168.1.88 3333

当然也可以用socat把套接字转成pty,然后用串口终端工具如putty、minicom等打开pty用,最方便的还是瑞士军刀nc。

 

一些参数调优

个人使用经验,uart的rx和tx buffer可能要按需调一调,就是uart初始化中下面这行代码的参数可以调一调,其它没什么需要调的。目前代码RX和TX都设成了2KB buffer,经测试基本上高波特率都可以满足并无丢数据现象

uart_driver_install(EX_UART_NUM, BUF_SIZE * 2, BUF_SIZE * 2, 20, &uart0_queue, 0);

未来可以提升的地方

1.串口的参数设定如波特率目前hardcoding的,将来能否再开一个tcp端口动态接收命令并处理

2.esp32c6板子的ip地址通知: wifi连上后usb cdc那个串口打印了AP分配的地址,将来能否利用mDNS服务免除寻找ip地址的过程

 

总结

本文先提出uart2tcp这个小工具的由来,然后把整个编程任务分成三个小任务,再寻找esp idf的对应示例,学习这三部分示例代码后,选择esp idf的tcp_server例子为主模板,然后通过类似搭乐高积木一样把它们综合起来手搓完成了工具开发任务,怎么样你学会了吗? 

此帖出自无线连接论坛

最新回复

不知道这个 uart2tcp透传工具 有没测试通过?因为esp32c6在Socket是有Bug的  详情 回复 发表于 2024-6-17 15:21
点赞 关注
 

回复
举报

163

帖子

0

TA的资源

一粒金砂(高级)

沙发
 

tcp_server例子地址在哪里查看数据啊?

此帖出自无线连接论坛

点评

tcp_server样例也是“nc 192.168.1.88  3333”命令  详情 回复 发表于 2024-5-16 12:47
 
 

回复

35

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
qzc飘曳 发表于 2024-5-16 12:13 tcp_server例子地址在哪里查看数据啊?

tcp_server样例也是“nc 192.168.1.88  3333”命令

此帖出自无线连接论坛
 
 
 

回复

35

帖子

0

TA的资源

一粒金砂(中级)

4
 

样例工程供参考,但强烈建议按帖子的方法去试一试,看看能否自己搭积木搭出来,而不是直接用附件的工程,成就感是不一样的

uart2tcp.tar.gz

3.57 KB, 下载次数: 1

此帖出自无线连接论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

5
 
不知道这个 uart2tcp透传工具 有没测试通过?因为esp32c6在Socket是有Bug的
此帖出自无线连接论坛

点评

你所说的esp32c6 socket bug是什么表现?  详情 回复 发表于 2024-6-20 20:09
 
 
 

回复

35

帖子

0

TA的资源

一粒金砂(中级)

6
 
haiwangxing2016 发表于 2024-6-17 15:21 不知道这个 uart2tcp透传工具 有没测试通过?因为esp32c6在Socket是有Bug的

你所说的esp32c6 socket bug是什么表现?

此帖出自无线连接论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
推荐帖子
结构体、共用体、位段和动态链链表在AVR上的应用

结构体、共用体、位段和动态链链表在AVR上的应用 //双向动态链表应用头文件================================================= ...

4.3寸屏终于搞掂了

经过一个春节准备,和买了几个别人的板子来参考,终于把4.3寸屏点亮了。这个板子的控制部分是STM32的芯片,然后由专用的驱动芯片 ...

M4 Hanker开发板:uc/GUI的移植(加触摸功能+心得体会)

发现Triton.zhang老大提供的uc/GUI例程没有触摸功能,所以将触摸功能加入,同时跑了几个uc/GUI的小例子,因为下周有好多考试,所 ...

DIY射频功率放大器-记录了全部过程

本帖最后由 RF-刘海石 于 2018-9-10 11:05 编辑 好久没有来这里写帖子了,最近不是出差就是上班,时间太赶了,没有静下心来写 ...

【测评SGP40】1、开箱测评

要搬新家了,家里空气质量很是令人担忧,无意中看到这个测评贴,没想就得到这个名额了,非常高兴!感谢盛思锐!感谢EE! 话 ...

防反接电路这个R1电阻不要了会对电路功能有影响吗?

652252这个R1电阻不要了,G极直接接地,会对电路功能有影响吗?

【得捷电子Follow me第2期】ESP32-S3之网络连接和获取ntp时间(Arduino)

本帖最后由 小默叔叔 于 2023-10-9 13:45 编辑 # 【得捷电子Follow me第2期】ESP32-S3之网络连接和获取ntp时间(Arduino) # ...

肖特基二极管能替换稳压二极管吗

肖特基二极管和稳压二极管是两种常用的半导体元件,虽然它们在某些特性上有所相似,但它们的基本功能和用途存在明显差异。 肖特 ...

【兆易GD32H759I-EVAL】SDRAM测试

本帖最后由 TL-LED 于 2024-5-11 08:18 编辑 这篇测试板卡上SDRAM存储器的读写。 一、硬件部分 1.1、SDRAM电路 ...

快速回复 返回顶部 返回列表