独立html文件,更新motor注释

This commit is contained in:
murmur 2024-12-15 14:07:02 +08:00
parent e2c1876f63
commit bf53ee1d0a
7 changed files with 283 additions and 121 deletions

View File

@ -72,7 +72,9 @@
"Drivers/CMSIS/Include", "Drivers/CMSIS/Include",
"Core/ioLibrary_Driver/Ethernet/W5500", "Core/ioLibrary_Driver/Ethernet/W5500",
"Core/ioLibrary_Driver/Ethernet", "Core/ioLibrary_Driver/Ethernet",
"Core/ioLibrary_Driver/Internet/DNS" "Core/ioLibrary_Driver/Internet/DNS",
"Core/motor",
"Core/Html"
], ],
"libList": [], "libList": [],
"defineList": [ "defineList": [
@ -88,18 +90,15 @@
"afterBuildTasks": [], "afterBuildTasks": [],
"global": { "global": {
"$float-abi-type": "softfp", "$float-abi-type": "softfp",
"output-debug-info": "enable", "output-debug-info": "enable"
"misc-control": []
}, },
"c/cpp-compiler": { "c/cpp-compiler": {
"language-c": "c11", "language-c": "gnu17",
"language-cpp": "c++11", "language-cpp": "c++11",
"optimization": "level-debug", "optimization": "level-debug",
"warnings": "all-warnings", "warnings": "all-warnings",
"one-elf-section-per-function": true, "one-elf-section-per-function": true,
"one-elf-section-per-data": true, "one-elf-section-per-data": true
"C_FLAGS": "",
"CXX_FLAGS": ""
}, },
"asm-compiler": { "asm-compiler": {
"ASM_FLAGS": "-DDEBUG" "ASM_FLAGS": "-DDEBUG"
@ -108,7 +107,7 @@
"output-format": "elf", "output-format": "elf",
"remove-unused-input-sections": true, "remove-unused-input-sections": true,
"LD_FLAGS": "-TSTM32F103VCTX_FLASH.ld", "LD_FLAGS": "-TSTM32F103VCTX_FLASH.ld",
"LIB_FLAGS": "" "$toolName": "auto"
} }
} }
} }

189
Core/Html/index.html Normal file
View File

