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程序烧录失败,请检查错误信息")