UF2 is a file format, developed by Microsoft for PXT (also known as Microsoft MakeCode), that is particularly suitable for flashing microcontrollers over MSC (Mass Storage Class; aka removable flash drive).
The list of family IDs is stored in a separate JSON file:
https://github.com/microsoft/uf2/blob/master/utils/uf2families.json
This JSON file is regularly updated. The family_id enum should be kept in
sync with it. For simplicity and consistency, it's strongly recommended to
auto-generate this enum from uf2families.json directly. This was last done
using the following commands:
$ curl -fsSLO https://github.com/microsoft/uf2/raw/90e9741f217f5a40c98ba74d663e408041037578/utils/uf2families.json
$ jq -r '
.[]
| " \(.id | ascii_downcase):\n"
+ " id: \(.short_name | ascii_downcase | gsub("-"; "_"))\n"
+ " doc: \(.description | tojson)"
' uf2families.json
Test files, picked to cover as many different shapes as possible:
num_blocks.family_id::rp2xxx_absolute block that picotool prepends (see the
is_rp2350_e10_block value instance in the block type).file_size rather
than family_id.family_id::rp2040) is moved to the end of the second file, which was
intended for family_id::rp2xxx_absolute (see
https://github.com/raspberrypi/pico-examples/blob/c81c855ffdedc825975a40ba357723a71358ddf0/universal/CMakeLists.txt#L159-L169).flags.is_file_container flag set (for
example
https://github.com/microsoft/pxt-microsoft-boot-sequence/releases/download/v0.0.4/arcade-p0.uf2
is a pure file container for
file_name == "Projects/microsoft-boot-sequence.elf"). Generated by
MakeCode, the only known producer of file container UF2s.This page hosts a formal specification of UF2 (USB Flashing Format) using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.
All JavaScript code generated by Kaitai Struct depends on the Kaitai Struct runtime library for JavaScript. You must add this dependency to your project before you can parse or serialize any data.
The JavaScript runtime library is available at npm:
npm install kaitai-struct
See the usage examples in the JavaScript notes.
Parse structure from an ArrayBuffer:
var arrayBuffer = ...;
var data = new Uf2(new KaitaiStream(arrayBuffer));
After that, one can get various attributes from the structure by accessing fields or properties like:
data.firstBlock // => get first block
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(['exports', 'kaitai-struct/KaitaiStream'], factory);
} else if (typeof exports === 'object' && exports !== null && typeof exports.nodeType !== 'number') {
factory(exports, require('kaitai-struct/KaitaiStream'));
} else {
factory(root.Uf2 || (root.Uf2 = {}), root.KaitaiStream);
}
})(typeof self !== 'undefined' ? self : this, function (Uf2_, KaitaiStream) {
/**
* UF2 is a file format, developed by Microsoft for PXT (also known as
* Microsoft MakeCode), that is particularly suitable for flashing
* microcontrollers over MSC (Mass Storage Class; aka removable flash drive).
*
* The list of family IDs is stored in a separate JSON file:
*
* <https://github.com/microsoft/uf2/blob/master/utils/uf2families.json>
*
* This JSON file is regularly updated. The `family_id` enum should be kept in
* sync with it. For simplicity and consistency, it's strongly recommended to
* auto-generate this enum from `uf2families.json` directly. This was last done
* using the following commands:
*
* ```bash
* $ curl -fsSLO https://github.com/microsoft/uf2/raw/90e9741f217f5a40c98ba74d663e408041037578/utils/uf2families.json
* $ jq -r '
* .[]
* | " \(.id | ascii_downcase):\n"
* + " id: \(.short_name | ascii_downcase | gsub("-"; "_"))\n"
* + " doc: \(.description | tojson)"
* ' uf2families.json
* ```
*
* Test files, picked to cover as many different shapes as possible:
*
* * <https://micropython.org/download/RPI_PICO/> - a typical case: all blocks
* have the same family ID and `num_blocks`.
* * <https://micropython.org/download/RPI_PICO2/> - these .uf2 files are
* actually two UF2 files concatenated. The first UF2 file is the standalone
* `family_id::rp2xxx_absolute` block that `picotool` prepends (see the
* `is_rp2350_e10_block` value instance in the `block` type).
* * <https://circuitpython.org/downloads> - the builds for SAMD boards (for
* example
* [Feather M0 Express](https://circuitpython.org/board/feather_m0_express/))
* set no flags at all, so the field at offset 28 is read as `file_size` rather
* than `family_id`.
* * <https://github.com/raspberrypi/pico-sdk-prebuilts/releases> -
* [Universal UF2](https://github.com/raspberrypi/pico-examples/blob/c81c855ffdedc825975a40ba357723a71358ddf0/universal/README.md#universal-binary-vs-universal-uf2)
* files, which are again two UF2 files concatenated. What's interesting about
* these is that the last block of the first file (with the family ID
* `family_id::rp2040`) is moved to the end of the second file, which was
* intended for `family_id::rp2xxx_absolute` (see
* <https://github.com/raspberrypi/pico-examples/blob/c81c855ffdedc825975a40ba357723a71358ddf0/universal/CMakeLists.txt#L159-L169>).
* * <https://github.com/microsoft/pxt-microsoft-boot-sequence/releases> - some
* files contain blocks with the `flags.is_file_container` flag set (for
* example
* <https://github.com/microsoft/pxt-microsoft-boot-sequence/releases/download/v0.0.4/arcade-p0.uf2>
* is a pure file container for
* `file_name == "Projects/microsoft-boot-sequence.elf"`). Generated by
* MakeCode, the only known producer of file container UF2s.
* * <https://github.com/umi-eng/uftwo/tree/35bccf75b4f81c43f088696a8c4a9912f1f4104e/uftwo/tests> -
* synthetic test files for features that real firmware doesn't seem to use
* (e.g. MD5 checksums).
* @see {@link https://github.com/microsoft/uf2/blob/90e9741f217f5a40c98ba74d663e408041037578/README.md|Source}
*/
var Uf2 = (function() {
Uf2.ExtensionTagType = Object.freeze({
END: 0,
PAGE_SIZE: 780791,
DESCRIPTION: 6622621,
RP2_IGNORE_BLOCK: 10049507,
VERSION: 10471356,
SHA2_CHECKSUM: 11824560,
DEVICE_TYPE_ID: 13149993,
0: "END",
780791: "PAGE_SIZE",
6622621: "DESCRIPTION",
10049507: "RP2_IGNORE_BLOCK",
10471356: "VERSION",
11824560: "SHA2_CHECKSUM",
13149993: "DEVICE_TYPE_ID",
});
Uf2.FamilyId = Object.freeze({
STM32L4: 16738585,
STM32L5: 69471199,
STM32F411XC: 114362747,
M0SENSE: 299792458,
ATMEGA32: 374814231,
SAML21: 407992330,
NRF52: 458716255,
ESP32: 475996592,
STM32L1: 505365293,
STM32L0: 539900561,
STM32WL: 558239728,
RTL8710B: 585160444,
LPC55: 716994540,
ESP32C2: 730387100,
STM32F411XE: 767756741,
STM32G0: 806311475,
ESP32S31: 822212545,
GD32F350: 835856582,
ESP32H2: 858203894,
RTL8720D: 863621090,
ESP32P4: 1026592404,
MAIXPLAY_U4: 1265126769,
STM32G4: 1282483210,
STM32H5: 1318001757,
CSK4: 1332399698,
MIMXRT10XX: 1337120189,
XR809: 1374225320,
STM32F7: 1404571392,
ESP32C6: 1410195298,
SAMD51: 1427194976,
STM32F4: 1467308631,
FX2: 1511523995,
STM32F2: 1561987630,
STM32F1: 1591873650,
NRF52833: 1646171002,
STM32F0: 1685595318,
BK7231U: 1733968048,
SAMD21: 1760373640,
CH32V: 1771791084,
BK7251: 1786956866,
STM32F3: 1803837832,
STM32F407: 1829315322,
STM32H7: 1840668802,
CSK6: 1853049000,
NRF52832XXAB: 1869948536,
STM32WB: 1892771411,
NRF52832XXAA: 1920081230,
MAX32690: 1947226634,
ESP32C61: 2010665156,
BK7231N: 2067722800,
RA4M1: 2078840685,
PY32F071_UVK5_V3: 2105173743,
ESP8266: 2125160941,
KL32L2: 2139350931,
NRF52820: 2181929567,
STM32F407VG: 2410701054,
MAX78002: 2446589208,
RZA1LU: 2501329455,
GD32VF103: 2599435827,
ESP32H4: 2651564682,
RTL8710A: 2684343619,
AT32F415: 2697558926,
NRF52840: 2913282112,
ESP32H21: 3067936943,
ESP32S2: 3218951918,
ESP32S3: 3296614247,
ESP32C3: 3559628908,
MAX32650: 3594487346,
BL602: 3725750455,
RTL8720C: 3767498084,
RP2040: 3834380118,
RP2XXX_ABSOLUTE: 3834380119,
RP2XXX_DATA: 3834380120,
RP2350_ARM_S: 3834380121,
RP2350_RISCV: 3834380122,
RP2350_ARM_NS: 3834380123,
MAX32666: 4039314801,
ESP32C5: 4145808195,
16738585: "STM32L4",
69471199: "STM32L5",
114362747: "STM32F411XC",
299792458: "M0SENSE",
374814231: "ATMEGA32",
407992330: "SAML21",
458716255: "NRF52",
475996592: "ESP32",
505365293: "STM32L1",
539900561: "STM32L0",
558239728: "STM32WL",
585160444: "RTL8710B",
716994540: "LPC55",
730387100: "ESP32C2",
767756741: "STM32F411XE",
806311475: "STM32G0",
822212545: "ESP32S31",
835856582: "GD32F350",
858203894: "ESP32H2",
863621090: "RTL8720D",
1026592404: "ESP32P4",
1265126769: "MAIXPLAY_U4",
1282483210: "STM32G4",
1318001757: "STM32H5",
1332399698: "CSK4",
1337120189: "MIMXRT10XX",
1374225320: "XR809",
1404571392: "STM32F7",
1410195298: "ESP32C6",
1427194976: "SAMD51",
1467308631: "STM32F4",
1511523995: "FX2",
1561987630: "STM32F2",
1591873650: "STM32F1",
1646171002: "NRF52833",
1685595318: "STM32F0",
1733968048: "BK7231U",
1760373640: "SAMD21",
1771791084: "CH32V",
1786956866: "BK7251",
1803837832: "STM32F3",
1829315322: "STM32F407",
1840668802: "STM32H7",
1853049000: "CSK6",
1869948536: "NRF52832XXAB",
1892771411: "STM32WB",
1920081230: "NRF52832XXAA",
1947226634: "MAX32690",
2010665156: "ESP32C61",
2067722800: "BK7231N",
2078840685: "RA4M1",
2105173743: "PY32F071_UVK5_V3",
2125160941: "ESP8266",
2139350931: "KL32L2",
2181929567: "NRF52820",
2410701054: "STM32F407VG",
2446589208: "MAX78002",
2501329455: "RZA1LU",
2599435827: "GD32VF103",
2651564682: "ESP32H4",
2684343619: "RTL8710A",
2697558926: "AT32F415",
2913282112: "NRF52840",
3067936943: "ESP32H21",
3218951918: "ESP32S2",
3296614247: "ESP32S3",
3559628908: "ESP32C3",
3594487346: "MAX32650",
3725750455: "BL602",
3767498084: "RTL8720C",
3834380118: "RP2040",
3834380119: "RP2XXX_ABSOLUTE",
3834380120: "RP2XXX_DATA",
3834380121: "RP2350_ARM_S",
3834380122: "RP2350_RISCV",
3834380123: "RP2350_ARM_NS",
4039314801: "MAX32666",
4145808195: "ESP32C5",
});
function Uf2(_io, _parent, _root) {
this._io = _io;
this._parent = _parent;
this._root = _root || this;
this._read();
}
Uf2.prototype._read = function() {
this.firstBlock = new Block(this._io, this, this._root);
this.blocks = [];
for (var i = 0; i < this.firstBlock.numBlocks - 1; i++) {
this.blocks.push(new Block(this._io, this, this._root));
}
}
var Block = Uf2.Block = (function() {
function Block(_io, _parent, _root) {
this._io = _io;
this._parent = _parent;
this._root = _root;
this._read();
}
Block.prototype._read = function() {
this.magic = this._io.readBytes(4);
if (!((KaitaiStream.byteArrayCompare(this.magic, new Uint8Array([85, 70, 50, 10])) == 0))) {
throw new KaitaiStream.ValidationNotEqualError(new Uint8Array([85, 70, 50, 10]), this.magic, this._io, "/types/block/seq/0");
}
this.secondMagic = this._io.readBytes(4);
if (!((KaitaiStream.byteArrayCompare(this.secondMagic, new Uint8Array([87, 81, 93, 158])) == 0))) {
throw new KaitaiStream.ValidationNotEqualError(new Uint8Array([87, 81, 93, 158]), this.secondMagic, this._io, "/types/block/seq/1");
}
this.flags = new Flags(this._io, this, this._root);
this.targetAddress = this._io.readU4le();
var _ = this.targetAddress;
if (!(KaitaiStream.mod(_, 4) == 0)) {
throw new KaitaiStream.ValidationExprError(this.targetAddress, this._io, "/types/block/seq/3");
}
this.lenPayload = this._io.readU4le();
var _ = this.lenPayload;
if (!(KaitaiStream.mod(_, 4) == 0)) {
throw new KaitaiStream.ValidationExprError(this.lenPayload, this._io, "/types/block/seq/4");
}
this.blockNumber = this._io.readU4le();
this.numBlocksRaw = this._io.readU4le();
if (!(this.numBlocksRaw >= this.blockNumber + 1)) {
throw new KaitaiStream.ValidationLessThanError(this.blockNumber + 1, this.numBlocksRaw, this._io, "/types/block/seq/6");
}
if (!(this.flags.hasFamilyId)) {
this.fileSize = this._io.readU4le();
}
if (this.flags.hasFamilyId) {
this.familyId = this._io.readU4le();
}
this._raw_data = this._io.readBytes(476);
var _io__raw_data = new KaitaiStream(this._raw_data);
this.data = new BlockData(_io__raw_data, this, this._root);
this.finalMagic = this._io.readBytes(4);
if (!((KaitaiStream.byteArrayCompare(this.finalMagic, new Uint8Array([48, 111, 177, 10])) == 0))) {
throw new KaitaiStream.ValidationNotEqualError(new Uint8Array([48, 111, 177, 10]), this.finalMagic, this._io, "/types/block/seq/10");
}
}
/**
* Determines whether this is a block that `picotool` prepends to RP2350
* flash images as a workaround for erratum RP2350-E10 (i.e. a hardware
* bug in the A2 version of the RP2350 boot ROM).
*
* Such a block is always written on its own, but its `num_blocks_raw` is
* set to 2. If we trusted this value, we would attempt to read one block
* too many (which would most likely fail). Therefore, we must correct it
* to 1 before using it.
*
* The conditions for detecting this block come from the
* [`check_abs_block()`](https://github.com/raspberrypi/picotool/blob/6f6458d792b93685a11423b244a585eaa99eafcf/elf2uf2/elf2uf2.cpp#L147)
* function in `picotool`. However, there are some differences:
*
* 1. In Kaitai Struct, we cannot easily check whether all 256 payload
* bytes are set to `0xef`, so we only check the first and last bytes.
* 2. There are .uf2 files in the wild where `flags.has_extension_tags`
* is true, but there are actually no extension tags (the first and
* only tag has a size of 0, which is just a terminator), so our
* condition allows for this case. You can download an example of such
* a .uf2 file here:
* <https://github.com/neednotapply/DC32-cfw/releases/tag/1.69.13.37>
*
* It's worth noting that we cannot require the presence of the
* `extension_tag_type::rp2_ignore_block`
* (`UF2_EXTENSION_RP2_IGNORE_BLOCK`) tag because the UF2 files generated
* by `picotool` prior to
* <https://github.com/raspberrypi/picotool/commit/78c9bd121b09399823b67ee7ea89003ca0d3315f>
* don't have it. Therefore, we check whether this tag is present only if
* `flags.has_extension_tags` is set.
*
* Test .uf2 files with this special block can be downloaded from
* <https://micropython.org/download/RPI_PICO2/>. Note that all the .uf2
* files there are actually two UF2 (sub)files concatenated, and this
* Kaitai Struct implementation parses only one at a time (so in order to
* parse both, you need something like the helper spec `uf2_files.ksy`
* from
* <https://github.com/kaitai-io/kaitai_struct_formats/pull/542#discussion_r3906386820>).
* v1.24.x releases predate the `extension_tag_type::rp2_ignore_block`
* tag, while releases v1.25.0 and later include it.
* @see {@link https://github.com/raspberrypi/picotool/blob/6f6458d792b93685a11423b244a585eaa99eafcf/elf2uf2/elf2uf2.cpp#L147|Git tag "2.3.0"}
* @see {@link https://github.com/raspberrypi/picotool/commit/78c9bd121b09399823b67ee7ea89003ca0d3315f|Source}
*/
Object.defineProperty(Block.prototype, 'isRp2350E10Block', {
get: function() {
if (this._m_isRp2350E10Block !== undefined)
return this._m_isRp2350E10Block;
this._m_isRp2350E10Block = (( ((this.flags.value == 8192) || (this.flags.value == 40960)) ) && (this.familyId == Uf2.FamilyId.RP2XXX_ABSOLUTE) && (this.numBlocksRaw == 2) && (this.blockNumber == 0) && (this.lenPayload == 256) && (this.data.payload[0] == 239) && (this.data.payload[this.data.payload.length - 1] == 239) && ( ((!(this.flags.hasExtensionTags)) || (this.data.extensionTags[0].lenTag == 0) || ( ((this.data.extensionTags[0].lenTag == 4) && (this.data.extensionTags[0].tagType == Uf2.ExtensionTagType.RP2_IGNORE_BLOCK)) )) )) ;
return this._m_isRp2350E10Block;
}
});
Object.defineProperty(Block.prototype, 'numBlocks', {
get: function() {
if (this._m_numBlocks !== undefined)
return this._m_numBlocks;
this._m_numBlocks = (this.isRp2350E10Block ? 1 : this.numBlocksRaw);
return this._m_numBlocks;
}
});
/**
* Address in flash where `data.payload` should be written, or an offset
* in the file specified by `data.file_name` if `flags.is_file_container`
* is set.
*
* The [official
* spec](https://github.com/microsoft/uf2/blob/90e9741f217f5a40c98ba74d663e408041037578/README.md#payload-sizes)
* says:
*
* > In any event, payload size and target address should always be
* > 4-byte aligned.
*/
/**
* The [official
* spec](https://github.com/microsoft/uf2/blob/90e9741f217f5a40c98ba74d663e408041037578/README.md#payload-sizes)
* says:
*
* > In any event, payload size and target address should always be
* > 4-byte aligned.
*/
/**
* Number of blocks that make up the UF2 file to which this block
* belongs. Every block of a file has the same value. It is at least 1
* and every `block_number` in the file must be less than this value
* (which is validated by this Kaitai Struct implementation).
*/
/**
* Size of the file this block belongs to, but only if
* `flags.is_file_container` is true. Otherwise, the official spec allows
* this field to be set to anything - though in practice, it's always
* zero.
*/
return Block;
})();
var BlockData = Uf2.BlockData = (function() {
function BlockData(_io, _parent, _root) {
this._io = _io;
this._parent = _parent;
this._root = _root;
this._read();
}
BlockData.prototype._read = function() {
this.payload = this._io.readBytes(this._parent.lenPayload);
if (this._parent.flags.isFileContainer) {
this.fileName = KaitaiStream.bytesToStr(this._io.readBytesTerm(0, false, true, true), "UTF-8");
}
if (this._parent.flags.hasExtensionTags) {
this.extensionTags = [];
var i = 0;
do {
var _ = new ExtensionTag(this._io, this, this._root);
this.extensionTags.push(_);
i++;
} while (!(_.lenTag == 0));
}
}
/**
* Describes a region that doesn't need to be flashed again if the
* checksum matches.
*
* The [official
* spec](https://github.com/microsoft/uf2/blob/90e9741f217f5a40c98ba74d663e408041037578/README.md#md5-checksum)
* says that "This is currently only used on ESP32", but no real-world
* firmware sample has been found (at least none of the .uf2 files from
* <https://github.com/adafruit/tinyuf2/releases>,
* [MicroPython](https://micropython.org/download/) or
* [CircuitPython](https://circuitpython.org/downloads) contain it). It
* was found only in some synthetic test files, e.g.
* <https://github.com/umi-eng/uftwo/blob/35bccf75b4f81c43f088696a8c4a9912f1f4104e/uftwo/tests/checksum_256.uf2>.
*/
Object.defineProperty(BlockData.prototype, 'md5Checksum', {
get: function() {
if (this._m_md5Checksum !== undefined)
return this._m_md5Checksum;
if (this._parent.flags.hasMd5Checksum) {
var _pos = this._io.pos;
this._io.seek(this._io.size - 24);
this._m_md5Checksum = new Md5Checksum(this._io, this, this._root);
this._io.seek(_pos);
}
return this._m_md5Checksum;
}
});
/**
* The bytes to be written to `_parent.target_address`, which is either
* an address in flash, or an offset in the file specified by `file_name`
* if `_parent.flags.is_file_container` is set.
*/
return BlockData;
})();
/**
* @see {@link https://github.com/microsoft/uf2/blob/90e9741f217f5a40c98ba74d663e408041037578/README.md#extension-tags|Source}
*/
var ExtensionTag = Uf2.ExtensionTag = (function() {
function ExtensionTag(_io, _parent, _root) {
this._io = _io;
this._parent = _parent;
this._root = _root;
this._read();
}
ExtensionTag.prototype._read = function() {
this.lenTag = this._io.readU1();
var _ = this.lenTag;
if (!( ((_ == 0) || (_ >= this.minLenTag)) )) {
throw new KaitaiStream.ValidationExprError(this.lenTag, this._io, "/types/extension_tag/seq/0");
}
this.tagType = this._io.readBitsIntLe(24);
this._io.alignToByte();
if (this.lenTag != 0) {
this.value = this._io.readBytes(this.lenValue);
}
this.padding = this._io.readBytes(KaitaiStream.mod(-(this.lenTag), 4));
}
Object.defineProperty(ExtensionTag.prototype, 'lenValue', {
get: function() {
if (this._m_lenValue !== undefined)
return this._m_lenValue;
this._m_lenValue = (this.lenTag >= this.minLenTag ? this.lenTag - this.minLenTag : 0);
return this._m_lenValue;
}
});
Object.defineProperty(ExtensionTag.prototype, 'minLenTag', {
get: function() {
if (this._m_minLenTag !== undefined)
return this._m_minLenTag;
this._m_minLenTag = 1 + 3;
return this._m_minLenTag;
}
});
/**
* Total size of the tag in bytes, including this byte and `tag_type`, so
* at least 4. The exception is the last tag which terminates the list -
* it specifies a total size of 0.
*/
/**
* Tags are 4-byte aligned, so a tag whose size is not a multiple
* of 4 is followed by padding.
*/
return ExtensionTag;
})();
/**
* @see {@link https://github.com/microsoft/uf2/blob/90e9741f217f5a40c98ba74d663e408041037578/uf2.h#L43-L47|Source}
* @see {@link https://github.com/raspberrypi/pico-sdk/blob/98a542c1a62fb549ffb5d66a3e5892b06276b670/src/common/boot_uf2_headers/include/boot/uf2.h#L23-L27|Git tag "2.3.0"}
*/
var Flags = Uf2.Flags = (function() {
function Flags(_io, _parent, _root) {
this._io = _io;
this._parent = _parent;
this._root = _root;
this._read();
}
Flags.prototype._read = function() {
this.value = this._io.readU4le();
var _ = this.value;
if (!( (((_ & ~61441) == 0) && (!( ((this.isFileContainer) && (this.hasExtensionTags)) ))) )) {
throw new KaitaiStream.ValidationExprError(this.value, this._io, "/types/flags/seq/0");
}
}
/**
* Indicates whether extension tags are present after the payload.
*/
Object.defineProperty(Flags.prototype, 'hasExtensionTags', {
get: function() {
if (this._m_hasExtensionTags !== undefined)
return this._m_hasExtensionTags;
this._m_hasExtensionTags = (this.value & 32768) != 0;
return this._m_hasExtensionTags;
}
});
/**
* The field at offset 28 in the block is `family_id` instead of
* `file_size`.
*/
Object.defineProperty(Flags.prototype, 'hasFamilyId', {
get: function() {
if (this._m_hasFamilyId !== undefined)
return this._m_hasFamilyId;
this._m_hasFamilyId = (this.value & 8192) != 0;
return this._m_hasFamilyId;
}
});
/**
* Indicates whether `md5_checksum` is present at the end of `data`.
*/
Object.defineProperty(Flags.prototype, 'hasMd5Checksum', {
get: function() {
if (this._m_hasMd5Checksum !== undefined)
return this._m_hasMd5Checksum;
this._m_hasMd5Checksum = (this.value & 16384) != 0;
return this._m_hasMd5Checksum;
}
});
/**
* When set, the UF2 format is used as a container for regular files
* (akin to a TAR file, or ZIP archive without compression).
*
* `target_address` is the offset in the file where the payload is to be
* written, and `file_size` is the size of that file. The name of the
* destination file is stored in `data.file_name`.
*/
Object.defineProperty(Flags.prototype, 'isFileContainer', {
get: function() {
if (this._m_isFileContainer !== undefined)
return this._m_isFileContainer;
this._m_isFileContainer = (this.value & 4096) != 0;
return this._m_isFileContainer;
}
});
/**
* Indicates that this block should be skipped when writing the device
* flash. It can be used to store data that does not fit on the device,
* typically embedded source code or debug info.
*/
Object.defineProperty(Flags.prototype, 'notMainFlash', {
get: function() {
if (this._m_notMainFlash !== undefined)
return this._m_notMainFlash;
this._m_notMainFlash = (this.value & 1) != 0;
return this._m_notMainFlash;
}
});
/**
* Only the five bits that we cover in value instances below are defined,
* and no other bit may be set. The [official
* spec](https://github.com/microsoft/uf2/blob/90e9741f217f5a40c98ba74d663e408041037578/README.md#flags)
* says "Currently, there are five flags defined". If any other flags are
* added in the future, this .ksy spec will need to be updated.
*
* The `is_file_container` and `has_extension_tags` flags disagree about
* what follows the payload in `data` (a file name or a list of extension
* tags), so this Kaitai Struct implementation treats them as mutually
* exclusive and will reject a block that sets both. The official spec
* does not specify how this should be handled, but logically there's a
* conflict, so we've decided to strictly treat it as an error.
*/
return Flags;
})();
/**
* @see {@link https://github.com/microsoft/uf2/blob/90e9741f217f5a40c98ba74d663e408041037578/README.md#md5-checksum|Source}
*/
var Md5Checksum = Uf2.Md5Checksum = (function() {
function Md5Checksum(_io, _parent, _root) {
this._io = _io;
this._parent = _parent;
this._root = _root;
this._read();
}
Md5Checksum.prototype._read = function() {
this.startAddress = this._io.readU4le();
this.lenRegion = this._io.readU4le();
this.md5 = this._io.readBytes(16);
}
return Md5Checksum;
})();
return Uf2;
})();
Uf2_.Uf2 = Uf2;
});