flash.cc
Go to the documentation of this file.
00001 
00037 #include "details/channel.hh"
00038 #include "details/query.hh"
00039 
00040 #include "details/wire/AckMessage.h"
00041 #include "details/wire/SysFlashOpMessage.h"
00042 #include "details/wire/SysFlashResponseMessage.h"
00043 
00044 namespace crl {
00045 namespace multisense {
00046 namespace details {
00047 
00048 //
00049 // Erase a flash region
00050 
00051 void impl::eraseFlashRegion(uint32_t region)
00052 {
00053     wire::SysFlashResponse response;
00054 
00055     //
00056     // Start the erase operation
00057 
00058     Status status = waitData(wire::SysFlashOp(wire::SysFlashOp::OP_ERASE, region),
00059                              response);
00060     if (Status_Ok != status)
00061         CRL_EXCEPTION("OP_ERASE failed: %d", status);
00062 
00063     //
00064     // Check for success, or flash in progress
00065 
00066     switch(response.status) {
00067     case wire::SysFlashResponse::STATUS_SUCCESS:
00068     case wire::SysFlashResponse::STATUS_ERASE_IN_PROGRESS:
00069         break; // ok, erase is happening
00070     default:
00071         CRL_EXCEPTION("OP_ERASE ack'd, but failed: %d\n", response.status);
00072     }
00073 
00074     //
00075     // Wait for the erase to complete
00076 
00077     const double ERASE_TIMEOUT = 210.0; // seconds
00078 
00079     utility::TimeStamp start = utility::TimeStamp::getCurrentTime();
00080 
00081     int prevProgress = -1;
00082 
00083     while((utility::TimeStamp::getCurrentTime() - start) < ERASE_TIMEOUT) {
00084 
00085         //
00086         // Request current progress
00087 
00088         status = waitData(wire::SysFlashOp(), response);
00089         if (Status_Ok != status)
00090             CRL_EXCEPTION("failed to request flash erase status");
00091 
00092         //
00093         // IDLE means the flash has been erased
00094 
00095         if (wire::SysFlashResponse::STATUS_IDLE == response.status)
00096             return; // success
00097 
00098         //
00099         // Prompt and delay a bit
00100 
00101         if (response.erase_progress != prevProgress &&
00102             0 == (response.erase_progress % 5))
00103             CRL_DEBUG("erasing... %3d%%\n", response.erase_progress);
00104         usleep(100000);
00105 
00106         prevProgress = response.erase_progress;
00107     }
00108 
00109     CRL_EXCEPTION("erase op timed out after %.0f seconds", ERASE_TIMEOUT);
00110 }
00111 
00112 //
00113 // Program or verify a flash region from a file
00114 
00115 void impl::programOrVerifyFlashRegion(std::ifstream& file,
00116                                       uint32_t       operation,
00117                                       uint32_t       region)
00118 {
00119     //
00120     // Get file size
00121 
00122     file.seekg(0, file.end);
00123     std::streamoff fileLength = file.tellg();
00124     file.seekg(0, file.beg);
00125 
00126     wire::SysFlashOp op(operation, region, 0,
00127                         wire::SysFlashOp::MAX_LENGTH);
00128 
00129     int prevProgress = -1;
00130 
00131     const char *opNameP;
00132 
00133     switch(operation) {
00134     case wire::SysFlashOp::OP_PROGRAM: opNameP = "programming"; break;
00135     case wire::SysFlashOp::OP_VERIFY:  opNameP = "verifying";   break;
00136     default: 
00137         CRL_EXCEPTION("unknown operation type: %d", operation);
00138     }
00139 
00140     do {
00141 
00142         //
00143         // Initialize data and read next chunk
00144 
00145         memset(op.data, 0xFF, op.length);
00146         file.read((char *) op.data, op.length);
00147 
00148         //
00149         // Send command, await response
00150 
00151         wire::SysFlashResponse rsp;
00152 
00153         Status status = waitData(op, rsp, 0.5, 4);
00154         if (Status_Ok != status)
00155             CRL_EXCEPTION("SysFlashOp (%s) failed: %d", opNameP, status);
00156         else if (wire::SysFlashResponse::STATUS_SUCCESS != rsp.status)
00157             CRL_EXCEPTION("%s failed @ %d/%d bytes", opNameP,
00158                           file.tellg(), fileLength);
00159 
00160         //
00161         // Print out progress
00162 
00163         int progress = static_cast<int> ((100 * op.start_address) / fileLength);
00164         if (progress != prevProgress && 0 == (progress % 5))
00165             CRL_DEBUG("%s... %3d%%\n", opNameP, progress);
00166 
00167         //
00168         // Update state
00169 
00170         prevProgress = progress;
00171         op.start_address += op.length;
00172 
00173     } while (!file.eof());
00174 
00175     if ((int) op.start_address < fileLength)
00176         CRL_EXCEPTION("unexpected EOF while %s", opNameP);
00177 
00178     CRL_DEBUG("%s complete\n", opNameP);
00179 }
00180 
00181 //
00182 // Wrapper for all flash operations
00183 
00184 Status impl::doFlashOp(const std::string& filename,
00185                        uint32_t           operation,
00186                        uint32_t           region)
00187 {
00188     try {
00189         std::ifstream file(filename.c_str(), 
00190                            std::ios::in | std::ios::binary);
00191 
00192         if (!file.good()) 
00193             CRL_EXCEPTION("unable to open file: \"%s\"", 
00194                           filename.c_str());
00195 
00196         if (wire::SysFlashOp::OP_PROGRAM == operation)
00197             eraseFlashRegion(region);
00198 
00199         programOrVerifyFlashRegion(file, operation, region);
00200 
00201     } catch (const std::exception& e) {
00202         CRL_DEBUG("exception: %s\n", e.what());
00203         return Status_Exception;
00204     }
00205 
00206     return Status_Ok;
00207 }    
00208 
00209 }}}; // namespaces


multisense_lib
Author(s):
autogenerated on Thu Aug 27 2015 14:01:11