Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages | Examples

Memory Card File System


Detailed Description

File System API can be used only on devices with memory card:

File System has to be compiled in kernel.

Design aspects:

It turned out that existing file systems (notably FAT) were unusable for our purpose.

API

Note:
Spider provides functionality for filesystem browsing

Basic Filesystem API

Utility Filesystem API

Security Filesystem API

Filetype API

Low level Filesystem API

Important:
File or directory name does not have to be unique. The unique pointer is called inode pointer - u32 number determining inode.

Detail file system description

Note:
The following text is mainly for information and not necessary for development. Skip if you want to.

The DataFlash memory card is organized into pages, which turbo file system devides into 264 bytes blocks. The number of pages and the number of blocks per page depends on the memory card size. Currently Atmel provides DataFlash MMC packaged cards of three sizes - 2, 4 and 8 Mbytes:

fs_org.png

Memory Card Organization


The first page (page number 0), so called "INFO_PAGE" contains basic information, such as the magic string used for format detection, label of the card and also the file system root inode.

The next number_of_all_pages/2048 pages are used for block allocation map - bitmap array, where one bit means block.

The remaining pages are free for user files and directories.

fs_struct.png

File System Structure


Each block is 264 bytes long, the first 256 bytes are usable space and the remaining 8 bytes has some other meaning, depending whether the block is used for file or directory data. Some bytes have different meaning if the block is the first or the last block of the page.

fs_block.png

File System Block


In the above page the green block contains number of page (2 bytes), in case it is the first block of the page, or number of page flashings (4 bytes) in case of the last block of the page. The number of page flashings is used for page refreshing procedure (see Atmel DataFlash datasheets).

Both directory and file blocks have pointers Next Block and Previous Block, but its meaning is different. In case of directory the blocks are linked into 2-way cyclic list, while for the file blocks the Prev Block points:

The Next Block always points to the next block in file, the last points to the first.

The result is the semi-2-way cyclic list allowing oneway fast seek.

fs_dir.png

Directory Block


The directory block contains 8 inodes.

fs_inode.png

Inode


The inode is a structure containing:

fs_file.png

Structure of file block INODE_TYPE_FILE


The above picture shows the first regular file block.

fs_enc_data_key.png

Structure of encrypted file INODE_TYPE_PROTECTED_KEY_DATA block


This picture shows the Data, Key Encrypted file. The file is encrypted with 128bit Twofish cipher in CBC mode. The 8 byte initial vector is twice on positions [16...23] and [24...31]. This scenario allows to check whether given key is OK and decryption operation can be performed.

Attention:
While it weakens the protection and simplifies the brute force attack, it is better than decrypt the file with wrong key and damage it.
fs_enc_data_len.png

Structure of encrypted file INODE_TYPE_PROTECTED_DATA_LEN_TYPE


In this paranoid scheme the type and length of file are shifted to position [8...23] and encrypted as well. Attacker can reveal only the name of file and number of blocks - not even the exact length.

Data Structures

Defines

Typedefs

Functions


Define Documentation

#define APP_USE_DEFAULT
 

Filetype callback related, use default behaviour

#define FILE_APPEND
 

Indicates APPEND operation.

#define FILE_DELETE
 

File callback - DELETE action

#define FILE_DETAIL
 

File callback - DETAIL action

#define FILE_MOVE
 

File callback - MOVE action

#define FILE_READ
 

Indicates READ operation.

#define FILE_RENAME
 

File callback - RENAME action

#define FILE_REWRITE
 

Indicates REWRITE operation.

#define FILE_SELECT
 

File callback - SELECT action

#define FS_FIND_MSISDN
 

Interpret inode name as MSISDN. Name is expected to be MSISDN_ADN, while searched MSISDN type MSISDN_SMS.

#define FS_FIND_STRING
 

Search for string name.

#define INODE_TEXT_LEN
 

Max. name len (including terminal '\0')

#define MC_NOT_PRESENT
 

Memory Card not present

#define MC_NOT_READY
 

Memory Card present but not formatted

#define MC_OK
 

Memory Card present and formatted

#define SORT
 

Sort, case insensitive.


Typedef Documentation

typedef struct _inode Inode
 

fs_inode.png

Inode

typedef struct _MCFILE MCFILE
 

Memory Card FILE structure. Like FILE but spcific for turbo file system (FILE will be based on MCFILE once implemented).

typedef u8( t_file_cb)(u32 file, u8 file_action)
 

File handling callback, see reg_file_type(). Action can be FILE_SELECT, FILE_DETAIL, FILE_DELETE, FILE_MOVE, FILE_RENAME.


