FreeRTOS +TCP TCPServer 服务器

开启任务创建套接字,绑定服务器地址,监听套接字,循环接收监听,当都客户端连接成功,开启任务循环处理接收客户端发送过来的数据。

1.创建套接字,xListeningSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );

2.设置连接超时,FreeRTOS_setsockopt()。

3.绑定,FreeRTOS_bind( xListeningSocket, &xBindAddress, sizeof( xBindAddress ) );

4.监听,FreeRTOS_listen( xListeningSocket, xBacklog );

5.接收,xConnectedSocket = FreeRTOS_accept( xListeningSocket, &xClient, &xSize );

6.接收到客户端套接字,处理客户端接收和发送。

             FreeRTOS_recv( xConnectedSocket, pucRxBuffer, ipconfigTCP_MSS, 0 );,

             FreeRTOS_send( xConnectedSocket, pucRxBuffer, lBytes - lTotalSent, 0 );

 

#include <stdint.h>
#include <stdio.h>

/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"

/* FreeRTOS+TCP includes. */
#include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h"

#include "TCPServer.h"

/* The maximum time to wait for a closing socket to close. */
#define tcpechoSHUTDOWN_DELAY	( pdMS_TO_TICKS( 5000 ) )

// 服务器监听端口
#define tcpechoPORT_NUMBER		8080

uint16_t acceptTaskSize;

static void vAcceptConnectionTask(void *parameters)
{
	int32_t lBytes, lSent, lTotalSent;
	Socket_t xConnectedSocket;
	static const TickType_t xReceiveTimeOut = pdMS_TO_TICKS( 1000 );
	static const TickType_t xSendTimeOut = pdMS_TO_TICKS( 1000 );
	TickType_t xTimeOnShutdown;
	uint8_t *pucRxBuffer = NULL;

	xConnectedSocket = ( Socket_t ) parameters;
	pucRxBuffer = ( uint8_t * ) pvPortMalloc( ipconfigTCP_MSS );
	
	if(pucRxBuffer != NULL)
	{
		FreeRTOS_setsockopt( xConnectedSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) );
		FreeRTOS_setsockopt( xConnectedSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xReceiveTimeOut ) );
	
		for( ;; )
		{
			/* Zero out the receive array so there is NULL at the end of the string
			when it is printed out. */
			memset( pucRxBuffer, 0x00, ipconfigTCP_MSS );
	
			/* Receive data on the socket. */
			lBytes = FreeRTOS_recv( xConnectedSocket, pucRxBuffer, ipconfigTCP_MSS, 0 );

			/* If data was received, echo it back. */
			if( lBytes > 0 )
			{
				lSent = 0;
				lTotalSent = 0;

				/* Call send() until all the data has been sent. */
				while( ( lSent >= 0 ) && ( lTotalSent < lBytes ) )
				{
					lSent = FreeRTOS_send( xConnectedSocket, pucRxBuffer, lBytes - lTotalSent, 0 );
					lTotalSent += lSent;
				}
				if( lSent < 0 )
				{
					/* Socket closed? */
					break;
				}
			}
			else if(lBytes < 0 )
			{
				/* Socket closed? */
				break;
			}
		}
	}
	/* Initiate a shutdown in case it has not already been initiated. */
	FreeRTOS_shutdown( xConnectedSocket, FREERTOS_SHUT_RDWR );

	/* Wait for the shutdown to take effect, indicated by FreeRTOS_recv()
	returning an error. */
	xTimeOnShutdown = xTaskGetTickCount();
	do
	{
		if( FreeRTOS_recv( xConnectedSocket, pucRxBuffer, ipconfigTCP_MSS, 0 ) < 0 )
		{
			break;
		}
	} while( ( xTaskGetTickCount() - xTimeOnShutdown ) < tcpechoSHUTDOWN_DELAY );

	/* Finished with the socket, buffer, the task. */
	vPortFree( pucRxBuffer );
	FreeRTOS_closesocket( xConnectedSocket );

	vTaskDelete( NULL );
}

static void vListeningConnectionTask(void *parameters)
{
	struct freertos_sockaddr xClient, xBindAddress;
	Socket_t xListeningSocket, xConnectedSocket;
	socklen_t xSize = sizeof( xClient );
	static const TickType_t xReceiveTimeOut = portMAX_DELAY;
	const BaseType_t xBacklog = 20;
	
	xListeningSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
	configASSERT( xListeningSocket != FREERTOS_INVALID_SOCKET );
	
	FreeRTOS_setsockopt( xListeningSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) );
	
	xBindAddress.sin_port = tcpechoPORT_NUMBER;
	xBindAddress.sin_port = FreeRTOS_htons( xBindAddress.sin_port );
	FreeRTOS_bind( xListeningSocket, &xBindAddress, sizeof( xBindAddress ) );
	FreeRTOS_listen( xListeningSocket, xBacklog );
	
	while(1)
	{
		xConnectedSocket = FreeRTOS_accept( xListeningSocket, &xClient, &xSize );
		configASSERT( xConnectedSocket != FREERTOS_INVALID_SOCKET );
		
		xTaskCreate( vAcceptConnectionTask, "ClientInstance", acceptTaskSize, ( void * ) xConnectedSocket, tskIDLE_PRIORITY, NULL );
	}
}

void vStartTCPServerTask(uint16_t taskSize, UBaseType_t priority)
{
	xTaskCreate(vListeningConnectionTask, "TCPServerTask", taskSize, NULL, priority, NULL);
	acceptTaskSize = taskSize;
}

 

实现STM32 FreeRTOS LwIP TCP服务器需要按照以下步骤进行操作: 1. 首先,需要配置LwIP和FreeRTOS。可以在STM32CubeMX中选择配置相应的组件,生成对应的代码和初始化函数。 2. 在代码中创建任务来处理TCP服务器。通过创建一个任务,可以将其分配给特定的核心,以处理TCP请求和响应。 3. 在任务中,首先需要进行LwIP和FreeRTOS的初始化。这样可以确保网络和操作系统的适当设置。需要调用lwip_init()和vTaskStartScheduler()函数。 4. 配置和创建TCP服务器的套接字。可以通过调用lwip_socket()函数创建一个TCP套接字,并使用lwip_bind()函数将其与特定的IP地址和端口绑定。 5. 通过调用lwip_listen()函数监听TCP套接字,等待客户端的连接。 6. 使用lwip_accept()函数接受客户端的连接请求,并获得一个新的套接字来处理与该客户端之间的通信。 7. 通过调用lwip_recv()和lwip_send()函数来接收和发送数据。可以使用这些函数接收来自客户端的数据,并发送响应数据给客户端。 8. 当与客户端的通信完成后,使用lwip_close()函数关闭套接字。 9. 循环进行步骤6-8,以处理其他客户端的连接和通信请求。 需要注意的是,STM32系列芯片的内存和处理能力有限,因此在编写代码时需要谨慎处理内存和资源的分配和释放,以确保程序的稳定性和性能。 总结:通过以上步骤,可以在STM32上使用FreeRTOS和LwIP实现TCP服务器,使其能够接受和处理客户端的连接和通信请求。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值