[Tinyos-beta-commits] CVS: tinyos-1.x/beta/AT45DB FormatStorage.nc, NONE, 1.1 FormatStorageC.nc, NONE, 1.1 FormatStorageM.nc, NONE, 1.1 StorageManager.h, NONE, 1.1 AT45Remap.nc, 1.1, 1.2 BlockStorageC.nc, 1.3, 1.4 BlockStorageM.nc, 1.4, 1.5 StorageManagerC.nc, 1.2, 1.3 StorageManagerM.nc, 1.2, 1.3 Storage_chip.h, 1.1, 1.2

David Gay idgay at users.sourceforge.net
Wed Jun 8 14:45:14 PDT 2005


Update of /cvsroot/tinyos/tinyos-1.x/beta/AT45DB
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25983

Modified Files:
	AT45Remap.nc BlockStorageC.nc BlockStorageM.nc 
	StorageManagerC.nc StorageManagerM.nc Storage_chip.h 
Added Files:
	FormatStorage.nc FormatStorageC.nc FormatStorageM.nc 
	StorageManager.h 
Log Message:
flash storage table using internal eeprom
  issue: needs fuse bit change (otherwise eeprom erased during reprog)
  -> will switch to using a page of external eeprom


--- NEW FILE: FormatStorage.nc ---
// $Id: FormatStorage.nc,v 1.1 2005/06/08 21:45:11 idgay Exp $

/*									tab:2
 * "Copyright (c) 2000-2005 The Regents of the University  of California.  
 * All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice, the following
 * two paragraphs and the author appear in all copies of this software.
 * 
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
 */

/*
 * @author: Jonathan Hui <jwhui at cs.berkeley.edu>
 */

includes Storage;

interface FormatStorage {

  command result_t init();

  command result_t allocate(volume_id_t id, storage_addr_t size);
  command result_t allocateFixed(volume_id_t id, storage_addr_t addr, storage_addr_t size);

  command result_t commit();
  event void commitDone(storage_result_t result);

}

--- NEW FILE: FormatStorageC.nc ---
// $Id: FormatStorageC.nc,v 1.1 2005/06/08 21:45:12 idgay Exp $

/*									tab:2
 * "Copyright (c) 2000-2005 The Regents of the University  of California.  
 * All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice, the following
 * two paragraphs and the author appear in all copies of this software.
 * 
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
 */

/*
 * @author Jonathan Hui <jwhui at cs.berkeley.edu>
 * @author David Gay
 */

includes crc;

configuration FormatStorageC {
  provides interface FormatStorage;
}
implementation {
  components FormatStorageM, InternalFlashC, Main;

  FormatStorage = FormatStorageM;

  Main.StdControl -> FormatStorageM;
  FormatStorageM.InternalFlash -> InternalFlashC;
}

--- NEW FILE: FormatStorageM.nc ---
// $Id: FormatStorageM.nc,v 1.1 2005/06/08 21:45:12 idgay Exp $

/*									tab:2
 * "Copyright (c) 2000-2005 The Regents of the University  of California.  
 * All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice, the following
 * two paragraphs and the author appear in all copies of this software.
 * 
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
 */

/*
 * @author Jonathan Hui <jwhui at cs.berkeley.edu>
 * @author David Gay
 */

includes Storage;
includes StorageManager;
includes crc;

