stm25plogp.nc
来自「tinyos-2.x.rar」· NC 代码 · 共 533 行 · 第 1/2 页
NC
533 行
}
}
void continueReadOp( uint8_t client ) {
stm25p_addr_t read_addr = m_log_info[ client ].read_addr;
uint8_t* buf;
uint8_t len;
// check if all done
if ( m_len == 0 || read_addr >= m_log_info[ client ].write_addr ) {
signalDone( client, SUCCESS );
return;
}
buf = &m_header;
len = sizeof( m_header );
if ( m_rw_state == S_DATA ) {
// if header is invalid, move to next block
if ( m_header == INVALID_HEADER ) {
m_rw_state = S_HEADER;
read_addr += BLOCK_SIZE;
read_addr &= ~BLOCK_MASK;
}
else {
buf = m_log_state[ client ].buf + m_log_state[ client ].len - m_len;
// truncate if record is shorter than requested length
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( m_addr );
m_log_info[ client ].read_addr = read_addr;
call Sector.read[ client ]( calcAddr( client, read_addr ), buf, len );
}
event void Sector.readDone[ uint8_t id ]( stm25p_addr_t addr, uint8_t* buf,
stm25p_len_t len, error_t error ) {
stm25p_log_info_t* log_info = &m_log_info[ id ];
// searching for the first and last log blocks
switch( m_rw_state ) {
case S_SEARCH_BLOCKS:
{
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 )
log_info->read_addr = m_addr;
if ( m_addr > log_info->write_addr )
log_info->write_addr = m_addr;
}
// move on to next log block
if (++block < (call Sector.getNumSectors[ id ]()*BLOCKS_PER_SECTOR)) {
addr += BLOCK_SIZE;
call Sector.read[ id ]( addr, (uint8_t*)&m_addr, sizeof( m_addr ) );
}
// if log is empty, continue operation
else if ( log_info->read_addr == STM25P_INVALID_ADDRESS ) {
log_info->read_addr = 0;
log_info->write_addr = 0;
signal ClientResource.granted[ id ]();
}
// search for last record
else {
log_info->write_addr += sizeof( m_addr );
m_rw_state = S_SEARCH_RECORDS;
call Sector.read[ id ]( calcAddr(id, log_info->write_addr), &m_header,
sizeof( m_header ) );
}
}
break;
case S_SEARCH_RECORDS:
{
// searching for the last log record to write
uint16_t cur_block = log_info->write_addr >> BLOCK_SIZE_LOG2;
uint16_t new_block = ( log_info->write_addr + sizeof( m_header ) +
m_header ) >> BLOCK_SIZE_LOG2;
// 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 ]( calcAddr( id, log_info->write_addr ),
&m_header, sizeof( m_header ) );
}
// found last record
else {
signal ClientResource.granted[ id ]();
}
}
break;
case S_SEARCH_SEEK:
{
// 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[ id ].cookie ) {
call Sector.read[ id ]( calcAddr(id, log_info->read_addr), &m_header,
sizeof( m_header ) );
}
// at or passed cookie, stop
else {
log_info->remaining = log_info->read_addr - m_log_state[ id ].cookie;
log_info->read_addr = m_log_state[ id ].cookie;
signalDone( id, error );
}
}
break;
case S_HEADER:
{
// if header is invalid, move to next block
if ( m_header == INVALID_HEADER ) {
log_info->read_addr += BLOCK_SIZE;
log_info->read_addr &= ~BLOCK_MASK;
}
else {
log_info->read_addr += sizeof( m_header );
log_info->remaining = m_header;
m_rw_state = S_DATA;
}
continueReadOp( id );
}
break;
case S_DATA:
{
log_info->read_addr += len;
log_info->remaining -= len;
m_len -= len;
m_rw_state = S_HEADER;
continueReadOp( id );
break;
}
}
}
void continueAppendOp( uint8_t client ) {
stm25p_addr_t write_addr = m_log_info[ client ].write_addr;
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 ( !((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 );
}
else {
buf = m_log_state[ client ].buf;
len = m_log_state[ client ].len;
}
call Sector.write[ client ]( calcAddr( client, write_addr ), buf, len );
}
}
event void Sector.eraseDone[ uint8_t id ]( uint8_t sector,
uint8_t num_sectors,
error_t error ) {
if ( m_log_state[ id ].req == S_ERASE ) {
m_log_info[ id ].read_addr = 0;
m_log_info[ id ].write_addr = 0;
signalDone( id, error );
}
else {
// advance read pointer if write pointer has gone too far ahead
// (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 ) {
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;
}
m_addr = m_log_info[ id ].write_addr;
call Sector.write[ id ]( calcAddr( id, m_addr ), (uint8_t*)&m_addr,
sizeof( m_addr ) );
}
}
event void Sector.writeDone[ uint8_t id ]( storage_addr_t addr,
uint8_t* buf,
storage_len_t len,
error_t error ) {
m_log_info[ id ].write_addr += len;
if ( m_rw_state == S_HEADER ) {
if ( len == sizeof( m_header ) )
m_rw_state = S_DATA;
continueAppendOp( id );
}
else {
signalDone( id, error );
}
}
void signalDone( uint8_t id, error_t error ) {
stm25p_log_req_t req = m_log_state[ id ].req;
void* buf = m_log_state[ id ].buf;
storage_len_t len = m_log_state[ id ].len;
call ClientResource.release[ id ]();
m_log_state[ id ].req = S_IDLE;
switch( req ) {
case S_IDLE:
break;
case S_READ:
signal Read.readDone[ id ]( buf, len - m_len, error );
break;
case S_SEEK:
signal Read.seekDone[ id ]( error );
break;
case S_ERASE:
signal Write.eraseDone[ id ]( error );
break;
case S_APPEND:
signal Write.appendDone[ id ]( buf, len, m_records_lost, error );
break;
case S_SYNC:
signal Write.syncDone[ id ]( error );
break;
}
}
event void Sector.computeCrcDone[ uint8_t id ]( stm25p_addr_t addr, stm25p_len_t len, uint16_t crc, error_t error ) {}
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, 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; }
default command uint8_t Sector.getNumSectors[ uint8_t id ]() { return 0; }
default command error_t Sector.read[ uint8_t id ]( storage_addr_t addr, uint8_t* buf, storage_len_t len ) { return FAIL; }
default command error_t Sector.write[ uint8_t id ]( storage_addr_t addr, uint8_t* buf, storage_len_t len ) { return FAIL; }
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 error_t ClientResource.release[ uint8_t id ]() { return FAIL; }
default command bool Circular.get[ uint8_t id ]() { return FALSE; }
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?