OPTY

简单实现ESP远程烧录固件

获取文件的直链之后通过代码可以远程烧录固件


 

import esptool
import serial.tools.list_ports
import time
import requests
import tempfile
import os

# 固件下载链接(请替换为实际的下载链接)
FIRMWARE_URLS = {
    'bootloader': 'http://ioos.opty.fun',  # 替换为实际的bootloader下载链接
    'partition': 'http://ioos.opty.fun',   # 替换为实际的partition-table下载链接
    'app': 'http://ioos.opty.fun/'          # 替换为实际的应用程序下载链接
}

def download_firmware(url):
    """从URL下载固件到内存"""
    try:
        response = requests.get(url, stream=True)
        response.raise_for_status()
        return response.content
    except Exception as e:
        print(f"下载固件失败: {str(e)}")
        return None

def find_esp32_port():
    """查找ESP32开发板的串口"""
    ports = list(serial.tools.list_ports.comports())
    for port in ports:
        if "CP210" in port.description or "CH343" or "CH340" in port.description:
            return port.device
    return None

def flash_esp32():
    """烧录ESP32程序"""
    # 查找ESP32串口
    port = find_esp32_port()
    if not port:
        print("未找到ESP32开发板,请检查连接")
        return False
    
    print(f"找到ESP32开发板,串口: {port}")
    
    # 下载所有固件
    print("加载远程固件...")
    bootloader_data = download_firmware(FIRMWARE_URLS['bootloader'])
    partition_data = download_firmware(FIRMWARE_URLS['partition'])
    app_data = download_firmware(FIRMWARE_URLS['app'])
    
    if not all([bootloader_data, partition_data, app_data]):
        print("固件下载失败")
        return False
    
    # 创建临时文件
    with tempfile.NamedTemporaryFile(delete=False, suffix='.bin') as bootloader_file, \
         tempfile.NamedTemporaryFile(delete=False, suffix='.bin') as partition_file, \
         tempfile.NamedTemporaryFile(delete=False, suffix='.bin') as app_file:
        
        # 写入固件数据
        bootloader_file.write(bootloader_data)
        partition_file.write(partition_data)
        app_file.write(app_data)
        
        # 关闭文件以确保数据写入
        bootloader_file.close()
        partition_file.close()
        app_file.close()
        
        try:
            print("开始烧录...")
            # 创建esptool命令
            command = [
                '--chip', 'esp32s3',
                '--port', port,
                '--baud', '921600',
                '--before', 'default_reset',
                '--after', 'hard_reset',
                'write_flash',
                '--flash_mode', 'dio',
                '--flash_freq', '80m',
                '--flash_size', '2MB',
                '0x0', bootloader_file.name,
                '0x8000', partition_file.name,
                '0x10000', app_file.name
            ]
            
            # 执行烧录
            esptool.main(command)
            print("烧录完成!")
            return True
        except Exception as e:
            print(f"烧录失败: {str(e)}")
            return False
        finally:
            # 清理临时文件
            try:
                os.unlink(bootloader_file.name)
                os.unlink(partition_file.name)
                os.unlink(app_file.name)
            except:
                pass

if __name__ == "__main__":
    print("ESP32远程烧录工具")
    print("=" * 50)
    
    if flash_esp32():
        print("\n程序烧录成功!")
    else:
        print("\n程序烧录失败,请检查错误信息")