Flash
约 2239 字大约 7 分钟
2026-03-19
构建固件和导入到JS
在 C++ 里加入以下代码, 然后重新编译构建固件:
// 为了控制固件的尺寸,BeShell 的 module 是按需引入的。
beshell.use<be::Flash>() ;在JS中导入 flash module:
import * as flash from 'flash'import flash模块函数
函数 allPartitions
原型: allPartitions ()
获取所有 Flash 分区的列表
返回一个对象,包含系统中所有的 Flash 分区信息。
示例:
import * as flash from "flash"
// 获取所有分区
const partitions = flash.allPartitions()
// 遍历所有分区
for (let label in partitions) {
let part = partitions[label]
console.log("Label:", part.label)
console.log("Type:", part.type)
console.log("Size:", part.size, "bytes")
console.log("Address:", part.address)
console.log("Readonly:", part.readonly)
}
// 获取特定分区
const fsPartition = partitions["fs"]
if (fsPartition) {
console.log("FS partition size:", fsPartition.size)
}异常:
- 无法找到分区
返回值:
类型object
说明包含所有分区的对象,key 为分区标签,value 为 Partition 对象
函数 partition
原型: partition (name:string)
根据名称获取指定的 Flash 分区,返回值是一个 Partition 类
通过分区标签名称获取特定的 Flash 分区对象。
示例:
import * as flash from "flash"
// 获取名为 "fs" 的分区(通常是文件系统分区)
const fsPart = flash.partition("fs")
console.log("FS partition:", fsPart.label)
console.log("Size:", fsPart.size)
// 获取应用程序分区
const appPart = flash.partition("app")
console.log("App partition type:", appPart.type)
// 读取分区数据
const data = fsPart.read(0, 1024)
console.log("Read", data.byteLength, "bytes")
// 写入数据(注意:只适用于可写分区)
fsPart.write(0, "Hello World")
// 计算校验和
const checksum = fsPart.checksum(1024, 0)
console.log("Checksum:", checksum)参数:
name
类型string
参数说明分区名称
异常:
- 分区不存在
返回值:
说明分区对象
Partition 类
属性 label (只读)
类型: string
获取分区标签名称
属性 type (只读)
类型: string
获取分区类型
分区类型,可能值为 "app"、"data"、"bootloader"、"partition_table" 或 "UNKNOWN"
属性 subtype (只读)
类型: number
获取分区子类型
属性 address (只读)
类型: number
获取分区起始地址
属性 size (只读)
类型: number
获取分区大小(字节)
属性 readonly (只读)
类型: bool
检查分区是否只读
属性 encrypted (只读)
类型: bool
检查分区是否加密
方法 erase
原型: erase (offset:number, length:number)
擦除分区指定范围的数据
擦除操作会将指定范围内的 Flash 存储单元设置为全 0xFF。 注意:擦除操作是必需的,在写入数据之前,必须先擦除对应区域。
示例:
import * as flash from "flash"
// 获取 fs 分区
const fs = flash.partition("fs")
// 擦除从偏移量 0 开始的 4096 字节(一个扇区)
fs.erase(0, 4096)
console.log("Sector erased")
// 擦除整个分区(谨慎操作!)
// fs.erase(0, fs.size)参数:
offset
类型number
参数说明起始偏移量
length
类型number
参数说明擦除长度
异常:
- 擦除失败
返回值:
类型undefined
方法 read
原型: read (offset:number, length:number)
从分区读取数据
从指定的偏移位置读取指定长度的数据,返回 ArrayBuffer 对象。
示例:
import * as flash from "flash"
// 获取 fs 分区
const fs = flash.partition("fs")
// 从偏移量 0 读取 1024 字节
const data = fs.read(0, 1024)
console.log("Read", data.byteLength, "bytes")
// 将 ArrayBuffer 转换为字符串
const decoder = new TextDecoder()
const str = decoder.decode(data)
console.log("Content:", str)
// 读取整个分区(注意内存限制,最大 1MB)
// const allData = fs.read(0, Math.min(fs.size, 1024 * 1024))参数:
offset
类型number
参数说明起始偏移量
length
类型number
参数说明读取长度
异常:
- 读取长度超过 1MB
- 超出分区范围
- 读取失败
- 内存分配失败
返回值:
类型ArrayBuffer
说明读取到的数据
方法 write
原型: write (offset:number, data:ArrayBuffer|string)
向分区写入数据
向指定的偏移位置写入数据。支持 ArrayBuffer 或字符串类型的数据。 注意:写入前必须先擦除对应区域!
示例:
import * as flash from "flash"
// 获取 fs 分区
const fs = flash.partition("fs")
// 先擦除要写入的区域
fs.erase(0, 4096)
// 写入字符串
fs.write(0, "Hello, World!")
console.log("String written")
// 写入 ArrayBuffer
const buffer = new ArrayBuffer(16)
const view = new Uint8Array(buffer)
view.set([0x01, 0x02, 0x03, 0x04])
fs.write(100, buffer)
console.log("Buffer written")
// 验证写入的数据
const readBack = fs.read(0, 13)
const decoder = new TextDecoder()
console.log("Read back:", decoder.decode(readBack))参数:
offset
类型number
参数说明起始偏移量
data
类型ArrayBuffer, string
参数说明要写入的数据
异常:
- 写入失败
- 数据类型无效
返回值:
类型undefined
方法 checksum
原型: checksum (length:number, offset:number=0)
计算分区指定范围的数据校验和(所有字节累加)
计算指定范围内所有字节的累加和,用于数据完整性验证。
使用示例
import * as flash from "flash"
// 获取 fs 分区
const fs = flash.partition("fs")
// 写入一些数据
fs.erase(0, 4096)
fs.write(0, "Test data")
// 计算前 1024 字节的校验和
const sum1 = fs.checksum(1024, 0)
console.log("Checksum:", sum1)
// 修改数据
fs.erase(0, 4096)
fs.write(0, "Modified data")
// 重新计算校验和
const sum2 = fs.checksum(1024, 0)
console.log("New checksum:", sum2)
// 校验和不同时说明数据已改变
if (sum1 !== sum2) {
console.log("Data has changed")
}
// 计算整个分区的校验和(注意内存和性能)
// const totalSum = fs.checksum(fs.size, 0)CheckSum 算法说明
校验和采用简单字节累加算法,具体步骤如下:
- 从指定的
offset偏移位置开始读取数据 - 逐个将每个字节的值(0-255)累加到一个 32 位无符号整数中
- 累加范围为
[offset, offset + length),共length个字节 - 返回最终的累加和(32 位无符号整数,范围 0 到 4294967295)
数学表达式:
checksum=i=offset∑offset+length−1data[i]
CheckSum JavaScript 等效实现
以下是等效的 JavaScript 实现代码,可用于在 PC 端计算固件文件的校验和:
//计算 ArrayBuffer 的校验和(与 Partition.checksum() 算法一致)
function calculateChecksum(buffer, length, offset = 0) {
const view = new Uint8Array(buffer, offset, length)
let checksum = 0
for (let i = 0; i < view.length; i++) {
checksum += view[i]
}
// 确保返回 32 位无符号整数
return checksum >>> 0
}
// 使用示例:计算文件校验和
// 在 Node.js 中:
const fs = require('fs')
const data = fs.readFileSync('firmware.bin')
const checksum = calculateChecksum(data.buffer, data.length)
console.log('Checksum: 0x' + checksum.toString(16).toUpperCase())
// 在浏览器中:
// const response = await fetch('firmware.bin')
// const buffer = await response.arrayBuffer()
// const checksum = calculateChecksum(buffer, buffer.byteLength)参数:
length
类型number
参数说明计算长度(字节数)
offset
类型number
默认值0
参数说明起始偏移量(字节)
异常:
- 超出分区范围
- 内存分配失败
- 读取失败
返回值:
类型number
说明32 位无符号整数校验和(范围 0 到 4294967295)