@ -0,0 +1,189 @@
R"(<!DOCTYPE html>
<html><head>
<title>W5500 Configuration</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 20px auto;
padding: 20px;
background-color: #f5f5f5;
}
h2 {
color: #333;
text-align: center;
padding-bottom: 10px;
border-bottom: 2px solid #ddd;
font-size: clamp(1.5rem, 4vw, 2rem);
}
form {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
width: 100%;
max-width: 600px;
margin: 0 auto;
}
.form-group {
margin-bottom: 15px;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 10px;
}
label {
font-weight: bold;
color: #555;
min-width: 80px;
flex: 0 0 auto;
}
input[type='text'] {
flex: 1;
min-width: 200px;
max-width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
font-family: monospace;
box-sizing: border-box;
}
input[type='submit'] {
background-color: #4CAF50;
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
margin-top: 10px;
width: 100%;
max-width: 300px;
display: block;
margin: 20px auto 0;
}
input[type='submit']:hover {
background-color: #45a049;
}
.status {
margin-top: 20px;
padding: 10px;
border-radius: 4px;
text-align: center;
width: 100%;
max-width: 600px;
margin: 20px auto;
box-sizing: border-box;
}
.connected {
background-color: #dff0d8;
color: #3c763d;
border: 1px solid #d6e9c6;
}
.disconnected {
background-color: #f2dede;
color: #a94442;
border: 1px solid #ebccd1;
}
@media screen and (max-width: 600px) {
body {
padding: 10px;
margin: 10px;
}
form {
padding: 15px;
}
.form-group {
flex-direction: column;
align-items: stretch;
}
label {
margin-bottom: 5px;
}
input[type='text'] {
width: 100%;
}
}
@media screen and (max-width: 400px) {
h2 {
font-size: 1.2rem;
}
form {
padding: 10px;
}
input[type='submit'] {
padding: 8px 16px;
font-size: 14px;
}
}
.loading {
display: none;
text-align: center;
padding: 10px;
color: #666;
}
.loading.active {
display: block;
}
form.submitting input {
opacity: 0.7;
pointer-events: none;
}
input[type='submit'].loading {
background-color: #cccccc;
cursor: not-allowed;
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
const form = document.querySelector('form');
const submitBtn = form.querySelector('input[type="submit"]');
form.addEventListener('submit', function(e) {
submitBtn.value = 'Saving...';
submitBtn.classList.add('loading');
form.classList.add('submitting');
setTimeout(function() {
if(submitBtn.classList.contains('loading')) {
submitBtn.value = 'Save Configuration';
submitBtn.classList.remove('loading');
form.classList.remove('submitting');
alert('Request timeout. Please try again.');
}
}, 5000);
});
});
</script>
</head><body>
<h2>W5500 Network Configuration</h2>
<form method='post' action='/config'>
<div class='form-group'>
<label>MAC:</label>
<input type='text' name='mac' value='%02X:%02X:%02X:%02X:%02X:%02X'>
</div>
<div class='form-group'>
<label>IP:</label>
<input type='text' name='ip' value='%d.%d.%d.%d'>
</div>
<div class='form-group'>
<label>Subnet:</label>
<input type='text' name='subnet' value='%d.%d.%d.%d'>
</div>
<div class='form-group'>
<label>Gateway:</label>
<input type='text' name='gateway' value='%d.%d.%d.%d'>
</div>
<input type='submit' value='Save Configuration'>
</form>
<div class='status %s'>
Network Status: %s
</div>
</body></html>)"

15
Core/Inc/html_files.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef __HTML_FILES_H
#define __HTML_FILES_H
#ifdef __cplusplus
extern "C" {
#endif
// 声明HTML页面内容
extern const char index_html[];
#ifdef __cplusplus
}
#endif
#endif /* __HTML_FILES_H */

6
Core/Src/html_files.c Normal file
View File

@ -0,0 +1,6 @@
#include "html_files.h"
// 主页HTML内容
const char index_html[] =
#include "index.html"
;

View File

