📄 tep103.txt
字号:
If the ``circular`` argument is TRUE, the log is circular; otherwise
it is linear.
The ``LogRead`` and ``LogWrite`` interfaces (briefly presented in
Appendix B) contain the following operations (all split-phase except
``LogWrite.currentOffset``, ``LogRead.currentOffset`` and
``LogRead.getSize``):
- ``LogWrite.erase``: erase the log. A log MUST be erased (possibly in
some previous session) before any other operation can be used.
- ``LogWrite.append``: append some bytes to the log. In a circular log,
this may overwrite the current read position. In this case, the
read position MUST be advanced to the log's current beginning
(i.e., as if ``LogRead.seek`` had been called with ``SEEK_BEGINNING``).
Additionally, the ``LogWrite.appendDone`` event reports whenever, in a
circular log, an append MAY have erased old records.
Each append creates a separate record. Log implementations may have a
maximum record size; all implementations MUST support records of up
to 255 bytes.
- ``LogWrite.sync``: guarantee that data written so far will not be lost to
a crash or reboot (it can still be overwritten when a circular log wraps
around). Using ``sync`` MAY waste some space in the log.
- ``LogWrite.currentOffset``: return cookie representing current
append position (for use with ``LogRead.seek``).
- ``LogRead.read``: read some bytes from the current read position in
the log and advance the read position.
``LogStorageC`` implementations MUST include error detection codes
to increase the likelihood of detection of corrupted or invalid log
data. Data returned by a successful read MUST have passed this
error detection check. The behaviour on failure of this check is
unspecified (e.g., the at45db believes as if the end of the log has
been reached; other implementations may behave differently).
- ``LogRead.currentOffset``: return cookie representing current
read position (for use with ``LogRead.seek``).
- ``LogRead.seek``: set the read position to a value returned by
a prior call to ``LogWrite.currentOffset`` or ``LogRead.currentOffset``,
or to the special ``SEEK_BEGINNING`` value. In a circular log, if
the specified position has been overwritten, behave as if
``SEEK_BEGINNING`` was requested.
``SEEK_BEGINNING`` positions the read position at the beginning of
the oldest record still present in the log.
After reboot, the current read position is ``SEEK_BEGINNING``.
- ``LogRead.getSize``: return an approximation of the log's capacity
in bytes. Uses of ``sync`` and other overhead may reduce this number.
For full details on arguments, etc, see the comments in the interface
definitions.
Note that while each call to ``append`` logically creates a separate
record, the ``LogStorageC`` API does not report record
boundaries. Additionally, crashes, reboots, and appends after
wrap-around in a circular log can cause the loss of multiple consecutive
records. Taken together, these restrictions mean that a ``LogStorageC``
implementation MAY internally aggregate several consecutive appends into
a single record. However, the guarantee that only whole records are lost
is sufficient to ensure that applications do not to have worry about
incomplete or inconsistent log entries.
4.4 Small objects:
------------------------------------------------------------------
Sensor network applications need to store configuration data, e.g.,
mote identity, radio frequency, sample rates, etc. Such data is not large, but
losing it may lead to a mote misbehaving or losing contact with the
network.
The ``ConfigStorageC`` abstraction stores a single small object in a volume. It:
- Assumes that configuration data is relatively small (a few
hundred bytes).
- Allows random reads and writes.
- Has simple transactional behaviour: each read is a separate transaction,
all writes up to a commit form a single transaction.
- At reboot, the volume contains the data as of the most recent successful
commit.
Small objects are accessed by instantiating a ConfigStorageC component
which takes a volume id argument: ::
generic configuration ConfigStorageC(volume_id_t volid) {
provides {
interface Mount;
interface ConfigStorage;
}
} ...
A small object MUST be mounted (via the ``Mount`` interface) before
the first use.
The ``Mount`` and ``ConfigStorage`` interfaces (briefly presented in
Appendix B) contain the following operations (all split-phase except
``ConfigStorage.getSize`` and ``ConfigStorage.valid``):
- ``Mount.mount``: mount the volume.
- ``ConfigStorage.valid``: return TRUE if the volume contains a
valid small object.
- ``ConfigStorage.read``: read some bytes starting at a given offset.
Fails if the small object is not valid. Note that this reads the
data as of the last successful commit.
- ``ConfigStorage.write``: write some bytes to a given offset.
- ``ConfigStorage.commit``: make the small object contents reflect all the
writes since the last commit.
- ``ConfigStorage.getSize``: return the number of bytes that can be stored
in the small object.
For full details on arguments, etc, see the comments in the interface
definitions.
5. Implementations
====================================================================
An AT45DB implementation can be found in tinyos-2.x/tos/chips/at45db.
An ST M25P implementation can be found in tinyos-2.x/tos/chips/stm25p.
6. Authors' Addresses
====================================================================
| David Gay
| 2150 Shattuck Ave, Suite 1300
| Intel Research
| Berkeley, CA 94704
|
| phone - +1 510 495 3055
| email - david.e.gay@intel.com
|
|
| Jonathan Hui
| 657 Mission St. Ste. 600
| Arched Rock Corporation
| San Francisco, CA 94105-4120
|
| phone - +1 415 692 0828
| email - jhui@archedrock.com
7. Citations
====================================================================
.. [1] David Gay. "Design of Matchbox, the simple filing system for
motes. (version 1.0)."
.. [2] TEP 2: Hardware Abstraction Architecture.
Appendix A. HAA for some existing flash chips
====================================================================
A.1 AT45DB
------------------------------------------------------------------
The Atmel AT45DB family HPL is: ::
configuration HplAt45dbC {
provides interface HplAt45db;
} ...
The ``HplAt45db`` interface has flash->buffer, buffer->flash, compare
buffer to flash, erase page, read, compute CRC, and write operations. Most
of these operations are asynchronous, i.e., their completion is signaled
before the flash chip has completed the operation. The HPL also includes
operations to wait for asynchronous operations to complete.
A generic, system-independent implementation of the HPL
(``HplAt45dbByteC``) is included allowing platforms to just provide SPI and
chip selection interfaces.
Different members of the AT45DB family are supported by specifying a few
constants (number of pages, page size).
The AT45DB HAL has two components, one for chip access and the other
providing volume information: ::
component At45dbC
{
provides {
interface At45db;
interface Resource[uint8_t client];
interface ResourceController;
interface ArbiterInfo;
}
} ...
configuration At45dbStorageManagerC {
provides interface At45dbVolume[volume_id_t volid];
} ...
Note that the AT45DB HAL resource management is independent of the
underlying HPL's power management. The motivation for this is that
individual flash operations may take a long time, so it may be desirable to
release the flash's bus during long-running operations.
The ``At45db`` interface abstracts from the low-level HPL operations by:
- using the flash's 2 RAM buffers as a cache to allow faster reads and
writes
- hiding the asynchronous nature of the HPL operations
- verifying that all writes were successful
It provides cached read, write and CRC computation, and page erase and
copy. It also includes flush and sync operations to manage the cache.
The ``At45dbVolume`` interface has operations to report volume size and
map volume-relative pages to absolute pages.
A.2 ST M25P
------------------------------------------------------------------
The ST M25P family HPL is: ::
configuration Stm25pSpiC {
provides interface Init;
provides interface Resource;
provides interface Stm25pSpi;
}
The ``Stm25pSpi`` interface has read, write, compute CRC, sector erase
and block erase operations. The implementation of this HPL is
system-independent, built over a few system-dependent components
providing SPI and chip selection interfaces.
Note that these two examples have different resource management policies:
the AT45DB encapsulates resource acquisition and release within each
operation, while the M25P family requires that HPL users acquire and
release the resource itself.
The ST M25P HAL is: ::
configuration Stm25pSectorC {
provides interface Resource as ClientResource[storage_volume_t volume];
provides interface Stm25pSector as Sector[storage_volume_t volume];
provides interface Stm25pVolume as Volume[storage_volume_t volume];
}
The ``Stm25pSector`` interface provides volume-relative operations similar
to those from the HPL interface: read, write, compute CRC and
erase. Additionally, it has operations to report volume size and remap
volume-relative addresses. Clients of the ST M25P HAL must implement the
``getVolumeId`` event of the ``Stm25pVolume`` interface so that the HAL can
obtain the volume id of each of its clients.
Appendix B. Storage interfaces
====================================================================
These interfaces are presented briefly here for reference; please refer
to the TinyOS documentation for a full description of the commands,
events and their parameters.
B.1 BlockStorage interfaces
------------------------------------------------------------------
The BlockStorage interfaces are: ::
interface BlockRead {
command error_t read(storage_addr_t addr, void* buf, storage_len_t len);
event void readDone(storage_addr_t addr, void* buf, storage_len_t len,
error_t error);
command error_t computeCrc(storage_addr_t addr, storage_len_t len,
uint16_t crc);
event void computeCrcDone(storage_addr_t addr, storage_len_t len,
uint16_t crc, error_t error);
command storage_len_t getSize();
}
interface BlockWrite {
command error_t write(storage_addr_t addr, void* buf, storage_len_t len);
event void writeDone(storage_addr_t addr, void* buf, storage_len_t len,
error_t error);
command error_t erase();
event void eraseDone(error_t error);
command error_t sync();
event void syncDone(error_t error);
}
B.2 ConfigStorage interfaces
------------------------------------------------------------------
The ConfigStorage interfaces are: ::
interface Mount {
command error_t mount();
event void mountDone(error_t error);
}
interface ConfigStorage {
command error_t read(storage_addr_t addr, void* buf, storage_len_t len);
event void readDone(storage_addr_t addr, void* buf, storage_len_t len,
error_t error);
command error_t write(storage_addr_t addr, void* buf, storage_len_t len);
event void writeDone(storage_addr_t addr, void* buf, storage_len_t len,
error_t error);
command error_t commit();
event void commitDone(error_t error);
command storage_len_t getSize();
command bool valid();
}
B.3 LogStorage interfaces
------------------------------------------------------------------
The LogStorage interfaces are: ::
interface LogRead {
command error_t read(void* buf, storage_len_t len);
event void readDone(void* buf, storage_len_t len, error_t error);
command storage_cookie_t currentOffset();
command error_t seek(storage_cookie_t offset);
event void seekDone(error_t error);
command storage_len_t getSize();
}
interface LogWrite {
command error_t append(void* buf, storage_len_t len);
event void appendDone(void* buf, storage_len_t len, bool recordsLost,
error_t error);
command storage_cookie_t currentOffset();
command error_t erase();
event void eraseDone(error_t error);
command error_t sync();
event void syncDone(error_t error);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -