【雕爷学编程】MicroPython手册之 esp8266 esp32 特定端口库 esp.flash_read()

在这里插入图片描述

MicroPython是为了在嵌入式系统中运行Python 3编程语言而设计的轻量级版本解释器。与常规Python相比,MicroPython解释器体积小(仅100KB左右),通过编译成二进制Executable文件运行,执行效率较高。它使用了轻量级的垃圾回收机制并移除了大部分Python标准库,以适应资源限制的微控制器。

MicroPython主要特点包括:
1、语法和功能与标准Python兼容,易学易用。支持Python大多数核心语法。
2、对硬件直接访问和控制,像Arduino一样控制GPIO、I2C、SPI等。
3、强大的模块系统,提供文件系统、网络、图形界面等功能。
4、支持交叉编译生成高效的原生代码,速度比解释器快10-100倍。
5、代码量少,内存占用小,适合运行在MCU和内存小的开发板上。
6、开源许可,免费使用。Shell交互环境为开发测试提供便利。
7、内置I/O驱动支持大量微控制器平台,如ESP8266、ESP32、STM32、micro:bit、掌控板和PyBoard等。有活跃的社区。

MicroPython的应用场景包括:
1、为嵌入式产品快速构建原型和用户交互。
2、制作一些小型的可 programmable 硬件项目。
3、作为教育工具,帮助初学者学习Python和物联网编程。
4、构建智能设备固件,实现高级控制和云连接。
5、各种微控制器应用如物联网、嵌入式智能、机器人等。

使用MicroPython需要注意:
1、内存和Flash空间有限。
2、解释执行效率不如C语言。
3、部分库函数与标准版有差异。
4、针对平台优化语法,订正与标准Python的差异。
5、合理使用内存资源,避免频繁分配大内存块。
6、利用原生代码提升速度关键部位的性能。
7、适当使用抽象来封装底层硬件操作。

总体来说,MicroPython让Python进入了微控制器领域,是一项重要的创新,既降低了编程门槛,又提供了良好的硬件控制能力。非常适合各类物联网和智能硬件的开发。
在这里插入图片描述

MicroPython的esp是指针对ESP8266和ESP32芯片的MicroPython固件和相关软件库。ESP8266和ESP32是一类广泛应用于物联网和嵌入式系统的低成本、低功耗的Wi-Fi和蓝牙模块。MicroPython的esp为这两种芯片提供了高级的脚本编程环境,使开发者能够使用Python语言进行快速原型设计和开发。

ESP8266:是一款低成本、低功耗的Wi-Fi模块/芯片,由Espressif Systems开发。它内置了TCP/IP协议栈,可以用于连接互联网,并具备较强的处理能力。MicroPython的esp提供了针对ESP8266的固件和相关软件库,使开发者可以使用MicroPython语言进行ESP8266应用的开发。

ESP32:是Espressif Systems推出的一款高度集成的Wi-Fi和蓝牙模块/芯片,与ESP8266相比,它具备更强大的处理能力、更多的外设接口和更多的内存。MicroPython的esp也提供了针对ESP32的固件和相关软件库,使开发者可以使用MicroPython语言进行ESP32应用的开发。

MicroPython的esp固件:是专门针对ESP8266和ESP32芯片的MicroPython固件版本。这些固件经过了针对性的优化,使得它们可以在ESP8266和ESP32上运行,并提供了与硬件交互、网络通信和外设控制等功能的API。

软件库:MicroPython的esp还提供了一系列与ESP8266和ESP32硬件相关的软件库,用于简化和加速开发过程。这些软件库提供了丰富的功能接口,涵盖了Wi-Fi、蓝牙、GPIO(通用输入输出)、I2C、SPI、PWM等常用的硬件和通信协议,使开发者可以方便地访问和控制硬件资源。
在这里插入图片描述
MicroPython 的 esp.flash_read() 是一个用于从 ESP8266 和 ESP32 芯片的闪存中读取数据的函数。闪存是一种非易失性的存储器,可以用来存储固件、文件系统和用户数据。

esp.flash_read() 的主要特点是:

它是一种简单而方便的闪存读取对象操作方式,可以用 esp.flash_read(byte_offset, buffer) 的形式来从闪存中读取数据,需要指定两个参数:byte_offset 和 buffer。
它是一种灵活而强大的闪存读取对象控制方式,可以通过传入不同的 byte_offset 和 buffer 参数来控制从闪存中读取数据的起始地址和长度,以及将数据放入的缓冲区对象。
它是一种兼容而可扩展的闪存读取对象接口方式,可以用其他模块或函数来访问或修改闪存读取对象的属性和方法,可以用 esp.flash_size() 方法来获取闪存总大小。

esp.flash_read() 的应用场景有:

用于从闪存中读取固件或文件系统的数据,如在使用 uos 模块或其他模块之前,使用 esp.flash_read() 来从闪存中读取固件或文件系统的元数据或内容,以便加载和解析。
用于从闪存中读取用户数据,如在使用 esp.flash_write() 或 esp.flash_erase() 方法之前,使用 esp.flash_read() 来从闪存中读取用户数据,并根据需要进行处理或备份。
用于从闪存中读取自定义的数据结构,如在使用自己设计和实现的文件系统或数据结构之前,使用 esp.flash_read() 来从闪存中读取自定义的数据结构,并根据自己的需求进行解析或操作。

esp.flash_read() 的需注意事项有:

在使用 esp.flash_read() 之前,需要确保 ESP8266 或 ESP32 开发板已经正确地连接到电源和电脑,并且已经安装了 MicroPython 的固件。
在使用 esp.flash_read() 时,需要注意 byte_offset 和 buffer 参数的合法性和有效性,避免造成地址越界或缓冲区溢出等错误。
在使用 esp.flash_read() 时,需要注意与其他模块或函数的协调和兼容问题,避免造成功能冲突或干扰。例如,如果使用 esp.flash_read() 方法,则不能同时使用 machine.deepsleep() 方法。