module FormatStorageM {
  provides {
    interface FormatStorage;
    interface StdControl;
  }
  uses {
    interface InternalFlash;
  }
}
implementation {
  struct volume_definition_header_t header;
  struct volume_definition_t volumes[MAX_VOLUMES];

  uint8_t state;

  enum {
    S_INIT,
    S_COMMIT,
    S_COMMIT_DONE,
  };
  
  void signalDone(storage_result_t result) {
    state = S_COMMIT_DONE;
    signal FormatStorage.commitDone(result);
  }

  command result_t StdControl.init() {
    state = S_COMMIT_DONE;
    return SUCCESS;
  }

  command result_t StdControl.start() {
    return SUCCESS;
  }

  command result_t StdControl.stop() {
    return SUCCESS;
  }

  command result_t FormatStorage.init() {
    header.nvolumes = 0;
    state = S_INIT;

    return SUCCESS;
  }

  bool checkNewVolume(volume_id_t id, storage_addr_t addr, storage_addr_t size) {
    volume_id_t i;

    if (state != S_INIT)
      return FALSE;

    if (addr & ((1 << AT45_PAGE_SIZE_LOG2) - 1))
      return FALSE;

    // size must be a multiple of sector size
    if (size & ((1 << AT45_PAGE_SIZE_LOG2) - 1))
      return FALSE;

    // check if id is already taken
    for (i = 0; i < header.nvolumes; i++)
      if (volumes[i].id == id)
	return FALSE;

    return TRUE;
  }

  bool pageWithin(at45page_t page, at45page_t s, at45page_t len) {
    // page - s < len rather page < s + len to avoid overflow
    return page >= s && page - s < len;
  }

  result_t newVolume(uint8_t i, volume_id_t id, at45page_t start, at45page_t length) {
    if (start >= AT45_MAX_PAGES || length > AT45_MAX_PAGES - start)
      return FAIL;

    volumes[i].start = start;
    volumes[i].length = length;
    volumes[i].id = id;
    header.nvolumes++;

    return SUCCESS;
  }

  command result_t FormatStorage.allocate(volume_id_t id, storage_addr_t size) {
    at45page_t addr;
    uint8_t i;

    if (!checkNewVolume(id, 0, size))
      return FAIL;

    size >>= AT45_PAGE_SIZE_LOG2;

    /* First fit. */
    addr = 0;
    for (i = 0; i < header.nvolumes; i++)
      if (addr < volumes[i].start && size < volumes[i].start - addr)
	{
	  memmove(&volumes[i + 1], &volumes[i],
		  (header.nvolumes - i) * sizeof(volumes[i]));
	  break;
	}
      else
	addr = volumes[i].start + volumes[i].length;

    return newVolume(i, id, addr, size);
  }

  command result_t FormatStorage.allocateFixed(volume_id_t id, storage_addr_t addr, storage_addr_t size) {
    uint8_t i;

    if (!checkNewVolume(id, addr, size))
      return FAIL;

    addr >>= AT45_PAGE_SIZE_LOG2;
    size >>= AT45_PAGE_SIZE_LOG2;

    // Check if overlaps any existing allocation
    for (i = 0; i < header.nvolumes; i++)
      if (pageWithin(addr, volumes[i].start, volumes[i].length) ||
	  pageWithin(addr + size - 1, volumes[i].start, volumes[i].length) ||
	  pageWithin(volumes[i].start, addr, size) ||
	  pageWithin(volumes[i].start + volumes[i].length - 1, addr, size))
	return FAIL;

    // Insert at correct position.  These last two loops could be merged,
    // if there was any reason to care about performance
    for (i = 0; i < header.nvolumes; i++)
      if (addr < volumes[i].start)
	{
	  memmove(&volumes[i + 1], &volumes[i],
		  (header.nvolumes - i) * sizeof(volumes[i]));
	  break;
	}

    return newVolume(i, id, addr, size);
  }
   
  uint16_t computeSectorTableCrc() {
    uint16_t crc = crcByte(0, header.nvolumes);
    unsigned char *vtable = (unsigned char *)volumes;
    size_t i;

    for (i = 0; i < header.nvolumes * sizeof *volumes; i++)
      crc = crcByte(crc, vtable[i]);

    return crc;
  }

  task void commitVolumes() {
    result_t ok1, ok2;

    header.crc = computeSectorTableCrc();
    ok1 = call InternalFlash.write((uint8_t *)VOLUME_TABLE_ADDRESS, &header, sizeof header);
    ok2 = call InternalFlash.write((uint8_t *)VOLUME_DEF_ADDRESS, &volumes, sizeof *volumes * header.nvolumes);

    signal FormatStorage.commitDone(rcombine(ok1, ok2) != FAIL ? STORAGE_OK : STORAGE_FAIL);
  }

  command result_t FormatStorage.commit() {
    if (state != S_INIT)
      return FAIL;

    state = S_COMMIT;

    post commitVolumes();

    return SUCCESS;
  }
}

--- NEW FILE: StorageManager.h ---
#ifndef STORAGE_MANAGER_H
#define STORAGE_MANAGER_H

struct volume_definition_header_t
{
  uint16_t crc;
  uint8_t nvolumes;
};

struct volume_definition_t
{
  volume_id_t id;
  at45page_t start, length;
};

enum {
  INVALID_VOLUME_ID = 0,
  VOLUME_TABLE_SIZE = 256,
  VOLUME_TABLE_ADDRESS = 0xf00, // in on-chip eeprom
  VOLUME_DEF_ADDRESS = VOLUME_TABLE_ADDRESS + sizeof(struct volume_definition_header_t),
  MAX_VOLUMES = (VOLUME_TABLE_SIZE - sizeof(struct volume_definition_header_t)) / sizeof(struct volume_definition_t)
};

#endif

Index: AT45Remap.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-1.x/beta/AT45DB/AT45Remap.nc,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** AT45Remap.nc	2 Feb 2005 22:56:39 -0000	1.1
--- AT45Remap.nc	8 Jun 2005 21:45:11 -0000	1.2
***************
*** 3,5 ****
--- 3,6 ----
    /* Returns AT45_MAX_PAGES for invalid request (out of volume) */
    command at45page_t remap(volume_t volume, at45page_t volumePage);
+   command storage_addr_t volumeSize(volume_t volume);
  }

Index: BlockStorageC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-1.x/beta/AT45DB/BlockStorageC.nc,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** BlockStorageC.nc	4 Jun 2005 00:04:34 -0000	1.3
--- BlockStorageC.nc	8 Jun 2005 21:45:11 -0000	1.4
***************
*** 21,23 ****
--- 21,24 ----
    BlockStorageM.HALAT45DB -> StorageManagerC.HALAT45DB;
    BlockStorageM.ActualMount -> StorageManagerC.Mount;
+   BlockStorageM.AT45Remap -> StorageManagerC;
  }

Index: BlockStorageM.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-1.x/beta/AT45DB/BlockStorageM.nc,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** BlockStorageM.nc	7 Jun 2005 00:30:23 -0000	1.4
--- BlockStorageM.nc	8 Jun 2005 21:45:11 -0000	1.5
***************
*** 40,43 ****
--- 40,44 ----
      interface HALAT45DB[blockstorage_t blockId];
      interface Mount as ActualMount[blockstorage_t blockId];
+     interface AT45Remap;
    }
  }
***************
*** 232,236 ****
  
    command uint32_t BlockRead.getSize[blockstorage_t blockId]() {
!     return 0;//call StorageManager.getVolumeSize[blockId]();
    }
  
--- 233,237 ----
  
    command uint32_t BlockRead.getSize[blockstorage_t blockId]() {
!     return call AT45Remap.volumeSize(blockId);
    }
  

Index: StorageManagerC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-1.x/beta/AT45DB/StorageManagerC.nc,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** StorageManagerC.nc	4 Jun 2005 00:04:34 -0000	1.2
--- StorageManagerC.nc	8 Jun 2005 21:45:12 -0000	1.3
***************
*** 8,15 ****
      interface Mount[volume_t volume];
      interface HALAT45DB[volume_t volume];
    }
  }
  implementation {
!   components StorageManagerM, PageEEPROMC as HALAT45DBC, HALAT45DBShare;
  
    StdControl = StorageManagerM;
--- 8,16 ----
      interface Mount[volume_t volume];
      interface HALAT45DB[volume_t volume];
+     interface AT45Remap;
    }
  }
  implementation {
!   components StorageManagerM, PageEEPROMC as HALAT45DBC, HALAT45DBShare, InternalFlashC;
  
    StdControl = StorageManagerM;
***************
*** 17,20 ****
--- 18,24 ----
    Mount = StorageManagerM;
    HALAT45DB = HALAT45DBShare;
+   AT45Remap = StorageManagerM;
+ 
+   StorageManagerM.InternalFlash -> InternalFlashC;
  
    HALAT45DBShare.ActualAT45 -> HALAT45DBC.PageEEPROM[unique("PageEEPROM")];

Index: StorageManagerM.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-1.x/beta/AT45DB/StorageManagerM.nc,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** StorageManagerM.nc	4 Jun 2005 00:04:34 -0000	1.2
--- StorageManagerM.nc	8 Jun 2005 21:45:12 -0000	1.3
***************
*** 1,2 ****
--- 1,4 ----
+ includes crc;
+ includes StorageManager;
  module StorageManagerM {
    provides {
***************
*** 5,14 ****
--- 7,38 ----
      interface AT45Remap;
    }
+   uses interface InternalFlash;
  }
  implementation {
+   enum {
+     NVOLUMES = uniqueCount("StorageManager")
+   };
+ 
+   struct volume_definition_t volumes[NVOLUMES];
+   uint8_t nvolumes;
+ 
+   enum {
+     S_BOOT,
+     S_READY,
+     S_MOUNTING,
+     S_INVALID
+   };
+   uint8_t state;
+ 
    volume_t client;
    volume_id_t id;
  
    command result_t StdControl.init() {
+     uint8_t i;
+ 
+     for (i = 0; i < NVOLUMES; i++)
+       volumes[i].id = INVALID_VOLUME_ID;
+ 
+     state = S_BOOT;
      return SUCCESS;
    }
***************
*** 22,41 ****
    }
  
!   task void mounted() {
!     signal Mount.mountDone[client](STORAGE_OK, id);
    }
  
    command result_t Mount.mount[volume_t v](volume_id_t i) {
      client = v;
      id = i;
!     post mounted();
      return SUCCESS;
    }
  
    command at45page_t AT45Remap.remap(volume_t volume, at45page_t volumePage) {
!     if (volume == 0)
!       return volumePage;
!     else
!       return volumePage + 1024;
    }
  }
