X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=tos%2Fchips%2Fstm25p%2FStm25pLogP.nc;h=e454de79d88c27d03d5b8dafb4aca2e937632343;hb=e9bfab607e051bae6afb47b44892ce37541d1b44;hp=7ccde10fe9b4a7b31f6a3556f05f3bf555f560fe;hpb=1ba974b83d19fc41bf80acd52726f36f7f1df297;p=tinyos-2.x.git diff --git a/tos/chips/stm25p/Stm25pLogP.nc b/tos/chips/stm25p/Stm25pLogP.nc index 7ccde10f..e454de79 100644 --- a/tos/chips/stm25p/Stm25pLogP.nc +++ b/tos/chips/stm25p/Stm25pLogP.nc @@ -87,8 +87,8 @@ implementation { 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_remaining; uint8_t m_len; typedef enum { @@ -161,8 +161,8 @@ implementation { // don't allow appends larger than maximum record size if ( len > MAX_RECORD_SIZE ) - return ESIZE; - + return EINVAL; + // 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; @@ -172,7 +172,8 @@ implementation { ( (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; @@ -198,6 +199,18 @@ implementation { } + 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 @@ -227,12 +240,14 @@ implementation { (storage_cookie_t)(writeSector-numSectors) <> 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; - } - void continueReadOp( uint8_t client ) { stm25p_addr_t read_addr = m_log_info[ client ].read_addr; @@ -279,7 +282,7 @@ implementation { } buf = &m_header; - len = sizeof( len ); + len = sizeof( m_header ); if ( m_rw_state == S_DATA ) { // if header is invalid, move to next block @@ -289,17 +292,18 @@ implementation { read_addr &= ~BLOCK_MASK; } else { - buf = m_log_state[ client ].buf; + buf = m_log_state[ client ].buf + m_log_state[ client ].len - m_len; // truncate if record is shorter than requested length - if ( m_remaining < m_len ) - m_log_state[ client ].len = m_remaining; - len = m_len; + if ( m_log_info[ client ].remaining < m_len ) + len = m_log_info[ client ].remaining; + else + len = m_len; } } // if on block boundary if ( !((uint16_t)read_addr & BLOCK_MASK ) ) - read_addr += sizeof( storage_addr_t ); + read_addr += sizeof( m_addr ); m_log_info[ client ].read_addr = read_addr; call Sector.read[ client ]( calcAddr( client, read_addr ), buf, len ); @@ -315,7 +319,7 @@ implementation { switch( m_rw_state ) { case S_SEARCH_BLOCKS: { - uint8_t block = addr >> BLOCK_SIZE_LOG2; + uint16_t block = addr >> BLOCK_SIZE_LOG2; // record potential starting and ending addresses if ( m_addr != STM25P_INVALID_ADDRESS ) { if ( m_addr < log_info->read_addr ) @@ -324,8 +328,7 @@ implementation { log_info->write_addr = m_addr; } // move on to next log block - if ( (uint16_t)m_addr == 0 && - ++block < (call Sector.getNumSectors[ id ]()*BLOCKS_PER_SECTOR)) { + if (++block < (call Sector.getNumSectors[ id ]()*BLOCKS_PER_SECTOR)) { addr += BLOCK_SIZE; call Sector.read[ id ]( addr, (uint8_t*)&m_addr, sizeof( m_addr ) ); } @@ -339,7 +342,7 @@ implementation { else { log_info->write_addr += sizeof( m_addr ); m_rw_state = S_SEARCH_RECORDS; - call Sector.read[ id ]( log_info->write_addr, &m_header, + call Sector.read[ id ]( calcAddr(id, log_info->write_addr), &m_header, sizeof( m_header ) ); } } @@ -354,8 +357,8 @@ implementation { // if header is valid and is on same block, move to next record if ( m_header != INVALID_HEADER && cur_block == new_block ) { log_info->write_addr += sizeof( m_header ) + m_header; - call Sector.read[ id ]( log_info->write_addr, &m_header, - sizeof( m_header ) ); + call Sector.read[ id ]( calcAddr( id, log_info->write_addr ), + &m_header, sizeof( m_header ) ); } // found last record else { @@ -369,8 +372,8 @@ implementation { // searching for last log record to read log_info->read_addr += sizeof( m_header ) + m_header; // if not yet at cookie, keep searching - if ( log_info->read_addr < m_log_state->cookie ) { - call Sector.read[ id ]( log_info->read_addr, &m_header, + if ( log_info->read_addr < m_log_state[ id ].cookie ) { + call Sector.read[ id ]( calcAddr(id, log_info->read_addr), &m_header, sizeof( m_header ) ); } // at or passed cookie, stop @@ -415,14 +418,19 @@ implementation { void continueAppendOp( uint8_t client ) { stm25p_addr_t write_addr = m_log_info[ client ].write_addr; - uint8_t* buf; + void* buf; uint8_t len; if ( !(uint16_t)write_addr ) { + m_records_lost = TRUE; call Sector.erase[ client ]( calcSector( client, write_addr ), 1 ); } else { - if ( m_rw_state == S_HEADER ) { + if ( !((uint16_t)write_addr & BLOCK_MASK) ) { + buf = &m_log_info[ client ].write_addr; + len = sizeof( m_addr ); + } + else if ( m_rw_state == S_HEADER ) { buf = &m_log_state[ client ].len; len = sizeof( m_log_state[ client ].len ); } @@ -448,7 +456,7 @@ implementation { // (the log could have cycled around) stm25p_addr_t volume_size = STM25P_SECTOR_SIZE * ( call Sector.getNumSectors[ id ]() - 1 ); - if ( m_log_info[ id ].write_addr >= volume_size ) { + if ( m_log_info[ id ].write_addr > volume_size ) { stm25p_addr_t read_addr = m_log_info[ id ].write_addr - volume_size; if ( m_log_info[ id ].read_addr < read_addr ) m_log_info[ id ].read_addr = read_addr; @@ -495,7 +503,7 @@ implementation { signal Write.eraseDone[ id ]( error ); break; case S_APPEND: - signal Write.appendDone[ id ]( buf, len, error ); + signal Write.appendDone[ id ]( buf, len, m_records_lost, error ); break; case S_SYNC: signal Write.syncDone[ id ]( error ); @@ -508,7 +516,7 @@ implementation { default event void Read.readDone[ uint8_t id ]( void* data, storage_len_t len, error_t error ) {} default event void Read.seekDone[ uint8_t id ]( error_t error ) {} default event void Write.eraseDone[ uint8_t id ]( error_t error ) {} - default event void Write.appendDone[ uint8_t id ]( void* data, storage_len_t len, error_t error ) {} + default event void Write.appendDone[ uint8_t id ]( void* data, storage_len_t len, bool recordsLost, error_t error ) {} default event void Write.syncDone[ uint8_t id ]( error_t error ) {} default command storage_addr_t Sector.getPhysicalAddress[ uint8_t id ]( storage_addr_t addr ) { return 0xffffffff; } @@ -518,7 +526,7 @@ implementation { default command error_t Sector.erase[ uint8_t id ]( uint8_t sector, uint8_t num_sectors ) { return FAIL; } default command error_t Sector.computeCrc[ uint8_t id ]( uint16_t crc, storage_addr_t addr, storage_len_t len ) { return FAIL; } default async command error_t ClientResource.request[ uint8_t id ]() { return FAIL; } - default async command void ClientResource.release[ uint8_t id ]() {} + default async command error_t ClientResource.release[ uint8_t id ]() { return FAIL; } default command bool Circular.get[ uint8_t id ]() { return FALSE; } }