@ -1,100 +1,7 @@
#include "http_server.h" #include "http_server.h"
// HTML页面模板 // HTML页面模板
const char* html_page = "<!DOCTYPE html>" #include "html_files.h"
"<html><head>"
"<title>W5500 Configuration</title>"
"<style>"
" body {"
" font-family: Arial, sans-serif;"
" max-width: 800px;"
" margin: 20px auto;"
" padding: 20px;"
" background-color: #f5f5f5;"
" }"
" h2 {"
" color: #333;"
" text-align: center;"
" padding-bottom: 10px;"
" border-bottom: 2px solid #ddd;"
" }"
" form {"
" background: white;"
" padding: 20px;"
" border-radius: 8px;"
" box-shadow: 0 2px 4px rgba(0,0,0,0.1);"
" }"
" .form-group {"
" margin-bottom: 15px;"
" }"
" label {"
" display: inline-block;"
" width: 80px;"
" font-weight: bold;"
" color: #555;"
" }"
" input[type='text'] {"
" width: 200px;"
" padding: 8px;"
" border: 1px solid #ddd;"
" border-radius: 4px;"
" font-family: monospace;"
" }"
" input[type='submit'] {"
" background-color: #4CAF50;"
" color: white;"
" padding: 10px 20px;"
" border: none;"
" border-radius: 4px;"
" cursor: pointer;"
" font-size: 16px;"
" margin-top: 10px;"
" }"
" input[type='submit']:hover {"
" background-color: #45a049;"
" }"
" .status {"
" margin-top: 20px;"
" padding: 10px;"
" border-radius: 4px;"
" text-align: center;"
" }"
" .connected {"
" background-color: #dff0d8;"
" color: #3c763d;"
" border: 1px solid #d6e9c6;"
" }"
" .disconnected {"
" background-color: #f2dede;"
" color: #a94442;"
" border: 1px solid #ebccd1;"
" }"
"</style>"
"</head><body>"
"<h2>W5500 Network Configuration</h2>"
"<form method='post' action='/config'>"
" <div class='form-group'>"
" <label>MAC:</label>"
" <input type='text' name='mac' value='%02X:%02X:%02X:%02X:%02X:%02X'>"
" </div>"
" <div class='form-group'>"
" <label>IP:</label>"
" <input type='text' name='ip' value='%d.%d.%d.%d'>"
" </div>"
" <div class='form-group'>"
" <label>Subnet:</label>"
" <input type='text' name='subnet' value='%d.%d.%d.%d'>"
" </div>"
" <div class='form-group'>"
" <label>Gateway:</label>"
" <input type='text' name='gateway' value='%d.%d.%d.%d'>"
" </div>"
" <input type='submit' value='Save Configuration'>"
"</form>"
"<div class='status %s'>"
" Network Status: %s"
"</div>"
"</body></html>";
// 解析HTTP请求 // 解析HTTP请求
static void parse_http_request(uint8_t* buffer, uint16_t length, http_request* req) static void parse_http_request(uint8_t* buffer, uint16_t length, http_request* req)
@ -124,28 +31,57 @@ static void parse_http_request(uint8_t* buffer, uint16_t length, http_request* r
} }
// 发送HTTP响应 // 发送HTTP响应
static void send_response(uint8_t sn, const char* content, uint16_t length) static int send_all(uint8_t sn, const uint8_t* data, uint16_t length)
{ {
char header[128]; int total_sent = 0;
sprintf(header, while (total_sent < length) {
int sent = send(sn, data + total_sent, length - total_sent);
if (sent <= 0) {
return -1; // 发送错误
}
total_sent += sent;
}
return total_sent;
}
static void send_chunked_response_header(uint8_t sn)
{
const char* header =
"HTTP/1.1 200 OK\r\n" "HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n" "Content-Type: text/html\r\n"
"Content-Length: %d\r\n" "Transfer-Encoding: chunked\r\n"
"\r\n", length); "\r\n";
send(sn, (uint8_t*)header, strlen(header)); send_all(sn, (uint8_t*)header, strlen(header));
send(sn, (uint8_t*)content, length);
} }
static void send_chunk(uint8_t sn, const char* data, uint16_t length)
{
char chunk_header[10];
sprintf(chunk_header, "%X\r\n", length);
send_all(sn, (uint8_t*)chunk_header, strlen(chunk_header));
send_all(sn, (uint8_t*)data, length);
send_all(sn, (uint8_t*)"\r\n", 2);
}
static void send_chunk_end(uint8_t sn)
{
send_all(sn, (uint8_t*)"0\r\n\r\n", 5);
}
#define CHUNK_SIZE 512
// 处理配置页面请求 // 处理配置页面请求
static void handle_config_page(uint8_t sn) static void handle_config_page(uint8_t sn)
{ {
char page[4096]; // 增加缓冲区大小以适应新的HTML内容 char buffer[CHUNK_SIZE];
bool is_connected = (wizphy_getphylink() == PHY_LINK_ON); bool is_connected = (wizphy_getphylink() == PHY_LINK_ON);
char* link_status = is_connected ? "Connected" : "Disconnected"; char* link_status = is_connected ? "Connected" : "Disconnected";
char* status_class = is_connected ? "connected" : "disconnected"; char* status_class = is_connected ? "connected" : "disconnected";
sprintf(page, html_page, // 先将完整的HTML内容格式化到一个临时缓冲区
char full_page[8192]; // 确保足够大
int total_len = sprintf(full_page, index_html,
gWIZNETINFO.mac[0], gWIZNETINFO.mac[1], gWIZNETINFO.mac[2], gWIZNETINFO.mac[0], gWIZNETINFO.mac[1], gWIZNETINFO.mac[2],
gWIZNETINFO.mac[3], gWIZNETINFO.mac[4], gWIZNETINFO.mac[5], gWIZNETINFO.mac[3], gWIZNETINFO.mac[4], gWIZNETINFO.mac[5],
gWIZNETINFO.ip[0], gWIZNETINFO.ip[1], gWIZNETINFO.ip[2], gWIZNETINFO.ip[3], gWIZNETINFO.ip[0], gWIZNETINFO.ip[1], gWIZNETINFO.ip[2], gWIZNETINFO.ip[3],
@ -153,7 +89,20 @@ static void handle_config_page(uint8_t sn)
gWIZNETINFO.gw[0], gWIZNETINFO.gw[1], gWIZNETINFO.gw[2], gWIZNETINFO.gw[3], gWIZNETINFO.gw[0], gWIZNETINFO.gw[1], gWIZNETINFO.gw[2], gWIZNETINFO.gw[3],
status_class, link_status); status_class, link_status);
send_response(sn, page, strlen(page)); // 发送响应头
send_chunked_response_header(sn);
// 分块发送内容
int sent = 0;
while (sent < total_len) {
int chunk_len = (total_len - sent) > CHUNK_SIZE ? CHUNK_SIZE : (total_len - sent);
memcpy(buffer, full_page + sent, chunk_len);
send_chunk(sn, buffer, chunk_len);
sent += chunk_len;
}
// 发送结束块
send_chunk_end(sn);
} }
// 解析并更新网络配置 // 解析并更新网络配置
@ -225,9 +174,11 @@ void http_server_task(void)
else if(req.method == HTTP_POST && strcmp(req.uri, "/config") == 0) { else if(req.method == HTTP_POST && strcmp(req.uri, "/config") == 0) {
update_network_config((char*)req.body); update_network_config((char*)req.body);
// 重定向回配置页面 // 重定向回配置页面
send_response(HTTP_SERVER_SOCKET, send_chunked_response_header(HTTP_SERVER_SOCKET);
send_chunk(HTTP_SERVER_SOCKET,
"<html><head><meta http-equiv='refresh' content='0;url=/'></head></html>", "<html><head><meta http-equiv='refresh' content='0;url=/'></head></html>",
strlen("<html><head><meta http-equiv='refresh' content='0;url=/'></head></html>")); strlen("<html><head><meta http-equiv='refresh' content='0;url=/'></head></html>"));
send_chunk_end(HTTP_SERVER_SOCKET);
} }
} }
} }

