diff --git a/APP_Framework/Applications/app_test/Makefile b/APP_Framework/Applications/app_test/Makefile
index ee75fe950..6c38cba7d 100644
--- a/APP_Framework/Applications/app_test/Makefile
+++ b/APP_Framework/Applications/app_test/Makefile
@@ -126,7 +126,7 @@ ifeq ($(CONFIG_ADD_XIZI_FEATURES),y)
endif
ifeq ($(CONFIG_USER_TEST_WEBSERVER),y)
- SRC_FILES +=
+ SRC_FILES += test_webserver/test_webserver.c
endif
ifeq ($(CONFIG_USER_TEST_MQTTCLIENT),y)
diff --git a/APP_Framework/Applications/app_test/test_webserver/README.md b/APP_Framework/Applications/app_test/test_webserver/README.md
new file mode 100644
index 000000000..fe0461c4e
--- /dev/null
+++ b/APP_Framework/Applications/app_test/test_webserver/README.md
@@ -0,0 +1,67 @@
+# 基于矽璓已实现的Lwip,在ARM上实现基本的Web服务##
+
+## 1. 简介
+基于矽璓已实现的Lwip,在ARM上实现基本的Web服务,其功能支持IP、GateWay、DNS、子网掩码等网络参数的设置。
+主要功能为:web服务等待Http请求的到来,解析Http报文后,设置本机的网络参数信息,在终端打印设置后的网络参数信息,并返回浏览器客户端成功响应。
+
+## 2. 数据结构设计说明
+Server的网络结构参数为:
+```
+struct ServerNet
+{
+ char local_ip[20];
+ char local_mask[20];
+ char local_gw[20];
+ char local_dns[20];
+}ServerNet;
+```
+
+主要实现了以下几个函数:
+```
+TcpThread: 建立socket监听,循环等待网络通信事件的到来;
+HandleHttpRequest:处理并解析Http报文,得到网络参数信息;
+AddrUpdate: 根据到来的参数,更新本机网络参数;
+LwipShowIP:显示网络参数信息,包括IP、GateWay、DNS、子网掩码;
+LwipSetIP: 设置网络参数信息,包括IP、GateWay、DNS、子网掩码;
+ShowDns: 显示dns网址;
+SetDns: 设置dns网址;
+```
+除此之外,还包括两个工具函数:
+```
+SubstractServerNet: 截取http报文的请求体,格式为:ip=192.168.1.9&netmask=255.255.255.0&iproute=192.168.1.1&dns=114.114.114.114
+substring: 截取字符串
+
+```
+
+## 3. 测试程序说明
+1. 通过数据线将开发板连接电脑,并通过网线连接使开发板接入家庭局域网。
+2. 将TestWebserver注册为shell 命令,编译前通过menuconfig打开lwip和TestWebserver功能。
+3. 将编译成功的XiZi-edu-arm32.bin文件烧录到arm板子。烧录bin文件前,需要将开发板boot引脚拉高(盖上跳帽),上电后再按下reset按键,之后可以点击烧写工具的执行按钮,等待烧写完成。
+4. 将boot引脚拉低(摘下跳帽),按下reset按键,使用串口工具显示xiuos的命令行界面。
+5. 将开发板的本机ip通过setip命令设置为与电脑端在同一个局域网之下,利用ping命令检测成功通信。
+6. 运行TestWebserver命令验证功能。
+
+## 4. 运行结果(##需结合运行测试截图按步骤说明##)
+
+
+烧录程序,boot引脚拉高,按下reset按键。
+
+
+
+点击执行烧录,程序烧录成功。
+
+
+
+打开串口调试工具,xiuos程序成功在开发板上运行。
+
+
+
+利用setip命令,修改开发板ip,使得开发板和电脑在同一个局域网内,并使用ping命令测试。
+
+
+
+在服务端运行TestWebserver命令,打开index.html,设置网络参数信息,点击提交,发送http请求。
+
+
+
+web服务收到http请求后并打印post请求报文,以及修改后的开发板的网络参数信息,包括IP、子网掩码、GateWay和DNS。
diff --git a/APP_Framework/Applications/app_test/test_webserver/index.html b/APP_Framework/Applications/app_test/test_webserver/index.html
new file mode 100644
index 000000000..d0514189a
--- /dev/null
+++ b/APP_Framework/Applications/app_test/test_webserver/index.html
@@ -0,0 +1,33 @@
+
+
+
+
+ 表单
+
+
+
+
+
+
+
+
diff --git a/APP_Framework/Applications/app_test/test_webserver/photos/1.png b/APP_Framework/Applications/app_test/test_webserver/photos/1.png
new file mode 100644
index 000000000..2c3980afd
Binary files /dev/null and b/APP_Framework/Applications/app_test/test_webserver/photos/1.png differ
diff --git a/APP_Framework/Applications/app_test/test_webserver/photos/2.png b/APP_Framework/Applications/app_test/test_webserver/photos/2.png
new file mode 100644
index 000000000..e2fc46ebd
Binary files /dev/null and b/APP_Framework/Applications/app_test/test_webserver/photos/2.png differ
diff --git a/APP_Framework/Applications/app_test/test_webserver/photos/3.png b/APP_Framework/Applications/app_test/test_webserver/photos/3.png
new file mode 100644
index 000000000..0db94c2f8
Binary files /dev/null and b/APP_Framework/Applications/app_test/test_webserver/photos/3.png differ
diff --git a/APP_Framework/Applications/app_test/test_webserver/photos/4.png b/APP_Framework/Applications/app_test/test_webserver/photos/4.png
new file mode 100644
index 000000000..7f337458a
Binary files /dev/null and b/APP_Framework/Applications/app_test/test_webserver/photos/4.png differ
diff --git a/APP_Framework/Applications/app_test/test_webserver/photos/5.png b/APP_Framework/Applications/app_test/test_webserver/photos/5.png
new file mode 100644
index 000000000..85ab2f41e
Binary files /dev/null and b/APP_Framework/Applications/app_test/test_webserver/photos/5.png differ
diff --git a/APP_Framework/Applications/app_test/test_webserver/photos/6.png b/APP_Framework/Applications/app_test/test_webserver/photos/6.png
new file mode 100644
index 000000000..37b6e162f
Binary files /dev/null and b/APP_Framework/Applications/app_test/test_webserver/photos/6.png differ
diff --git a/APP_Framework/Applications/app_test/test_webserver/test_webserver.c b/APP_Framework/Applications/app_test/test_webserver/test_webserver.c
new file mode 100644
index 000000000..a5f15f2c1
--- /dev/null
+++ b/APP_Framework/Applications/app_test/test_webserver/test_webserver.c
@@ -0,0 +1,218 @@
+/**
+* @file: test_webserver.c
+* @brief: a application of test webserver function
+* @version: 1.0
+* @author: Yao wenying
+* @date: 2023/08/20
+*/
+
+
+#include
+#include "test_webserver.h"
+
+/**设置ip,网关,子网掩码这部分参考lwip_config_demo.c*/
+void LwipShowIP()
+{
+ // find default netdev
+ lw_notice("\r\n************************************************\r\n");
+ lw_notice(" Network Configuration\r\n");
+ lw_notice("************************************************\r\n");
+ lw_notice(" ETH0 IPv4 Address : %u.%u.%u.%u\r\n", ((u8_t*)&lwip_eth0_ipaddr)[0], ((u8_t*)&lwip_eth0_ipaddr)[1],
+ ((u8_t*)&lwip_eth0_ipaddr)[2], ((u8_t*)&lwip_eth0_ipaddr)[3]);
+ lw_notice(" ETH0 IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t*)&lwip_eth0_netmask)[0], ((u8_t*)&lwip_eth0_netmask)[1],
+ ((u8_t*)&lwip_eth0_netmask)[2], ((u8_t*)&lwip_eth0_netmask)[3]);
+ lw_notice(" ETH0 IPv4 Gateway : %u.%u.%u.%u\r\n", ((u8_t*)&lwip_gwaddr)[0], ((u8_t*)&lwip_eth0_gwaddr)[1],
+ ((u8_t*)&lwip_eth0_gwaddr)[2], ((u8_t*)&lwip_eth0_gwaddr)[3]);
+ lw_notice("************************************************\r\n");
+}
+
+uint8_t enet_idd = 0;
+void LwipSetIP(int argc, char *argv[])
+{
+ if(argc >= 4)
+ {
+ printf("lw: [%s] ip %s mask %s gw %s netport %s\n", __func__, argv[1], argv[2], argv[3], argv[4]);
+ sscanf(argv[1], "%d.%d.%d.%d", &lwip_ipaddr[0], &lwip_ipaddr[1], &lwip_ipaddr[2], &lwip_ipaddr[3]);
+ sscanf(argv[2], "%d.%d.%d.%d", &lwip_netmask[0], &lwip_netmask[1], &lwip_netmask[2], &lwip_netmask[3]);
+ sscanf(argv[3], "%d.%d.%d.%d", &lwip_gwaddr[0], &lwip_gwaddr[1], &lwip_gwaddr[2], &lwip_gwaddr[3]);
+ sscanf(argv[4], "%d", &enet_idd);
+
+ if(0 == enet_idd)
+ {
+ printf("save eth0 info\n");
+ memcpy(lwip_eth0_ipaddr, lwip_ipaddr, 20);
+ memcpy(lwip_eth0_netmask, lwip_netmask, 20);
+ memcpy(lwip_eth0_gwaddr, lwip_gwaddr, 20);
+ }
+ else if(1 == enet_idd)
+ {
+ printf("save eth1 info\n");
+ memcpy(lwip_eth1_ipaddr, lwip_ipaddr, 20);
+ memcpy(lwip_eth1_netmask, lwip_netmask, 20);
+ memcpy(lwip_eth1_gwaddr, lwip_gwaddr, 20);
+ }
+ }
+ else if(argc == 2)
+ {
+ printf("lw: [%s] set eth0 ipaddr %s \n", __func__, argv[1]);
+ sscanf(argv[1], "%d.%d.%d.%d", &lwip_ipaddr[0], &lwip_ipaddr[1], &lwip_ipaddr[2], &lwip_ipaddr[3]);
+ memcpy(lwip_eth0_ipaddr, lwip_ipaddr, strlen(lwip_ipaddr));
+ }
+ // sys_thread_new("SET ip address", LwipSetIPTask, &enet_id, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
+ printf("lw: [%s] config netport id[%d]\n", __func__, enet_idd);
+ lwip_config_net(enet_idd, lwip_ipaddr, lwip_netmask, lwip_gwaddr);
+}
+
+void ShowDns(){
+ const ip_addr_t *dns = dns_getserver(0);
+ char *dns_ip = ipaddr_ntoa(dns);
+ printf("lw: eth0 dns is %s \n", dns_ip);
+}
+
+void SetDns(char* ip){
+ ip_addr_t dns;
+ ipaddr_aton(ip, &dns);
+ dns_setserver(0, &dns);
+ printf("ETH0 Set DNS Success!\n");
+}
+
+void AddrUpdate()
+{
+ char *argv[5];
+ argv[1] = ServerNet.local_ip;
+ argv[2] = ServerNet.local_mask;
+ argv[3] = ServerNet.local_gw ;
+ argv[4] = 0;
+ LwipSetIP(4, argv);
+ LwipShowIP();
+ SetDns(ServerNet.local_dns);
+ ShowDns();
+}
+
+char *substring(char *dst,char *src,int start,int len)
+{
+ char *p=dst;
+ char *q=src;
+ int length=strlen(src);
+ if(start>=length||start<0)
+ return NULL;
+ if(len>length)
+ len=length-start;
+ q+=start;
+ while(len--)
+ {
+ *(p++)=*(q++);
+ }
+ *(p++)='\0';
+ return dst;
+}
+
+void SubstractServerNet(char * params){
+ char *p =params;
+ p +=3;
+ char *end = strchr(p, '&');
+ int len = (int)(end-p);
+ substring(ServerNet.local_ip, p, 0,len);
+ p +=len;
+ p += 9;
+ end = strchr(p, '&');
+ len = (int)(end-p);
+ substring(ServerNet.local_mask , p, 0, len);
+ p +=len;
+ p +=9;
+ end = strchr(p, '&');
+ len = (int)(end-p);
+ substring(ServerNet.local_gw, p, 0, len);
+ p +=len;
+ p += 5;
+ strcpy(ServerNet.local_dns, p);
+}
+
+
+void HandleHttpRequest(char *params){
+ SubstractServerNet(params);
+ AddrUpdate(); //修改本机参数信息;
+}
+
+//设置socket
+//循环监听socket并修改网络信息,单线程
+void tcpecho_thread(){
+ int sock=-1, connected;
+ char *recv_data;
+ struct sockaddr_in server_addr, client_addr;
+ socklen_t sin_size;
+ int recv_data_len;
+
+ recv_data = (char *) malloc(RECV_DATA);
+
+ if(recv_data == NULL){
+ printf("No memory");
+ goto __exit;
+ }
+
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ if(sock < 0){
+ printf("Socket error\n");
+ goto __exit;
+ }
+ server_addr.sin_family = AF_INET;
+ server_addr.sin_addr.s_addr = INADDR_ANY;
+ server_addr.sin_port = htons(PORT);
+ memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
+
+ if(bind(sock,(struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == 1){
+ printf("Unable to bind\n");
+ goto __exit;
+ }
+ if (listen(sock, 5) == -1)
+ {
+ printf("Listen error\n");
+ goto __exit;
+ }
+
+ 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 */
+ }
+
+
+ recv_data_len = recv(connected, recv_data, RECV_DATA, 0);
+
+ printf("recv %d len data\n",recv_data_len);
+ recv_data[recv_data_len] = '\0';
+ printf("%s\n", recv_data);
+
+ char * params = strstr(recv_data, "ip=");
+ HandleHttpRequest(params);
+
+ char *response = "HTTP/1.1 200 OK\r\n"
+ "Content-Type: application/x-www-form-urlencoded\r\n"
+ "\r\n";
+ write(connected,response,strlen(response));
+ if (connected >= 0)
+ closesocket(connected);
+
+ connected = -1;
+ }
+ __exit:
+ if (sock >= 0) closesocket(sock);
+ if (recv_data) free(recv_data);
+}
+
+void TestWebserver(){
+ tcpecho_thread();
+}
+
+PRIV_SHELL_CMD_FUNCTION(TestWebserver, Implement web_server, PRIV_SHELL_CMD_MAIN_ATTR);
\ No newline at end of file
diff --git a/APP_Framework/Applications/app_test/test_webserver/test_webserver.h b/APP_Framework/Applications/app_test/test_webserver/test_webserver.h
new file mode 100644
index 000000000..105ff13c7
--- /dev/null
+++ b/APP_Framework/Applications/app_test/test_webserver/test_webserver.h
@@ -0,0 +1,43 @@
+/**
+* @file: test_webserver.h
+* @brief: a application of test webserver function
+* @version: 1.0
+* @author: Yao wenying
+* @date: 2023/08/20
+*/
+
+
+#ifndef __WEBSERVER_H__
+#define __WEBSERVER_H__
+
+#include "lwip/opt.h"
+#include
+#include "lwip/api.h"
+#include "lwip/sys.h"
+#include "netif/ethernet.h"
+#include "lwip/tcpip.h"
+#include "sys_arch.h"
+#include
+#include "dns.h"
+#include "string.h"
+
+
+#define PORT 80
+#define RECV_DATA 1024
+struct ServerNet
+{
+ char local_ip[20];
+ char local_mask[20];
+ char local_gw[20];
+ char local_dns[20];
+}ServerNet;
+
+void LwipShowIP();
+void LwipSetIP(int argc, char *argv[]);
+void ShowDns();
+void SetDns();
+void AddrUpdate(); //更新本机网络参数信息
+void HandleHttpRequest(); //解析报文,并返回响应
+void TcpThread();//建立socket监听,循环等待网络通信事件到来
+
+#endif
\ No newline at end of file