Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Wed Oct 10 05:54:12 2012 +0000
Revision:
21:ce51bb0ba4a5
Parent:
20:e5857b287b3b
Child:
22:f957c4f840ad
Uses USB comm. Fix rates calc. Power up/down ETH with Afar. Fix sending evt with status. Add num files and bytes of data to status. Can save a local file (i.e. reprogram MBED) via comms. Set config after each comm win (need if cards pow cycle).

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