freeRTOS操作系统机器人实现
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

264 lines
7.1 KiB

/******************************************************************************
版权所有 (C), 2018-2099, Radkil
******************************************************************************
文 件 名 : My_Lwip.c
版 本 号 : 初稿
作 者 : Radkil
生成日期 : 2026年5月21日
最近修改 :
功能描述 : LWIP中间层
修改历史 :
1.日 期 : 2026年5月21日
作 者 : Radkil
修改内容 : 创建文件
******************************************************************************/
#include "bsp_config.h"
#ifdef USE_LWIP
#include "lwip/sockets.h"
#include "lwip/netdb.h"
#include "FreeRTOS.h"
#include "task.h"
#include <stdio.h>
#include <string.h>
#include "common.h"
#include "ringbuffer.h"
#include "semphr.h"
#include "lua_base.h"
#include <stdarg.h>
/*----------------------------------------------*
* 外部变量说明 *
*----------------------------------------------*/
/*----------------------------------------------*
* 外部函数原型说明 *
*----------------------------------------------*/
/*----------------------------------------------*
* 内部函数原型说明 *
*----------------------------------------------*/
/*----------------------------------------------*
* 全局变量 *
*----------------------------------------------*/
/*----------------------------------------------*
* 模块级变量 *
*----------------------------------------------*/
/*----------------------------------------------*
* 常量定义 *
*----------------------------------------------*/
/*----------------------------------------------*
* 宏定义 *
*----------------------------------------------*/
#define PORT 23 // 监听的端口号
#define RECV_SIZE 256 // 接收缓冲区大小
static int connect_fd = -1; //socket套接字
#if 0
static rd_ringbuf_t *g_rb_handle = NULL;
SemaphoreHandle_t xSemaphore;
StaticSemaphore_t xSemaphoreBuffer;
SemaphoreHandle_t xMutex;
StaticSemaphore_t xMutexBuffer;
void Myprint_Init(void)
{
g_rb_handle = rd_RingbufferCreate(RECV_SIZE);
rd_RingbufferReset(g_rb_handle);
xSemaphore = xSemaphoreCreateCountingStatic(5, 0, &xSemaphoreBuffer);
xMutex = xSemaphoreCreateMutexStatic(&xMutexBuffer);
return;
}
void Myprint_timer(void)
{
return;
}
void Myprint_IRQHandler(void)
{
return;
}
int Myprint_putchar(uint8_t ch)
{
if (connect_fd < 0) return 0;
char tx_buf[2];
if (ch == '\n')
{
tx_buf[0] = '\r';
tx_buf[1] = '\n';
if (write(connect_fd, tx_buf, 2) < 0) return EOF;
return 2;
}
else
{
tx_buf[0] = ch;
if (write(connect_fd, tx_buf, 1) < 0) return EOF;
return 1;
}
}
void Myprint_getchar(char *ch)
{
while (1)
{
int ret;
if (xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE)
{
if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE)
{
ret = rd_RingbufferGet(g_rb_handle, ch, 1);
xSemaphoreGive(xMutex);
if (ret > 0)
{
return;
}
}
}
}
}
#endif
void ShowLWIPstate(void)
{
stats_display();
}
void luaprint_talnet(const char *fmt, ...)
{
char temp[RECV_SIZE];
va_list args;
va_start(args, fmt);
vsprintf(temp, fmt, args);
write(connect_fd, &temp, strlen(temp));
va_end(args);
}
void vTCPServer_Task(void *pvParameters)
{
int listen_fd;
struct sockaddr_in server_addr, client_addr;
char temp[RECV_SIZE];
int ret;
socklen_t addr_len = sizeof(struct sockaddr_in);
// 1. 创建 socket (AF_INET表示IPv4, SOCK_STREAM表示TCP)
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
if (listen_fd < 0)
{
log_e("Socket create failed!\r\n");
vTaskDelete(NULL);
return;
}
// 2. 绑定 IP 和端口 (INADDR_ANY 表示绑定本地所有网卡IP)
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(PORT);
if (bind(listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
log_e("Bind failed!\r\n");
close(listen_fd);
vTaskDelete(NULL);
return;
}
// 3. 开始监听,最大排队连接数为 5
if (listen(listen_fd, 5) < 0)
{
log_e("Listen failed!\r\n");
close(listen_fd);
vTaskDelete(NULL);
return;
}
log_i("TCP Server is running on port %d...\r\n", PORT);
while (1)
{
// 4. 阻塞等待客户端连接
connect_fd = accept(listen_fd, (struct sockaddr *)&client_addr, &addr_len);
if (connect_fd < 0)
{
log_w("Accept failed!\r\n");
continue;
}
#ifdef USE_TALNET
lua_init(luaprint_talnet);
#endif
// // 第一条指令:要求客户端关闭本地回显,交由服务器处理
// unsigned char cmd_echo[] = { 255, 254, 1 };
// // IAC(255) DO(253) ECHO(1)
//
// // 第二条指令:禁用“前进抑制”,强制进入实时字符流模式
// unsigned char cmd_sga[] = { 255, 254, 3 };
// // IAC(255) DO(253) SUPPRESS-GO-AHEAD(3)
//
// write(connect_fd, cmd_echo, sizeof(cmd_echo));
// write(connect_fd, cmd_sga, sizeof(cmd_sga));
// int enable = 1; // 1 表示启用 TCP_NODELAY(即禁用 Nagle 算法)
// setsockopt(connect_fd, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable));
// 打印连接的客户端 IP 和端口
log_i("New client connected: %s:%d\r\n",
inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
// 5. 循环接收并回显数据
// char *welcome = "\n> ";
// write(connect_fd, welcome, strlen(welcome));
while (1)
{
// 阻塞接收数据
ret = read(connect_fd, &temp, RECV_SIZE);
if (ret > 0)
{
#ifdef USE_TALNET
lua_repl(temp, ret, 0);
#else
write(connect_fd, temp, ret);
#endif
#if 0
if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE)
{
int iLen = rd_RingbufferPutForce(g_rb_handle, &temp, ret);
xSemaphoreGive(xMutex);
if (iLen > 0)
{
xSemaphoreGive(xSemaphore);
}
}
#endif
}
else if (ret == 0)
{
// 客户端正常断开连接
log_i("Client disconnected.\r\n");
break;
}
else
{
// 接收出错
log_e("Read data error!\r\n");
break;
}
}
// 关闭与当前客户端的连接
close(connect_fd);
}
}
#endif