📄 stm25plogp.nc
字号:
} } 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 ]( 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 ]( 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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -