通过STM32CubeMx配置LWIP+FreeRTOS并通过Socket实现TCP_Client/Sever
- 测试平台 → Nucleo_F429ZI
- 软件工具 → STM32CubeMx 6.6.1 MDK 5.3.0 网络调试助手V1.2
实现Ping通
-
在CubeMx上面选择NUCLEO-F429ZI开发板,并采用默认配置
-
使能FreeRTOS
-
修改defaultTask的栈大小
-
由于使用了FreeRTOS,因此系统的TimeBase Source修改成TIM1
-
使能LWIP,并且先禁用DHCP,设置好静态IP
-
Platform选择LAN8742
-
修改堆栈大小,生成工程
-
生成KEIL工程之后,勾选上use MicroLIB,代码上暂时无需做其他修改,编译下载
文章来源:https://www.toymoban.com/news/detail-716537.html -
打开电脑命令行,去ping这设置好的IP,能够实现Ping通
文章来源地址https://www.toymoban.com/news/detail-716537.html
使用Socket接口实现TCP Client
- 在实现ping通之后,新建一个C文件,将如下代码拷贝
#include "lwip/opt.h"
#include "lwip/api.h"
#include "lwip/inet.h"
#include "lwip/sockets.h"
#include "string.h"
#include "client_socket.h"
#include "cmsis_os.h"
#include <stdio.h>
#define IP_ADDR "192.168.0.120"
#define PORT 8088
static void client_socket_thread(void *arg)
{
int sock;
struct sockaddr_in address;
uint8_t send_buf[]= "This is a TCP Client test...\r\n";
/* create a TCP socket */
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("Socket error\n");
return;
}
address.sin_family = AF_INET;
address.sin_port = htons(PORT);
address.sin_addr.s_addr = inet_addr(IP_ADDR);
memset(&(address.sin_zero), 0, sizeof(address.sin_zero));
if (connect(sock,(struct sockaddr *)&address,sizeof(struct sockaddr)) == -1)
{
printf("Connect failed!\n");
closesocket(sock);
}
else
{
printf("Connect to iperf server successful!\n");
}
while (1)
{
if (write(sock,send_buf,sizeof(send_buf)) < 0)
break;
vTaskDelay(1000);
}
closesocket(sock);
}
void client_socket_init()
{
sys_thread_new("HTTP", client_socket_thread, NULL, DEFAULT_THREAD_STACKSIZE * 4, osPriorityAboveNormal);
}
- 新建一个头文件,将如下代码拷贝
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __CLIENT_SOCKET_H__
#define __CLIENT_SOCKET_H__
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void client_socket_init(void);
#endif /* __CLIENT_SOCKET_H__ */
- 在freertos.c中添加client_socket.h头文件,并且在StartDefaultTask任务中调用client_socket_init
- 编译下载完成后 ,打开网络调试助手V1.2,配置成TCP Server模式,本机IP配置成192.168.0.120,端口号配置为8088,再打开连接
- 复位开发板,开发板能够成功和网络调试助手连接,并且数据传输正常,网络调试助手每1s会接收到一包数据
使用Socket接口实现TCP Server
- 新建一个server_socket.c文件,将如下代码拷贝
#include "lwip/opt.h"
#include "lwip/api.h"
#include "lwip/inet.h"
#include "lwip/sockets.h"
#include "string.h"
#include "server_socket.h"
#include "cmsis_os.h"
#include <stdio.h>
#define PORT (8088)
#define RECV_DATA (1024)
static void server_socket_thread(void *arg)
{
int sock,connected;
struct sockaddr_in address,client_addr;
char *recv_data;
socklen_t sin_size;
int recv_data_len;
recv_data = (char *)pvPortMalloc(RECV_DATA);
if (recv_data == NULL)
{
printf("No memory\n");
return;
}
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("Socket error\n");
if (recv_data) free(recv_data);
return;
}
/* bind to port 80 at any interface */
address.sin_family = AF_INET;
address.sin_port = htons(PORT);
address.sin_addr.s_addr = INADDR_ANY;
memset(&(address.sin_zero), 0, sizeof(address.sin_zero));
if (bind(sock, (struct sockaddr *)&address, sizeof (address)) < 0)
{
printf("unable to bind\r\n");
if (recv_data) free(recv_data);
return;
}
/* listen for incoming connections (TCP listen backlog = 5) */
if(listen(sock, 5) == -1)
{
printf("listen error\r\n");
if (recv_data) free(recv_data);
return;
}
while (1)
{
sin_size = sizeof(struct sockaddr_in);
connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size);
printf("new client connected from (%s, %d)\n",inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
{
int flag = 1;
setsockopt(connected,IPPROTO_TCP, /* set option at TCP level */
TCP_NODELAY, /* name of option */
(void *) &flag, /* the cast is historical cruft */
sizeof(int)); /* length of option value */
}
while (1)
{
recv_data_len = recv(connected, recv_data, RECV_DATA, 0);
if(recv_data_len <= 0)
break;
printf("recv %d len data\n",recv_data_len);
write(connected,recv_data,recv_data_len);
}
if(connected >= 0)
closesocket(connected);
connected = -1;
}
if(recv_data) free(recv_data);
}
void server_socket_init()
{
sys_thread_new("HTTP", server_socket_thread, NULL, DEFAULT_THREAD_STACKSIZE * 4, osPriorityAboveNormal);
}
- 新建server_socket.h头文件,将如下代码拷贝
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __SERVER_SOCKET_H__
#define __SERVER_SOCKET_H__
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void server_socket_init(void);
#endif /* __SERVER_SOCKET_H__ */
- 在StartDefaultTask任务中调用server_socket_init
- 编译下载后复位开发板,在网络调试助手上配置成TCP Client,远程IP设置为192.168.0.10,端口号设置为8088,点击连接,可以从开发板串口打印中看到和Client连接成功。
- 通过网络调试助手向开发板发送数据,可以看到开发板串口打印接收到的数据长度,并且网络调试助手看到数据回传正常。
到了这里,关于【通过STM32CubeMx配置LWIP+FreeRTOS并通过Socket实现TCP_Client/Sever】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!