TFT启动报错

TFT启动报错

问题

执行命令service tftpd-hpa restart提示

root@localhost:~# service tftpd-hpa restart
Job for tftpd-hpa.service failed because the control process exited with error code.
See "systemctl status tftpd-hpa.service" and "journalctl -xe" for details.

排查

按照提示,执行journalctl -xe命令查看错误信息

root@localhost:~# journalctl -xe
--
-- A start job for unit tftpd-hpa.service has begun execution.
--
-- The job identifier is 1694.
May 05 15:14:08 localhost tftpd-hpa[3007]:  * Starting HPA's tftpd in.tftpd
May 05 15:14:08 localhost in.tftpd[3014]: cannot open IPv6 socket, disable IPv6: Address family not supported by protoc>
May 05 15:14:08 localhost in.tftpd[3014]: Cannot set nonblock flag on socket: Bad file descriptor
May 05 15:14:08 localhost systemd[1]: tftpd-hpa.service: Control process exited, code=exited, status=71/OSERR
-- Subject: Unit process exited
-- Defined-By: systemd
-- Support: http://www.ubuntu.com/support
--
-- An ExecStart= process belonging to unit tftpd-hpa.service has exited.
--
-- The process' exit code is 'exited' and its exit status is 71.
May 05 15:14:08 localhost systemd[1]: tftpd-hpa.service: Failed with result 'exit-code'.
-- Subject: Unit failed
-- Defined-By: systemd
-- Support: http://www.ubuntu.com/support
--
-- The unit tftpd-hpa.service has entered the 'failed' state with result 'exit-code'.
May 05 15:14:08 localhost systemd[1]: Failed to start LSB: HPA's tftp server.
-- Subject: A start job for unit tftpd-hpa.service has failed
-- Defined-By: systemd
-- Support: http://www.ubuntu.com/support

其中
在这里插入图片描述
这两行提示cannot open IPv6 socket, disable IPv6: Address family not supported by protoc
笔者之前确实禁用了WSL的ipv6服务

解决

找到原因了,那么指定tftp不使用ipv6服务

  1. 使用vim /etc/default/tftpd-hpa命令打开tftp的默认配置文件
  2. TFTP_OPTIONS参数中添加-4
    # /etc/default/tftpd-hpa
    
    TFTP_USERNAME="tftp"
    TFTP_DIRECTORY="/home/imx6ull/tftp_dir"
    TFTP_ADDRESS=":69"
    TFTP_OPTIONS="-4 -l -c -s"
    
  3. 使用service tftpd-hpa restart命令重新启动tftp
