Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Sat Aug 18 05:00:32 2012 +0000
Revision:
12:d472f9811262
Parent:
10:3c93db1cfb12
Child:
15:f2569d8e4176
Fixed bug in throttling timers. Now evt stores dt of triggers but throttle works on dt of events. AfarTCP communication possibly done. Debug output put behind precompiler macros.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
uci1 0:664899e0b988 1 #include "SnSDUtils.h"
uci1 0:664899e0b988 2
uci1 0:664899e0b988 3 #include "mbed.h"
uci1 0:664899e0b988 4 #include "SDFileSystem.h"
uci1 0:664899e0b988 5 #include <string.h>
uci1 12:d472f9811262 6 #include <string>
uci1 0:664899e0b988 7
uci1 0:664899e0b988 8 #include "SnConfigFrame.h"
uci1 0:664899e0b988 9 #include "SnEventFrame.h"
uci1 0:664899e0b988 10
uci1 0:664899e0b988 11
uci1 1:e392595b4b76 12 const char* const SnSDUtils::kSDsubDir = "/sd";
uci1 2:e67f7c158087 13 char SnSDUtils::fgCurFileName[kFNBufSize]={0};
uci1 1:e392595b4b76 14 FILE* SnSDUtils::fgCurFile = 0;
uci1 12:d472f9811262 15 uint16_t SnSDUtils::fgCurSeq = 0;
uci1 8:95a325df1f6b 16 const uint8_t SnSDUtils::kIOvers = 3;
uci1 5:9cea89700c66 17 const uint32_t SnSDUtils::kMaxSizeOfFileHdr =
uci1 5:9cea89700c66 18 sizeof(uint8_t)+sizeof(uint64_t)+sizeof(uint32_t)+sizeof(uint16_t)
uci1 8:95a325df1f6b 19 +(sizeof(uint8_t)+(2u*sizeof(uint16_t))); // power frame v1
uci1 4:a91682e19d6b 20
uci1 4:a91682e19d6b 21 static const uint16_t __kMaxUShort = ~0;
uci1 0:664899e0b988 22
uci1 0:664899e0b988 23 const char* SnSDUtils::GetOutFileName(const uint64_t macadr,
uci1 0:664899e0b988 24 const uint32_t run,
uci1 0:664899e0b988 25 const uint16_t seq) {
uci1 0:664899e0b988 26 // returns the formatted file name, or NULL if the directory is too long
uci1 0:664899e0b988 27 // and the full name cannot fit in the buffer
uci1 0:664899e0b988 28 // NOTE: this fcn uses a static buffer, and so should not be called
uci1 0:664899e0b988 29 // multiple times in the same line (that includes the calling of functions
uci1 0:664899e0b988 30 // that call this function!)
uci1 0:664899e0b988 31 //
uci1 0:664899e0b988 32 // filename = SnEvtsM[6-byte hex mac adr]r[6-digit run num]s[5-digit seq num].dat
uci1 0:664899e0b988 33 // 35 chars 7 + 12 +1+ 5 +1+ 5 + 4
uci1 0:664899e0b988 34
uci1 0:664899e0b988 35 if (strlen(kSDsubDir)<(kFNBufSize-37)) {
uci1 0:664899e0b988 36 static char tbuf[kFNBufSize];
uci1 0:664899e0b988 37 memset(tbuf, 0, sizeof(char)*kFNBufSize);
uci1 0:664899e0b988 38 // if file name format changes, GetSeqNum must be changed too
uci1 0:664899e0b988 39 sprintf(tbuf, "%s/SnEvtsM%012llXr%05ds%05d.dat",
uci1 0:664899e0b988 40 kSDsubDir,
uci1 0:664899e0b988 41 macadr>>16, // 64 -> 48 bits
uci1 0:664899e0b988 42 run, seq);
uci1 0:664899e0b988 43 return tbuf;
uci1 0:664899e0b988 44 } else {
uci1 0:664899e0b988 45 return NULL;
uci1 0:664899e0b988 46 }
uci1 0:664899e0b988 47 }
uci1 12:d472f9811262 48 /*
uci1 10:3c93db1cfb12 49 uint16_t SnSDUtils::GetCurSeqNum() {
uci1 10:3c93db1cfb12 50 return GetSeqNumFromFileName(fgCurFileName);
uci1 10:3c93db1cfb12 51 }
uci1 12:d472f9811262 52 */
uci1 10:3c93db1cfb12 53 uint16_t SnSDUtils::GetSeqNumFromFileName(const char* fn) {
uci1 10:3c93db1cfb12 54 uint16_t seq=0;
uci1 10:3c93db1cfb12 55 const uint32_t ncomp = strrchr(fn, 's') - fn;
uci1 10:3c93db1cfb12 56 if (ncomp<strlen(fn)) {
uci1 10:3c93db1cfb12 57 sscanf(fn+ncomp,"s%hu.dat",&seq);
uci1 10:3c93db1cfb12 58 }
uci1 10:3c93db1cfb12 59 return seq;
uci1 10:3c93db1cfb12 60 }
uci1 10:3c93db1cfb12 61
uci1 0:664899e0b988 62 uint16_t SnSDUtils::GetSeqNum(const uint64_t macadr,
uci1 0:664899e0b988 63 const uint32_t run) {
uci1 0:664899e0b988 64 // count the files having expected filename format
uci1 0:664899e0b988 65
uci1 0:664899e0b988 66 const char* fn = GetOutFileName(macadr, run, 0)
uci1 0:664899e0b988 67 + strlen(kSDsubDir) + 1; // take out dir and '/'s
uci1 0:664899e0b988 68
uci1 0:664899e0b988 69 DIR* d;
uci1 0:664899e0b988 70 struct dirent* dent;
uci1 0:664899e0b988 71
uci1 6:6f002d202f59 72 uint16_t seq=0, newseq=0;
uci1 0:664899e0b988 73 if ( (d = opendir( kSDsubDir ))!=NULL ) {
uci1 0:664899e0b988 74 // don't compare seq#. don't use num of chars in case seq is >999
uci1 0:664899e0b988 75 const uint32_t ncomp = strrchr(fn, 's') - fn;
uci1 0:664899e0b988 76 while ( (dent = readdir(d))!=NULL ) {
uci1 0:664899e0b988 77 if (strncmp(dent->d_name, fn, ncomp)==0) {
uci1 6:6f002d202f59 78 // allow for deleted files to make gaps.
uci1 6:6f002d202f59 79 // search for highest seq number and increase that
uci1 7:079617408fec 80 sscanf((dent->d_name)+ncomp,"s%hu.dat",&seq);
uci1 12:d472f9811262 81 #ifdef DEBUG
uci1 7:079617408fec 82 /*
uci1 7:079617408fec 83 printf("dn=%s, seq=%hu, __kMaxUShort=%hu\r\n",
uci1 7:079617408fec 84 dent->d_name, seq, __kMaxUShort);
uci1 7:079617408fec 85 */
uci1 12:d472f9811262 86 #endif
uci1 4:a91682e19d6b 87 if (seq==__kMaxUShort) {
uci1 6:6f002d202f59 88 newseq = seq;
uci1 6:6f002d202f59 89 break;
uci1 6:6f002d202f59 90 }
uci1 6:6f002d202f59 91 if (seq>=newseq) {
uci1 6:6f002d202f59 92 newseq=seq+1;
uci1 6:6f002d202f59 93 }
uci1 6:6f002d202f59 94 if (newseq==__kMaxUShort) {
uci1 4:a91682e19d6b 95 break;
uci1 4:a91682e19d6b 96 }
uci1 0:664899e0b988 97 }
uci1 0:664899e0b988 98 }
uci1 0:664899e0b988 99 closedir(d);
uci1 0:664899e0b988 100 }
uci1 7:079617408fec 101
uci1 6:6f002d202f59 102 return newseq;
uci1 0:664899e0b988 103 }
uci1 0:664899e0b988 104
uci1 3:24c5f0f50bf1 105 FILE* SnSDUtils::OpenExistingFile(const char* name, const bool setcurrent) {
uci1 0:664899e0b988 106 FILE* f = 0;
uci1 0:664899e0b988 107 if (name!=NULL) {
uci1 3:24c5f0f50bf1 108 f = OpenSDFile(name, "rb");
uci1 12:d472f9811262 109 /*
uci1 3:24c5f0f50bf1 110 if (setcurrent) {
uci1 3:24c5f0f50bf1 111 fgCurFile = f;
uci1 12:d472f9811262 112 strncpy(fgCurFileName, name, kFNBufSize-1);
uci1 12:d472f9811262 113 fgCurSeq = GetSeqNumFromFileName(fgCurFileName);
uci1 3:24c5f0f50bf1 114 }
uci1 12:d472f9811262 115 */
uci1 0:664899e0b988 116 }
uci1 0:664899e0b988 117 return f;
uci1 0:664899e0b988 118 }
uci1 0:664899e0b988 119
uci1 3:24c5f0f50bf1 120 FILE* SnSDUtils::OpenSDFile(const char* name, const char* mode) {
uci1 12:d472f9811262 121 // TODO: check if we have memory?
uci1 12:d472f9811262 122 std::string fn(name);
uci1 12:d472f9811262 123 if (strncmp(name, kSDsubDir, strlen(kSDsubDir))!=0) {
uci1 12:d472f9811262 124 // filename lacks directory
uci1 12:d472f9811262 125 fn = kSDsubDir;
uci1 12:d472f9811262 126 fn += "/";
uci1 12:d472f9811262 127 fn += name;
uci1 12:d472f9811262 128 }
uci1 12:d472f9811262 129 #ifdef DEBUG
uci1 12:d472f9811262 130 printf("OpenSDFile: %s, mode %s\r\n",fn.c_str(),mode);
uci1 12:d472f9811262 131 #endif
uci1 12:d472f9811262 132 FILE* f = fopen(fn.c_str(), mode);
uci1 1:e392595b4b76 133 //setvbuf(f, 0, _IONBF, 0); // no buffering
uci1 1:e392595b4b76 134 return f;
uci1 1:e392595b4b76 135 }
uci1 1:e392595b4b76 136
uci1 0:664899e0b988 137 FILE* SnSDUtils::OpenNewOutputFile(const uint64_t macadr,
uci1 8:95a325df1f6b 138 const uint32_t run) {
uci1 0:664899e0b988 139 // opens a new file in the specified directory and writes this
uci1 0:664899e0b988 140 // this mbed's mac address as the first sizeof(uint64_t) bytes (i.e. 4 bytes)
uci1 0:664899e0b988 141 //
uci1 12:d472f9811262 142 fgCurSeq = GetSeqNum(macadr, run);
uci1 0:664899e0b988 143 memset(fgCurFileName, 0, sizeof(char)*kFNBufSize);
uci1 12:d472f9811262 144 strncpy(fgCurFileName,GetOutFileName(macadr, run, fgCurSeq),kFNBufSize-1);
uci1 12:d472f9811262 145 //fprintf(stderr,"cur file = %s (%hu)\n\r",fgCurFileName,fgCurSeq);
uci1 1:e392595b4b76 146 fgCurFile = 0;
uci1 0:664899e0b988 147 if (fgCurFileName!=NULL) {
uci1 3:24c5f0f50bf1 148 fgCurFile = OpenSDFile(fgCurFileName, "wb");
uci1 2:e67f7c158087 149 if (fgCurFile!=NULL && ferror(fgCurFile)==0) {
uci1 12:d472f9811262 150 WriteFileHeader(fgCurFile, macadr, run, fgCurSeq);
uci1 2:e67f7c158087 151 }
uci1 0:664899e0b988 152 }
uci1 1:e392595b4b76 153 return fgCurFile;
uci1 0:664899e0b988 154 }
uci1 0:664899e0b988 155
uci1 0:664899e0b988 156 bool SnSDUtils::WriteEventTo(FILE* efile, char* const evtBuf,
uci1 0:664899e0b988 157 const SnEventFrame& evt,
uci1 0:664899e0b988 158 const SnConfigFrame& conf) {
uci1 0:664899e0b988 159 // write event to SD card
uci1 0:664899e0b988 160
uci1 0:664899e0b988 161 uint8_t sLoseLSB=0, sLoseMSB=0;
uci1 0:664899e0b988 162 uint16_t sWvBase=0;
uci1 0:664899e0b988 163 conf.GetPackParsFor(SnConfigFrame::kSDcard, sLoseLSB, sLoseMSB, sWvBase);
uci1 8:95a325df1f6b 164 SnHeaderFrame::WriteTo(efile, SnHeaderFrame::kEventCode,
uci1 8:95a325df1f6b 165 evt.SizeOf(SnEventFrame::kIOVers, sLoseLSB, sLoseMSB));
uci1 0:664899e0b988 166 const bool ret = evt.WriteTo(efile, evtBuf, sLoseLSB, sLoseMSB, sWvBase);
uci1 0:664899e0b988 167 fflush(efile);
uci1 0:664899e0b988 168 return ret;
uci1 0:664899e0b988 169 }
uci1 0:664899e0b988 170
uci1 0:664899e0b988 171 bool SnSDUtils::WriteConfig(FILE* efile,
uci1 0:664899e0b988 172 const SnConfigFrame& conf) {
uci1 8:95a325df1f6b 173 SnHeaderFrame::WriteTo(efile, SnHeaderFrame::kConfigCode,
uci1 8:95a325df1f6b 174 conf.SizeOf(SnConfigFrame::kIOVers));
uci1 0:664899e0b988 175 conf.WriteTo(efile);
uci1 0:664899e0b988 176 return true;
uci1 0:664899e0b988 177 }
uci1 0:664899e0b988 178
uci1 0:664899e0b988 179 void SnSDUtils::DeleteFile(FILE*& f, const char* fname) {
uci1 0:664899e0b988 180 fclose(f);
uci1 0:664899e0b988 181 f=0;
uci1 0:664899e0b988 182 remove(fname);
uci1 0:664899e0b988 183 }
uci1 0:664899e0b988 184
uci1 0:664899e0b988 185 SnCommWin::ECommWinResult SnSDUtils::SendAllFiles(SnCommWin* comm,
uci1 3:24c5f0f50bf1 186 const uint32_t timeout,
uci1 3:24c5f0f50bf1 187 char* const buf,
uci1 6:6f002d202f59 188 const uint32_t bsize,
uci1 6:6f002d202f59 189 const SnConfigFrame& curConf,
uci1 8:95a325df1f6b 190 SnEventFrame& evt,
uci1 12:d472f9811262 191 SnPowerFrame& pow,
uci1 12:d472f9811262 192 const uint32_t handshakeTimeout) {
uci1 0:664899e0b988 193
uci1 0:664899e0b988 194 DIR* d;
uci1 0:664899e0b988 195 struct dirent* dent;
uci1 0:664899e0b988 196
uci1 0:664899e0b988 197 SnCommWin::ECommWinResult rs = SnCommWin::kUndefFail;
uci1 0:664899e0b988 198
uci1 12:d472f9811262 199 const bool doDelete = curConf.IsDeletingFiles();
uci1 12:d472f9811262 200
uci1 0:664899e0b988 201 if ( (d = opendir( kSDsubDir ))!=NULL ) {
uci1 0:664899e0b988 202 FILE* f;
uci1 0:664899e0b988 203 while ( (dent = readdir(d))!=NULL ) {
uci1 0:664899e0b988 204 if (strncmp(dent->d_name, "SnEvts", 6)==0) {
uci1 1:e392595b4b76 205 const bool isCurFile =
uci1 1:e392595b4b76 206 (strcmp(dent->d_name, GetCurFileName())==0);
uci1 1:e392595b4b76 207 if (isCurFile) {
uci1 3:24c5f0f50bf1 208 // file must already be written out!
uci1 1:e392595b4b76 209 f = GetCurFile();
uci1 1:e392595b4b76 210 } else {
uci1 3:24c5f0f50bf1 211 f = OpenExistingFile(dent->d_name, false);
uci1 1:e392595b4b76 212 }
uci1 12:d472f9811262 213 #ifdef DEBUG
uci1 12:d472f9811262 214 printf("calling senddata: f=%p (cur %p), fn=%s\r\n",
uci1 12:d472f9811262 215 f, GetCurFile(), dent->d_name);
uci1 12:d472f9811262 216 #endif
uci1 6:6f002d202f59 217 rs = comm->SendData(f, dent->d_name,
uci1 8:95a325df1f6b 218 curConf, evt, pow, buf, bsize,
uci1 12:d472f9811262 219 0, timeout, handshakeTimeout);
uci1 12:d472f9811262 220 // send data should close or delete the file (if appropriate)
uci1 12:d472f9811262 221 // unless it's the current file
uci1 3:24c5f0f50bf1 222 if (isCurFile) {
uci1 3:24c5f0f50bf1 223 // move (back) to the end of the file
uci1 3:24c5f0f50bf1 224 // altho hopefully no writing will happen after this
uci1 3:24c5f0f50bf1 225 fseek(fgCurFile, 0, SEEK_END);
uci1 0:664899e0b988 226 }
uci1 0:664899e0b988 227 }
uci1 0:664899e0b988 228 }
uci1 0:664899e0b988 229 closedir(d);
uci1 0:664899e0b988 230 }
uci1 0:664899e0b988 231
uci1 0:664899e0b988 232 return rs;
uci1 0:664899e0b988 233 }
uci1 0:664899e0b988 234