以下是几个使用 esp.flash_read() 的实际运用程序案例:

案例一:使用 esp.flash_read() 来从闪存中读取并打印固件版本号。代码如下:

import esp # 导入 esp 模块
import struct # 导入 struct 模块
offset = 0x1000 # 设置固件版本号在闪存中的偏移量
buffer = bytearray(4) # 创建一个字节数组对象,大小为 4 字节
esp.flash_read(offset, buffer) # 从闪存中读取 4 字节到缓冲区中
version = struct.unpack('I', buffer)[0] # 将缓冲区中的字节转换为无符号整数
print('Firmware version:', version) # 打印固件版本号

这个程序可以从闪存中读取并打印固件版本号。你可以用其他方法来处理或显示这个值。

案例二:使用 esp.flash_read() 来从闪存中读取并备份用户数据。代码如下:

import esp # 导入 esp 模块
user_start = esp.flash_user_start() # 获取用户可用的闪存起始地址
user_size = esp.flash_size() - user_start # 计算用户可用的闪存空间大小
buffer = bytearray(user_size) # 创建一个字节数组对象,大小为用户可用的闪存空间大小
esp.flash_read(user_start, buffer) # 从闪存中读取用户数据到缓冲区中
with open('backup.bin', 'wb') as f: # 打开一个文件对象,以二进制写入模式
    f.write(buffer) # 将缓冲区中的数据写入文件中
print('User data backup done') # 打印提示信息

这个程序可以从闪存中读取并备份用户数据。你可以用其他方法来修改或验证这个操作。

案例三:使用 esp.flash_read() 来从闪存中读取并解析一个简单的文件系统,可以在用户可用的闪存空间中存储和读取字符串。代码如下:

import esp # 导入 esp 模块
user_start = esp.flash_user_start() # 获取用户可用的闪存起始地址
user_size = esp.flash_size() - user_start # 计算用户可用的闪存空间大小
sector_size = 4096 # 设置每个扇区的大小
sector_count = user_size // sector_size # 计算可用的扇区数量
sector_map = bytearray(sector_count) # 创建一个字节数组对象,大小为可用的扇区数量

def read_file(name):
    # 定义一个函数来读取文件,参数为文件名,返回值为文件内容或 None(如果没有找到)
    name = name.encode('utf-8') # 将文件名转换为字节串
    name_len = len(name) # 获取文件名的长度
    for i in range(sector_count): # 循环遍历每个扇区
        if sector_map[i] == 1: # 如果该扇区为占用状态
            offset = user_start + i * sector_size # 计算起始地址偏移量
            buffer = esp.flash_read(offset, sector_size) # 从闪存中读取该扇区数据到缓冲区中
            if buffer[0] == name_len & 0xff and buffer[1] == (name_len >> 8) & 0xff and buffer[2:name_len + 2] == name: # 如果找到匹配的文件名
                content_len = buffer[name_len + 3] + (buffer[name_len + 4] << 8) # 获取文件内容的长度
                content = buffer[name_len + 5:name_len + content_len + 5] # 获取文件内容
                return content.decode('utf-8') # 将文件内容转换为字符串并返回
    return None # 如果没有找到匹配的文件名,返回 None

# 测试代码
for i in range(sector_count): # 循环遍历每个扇区
    offset = user_start + i * sector_size # 计算起始地址偏移量
    buffer = esp.flash_read(offset, sector_size) # 从闪存中读取该扇区数据到缓冲区中
    if buffer[0] != 0xff: # 如果该扇区不为空白
        sector_map[i] = 1 # 标记该扇区为占用状态

print(read_file('hello.txt')) # 读取并打印第一个文件的内容
print(read_file('test.txt')) # 读取并打印第二个文件的内容
print(read_file('foo.txt')) # 尝试读取一个不存在的文件的内容

这个程序可以从闪存中读取并解析一个简单的文件系统,可以在用户可用的闪存空间中存储和读取字符串。

案例四:读取整个flash内容:

import esp

flash_size = esp.flash_size()
data = esp.flash_read(0, flash_size)

案例五:读取指定地址内容:

import esp

address = 0x1000
length = 4
data = esp.flash_read(address, length)

案例六:验证flash写入:

import esp

address = 0x2000
esp.flash_write(address, b'123')
data = esp.flash_read(address, 3)
print(data)

第一个例子读取整个flash。第二个例子根据地址读取固定长度内容。第三个例子通过读取验证之前的flash写入。这个函数可以读取ESP模块flash中的内容。它在读写验证、内容备份恢复等场景中经常用到。以上几个例子演示了esp.flash_read()在不同情况下的简单应用。

案例七:读取Flash指定地址的数据

import esp

data = esp.flash_read(0x100000, 4096) 
print(data)

这个例子将读取Flash从0x100000地址开始的4096字节数据。

案例八:备份固件分区

import esp

firmware_addr = 0x0
backup_file = 'firmware.bin'
with open(backup_file, 'wb') as f:
  f.write(esp.flash_read(firmware_addr, firmware_size))  

这个例子可以从固件分区地址读出数据,备份到文件中。

案例九:验证固件校验和

import esp

checksum_addr = 0x100000
firmware_addr = 0x200000
checksum = esp.flash_read(checksum_addr, 32)
data = esp.flash_read(firmware_addr, firmware_size)
verify(data, checksum)

这个例子读取固件校验和和数据,然后可以验证固件是否完整正确。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_41659040/article/details/132908452