Function Documentation

b32 cd const u8 path  ) 
 

Change working directory to a given path.

Warning:
Internal inode() use - content will be destroyed.
Parameters:
path Path, can be stored in RAM, EEPROM, PROGMEM.
Returns:
inode pointer of directory if successful, -ERR_FILE_NOT_FOUND if failed.
Examples:
cells.c, and reader.c.

void cd_i u32  fp  ) 
 

Change working directory to directory pointed by pointer.

Warning:
Internal inode() use - content will be destroyed.
Parameters:
fp inode pointer.
Examples:
cells.c, mc.c, and reader.c.

b32 create_dir u32  dir,
const u8 name,
u8  sort_flag
 

Create the new dir in a given directory.

u8 PROGMEM t_dir_name[] = "My Directory";

void foo()
{
b32 dir;

dir=create_dir(root(), t_dir_name, SORT); // create "/My Directory"

}
Warning:
Internal inode() use - content will be destroyed.
Parameters:
dir Directory inode pointer.
name New directory name, ALPHA coding. Can be RAM, EEPROM, PROGMEM.
sort_flag Required sorting, SORT_APPEND, SORT_SMS, #SORT_SMS_SKIP, SORT.
Returns:
inode pointer>0 if successfull, -ERR_NO_RAM, -ERR_NO_SPACE.
Examples:
cells.c.

b32 create_file u32  dir,
const u8 name,
u8  sort_flag
 

Create the new file in a given directory.

u8 PROGMEM t_dir_name[] = "My Directory";
u8 PROGMEM t_file_name[] = "My File";
u8 PROGMEM t_file_ext[] = "mxt";        // My Extension

void foo()
{
b32 dir;
b32 file;
MCFILE *fd;

cd_i(root());
dir=cd(t_dir_name);

if(dir<0) 
{
// dir "/My Direcory" does not exist
}

file=create_dir(dir, t_file_name, SORT); // create "/My Directory/My File"

if(file<0)
{
// could not create
}

mc_set_type (file, t_file_ext);

fd = mc_open (file, FILE_APPEND);
mc_append (fd, some_data, len_of_some_data);
mc_close (fd);
}

Warning:
Internal inode() use - content will be destroyed.
Parameters:
dir Directory inode pointer.
name File name, ALPHA coding. Can be RAM, EEPROM, PROGMEM.
sort_flag Required sorting, SORT_APPEND, SORT_SMS, #SORT_SMS_SKIP, SORT.
Returns:
inode pointer>0 if successfull, -ERR_NO_RAM, -ERR_NO_SPACE.
Examples:
cells.c.

b16 delete_files u32  fp  ) 
 

Delete all files in the directory.

Note:
Because of memory reasons the number of deleted files is limited to 85. Use the function more times to delete all files.
Warning:
Internal inode() use - content will be destroyed.
Parameters:
fp Directory inode pointer.
Returns:
NO_ERROR, ERR_BAD_FILE.

b16 delete_inode u32  fp  ) 
 

Delete file or directory - including subdirs.

Warning:
Internal inode() use - content will be destroyed.
Parameters:
fp File pointer.
Returns:
NO_ERROR, -ERR_BAD_FILE, -ERR_NO_RAM.

t_file_cb* file_type u32  file_id  ) 
 

Returns file callback for given file

Parameters:
file_id 
Returns:
callback or NULL if none is associated to the type of given file.
Examples:
mc.c.

void format void   ) 
 

Format memory card.

Attention:
Only for tfslib, i.e. programmer. Not available for Turbo.
Warning:
Internal inode() use - content will be destroyed.

u16 fs_ino_block u32  fp  ) 
 

Returns the block part of inode pointer.

Parameters:
fp inode pointer.
Returns:
inode block.

u8 fs_ino_index u32  fp  ) 
 

Returns the index part of inode pointer.

Parameters:
fp inode pointer.
Returns:
inode index.

u32 fs_ino_p u16  block,
u8  index
 

Converts the block and index to the inode pointer.

Parameters:
block 
index 
Returns:
inode pointer.

void get_inode Inode ino,
u32  fp
 

Returns the content of inode.

Parameters:
ino Pointer on Inode structure to be filled with inode.
fp Inode pointer.
Examples:
mc.c, and reader.c.

b32 get_len u32  fp  ) 
 

Returns length of file. In the case of INODE_TYPE_PROTECTED_DATA_LEN_TYPE it returns number of 256 byte blocks. In the case of INODE_TYPE_PROTECTED_KEY_DATA it returns length ceiled to be divisible by 16 (size of encryption chunk - 128 bits).

Warning:
Internal inode() use - content will be destroyed.
Parameters:
fp Inode pointer.
Returns:
len>=0 if OK, -ERR_BAD_FILE if failed.
See also:
Detail file system description

b32 get_len_raw u32  fp  ) 
 

Returns length of file.In the case of INODE_TYPE_PROTECTED_DATA_LEN_TYPE it returns -ERR_BAD_FILE.

Attention:
In case of INODE_TYPE_PROTECTED_KEY_DATA this value is wrong - it is not ceiled to be divisible by 16, see get_len().
Warning:
Internal inode() use - content will be destroyed.
Parameters:
fp Inode pointer.
Returns:
len>=0 if OK, -ERR_BAD_FILE if failed.
See also:
Detail file system description

u32 ino_parent Inode ino  ) 
 

Returns inode pointer of parent.

Parameters:
ino 
Returns:
inode pointer.
Examples:
mc.c.

Inode* inode void   ) 
 

The inode() function returns pointer to the Inode structure, which is globaly allocated and usable in your code. Saves RAM and code.

Warning:
This structure can be used by other functions.
Examples:
mc.c, and reader.c.

b16 mc_append MCFILE file,
u8 buf,
u8  len
 

Appends len bytes from buf to file.

Parameters:
file 
len length of data in buffer
buf buffer
Returns:
NO_ERROR if OK, -ERR_BAD_FILE if error.
Examples:
cells.c.

u8 mc_blocks void   ) 
 

Returns the number of 264bytes long blocks per page.

b16 mc_clear u32  fp  ) 
 

Truncate file - clear all the content.

Warning:
Internal inode() use - content will be destroyed.
Parameters:
fp inode pointer.
Returns:
NO_ERROR, -ERR_BAD_FILE.

b16 mc_close MCFILE file  ) 
 

Closes file - must be called to flush all content to memory card and to free all memory.

Parameters:
file 
Returns:
NO_ERROR.
Examples:
cells.c.

u8 mc_detect void   ) 
 

Detect memory card.

Returns:
MC_OK if OK, MC_NOT_PRESENT or MC_NOT_READY (=not formatted) if error.
Examples:
cells.c, mc.c, and reader.c.

u8 mc_file_decrypt u32  desc,
u8  key[16]
 

Decrypt encrypted file.

Warning:
Internal inode() use - content will be destroyed.
Parameters:
desc Inode pointer on encrypted file (either INODE_TYPE_PROTECTED_KEY_DATA or INODE_TYPE_PROTECTED_DATA_LEN_TYPE.
key Key, all 16 bytes has to be valid, RAM only.
Returns:
NO_ERROR, ERR_BAD_FILE if not encrypted file, ERR_WRONG_KEY if INODE_TYPE_PROTECTED_KEY_DATA and supplied key is wrong, ERR_NO_RAM if memory problem.
Examples:
mc.c.

u8 mc_file_encrypt u32  fp,
u8  key[16],
u8  flag
 

Encrypt file pointed on by inode pointer with key and twofish 128bit cypher.

Warning:
Internal inode() use - content will be destroyed.
Parameters:
fp Inode pointer.
key Key, all 16 bytes has to be valid, RAM only
flag INODE_TYPE_PROTECTED_KEY_DATA or INODE_TYPE_PROTECTED_DATA_LEN_TYPE.
Returns:
NO_ERROR, #ERR_BAD_PARMS if wrong flag, ERR_BAD_FILE if not file, ERR_NO_RAM if memory problem.
Examples:
mc.c.

b32 mc_find b32  file,
const u8 name,
u8  type
 

Find inodes of the given name in the current dir.

Example - Find all occurences of "My File" name
u8 PROGMEM t_file_name[] = "My File";

void foo()
{
b32 file = 0;

cd(...);

do
{
file = mc_find (file, t_file_name, FS_FIND_STRING);
if(file>0)
{
// file found
}
} while(file>0);

}
Warning:
Internal inode() use - content will be destroyed.
Parameters:
file previous hit, use 0 for start.
name name to look for, ALPHA coding. Can be stored in RAM, EEPROM, PROGMEM
type search type, FS_FIND_STRING, FS_FIND_MSISDN.
Returns:
inode pointer if >0, -ERR_FILE_NOT_FOUND if not found.

u16 mc_free void   ) 
 

Returns the number of free file system blocks.

void mc_get_label u8  label[15]  ) 
 

