⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stm25plogp.nc

📁 tinyos2.0版本驱动
💻 NC
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2005-2006 Arch Rock Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * - Redistributions of source code must retain the above copyright *   notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright *   notice, this list of conditions and the following disclaimer in the *   documentation and/or other materials provided with the *   distribution. * - Neither the name of the Arch Rock Corporation nor the names of *   its contributors may be used to endorse or promote products derived *   from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE *//** * @author Jonathan Hui <jhui@archrock.com> * @version $Revision: 1.7 $ $Date: 2007/11/28 03:15:30 $ */#include <Stm25p.h>module Stm25pLogP {    provides interface Init;  provides interface LogRead as Read[ uint8_t id ];  provides interface LogWrite as Write[ uint8_t id ];    uses interface Stm25pSector as Sector[ uint8_t id ];  uses interface Resource as ClientResource[ uint8_t id ];  uses interface Get<bool> as Circular[ uint8_t id ];  uses interface Leds;}implementation {  enum {    NUM_LOGS = uniqueCount( "Stm25p.Log" ),    BLOCK_SIZE = 4096,    BLOCK_SIZE_LOG2 = 12,    BLOCK_MASK = BLOCK_SIZE - 1,    BLOCKS_PER_SECTOR = STM25P_SECTOR_SIZE / BLOCK_SIZE,    MAX_RECORD_SIZE = 254,    INVALID_HEADER = 0xff,  };    typedef enum {    S_IDLE,    S_READ,    S_SEEK,    S_ERASE,    S_APPEND,    S_SYNC,  } stm25p_log_req_t;  typedef struct stm25p_log_state_t {    storage_cookie_t cookie;    void* buf;    uint8_t len;    stm25p_log_req_t req;  } stm25p_log_state_t;  typedef struct stm25p_log_info_t {    stm25p_addr_t read_addr;    stm25p_addr_t remaining;    stm25p_addr_t write_addr;  } stm25p_log_info_t;    stm25p_log_state_t m_log_state[ NUM_LOGS ];  stm25p_log_state_t m_req;  stm25p_log_info_t m_log_info[ NUM_LOGS ];  stm25p_addr_t m_addr;  bool m_records_lost;  uint8_t m_header;  uint8_t m_len;  typedef enum {    S_SEARCH_BLOCKS,    S_SEARCH_RECORDS,    S_SEARCH_SEEK,    S_HEADER,    S_DATA,  } stm25p_log_rw_state_t;  stm25p_log_rw_state_t m_rw_state;  error_t newRequest( uint8_t client );  void continueReadOp( uint8_t client );  void continueAppendOp( uint8_t client );  void signalDone( uint8_t id, error_t error );    command error_t Init.init() {    int i;    for ( i = 0; i < NUM_LOGS; i++ ) {      m_log_info[ i ].read_addr = STM25P_INVALID_ADDRESS;      m_log_info[ i ].write_addr = 0;    }    return SUCCESS;  }    command error_t Read.read[ uint8_t id ]( void* buf, storage_len_t len ) {        m_req.req = S_READ;    m_req.buf = buf;    m_req.len = len;    m_len = len;    return newRequest( id );      }    command error_t Read.seek[ uint8_t id ]( storage_addr_t cookie ) {        if ( cookie > m_log_info[ id ].write_addr )      return FAIL;        m_req.req = S_SEEK;    m_req.cookie = cookie;    return newRequest( id );      }    command storage_cookie_t Read.currentOffset[ uint8_t id ]() {    return m_log_info[ id ].read_addr;  }    command storage_cookie_t Read.getSize[ uint8_t id ]() {    return ( (storage_len_t)call Sector.getNumSectors[ id ]()             << STM25P_SECTOR_SIZE_LOG2 );  }    command storage_cookie_t Write.currentOffset[ uint8_t id ]() {    return m_log_info[ id ].write_addr;  }    command error_t Write.erase[ uint8_t id ]() {    m_req.req = S_ERASE;    return newRequest( id );  }    command error_t Write.append[ uint8_t id ]( void* buf, storage_len_t len ) {        uint16_t bytes_left = (uint16_t)m_log_info[ id ].write_addr % BLOCK_SIZE;    bytes_left = BLOCK_SIZE - bytes_left;        // don't allow appends larger than maximum record size    if ( len > MAX_RECORD_SIZE )      return ESIZE;        // move to next block if current block doesn't have enough space    if ( sizeof( m_header ) + len > bytes_left )      m_log_info[ id ].write_addr += bytes_left;        // if log is not circular, make sure it doesn't grow too large    if ( !call Circular.get[ id ]() &&	 ( (uint8_t)(m_log_info[ id ].write_addr >> STM25P_SECTOR_SIZE_LOG2) >=	   call Sector.getNumSectors[ id ]() ) )      return ESIZE;        m_records_lost = FALSE;    m_req.req = S_APPEND;    m_req.buf = buf;    m_req.len = len;    return newRequest( id );  }    command error_t Write.sync[ uint8_t id ]() {    m_req.req = S_SYNC;    return newRequest( id );  }    error_t newRequest( uint8_t client ) {        if ( m_log_state[ client ].req != S_IDLE )      return FAIL;        call ClientResource.request[ client ]();    m_log_state[ client ] = m_req;        return SUCCESS;      }    uint8_t calcSector( uint8_t client, stm25p_addr_t addr ) {    uint8_t sector = call Sector.getNumSectors[ client ]();    return (uint8_t)( addr >> STM25P_SECTOR_SIZE_LOG2 ) % sector;  }  stm25p_addr_t calcAddr( uint8_t client, stm25p_addr_t addr  ) {    stm25p_addr_t result = calcSector( client, addr );    result <<= STM25P_SECTOR_SIZE_LOG2;    result |= addr & STM25P_SECTOR_MASK;    return result;  }  event void ClientResource.granted[ uint8_t id ]() {    // log never used, need to find start and end of log    if ( m_log_info[ id ].read_addr == STM25P_INVALID_ADDRESS &&	 m_log_state[ id ].req != S_ERASE ) {      m_rw_state = S_SEARCH_BLOCKS;      call Sector.read[ id ]( 0, (uint8_t*)&m_addr, sizeof( m_addr ) );    }    // start and end of log known, do the requested operation    else {      switch( m_log_state[ id ].req ) {      case S_READ:	m_rw_state = (m_log_info[ id ].remaining) ? S_DATA : S_HEADER;	continueReadOp( id );	break;      case S_SEEK:	{	  // make sure the cookie is still within the range of valid data	  uint8_t numSectors = call Sector.getNumSectors[ id ]();	  uint8_t readSector = 	    (m_log_state[ id ].cookie >> STM25P_SECTOR_SIZE_LOG2);	  uint8_t writeSector =	    ((m_log_info[ id ].write_addr-1)>>STM25P_SECTOR_SIZE_LOG2)+1;	  // if cookie is overwritten, advance to beginning of log	  if ( (writeSector - readSector) > numSectors ) {	    m_log_state[ id ].cookie = 	      (storage_cookie_t)(writeSector-numSectors)		<<STM25P_SECTOR_SIZE_LOG2;	  }	  m_log_info[ id ].read_addr = m_log_state[ id ].cookie & ~BLOCK_MASK;	  m_log_info[ id ].remaining = 0;	  m_rw_state = S_SEARCH_SEEK;	  if ( m_log_info[ id ].read_addr != m_log_state[ id ].cookie ) {	    m_log_info[ id ].read_addr += sizeof( m_addr );	    call Sector.read[ id ]( calcAddr( id, m_log_info[ id ].read_addr ),				    &m_header, sizeof( m_header ) );	  }	  else	    signalDone( id, SUCCESS );	}	break;      case S_ERASE:	call Sector.erase[ id ]( 0, call Sector.getNumSectors[ id ]() );	break;      case S_APPEND:	m_rw_state = S_HEADER;	continueAppendOp( id );	break;      case S_SYNC:	signalDone( id, SUCCESS );	break;      case S_IDLE:	break;      }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -