Home - rogerz/uffs GitHub Wiki

Data Structures

  • TreeNode

    • One node for one block.
    • The node for a specified block can be located by calculating the offset
    • The link between node is represented by parent and serial
    • A notable point is that the tree node actually does NOT store any link to its child.
    • The child is located from hash table directly. This may reduce the memory cost in a low price of searching performance.
  • uffs_Object

    • File and directory handle in runtime
    • Objects are distinguished by parent and serial
      • File and directory objects have unique serial
      • Data objects have unique parent and serial pair
      • File and dir header serial (fsn) are allocated from pool
      • File data serial (fdn) is the sequence number of data blocks belonging to each file
    • Given the serial, the node can be located from hash table. From node you get the block number
      • Q: Why not mapping node to block directly by index???
  • uffs_TagStoreSt, tag for each page

  • uffs_MiniHeaderSt, get the status of page at minimum cost

    • status (0xFF = CLEAN)
    • crc

Memory

  • Object pool: sizeof(_object_pool) = MAX_OBJECT_HANDLE * sizeof(uffs_Object)
  • Node pool: sizeof(dev->mem->tree_node_pool_buf) = (number of blocks) * sizeof(TreeNode)
  • Block info cache: sizeof(dev->mem->blockinfo_pool_buf) = ???
  • Page buffer: sizeof(dev->mem->pagebuf_pool_buf) = ???
  • Spare buffer: sizeof(dev->mem->spare_pool_buf) = ???

Spare Layout

s = dev->attr->block_status_offs;
if (s>=TAG_STORE_SIZE+ECC_SIZE)
    spare = {TAG, ECC, STATUS}
    dev->attr->_uffs_data_layout = [0, TAG_STORE_SIZE, 0xff, 1]
    dev->attr->_uffs_ecc_layout = [TAG_STORE_SIZE, ECC_SIZE, 0xff, 1]
else if (TAG_STORE_SIZE<=s<ECC_SIZE)
    spare = {TAG, ECC', STATUS, ECC''}  //STATUS cuts ECC into two parts
    dev->attr->_uffs_data_layout = [0, TAG_STORE_SIZE, 0xff, 1]
    dev->attr->_uffs_ecc_layout = [TAG_STORE_SIZE, s-TAG_STORE_SIZE, s-TAG_STORE_SIZE+1, TAG_STORE_SIZE+ECC_SIZE-s, 0xff, 1]
else if (s<TAG_STORE_SIZE)
    spare = {TAG', STATUS, TAG'', ECC}  //STATUS cuts TAG into two parts
    dev->attr->_uffs_data_layout = [0, STATUS, STATUS+1, TAG_STORE_SIZE-STATUS, 0xff, 1]
    dev->attr->_uffs_ecc_layout = [TAG_STORE_SIZE+1, ECC_SIZE, 0xff, 1]

Link

  • uffs_Object to TreeNode

    • Index of block can be found in hash table (uffs_TreeSt.dir_entry[hash])
    • Hash value is the lower 5 bits of serial (hash = serial & 0x1f)
    • The memory address of the node can be calculated from index (uffs_Poll->mem + index * pool->buf_size)
  • fd to uffs_Object

    • Get uffs_Object from the pool by index (uffs_Poll->mem + fd * pool->buf_size)

Function Details

Limits

  • File length: 2^(14+1)*block_size (14<-uffs_TagStoreSt::serial, block_size 64KB=>1G)
  • Max open files: default 10 (MAX_OBJECT_HANDLE)
  • Max files and dirs: 0x3ff (MAX_UFFS_FSN)
  • Max data blocks in a file: 0x3fff (MAX_UFFS_FDN)
  • Each block can hold only one file or directory or data of one file

FAQ