View File

@ -26,7 +26,7 @@
/* Private includes ----------------------------------------------------------*/ /* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */ /* USER CODE BEGIN Includes */
#include "w5500_init.h" #include "w5500_init.h"
#include "http_test.h" // #include "http_test.h"
#include "http_server.h" #include "http_server.h"
/* USER CODE END Includes */ /* USER CODE END Includes */
@ -108,7 +108,8 @@ int main(void)
http_server_init(); http_server_init();
// 执行一次HTTP客户端测试 // 执行一次HTTP客户端测试
http_test_request(); // http_test_request();
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
/* USER CODE END 2 */ /* USER CODE END 2 */
/* Infinite loop */ /* Infinite loop */
@ -119,8 +120,8 @@ int main(void)
/* USER CODE BEGIN 3 */ /* USER CODE BEGIN 3 */
http_server_task(); http_server_task();
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); // HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
HAL_Delay(500); // HAL_Delay(100);
} }
/* USER CODE END 3 */ /* USER CODE END 3 */
} }

View File

@ -18,7 +18,8 @@
"*.c++": "cpp", "*.c++": "cpp",
"*.cpp": "cpp", "*.cpp": "cpp",
"*.cxx": "cpp", "*.cxx": "cpp",
"*.cc": "cpp" "*.cc": "cpp",
"*.html": "c"
}, },
"[yaml]": { "[yaml]": {
"editor.insertSpaces": true, "editor.insertSpaces": true,