--- 46,130 ----
    }
  
!   void mountComplete(storage_result_t r) {
!     state = S_READY;
!     signal Mount.mountDone[client](r, id);
!   }
! 
!   task void mountVolume() {
!     uint8_t i;
!     uint8_t *addr = (uint8_t *)VOLUME_DEF_ADDRESS;
! 
!     for (i = 0; i < nvolumes; i++)
!       {
! 	volume_id_t vid;
! 
! 	if (call InternalFlash.read(addr + offsetof(struct volume_definition_t, id),
! 				    &vid, sizeof vid) == FAIL)
! 	  {
! 	    mountComplete(STORAGE_FAIL);
! 	    return;
! 	  }
! 	if (vid == id &&
! 	    call InternalFlash.read(addr, &volumes[client], sizeof volumes[client]) != FAIL)
! 	  {
! 	    mountComplete(STORAGE_OK);
! 	    return;
! 	  }
! 	addr += sizeof(struct volume_definition_t);
!       }
!     mountComplete(STORAGE_FAIL);
!   }
! 
!   task void validateVolumeTable() {
!     struct volume_definition_header_t header;
!     uint16_t i;
!     uint16_t crc;
! 
!     if (call InternalFlash.read((uint8_t *)VOLUME_TABLE_ADDRESS, &header, sizeof header))
!       {
! 	/* Compute crc of volume table */
! 	nvolumes = header.nvolumes;
! 	crc = crcByte(0, nvolumes);
! 	for (i = 0; i < nvolumes * sizeof(struct volume_definition_t); i++)
! 	  {
! 	    uint8_t x;
! 
! 	    if (call InternalFlash.read((uint8_t *)VOLUME_DEF_ADDRESS + i, &x, 1) == FAIL)
! 	      goto invalid;
! 	    crc = crcByte(crc, x);
! 	  }
! 	if (crc == header.crc)
! 	  {
! 	    post mountVolume();
! 	    return;
! 	  }
!       }
!   invalid:
!     state = S_INVALID;
!     signal Mount.mountDone[client](STORAGE_FAIL, id);
    }
  
    command result_t Mount.mount[volume_t v](volume_id_t i) {
+     if (state == S_MOUNTING || state == S_INVALID || volumes[v].id != INVALID_VOLUME_ID)
+       return FAIL;
+ 
      client = v;
      id = i;
! 
!     if (state == S_BOOT)
!       post validateVolumeTable();
!     else
!       post mountVolume();
!     state = S_MOUNTING;
! 
      return SUCCESS;
    }
  
    command at45page_t AT45Remap.remap(volume_t volume, at45page_t volumePage) {
!     return volumePage + volumes[volume].start;
!   }
! 
!   command storage_addr_t AT45Remap.volumeSize(volume_t volume) {
!     return (storage_addr_t)volumes[volume].length << AT45_PAGE_SIZE_LOG2;
    }
  }

Index: Storage_chip.h
===================================================================
RCS file: /cvsroot/tinyos/tinyos-1.x/beta/AT45DB/Storage_chip.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** Storage_chip.h	4 Jun 2005 00:04:34 -0000	1.1
--- Storage_chip.h	8 Jun 2005 21:45:12 -0000	1.2
***************
*** 1 ****
--- 1,3 ----
  #include "HALAT45DB.h"
+ 
+ typedef uint32_t storage_addr_t;



More information about the Tinyos-beta-commits mailing list