alif — Alif Ensemble SoC functions

The alif module exposes port-specific functionality for the Alif Ensemble SoC, including a block-device wrapper for the on-board OSPI flash and a helper to dump SoC information from the Secure Enclave services.

Example:

import alif

alif.info()
flash = alif.Flash()

Functions

alif.info() None

Dumps device information collected from the Alif Secure Enclave services (SE services) to the serial terminal.

Classes

class alif.Flash(*, start: int = -1, len: int = -1)

Creates a block-device object backed by the on-board OSPI flash. This class is only available when the firmware is built with OSPI support enabled.

When called with no arguments, returns the default singleton object covering the writable filesystem region of flash.

start is the byte offset into the flash storage region. Must be a multiple of the flash block size and within the flash storage range. Defaults to -1 which means start at offset 0.

len is the length in bytes of the flash region exposed by the object. Must be a multiple of the flash block size and not extend past the end of the flash storage region. Defaults to -1 which means use all remaining bytes from start.

The object also implements the buffer protocol, allowing read-only memory-mapped access to the flash region via the OSPI XIP base. This makes a zero-copy view of the entire region available without issuing any flash reads:

flash = alif.Flash()
view = memoryview(flash)
magic = bytes(view[:4])      # read the first 4 bytes directly from XIP
readblocks(block_num: int, buf: bytearray) int
readblocks(block_num: int, buf: bytearray, offset: int) int

Read bytes from the flash into buf. Two overloads expose the simple and extended interfaces:

Simple form (readblocks(block_num, buf)): reads whole blocks starting at block index block_num. len(buf) must be a multiple of the flash block size.

Extended form (readblocks(block_num, buf, offset)): reads len(buf) bytes – not necessarily a whole number of blocks – starting at byte offset within block block_num. len(buf) has no alignment constraint.

Returns 0 on success or a negative error code. Note that the standard MicroPython block-device protocol returns None; the alif driver intentionally exposes the underlying OSPI status code so callers that bypass vfs can react to hardware errors.

writeblocks(block_num: int, buf: bytes) int
writeblocks(block_num: int, buf: bytes, offset: int) int

Write bytes from buf to the flash. Two overloads expose the simple and extended interfaces:

Simple form (writeblocks(block_num, buf)): writes whole blocks starting at block index block_num. len(buf) must be a multiple of the flash block size. Each affected block is erased automatically before being written.

Extended form (writeblocks(block_num, buf, offset)): writes len(buf) bytes – not necessarily a whole number of blocks – starting at byte offset within block block_num. len(buf) has no alignment constraint, and no implicit erase is performed – the caller must ensure the affected blocks have been erased via a prior ioctl(6, block_num) call.

Returns 0 on success or a negative error code (see readblocks() for the rationale).

ioctl(cmd: int, arg: int) int

Performs a block-device control operation. cmd is one of the standard MicroPython MP_BLOCKDEV_IOCTL_* commands:

  • 1 (init) — returns 0.

  • 2 (deinit) — returns 0.

  • 3 (sync) — returns 0.

  • 4 (block count) — returns the number of blocks in the region.

  • 5 (block size) — returns the flash block size in bytes.

  • 6 (block erase) — erases the block at index arg and returns the result of the erase operation.

Other cmd values return None.

Constants

alif.usb_msc: bool

Present and set to True only when the firmware is built with USB Mass Storage Class support enabled. The attribute is absent otherwise.