SAL全称Socket Abstract Layer,即套接字抽象层,主要作用是对上层应用提供统一的 socket 编程接口,屏蔽底层网络硬件的差异。 SAL层向下提供的接口在 这些接口需要用户实现,一般使用AT框架与模组通信实现,也就是常说的通信模组驱动,比如 实现之后调用 SAL层提供了以下的API供上层网络应用程序调用: 功能描述 注册一个联网模组 参数解释 返回值 0,返回成功。 -1,返回失败。 功能描述 初始化模组 参数解释 无 返回值 0,返回成功。 -1,返回失败。 功能描述 域名解析,将一个域名转换为IP地址。 参数解释 返回值 0,返回成功。 -1,返回失败。 功能描述 向远端发起连接 参数解释 返回值 成功,则返回连接的socket id。 失败,返回-1。 功能描述 向远端发送数据(TCP协议栈) 参数解释 返回值 功能描述 从远端读取数据(TCP协议栈) 参数解释 返回值 功能描述 从远端接收数据(TCP协议栈) 参数解释 返回值 功能描述 向远端发送数据(UDP协议栈) 参数解释 返回值 功能描述 从远端接收数据(UDP协议栈) 参数解释 返回值 功能描述 关闭与远端的连接 参数解释 返回值 0,返回成功。 服务器使用Python编写,本文中开启两个TCP服务器,一个监听8080端口,另一个接收8001端口: 在服务器上开启第一个监听程序: 在helloworld工程的基础上开始创建TCP测试工程。 首先添加串口的HAL驱动,此驱动和具体的硬件平台相关,在 然后添加AT框架的源码,在 再添加SAL框架的源码,在 最后添加EC20的设备驱动,在 添加以上组件的头文件路径: 移植helloworld示例程序,添加位于 示例程序是使用ESP8266的,修改使用EC20: ② 修改模组初始化 ③ 修改ip: 接下来编译、下载、在串口终端查看实验结果: 第一个程序启动后如图: 第二个程序启动后如图: 在之前的基础上去除TCP的测试文件,添加UDP的测试文件: 同样进行修改。 ① 修改头文件: ② 修改初始化: ③ 修改ip和端口: 编译,下载,查看串口输出: 在第一个服务器程序可以看到模组发送的数据: 接收更多精彩文章及资源推送,欢迎订阅我的微信公众号:『mculover666』。
1. SAL套接字抽象层
1.1. SAL层向下提供的接口
net/sal_module_wrapper/sal_module_wrapper.h
文件中声明,如下:typedef struct sal_module_st { int (*init)(void); int (*get_local_mac)(char *mac); int (*get_local_ip)(char *ip, char *gw, char *mask); int (*parse_domain)(const char *host_name, char *host_ip, size_t host_ip_len); int (*connect)(const char *ip, const char *port, sal_proto_t proto); int (*send)(int sock, const void *buf, size_t len); int (*recv_timeout)(int sock, void *buf, size_t len, uint32_t timeout); int (*recv)(int sock, void *buf, size_t len); int (*sendto)(int sock, char *ip, char *port, const void *buf, size_t len); int (*recvfrom)(int sock, void *buf, size_t len); int (*recvfrom_timeout)(int sock, void *buf, size_t len, uint32_t timeout); int (*close)(int sock); } sal_module_t;
device
文件夹下存放的ESP2866、M26、EC20这些驱动:
以本节文章使用的EC20为例,实现接口的代码如下:sal_module_t sal_module_ec20 = { .init = ec20_init, .connect = ec20_connect, .send = ec20_send, .recv_timeout = ec20_recv_timeout, .recv = ec20_recv, .close = ec20_close, .parse_domain = ec20_parse_domain, };
tos_sal_module_register
注册到系统中,如下:if (tos_sal_module_register(&sal_module_ec20) != 0) { return -1; }
1.2. SAL层向上提供的API
net/sal_module_wrapper/sal_module_wrapper.h
net/sal_module_wrapper/sal_module_wrapper.c
tos_sal_module_register
int tos_sal_module_register(sal_module_t *module);
IN/OUT
参数名
描述
[in]
module
联网模组句柄
tos_sal_module_init
int tos_sal_module_init(void);
tos_sal_module_parse_domain
int tos_sal_module_parse_domain(const char *host_name, char *host_ip);
IN/OUT
参数名
描述
[in]
host_name
待解析的域名
[out]
host_ip
解析后的IP地址
tos_sal_module_connect
int tos_sal_module_connect(const char *ip, const char *port, sal_proto_t proto);
IN/OUT
参数名
描述
[in]
ip
IP地址
[in]
port
端口
[in]
proto
TCP/UDP协议
tos_sal_module_send
int tos_sal_module_send(int sock, const void *buf, size_t len);
IN/OUT
参数名
描述
[in]
sock
socket id(由tos_sal_module_connect获取)
[in]
buf
发送的数据起始地址
[in]
len
发送的数据长度
发送的数据长度。tos_sal_module_recv
int tos_sal_module_recv(int sock, void *buf, size_t len);
IN/OUT
参数名
描述
[in]
sock
socket id(由tos_sal_module_connect获取)
[out]
buf
接收数据buffer
[in]
len
接收数据buffer长度
实际接收到的数据长度。tos_sal_module_recv_timeout
int tos_sal_module_recv_timeout(int sock, void *buf, size_t len, uint32_t timeout);
IN/OUT
参数名
描述
[in]
sock
socket id(由tos_sal_module_connect获取)
[in]
buf
数据起始地址
[in]
len
数据长度
[in]
timeout
超时参数
实际接收到的数据长度。tos_sal_module_sendto
int tos_sal_module_sendto(int sock, char *ip, char *port, void *buf, size_t len);
IN/OUT
参数名
描述
[in]
sock
socket id(由tos_sal_module_connect获取)
[in]
ip
IP地址
[in]
port
端口
[in]
buf
待发送数据起始地址
[in]
len
待发送数据长度
发送的数据长度。tos_sal_module_recvfrom
int tos_sal_module_recvfrom(int sock, char *ip, char *port, void *buf, size_t len);
IN/OUT
参数名
描述
[in]
sock
socket id(由tos_sal_module_connect获取)
[in]
ip
IP地址
[in]
port
端口
[in]
buf
接收数据buffer起始地址
[in]
len
接收数据buffer长度
实际接收到的数据长度。tos_sal_module_close
int tos_sal_module_close(int sock);
IN/OUT
参数名
描述
[in]
sock
socket id(由tos_sal_module_connect获取)
-1,返回失败。2. 搭建TCP服务器
# tcpserver.py from socket import * host = '' #第一个程序监听8080,第二个程序监听8001端口 port = 8080 # 创建server socket server_socket = socket(AF_INET,SOCK_STREAM) # 绑定socket监听地址 server_addr = (host,port) server_socket.bind(server_addr) # 开始监听,最大允许连接数5 server_socket.listen(5) # 处理连接请求 try: while True: print('waiting for connect...') #阻塞等待客户端的连接 client_socket, client_addr = server_socket.accept() # 连接成功后,打印客户端信息 print('a client connnect from:', client_addr) while(True): # 向客户端发送数据 client_socket.send('Hello, client!'.encode()) # 接收客户端的数据 data = client_socket.recv(1024) print('recv data is ', data.decode()) # 接收到quit则关闭socket if "quit" in data.decode(): break # 关闭socket client_socket.close() server_socket.close() print("socket closed.") break except: client_socket.close() server_socket.close() print("socket closed.")
在服务器上开启第二个监听程序:
3. 创建TCP测试工程
3.1. 添加C文件
platformhalststm32l4xxsrc
路径中:
netatsrc
路径中:
netsal_module_wrapper
路径中:
devicesec20
路径中:
3.2. 添加头文件路径
3.3. 添加demo测试文件
examplestcp_through_module
路径下的示例文件:
① 修改头文件://#include "esp8266.h" #include "ec20.h" //#define USE_ESP8266 #define USE_EC20
#ifdef USE_EC20 ec20_sal_init(HAL_UART_PORT_0); #endif
socket_id_0 = tos_sal_module_connect("117.50.111.72", "8080", TOS_SAL_PROTO_TCP); ... socket_id_1 = tos_sal_module_connect("117.50.111.72", "8001", TOS_SAL_PROTO_TCP);
在第一个服务器可以看到模组发送的小修:
在第二个服务器可以看到模组发送的不同消息:
4. 搭建UDP服务器
# udp-server.py from socket import * host = '' #第一个程序为8001,二个程序为8081 port = 8001 # 创建server socket server_socket = socket(AF_INET,SOCK_DGRAM) # 绑定socket监听地址 server_addr = (host,port) server_socket.bind(server_addr) print('UDP Server Start...') # 处理连接请求 while(True): # 接收客户端的数据 data, addr = server_socket.recvfrom(1024) print("Receive from %s:%s" % addr % data) if data == b"quit": server_socket.sendto(b"Good bye!n", addr) continue server_socket.sendto(b"Hello,udp client!n", addr)
5. 创建DUP测试工程
//#include "esp8266.h" #include "ec20.h" ... //#define USE_ESP8266 #define USE_EC20
#ifdef USE_EC20 ec20_sal_init(HAL_UART_PORT_0); #endif
socket_id_0 = tos_sal_module_connect("117.50.111.72", "8002", TOS_SAL_PROTO_UDP); ... socket_id_1 = tos_sal_module_connect("117.50.111.72", "8081", TOS_SAL_PROTO_UDP);
在第二个服务器程序可以看到模组发送的数据:
至此,测试完成。
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算