Returns label of the Memory Card.

Parameters:
label Pointer on the buffer where the label is returned.
Examples:
mc.c.

u8 mc_get_type u32  fp,
u8  type[3]
 

Returns file type (3 bytes extension/magic).

Warning:
Internal inode() use - content will be destroyed.
Parameters:
fp Inode pointer on file.
type Returned type.
Returns:
ERR_BAD_FILE, NO_ERROR.
Examples:
mc.c.

b32 mc_move u32  what,
u32  to,
u8  sort_flag
 

Move file/dir form one dir to another.

Parameters:
what Inode pointer on what to move.
to Inode pointer on target directory.
sort_flag Required sorting, SORT_APPEND, SORT_SMS, #SORT_SMS_SKIP, SORT.
Returns:
NO_ERROR, -ERR_NO_RAM.

MCFILE* mc_open u32  fp,
u8  flag
 

Open file for reading or writing (=appending).

Warning:
Internal inode() use - content will be destroyed.
Parameters:
fp Inode pointer.
flag FILE_READ, FILE_APPEND or FILE_REWRITE
Returns:
NULL if failed, MCFILE struct if OK.
Examples:
cells.c.

u16 mc_pages void   ) 
 

Returns the number of Memory Card (DataFlash) pages.

b16 mc_read MCFILE file,
u32  pos,
u8 buf,
u8  len
 

Read len bytes into buf at pos from file.

Parameters:
file 
pos position
buf buffer to fill
len length of read
Returns:
nr. of bytes read>=0 if OK, -ERR_WRONG_POS, -ERR_BAD_FILE if error.

b16 mc_rewrite MCFILE file,
u32  pos,
u8 buf,
u8  len
 

Write len bytes in buf at pos in file. Pos has to be <= file_len - len, otherwise only truncated len.

Parameters:
file 
pos position
buf buffer to write
len length of data in buffer
Returns:
nr. of bytes rewriten>=0 OK, -ERR_WRONG_POS, -ERR_BAD_FILE if error.

void mc_set_label u8  label[15]  ) 
 

Set Memory Card label.

Parameters:
label New Memory Card label.
Examples:
mc.c.

u8 mc_set_type u32  fp,
const u8 type
 

Set file type (3 bytes extension/magic).

Warning:
Internal inode() use - content will be destroyed.
Parameters:
fp Inode pointer on file.
type Pointer on u8 type[3], can be RAM, EEPROM, PROGMEM.
Returns:
ERR_BAD_FILE, NO_ERROR.
Examples:
cells.c.

u32 pwd void   ) 
 

Returns inode pointer of working directory.

Returns:
inode pointer.
Examples:
mc.c, and reader.c.

u8 reg_file_type const u8 type,
t_file_cb cb
 

Associate file type, i.e. 3 letter extension/magic with a given file callback function.

Any application can obtain the cb with file_type() and work with the file.

The following extensions are registered by kernel:

  • trb - turbo application
  • txt - text file

Example scenario.

We have a file containing SMS specific format message, which viewed as text would not be readable. We have one application (e.g. SMSM Archive) that knows how to display such message and the second application (e.g. memory card viewer) viewing the message.

Application that knows the file (e.g. SMS Archive)

u8 PROGMEM t_ext_sms[] = "sms";

u8 file_sms_cb (u32 f, u8 action)
{
  if (action == FILE_SELECT)    // for file action SELECT
  {
    return view_msg (f);        // decode sms format and display text
  }
return APP_USE_DEFAULT;         // for any other file actions use default
}

void turbo_handler (u8 action, void *data)
{
  switch (action)
    {
    ....
        case ACTION_APP_REGISTER:
                reg_file_type (t_ext_sms, file_sms_cb);
    ....        
    }
}

Application that wants to view the file

t_file_cb *cb = file_type (f);
u8 j;

j = APP_USE_DEFAULT;
if (cb != NULL) 
        j = cb (f, FILE_SELECT);
        
if (j == APP_USE_DEFAULT)
        display_more(f);

Parameters:
type pointer on type in PROGMEM
cb callback function
Returns:
NO_ERROR, ERR_NO_EEPROM.
See also:
file_type()

u32 root void   ) 
 

Returns inode pointer of root directory.

Returns:
root inode pointer.
Examples:
mc.c.

void set_inode Inode ino,
u32  fp
 

Sets new inode structure.

Parameters:
ino Pointer on Inode structure containing new inode content.
fp inode pointer.


Copyright © 2004-2006 BLADOX
Turbo version 1.2