这是我所有代码,怎么播放不了视频,还报错/******************** ESP32-C3 NV3007 TFT视频播放器 ********************/ #include <WiFi.h> #include <WebServer.h> // 请先使用转换脚本生成video_data.h,然后取消注释下面这行 #include "142x428.h" // 如果没有video_data.h,使用这些默认值(用于测试) //#define VIDEO_FRAMES 10 //#define VIDEO_WIDTH 142 //#define VIDEO_HEIGHT 428 // ESP32-C3引脚定义 #define TFT_SCK_PIN 2 #define TFT_SDA_PIN 3 #define TFT_RST_PIN 10 #define TFT_DC_PIN 6 #define TFT_CS_PIN 7 #define TFT_BL_PIN 11 // 引脚控制宏 #define TFT_SCK_0 digitalWrite(TFT_SCK_PIN, LOW) #define TFT_SCK_1 digitalWrite(TFT_SCK_PIN, HIGH) #define TFT_SDA_0 digitalWrite(TFT_SDA_PIN, LOW) #define TFT_SDA_1 digitalWrite(TFT_SDA_PIN, HIGH) #define TFT_RST_0 digitalWrite(TFT_RST_PIN, LOW) #define TFT_RST_1 digitalWrite(TFT_RST_PIN, HIGH) #define TFT_DC_0 digitalWrite(TFT_DC_PIN, LOW) #define TFT_DC_1 digitalWrite(TFT_DC_PIN, HIGH) #define TFT_CS_0 digitalWrite(TFT_CS_PIN, LOW) #define TFT_CS_1 digitalWrite(TFT_CS_PIN, HIGH) #define TFT_BL_0 digitalWrite(TFT_BL_PIN, LOW) #define TFT_BL_1 digitalWrite(TFT_BL_PIN, HIGH) // WiFi配置 const char* ssid = "ESP32-TFT-Video"; const char* password = "12345678"; WebServer server(80); // 颜色定义 #define RED 0XF800 #define GREEN 0X07E0 #define BLUE 0X001F #define WHITE 0XFFFF #define BLACK 0X0000 #define YELLOW 0xFFE0 #define CYAN 0x07FF #define MAGENTA 0xF81F // 视频播放状态 bool isPlayingVideo = false; int currentVideoFrame = 0; unsigned long lastFrameTime = 0; int frameDelay = 100; // 毫秒 bool loopPlayback = true; // 简化版视频帧数据(用于测试) const uint16_t testFrames[VIDEO_FRAMES][VIDEO_WIDTH * VIDEO_HEIGHT] = {0}; // 空数据,仅用于编译测试 void IO_init(void) { pinMode(TFT_SCK_PIN, OUTPUT); pinMode(TFT_SDA_PIN, OUTPUT); pinMode(TFT_RST_PIN, OUTPUT); pinMode(TFT_DC_PIN, OUTPUT); pinMode(TFT_CS_PIN, OUTPUT); pinMode(TFT_BL_PIN, OUTPUT); } void SPI_SendByte(unsigned char byte) { unsigned char counter; for(counter = 0; counter < 8; counter++) { TFT_SCK_0; if((byte & 0x80) == 0) { TFT_SDA_0; } else { TFT_SDA_1; } byte = byte << 1; TFT_SCK_1; } TFT_SCK_0; } void TFT_SEND_CMD(unsigned char o_command) { TFT_CS_0; TFT_DC_0; SPI_SendByte(o_command); TFT_CS_1; } void TFT_SEND_DATA(unsigned char o_data) { TFT_CS_0; TFT_DC_1; SPI_SendByte(o_data); TFT_CS_1; } void TFT_SET_ADD(unsigned short int X, unsigned short int Y, unsigned short int X_END, unsigned short int Y_END) { X += 12; // 偏移量 X_END += 12; TFT_SEND_CMD(0x2A); // 列地址设置 TFT_SEND_DATA(X >> 8); TFT_SEND_DATA(X); TFT_SEND_DATA(X_END >> 8); TFT_SEND_DATA(X_END); TFT_SEND_CMD(0x2B); // 行地址设置 TFT_SEND_DATA(Y >> 8); TFT_SEND_DATA(Y); TFT_SEND_DATA(Y_END >> 8); TFT_SEND_DATA(Y_END); TFT_SEND_CMD(0x2C); // 开始写入数据 } // 清屏函数 void TFT_Clear(unsigned short int color) { TFT_SET_ADD(0, 0, VIDEO_WIDTH - 1, VIDEO_HEIGHT - 1); for(int i = 0; i < VIDEO_WIDTH * VIDEO_HEIGHT; i++) { TFT_SEND_DATA(color >> 8); TFT_SEND_DATA(color & 0xFF); } } // 绘制矩形函数 void TFT_DrawRect(unsigned short x, unsigned short y, unsigned short w, unsigned short h, unsigned short color) { TFT_SET_ADD(x, y, x + w - 1, y + h - 1); for(int i = 0; i < w * h; i++) { TFT_SEND_DATA(color >> 8); TFT_SEND_DATA(color & 0xFF); } } // 显示一帧视频 void displayVideoFrame(int frameIndex) { if (frameIndex < 0 || frameIndex >= VIDEO_FRAMES) return; TFT_SET_ADD(0, 0, VIDEO_WIDTH - 1, VIDEO_HEIGHT - 1); // 这里使用测试数据,实际使用时应该从video_data.h读取 for(int i = 0; i < VIDEO_WIDTH * VIDEO_HEIGHT; i++) { uint16_t pixel = testFrames[frameIndex][i]; // 测试数据,实际应该用真实数据 TFT_SEND_DATA(pixel >> 8); TFT_SEND_DATA(pixel & 0xFF); } } void displayVideoFrame(int frameIndex) { if (frameIndex < 0 || frameIndex >= VIDEO_FRAMES) return; TFT_SET_ADD(0, 0, VIDEO_WIDTH - 1, VIDEO_HEIGHT - 1); // 使用真实视频数据(取消注释下面这行) // const uint16_t* frameData = video_frames[frameIndex]; for(int i = 0; i < VIDEO_WIDTH * VIDEO_HEIGHT; i++) { uint16_t pixel = frameData[i]; // 使用真实数据 TFT_SEND_DATA(pixel >> 8); TFT_SEND_DATA(pixel & 0xFF); } } // 视频播放函数 void playVideo() { if (!isPlayingVideo) return; unsigned long currentTime = millis(); if (currentTime - lastFrameTime >= frameDelay) { displayVideoFrame(currentVideoFrame); currentVideoFrame++; if (currentVideoFrame >= VIDEO_FRAMES) { if (loopPlayback) { currentVideoFrame = 0; } else { isPlayingVideo = false; currentVideoFrame = 0; } } lastFrameTime = currentTime; } } // 完整的TFT初始化序列 void TFT_Init(void) { Serial.println("开始TFT初始化..."); TFT_RST_0; delay(100); TFT_RST_1; delay(120); Serial.println("发送完整初始化序列..."); TFT_SEND_CMD(0xff); TFT_SEND_DATA(0xa5); TFT_SEND_CMD(0x9a); TFT_SEND_DATA(0x08); TFT_SEND_CMD(0x9b); TFT_SEND_DATA(0x08); TFT_SEND_CMD(0x9c); TFT_SEND_DATA(0xb0); TFT_SEND_CMD(0x9d); TFT_SEND_DATA(0x16); TFT_SEND_CMD(0x9e); TFT_SEND_DATA(0xc4); TFT_SEND_CMD(0x8f); TFT_SEND_DATA(0x55); TFT_SEND_DATA(0x04); TFT_SEND_CMD(0x84); TFT_SEND_DATA(0x90); TFT_SEND_CMD(0x83); TFT_SEND_DATA(0x7b); TFT_SEND_CMD(0x85); TFT_SEND_DATA(0x33); TFT_SEND_CMD(0x60); TFT_SEND_DATA(0x00); TFT_SEND_CMD(0x70); TFT_SEND_DATA(0x00); TFT_SEND_CMD(0x61); TFT_SEND_DATA(0x02); TFT_SEND_CMD(0x71); TFT_SEND_DATA(0x02); TFT_SEND_CMD(0x62); TFT_SEND_DATA(0x04); TFT_SEND_CMD(0x72); TFT_SEND_DATA(0x04); TFT_SEND_CMD(0x6c); TFT_SEND_DATA(0x29); TFT_SEND_CMD(0x7c); TFT_SEND_DATA(0x29); TFT_SEND_CMD(0x6d); TFT_SEND_DATA(0x31); TFT_SEND_CMD(0x7d); TFT_SEND_DATA(0x31); TFT_SEND_CMD(0x6e); TFT_SEND_DATA(0x0f); TFT_SEND_CMD(0x7e); TFT_SEND_DATA(0x0f); TFT_SEND_CMD(0x66); TFT_SEND_DATA(0x21); TFT_SEND_CMD(0x76); TFT_SEND_DATA(0x21); TFT_SEND_CMD(0x68); TFT_SEND_DATA(0x3A); TFT_SEND_CMD(0x78); TFT_SEND_DATA(0x3A); TFT_SEND_CMD(0x63); TFT_SEND_DATA(0x07); TFT_SEND_CMD(0x73); TFT_SEND_DATA(0x07); TFT_SEND_CMD(0x64); TFT_SEND_DATA(0x05); TFT_SEND_CMD(0x74); TFT_SEND_DATA(0x05); TFT_SEND_CMD(0x65); TFT_SEND_DATA(0x02); TFT_SEND_CMD(0x75); TFT_SEND_DATA(0x02); TFT_SEND_CMD(0x67); TFT_SEND_DATA(0x23); TFT_SEND_CMD(0x77); TFT_SEND_DATA(0x23); TFT_SEND_CMD(0x69); TFT_SEND_DATA(0x08); TFT_SEND_CMD(0x79); TFT_SEND_DATA(0x08); TFT_SEND_CMD(0x6a); TFT_SEND_DATA(0x13); TFT_SEND_CMD(0x7a); TFT_SEND_DATA(0x13); TFT_SEND_CMD(0x6b); TFT_SEND_DATA(0x13); TFT_SEND_CMD(0x7b); TFT_SEND_DATA(0x13); TFT_SEND_CMD(0x6f); TFT_SEND_DATA(0x00); TFT_SEND_CMD(0x7f); TFT_SEND_DATA(0x00); TFT_SEND_CMD(0x50); TFT_SEND_DATA(0x00); TFT_SEND_CMD(0x52); TFT_SEND_DATA(0xd6); TFT_SEND_CMD(0x53); TFT_SEND_DATA(0x08); TFT_SEND_CMD(0x54); TFT_SEND_DATA(0x08); TFT_SEND_CMD(0x55); TFT_SEND_DATA(0x1e); TFT_SEND_CMD(0x56); TFT_SEND_DATA(0x1c); //goa map_sel TFT_SEND_CMD(0xa0); TFT_SEND_DATA(0x2b); TFT_SEND_DATA(0x24); TFT_SEND_DATA(0x00); TFT_SEND_CMD(0xa1); TFT_SEND_DATA(0x87); TFT_SEND_CMD(0xa2); TFT_SEND_DATA(0x86); TFT_SEND_CMD(0xa5); TFT_SEND_DATA(0x00); TFT_SEND_CMD(0xa6); TFT_SEND_DATA(0x00); TFT_SEND_CMD(0xa7); TFT_SEND_DATA(0x00); TFT_SEND_CMD(0xa8); TFT_SEND_DATA(0x36); TFT_SEND_CMD(0xa9); TFT_SEND_DATA(0x7e); TFT_SEND_CMD(0xaa); TFT_SEND_DATA(0x7e); TFT_SEND_CMD(0xB9); TFT_SEND_DATA(0x85); TFT_SEND_CMD(0xBA); TFT_SEND_DATA(0x84); TFT_SEND_CMD(0xBB); TFT_SEND_DATA(0x83); TFT_SEND_CMD(0xBC); TFT_SEND_DATA(0x82); TFT_SEND_CMD(0xBD); TFT_SEND_DATA(0x81); TFT_SEND_CMD(0xBE); TFT_SEND_DATA(0x80); TFT_SEND_CMD(0xBF); TFT_SEND_DATA(0x01); TFT_SEND_CMD(0xC0); TFT_SEND_DATA(0x02); TFT_SEND_CMD(0xc1); TFT_SEND_DATA(0x00); TFT_SEND_CMD(0xc2); TFT_SEND_DATA(0x00); TFT_SEND_CMD(0xc3); TFT_SEND_DATA(0x00); TFT_SEND_CMD(0xc4); TFT_SEND_DATA(0x33); TFT_SEND_CMD(0xc5); TFT_SEND_DATA(0x7e); TFT_SEND_CMD(0xc6); TFT_SEND_DATA(0x7e); TFT_SEND_CMD(0xC8); TFT_SEND_DATA(0x33); TFT_SEND_DATA(0x33); TFT_SEND_CMD(0xC9); TFT_SEND_DATA(0x68); TFT_SEND_CMD(0xCA); TFT_SEND_DATA(0x69); TFT_SEND_CMD(0xCB); TFT_SEND_DATA(0x6a); TFT_SEND_CMD(0xCC); TFT_SEND_DATA(0x6b); TFT_SEND_CMD(0xCD); TFT_SEND_DATA(0x33); TFT_SEND_DATA(0x33); TFT_SEND_CMD(0xCE); TFT_SEND_DATA(0x6c); TFT_SEND_CMD(0xCF); TFT_SEND_DATA(0x6d); TFT_SEND_CMD(0xD0); TFT_SEND_DATA(0x6e); TFT_SEND_CMD(0xD1); TFT_SEND_DATA(0x6f); TFT_SEND_CMD(0xAB); TFT_SEND_DATA(0x03); TFT_SEND_DATA(0x67); TFT_SEND_CMD(0xAC); TFT_SEND_DATA(0x03); TFT_SEND_DATA(0x6b); TFT_SEND_CMD(0xAD); TFT_SEND_DATA(0x03); TFT_SEND_DATA(0x68); TFT_SEND_CMD(0xAE); TFT_SEND_DATA(0x03); TFT_SEND_DATA(0x6c); TFT_SEND_CMD(0xb3); TFT_SEND_DATA(0x00); TFT_SEND_CMD(0xb4); TFT_SEND_DATA(0x00); TFT_SEND_CMD(0xb5); TFT_SEND_DATA(0x00); TFT_SEND_CMD(0xB6); TFT_SEND_DATA(0x32); TFT_SEND_CMD(0xB7); TFT_SEND_DATA(0x7e); TFT_SEND_CMD(0xB8); TFT_SEND_DATA(0x7e); TFT_SEND_CMD(0xe0); TFT_SEND_DATA(0x00); TFT_SEND_CMD(0xe1); TFT_SEND_DATA(0x03); TFT_SEND_DATA(0x0f); TFT_SEND_CMD(0xe2); TFT_SEND_DATA(0x04); TFT_SEND_CMD(0xe3); TFT_SEND_DATA(0x01); TFT_SEND_CMD(0xe4); TFT_SEND_DATA(0x0e); TFT_SEND_CMD(0xe5); TFT_SEND_DATA(0x01); TFT_SEND_CMD(0xe6); TFT_SEND_DATA(0x19); TFT_SEND_CMD(0xe7); TFT_SEND_DATA(0x10); TFT_SEND_CMD(0xe8); TFT_SEND_DATA(0x10); TFT_SEND_CMD(0xea); TFT_SEND_DATA(0x12); TFT_SEND_CMD(0xeb); TFT_SEND_DATA(0xd0); TFT_SEND_CMD(0xec); TFT_SEND_DATA(0x04); TFT_SEND_CMD(0xed); TFT_SEND_DATA(0x07); TFT_SEND_CMD(0xee); TFT_SEND_DATA(0x07); TFT_SEND_CMD(0xef); TFT_SEND_DATA(0x09); TFT_SEND_CMD(0xf0); TFT_SEND_DATA(0xd0); TFT_SEND_CMD(0xf1); TFT_SEND_DATA(0x0e); TFT_SEND_DATA(0x17); TFT_SEND_CMD(0xf2); TFT_SEND_DATA(0x2c); TFT_SEND_DATA(0x1b); TFT_SEND_DATA(0x0b); TFT_SEND_DATA(0x20); //1 dot TFT_SEND_CMD(0xe9); TFT_SEND_DATA(0x29); TFT_SEND_CMD(0xec); TFT_SEND_DATA(0x04); //TE TFT_SEND_CMD(0x35); TFT_SEND_DATA(0x00); TFT_SEND_CMD(0x44); TFT_SEND_DATA(0x00); TFT_SEND_DATA(0x10); TFT_SEND_CMD(0x46); TFT_SEND_DATA(0x10); TFT_SEND_CMD(0xff); TFT_SEND_DATA(0x00); TFT_SEND_CMD(0x3a); TFT_SEND_DATA(0x05); TFT_SEND_CMD(0x11); delay(220); TFT_SEND_CMD(0x29); Serial.println("TFT初始化完成"); } // 网页界面 const char* MAIN_page = R"=====( <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>TFT视频播放器</title> <style> body { font-family: Arial, sans-serif; text-align: center; margin: 20px; background: #f5f5f5; } .container { background: white; padding: 20px; border-radius: 15px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); max-width: 500px; margin: 0 auto; } h1 { color: #333; margin-bottom: 20px; } .btn { padding: 12px 24px; margin: 8px; border: none; border-radius: 8px; cursor: pointer; font-size: 16px; font-weight: bold; transition: all 0.3s; min-width: 120px; } .btn:hover { transform: translateY(-2px); box-shadow: 0 6px 8px rgba(0,0,0,0.2); } .btn:active { transform: translateY(0); } .red { background: #ff4444; color: white; } .green { background: #44ff44; color: black; } .blue { background: #4444ff; color: white; } .black { background: #333333; color: white; } .control { background: #666666; color: white; } .status { margin: 20px 0; padding: 15px; background: #e8f4fd; border-radius: 8px; } </style> </head> <body> <div class="container"> <h1>🎬 TFT视频播放器</h1> <div class="status"> <p>当前模式: <span id="currentMode">停止</span></p> <p>帧数: <span id="frameInfo">0/0</span></p> <p>速度: <span id="speedInfo">100ms/帧</span></p> </div> <div> <h3>颜色测试</h3> <button class="btn red" onclick="setColor('red')">红色</button> <button class="btn green" onclick="setColor('green')">绿色</button> <button class="btn blue" onclick="setColor('blue')">蓝色</button> <button class="btn black" onclick="setColor('black')">黑色</button> </div> <div style="margin-top: 20px;"> <h3>视频控制</h3> <button class="btn control" onclick="controlVideo('play')">播放视频</button> <button class="btn control" onclick="controlVideo('stop')">停止</button> <button class="btn control" onclick="controlVideo('restart')">重新开始</button> </div> <div style="margin-top: 20px;"> <label>帧延迟: <input type="range" id="frameDelay" min="50" max="500" value="100" onchange="updateSpeed()"> <span id="delayValue">100ms</span> </label> </div> </div> <script> function setColor(color) { fetch('/color?c=' + color) .then(response => response.text()) .then(data => { document.getElementById('currentMode').textContent = '颜色: ' + color; alert('设置为: ' + color); }); } function controlVideo(action) { fetch('/control?action=' + action) .then(response => response.text()) .then(data => { if (action === 'play') { document.getElementById('currentMode').textContent = '视频播放中'; } else { document.getElementById('currentMode').textContent = '停止'; } alert('操作: ' + action); }); } function updateSpeed() { const delay = document.getElementById('frameDelay').value; document.getElementById('delayValue').textContent = delay + 'ms'; document.getElementById('speedInfo').textContent = delay + 'ms/帧'; fetch('/control?action=speed&value=' + delay); } // 初始化 fetch('/videoinfo') .then(response => response.json()) .then(data => { document.getElementById('frameInfo').textContent = '0/' + data.frames; }); </script> </body> </html> )====="; void setup() { Serial.begin(115200); delay(2000); Serial.println("=== ESP32-C3 TFT视频播放器 ==="); Serial.printf("视频设置: %d帧, %dx%d分辨率\n", VIDEO_FRAMES, VIDEO_WIDTH, VIDEO_HEIGHT); // 初始化硬件 IO_init(); TFT_BL_1; TFT_Init(); // 清屏 TFT_Clear(BLACK); // 设置WiFi WiFi.softAP(ssid, password); IPAddress myIP = WiFi.softAPIP(); Serial.print("AP IP地址: "); Serial.println(myIP); // 设置网页路由 server.on("/", HTTP_GET, []() { server.send(200, "text/html", MAIN_page); }); server.on("/color", HTTP_GET, []() { if (server.hasArg("c")) { String color = server.arg("c"); uint16_t colorValue = BLACK; if (color == "red") colorValue = RED; else if (color == "green") colorValue = GREEN; else if (color == "blue") colorValue = BLUE; else if (color == "black") colorValue = BLACK; TFT_Clear(colorValue); server.send(200, "text/plain", "颜色设置为: " + color); Serial.println("颜色设置为: " + color); } }); server.on("/control", HTTP_GET, []() { if (server.hasArg("action")) { String action = server.arg("action"); if (action == "play") { isPlayingVideo = true; server.send(200, "text/plain", "开始播放视频"); } else if (action == "stop") { isPlayingVideo = false; server.send(200, "text/plain", "停止播放"); } else if (action == "restart") { currentVideoFrame = 0; isPlayingVideo = true; server.send(200, "text/plain", "重新开始"); } else if (action == "speed" && server.hasArg("value")) { frameDelay = server.arg("value").toInt(); server.send(200, "text/plain", "速度设置: " + String(frameDelay)); } } }); server.on("/videoinfo", HTTP_GET, []() { String json = "{\"frames\": " + String(VIDEO_FRAMES) + ", \"width\": " + String(VIDEO_WIDTH) + ", \"height\": " + String(VIDEO_HEIGHT) + "}"; server.send(200, "application/json", json); }); server.begin(); Serial.println("HTTP服务器启动完成"); // 显示初始信息 TFT_Clear(BLACK); Serial.println("系统就绪"); } void loop() { server.handleClient(); // 播放视频 if (isPlayingVideo) { playVideo(); } delay(10); }
最新发布
09-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值