# 【米尔 瑞芯微RK3568 工业开发板】基于libuv的客户端TCP连接
今天给大家带来的试用分享是在米尔出口的瑞芯微RK3568的工业开发板的以太网相关评测:基于开源库libuv的TCP客户端实现。
以太网,在现在的社会中,应该没有人说我没有上过网。人如此,机器设备亦如此。在工业设备通讯里面,相对于RS485,CAN,或者WiFi,蓝牙,zigbee等通讯方式,以太网仍然是带宽大,速度高,延迟低的通讯方式。这些特性也成为工业控制领域中设计 应用使用以太网通讯的重要筹码。对于实时性要求巨高的伺服电机驱动,也是在以太网基础上部署了EtherCAT协议。据科技媒体相关报道,现在部分头部新能源车企也开始部署车载以太网与更新适应汽车安全的以太网协议。可见,以太网功能是我们嵌入式工程师必备的一项基础知识与技能。
## 米尔RK3568开发板
既然以太网这么重要,那么,我们米尔的瑞芯微RK3568在这方面的设计又如何呢?
做为一款国产高性能4核芯片,RK3568拥有丰富的高速接口,比如,我们本次要评测的以太网接口。米尔贴心的为我们准备了两个接口,并且两个以太网接口均支持千兆速率。没错!是双千兆接口。这样,我们可以使用这两口接口分别加入两个不同的局域网,也可以使用一个接口连接入内网,另一个连接入外网。这样也可以隔离数据与通讯,而且增强了数据安全性。总之,双千兆网口足以胜任我们工业控制领域的大多数应用。
## libuv实现客户端
有了米尔RK3568强悍的硬件支持,优秀、稳定、可靠的软件软件驱动也要跟上。考虑到自身软件实现的水平,所以,本次我使用了开源的libuv来实现TCP客户端,并进行数据的收发。
libuv是一款开源的跨平台的异步IO库。它也是大名鼎鼎Node.js的底层库实现。libuv开源库的特性是异步IO方式,但我们本次使用它的客户端模式,借用其回调函数的实现方式。当然,对于我个人而言,在一个已有框架下编程,程序的健壮性也多少有点保证。
## 部署libuv客户端
我们需要从国外github.com上同步下载libuv的源代码。我建议大家直接下载libuv的zip包。如果使用git clone的方式,由于众所周知的原因,大概率会失败。
下载完成之后,将zip包解压到合适的文件夹。由于libuv使用纯C编写,并且并未依赖其它链接库,我们可以直接运行CMake来生成动态链接库.so文件。当然,如果是自己的程序,我还是非常建议使用静态链接库,主要是出于好发布,好维护的原因。我这里使用.so的动态链接库的原因还有一个,我也要在米尔RK3568的环境下运行TCP服务端。这样可以共用同一套libuv库,也充分体现动态链接库的优势。
## 编写我们自己的TCP客户端
有了libuv动态链接库,我们就基于libuv的框架来编写我们的程序代码。
我们让app连接到端口号为9012的服务端,并发送"Hello EEWORLD! Hello MYiR RK3568!"字符串。我的参考源代码如下:
```c
/**
******************************************************************************
*
@File main.c
*
@author jobs
*
@version v0.00
*
@date 2024-09-11
*
@brief * @note
*
******************************************************************************
*/
#include
#include
#include
#include
#include “uv.h”
#define DEFAULT_PORT (9012)
uv_buf_t iov;
char buffer[128];
const char hello_str[] = "Hello EEWORLD! Hello MYiR RK3568!";
uv_loop_t *loop;
uv_tcp_t client_tcp_socket;
uv_connect_t connect;
void send_done(uv_write_t *req, int status)
{
if (status < 0)
{
fprintf(stderr, "Connection error %s\n", uv_strerror(status));
return;
}
uv_close((uv_handle_t *)&client_tcp_socket, NULL);
}
void on_connect(uv_connect_t *req, int status)
{
if (status < 0)
{
fprintf(stderr, "Connection error %s\n", uv_strerror(status));
return;
}
fprintf(stdout, "Connect ok\n");
stpcpy(buffer, hello_str);
iov = uv_buf_init(buffer, sizeof(buffer));
iov.len = strlen(hello_str);
uv_write((uv_write_t *)req, (uv_stream_t *)&client_tcp_socket, &iov, 1, send_done);
}
int main()
{
int ret = 0;
struct sockaddr_in dest;
*loop = uv_default_loop();
uv_tcp_init(loop, &client_tcp_socket);
uv_ip4_addr("192.168.8.18", DEFAULT_PORT, &dest);
ret = uv_tcp_connect(&connect, &client_tcp_socket, (const struct sockaddr *)&dest, on_connect);
if (ret)
{
fprintf(stderr, "connect error %s\n", uv_strerror(ret));
return 1;
}
uv_run(loop, UV_RUN_DEFAULT);
return 0;
}
/******************************** END OF FILE *********************************/
```
我们可以看到,我们模拟的TCP服务端成功接收到米尔RK3568的连接,并接收到发送过来的字符串。
## 总结
通过本次试用TCP客户端的以太网接口,我们可以看到米尔RK3568在工业控制领域,自动化领域,机器人领域轻松实现TCP高速、大带宽的数据通讯。
本次原型验证也起到非常积极有效作用。我相信,经过本轮试用定会在实际项目选型中会优先考虑米尔RK3568,也必将会减少我实际项目的开发周期。