Arianna autonomous DAQ firmware
Dependencies: mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW
SnSDUtils.cpp
- Committer:
- uci1
- Date:
- 2012-08-04
- Revision:
- 7:079617408fec
- Parent:
- 6:6f002d202f59
- Child:
- 8:95a325df1f6b
File content as of revision 7:079617408fec:
#include "SnSDUtils.h" #include "mbed.h" #include "SDFileSystem.h" #include <string.h> #include "SnConfigFrame.h" #include "SnEventFrame.h" const char* const SnSDUtils::kSDsubDir = "/sd"; char SnSDUtils::fgCurFileName[kFNBufSize]={0}; FILE* SnSDUtils::fgCurFile = 0; const uint8_t SnSDUtils::kIOvers = 2; const uint32_t SnSDUtils::kMaxSizeOfFileHdr = sizeof(uint8_t)+sizeof(uint64_t)+sizeof(uint32_t)+sizeof(uint16_t) +SnPowerFrame::kMaxSizeOf; static const uint16_t __kMaxUShort = ~0; const char* SnSDUtils::GetOutFileName(const uint64_t macadr, const uint32_t run, const uint16_t seq) { // returns the formatted file name, or NULL if the directory is too long // and the full name cannot fit in the buffer // NOTE: this fcn uses a static buffer, and so should not be called // multiple times in the same line (that includes the calling of functions // that call this function!) // // filename = SnEvtsM[6-byte hex mac adr]r[6-digit run num]s[5-digit seq num].dat // 35 chars 7 + 12 +1+ 5 +1+ 5 + 4 if (strlen(kSDsubDir)<(kFNBufSize-37)) { static char tbuf[kFNBufSize]; memset(tbuf, 0, sizeof(char)*kFNBufSize); // if file name format changes, GetSeqNum must be changed too sprintf(tbuf, "%s/SnEvtsM%012llXr%05ds%05d.dat", kSDsubDir, macadr>>16, // 64 -> 48 bits run, seq); return tbuf; } else { return NULL; } } uint16_t SnSDUtils::GetSeqNum(const uint64_t macadr, const uint32_t run) { // count the files having expected filename format const char* fn = GetOutFileName(macadr, run, 0) + strlen(kSDsubDir) + 1; // take out dir and '/'s DIR* d; struct dirent* dent; uint16_t seq=0, newseq=0; if ( (d = opendir( kSDsubDir ))!=NULL ) { // don't compare seq#. don't use num of chars in case seq is >999 const uint32_t ncomp = strrchr(fn, 's') - fn; while ( (dent = readdir(d))!=NULL ) { if (strncmp(dent->d_name, fn, ncomp)==0) { // allow for deleted files to make gaps. // search for highest seq number and increase that sscanf((dent->d_name)+ncomp,"s%hu.dat",&seq); /* printf("dn=%s, seq=%hu, __kMaxUShort=%hu\r\n", dent->d_name, seq, __kMaxUShort); */ if (seq==__kMaxUShort) { newseq = seq; break; } if (seq>=newseq) { newseq=seq+1; } if (newseq==__kMaxUShort) { break; } } } closedir(d); } return newseq; } FILE* SnSDUtils::OpenExistingFile(const char* name, const bool setcurrent) { FILE* f = 0; if (name!=NULL) { f = OpenSDFile(name, "rb"); if (setcurrent) { fgCurFile = f; } } return f; } FILE* SnSDUtils::OpenSDFile(const char* name, const char* mode) { FILE* f = fopen(name, mode); //setvbuf(f, 0, _IONBF, 0); // no buffering return f; } FILE* SnSDUtils::OpenNewOutputFile(const uint64_t macadr, const uint32_t run, const uint16_t v1, const uint16_t v2) { // opens a new file in the specified directory and writes this // this mbed's mac address as the first sizeof(uint64_t) bytes (i.e. 4 bytes) // const uint16_t seq = GetSeqNum(macadr, run); memset(fgCurFileName, 0, sizeof(char)*kFNBufSize); strncpy(fgCurFileName,GetOutFileName(macadr, run, seq),kFNBufSize-1); //fprintf(stderr,"cur file = %s (%hu)\n\r",fgCurFileName,seq); fgCurFile = 0; if (fgCurFileName!=NULL) { fgCurFile = OpenSDFile(fgCurFileName, "wb"); if (fgCurFile!=NULL && ferror(fgCurFile)==0) { WriteFileHeader(fgCurFile, macadr, run, seq, v1, v2); } } return fgCurFile; } bool SnSDUtils::WriteEventTo(FILE* efile, char* const evtBuf, const SnEventFrame& evt, const SnConfigFrame& conf) { // write event to SD card uint8_t sLoseLSB=0, sLoseMSB=0; uint16_t sWvBase=0; conf.GetPackParsFor(SnConfigFrame::kSDcard, sLoseLSB, sLoseMSB, sWvBase); const bool ret = evt.WriteTo(efile, evtBuf, sLoseLSB, sLoseMSB, sWvBase); fflush(efile); return ret; } bool SnSDUtils::WriteConfig(FILE* efile, const SnConfigFrame& conf) { conf.WriteTo(efile); return true; } void SnSDUtils::DeleteFile(FILE*& f, const char* fname) { fclose(f); f=0; remove(fname); } SnCommWin::ECommWinResult SnSDUtils::SendAllFiles(SnCommWin* comm, const bool doDelete, const uint32_t timeout, char* const buf, const uint32_t bsize, const SnConfigFrame& curConf, SnEventFrame& evt) { DIR* d; struct dirent* dent; SnCommWin::ECommWinResult rs = SnCommWin::kUndefFail; if ( (d = opendir( kSDsubDir ))!=NULL ) { FILE* f; while ( (dent = readdir(d))!=NULL ) { if (strncmp(dent->d_name, "SnEvts", 6)==0) { const bool isCurFile = (strcmp(dent->d_name, GetCurFileName())==0); if (isCurFile) { // file must already be written out! f = GetCurFile(); } else { f = OpenExistingFile(dent->d_name, false); } rs = comm->SendData(f, dent->d_name, curConf, evt, buf, bsize, 0, timeout, 0); if (isCurFile) { // move (back) to the end of the file // altho hopefully no writing will happen after this fseek(fgCurFile, 0, SEEK_END); } } } closedir(d); } return rs; }