head 4.4; access ; symbols ; locks oasisa:4.4; strict; comment @ * @; 4.4 date 2001.06.19.12.14.26; author oasisa; state Exp; branches ; next ; desc @New Repository; 6/19/2001 (klh) @ 4.4 log @New Repository; 6/19/2001 (klh) @ text @/****************************************************************************/ /* Copyright 1991 MBARI */ /****************************************************************************/ /* $Header: log.c,v 1.1 2001/06/19 11:44:07 oasisa Exp $ */ /* Summary : Data Logging Routines for OASIS Mooring Controller */ /* Filename : log.c */ /* Author : Robert Herlien (rah) */ /* Project : OASIS Mooring */ /* $Revision: 1.1 $ */ /* Created : 02/21/91 */ /* */ /* MBARI provides this documentation and code "as is", with no warranty, */ /* express or implied, of its quality or consistency. It is provided without*/ /* support and without obligation on the part of the Monterey Bay Aquarium */ /* Research Institute to assist in its use, correction, modification, or */ /* enhancement. This information should not be published or distributed to */ /* third parties without specific written permission from MBARI. */ /* */ /****************************************************************************/ /* Modification History: */ /* 21feb91 rah - created */ /* $Log: log.c,v $ * Revision 1.1 2001/06/19 11:44:07 11:44:07 oasisa (Oasis users) * Initial revision * * Revision 4.2 98/09/09 10:48:07 10:48:07 bobh (Bob Herlien) * Sept/Oct '98 deployments of M1, Eqpac 1 & 2 * * Revision 4.0 98/03/09 11:44:46 11:44:46 bobh (Bob Herlien) * M3 Deployment of March '98, new Sat-Pac driver * * Revision 3.9 97/10/28 13:59:55 13:59:55 bobh (Bob Herlien) * EqPac Deployment of Nov 1997 * * Revision 3.8 97/09/12 10:51:02 10:51:02 bobh (Bob Herlien) * Redeploy M1 * * Revision 3.6 96/10/30 14:00:23 14:00:23 bobh (Bob Herlien) * Release for EqPac, M2 Test Replacement * * Revision 3.3 95/04/13 13:47:03 13:47:03 hebo (Bob Herlien) * Drifter Deployment for Coop (flip) cruise * * Revision 3.1 95/03/09 19:31:04 19:31:04 hebo (Bob Herlien) * March '95 Deployment of M1A * * Revision 3.0 95/02/21 18:42:49 18:42:49 hebo (Bob Herlien) * February '95 Deployment * * Revision 2.4 93/10/29 11:12:48 11:12:48 hebo (Bob Herlien) * November 1993 Deployment * * Revision 2.0 92/08/26 10:32:31 10:32:31 hebo (Bob Herlien) * August 1992 Deployment * * Revision 1.3 92/03/03 16:41:06 16:41:06 hebo (Bob Herlien 408-647-3748) * New defaults, restart check, perm power stuff, analog command * */ /****************************************************************************/ #include /* MBARI type definitions */ #include /* MBARI constants */ #include /* OASIS controller definitions */ #include /* DISK definition */ #include /* Log record definitions */ #include /* OASIS task dispatcher */ #include /* OASIS I/O definitions */ #include /* String library functions */ /********************************/ /* External Functions */ /********************************/ Extern Void bankCopy( Nat16 bank, const Byte *src, Byte *dst, Nat16 len ); Extern Void bankZero( Nat16 bank, Byte *dst, Nat16 len ); Extern Void bcopy( const Byte *src, Byte *dst, Nat16 len ); #ifdef DISK Extern Errno diskReadBlk( LogBlk dskblk, LogBlk memblk ); Extern Errno checkDiskWrite( LogBlk dskblk ); Extern Void diskColdInit( Void ); #endif #ifdef LOGGER Extern char *decToAscii( char *buff, Nat16 val ); #endif /********************************/ /* External Data */ /********************************/ Extern Reg TimeOfDay tod; /* Current time in TimeOfDay format */ /********************************/ /* Global Data */ /********************************/ Global LogPtr nextFreeLog; /* Next record to log */ Global LogPtr nextUsrLog; /* Next data to send to user */ /********************************/ /* Module Local Data */ /********************************/ #ifdef DISK MLocal LogBlk diskBlk; /* Block in disk buffer (DISK_BLK) */ #endif /* Forward Declarations */ Void logPutRec( LogRecHdr *hdrp, Byte *dp ); /************************************************************************/ /* Function : initLogPtr */ /* Purpose : Initialize one LogPtr */ /* Inputs : LogPtr */ /* Outputs : None */ /************************************************************************/ Void initLogPtr( LogPtr *lp ) { lp->lp_blk = 0; lp->lp_memblk = MEMBLK_OFFSET; lp->lp_addr = LOG_START_ADDR; lp->lp_rcd = 0; } /* initLogPtr() */ /************************************************************************/ /* Function : logColdInit */ /* Purpose : Initialize logging routines */ /* Inputs : None */ /* Outputs : None */ /************************************************************************/ Void logColdInit( Void ) { bankZero( Bank(MEMBLK_OFFSET, 0), Addr(0), LOG_RAMSIZE ); initLogPtr( &nextFreeLog ); /* Init free log pointer */ initLogPtr( &nextUsrLog ); /* Init user download pointer */ #ifdef DISK diskBlk = (LogBlk)(-1); /* Init disk log block */ diskColdInit(); /* Cold init disk module */ #endif } /* logColdInit() */ #ifdef DISK /************************************************************************/ /* Function : logDiskError */ /* Purpose : Log a disk error into log memory */ /* Inputs : Error vector */ /* Outputs : None */ /* Comment : Be careful with this. Since it's called from the log */ /* module, it would be easy to get into a recursive loop */ /************************************************************************/ Void logDiskError( Errno errno ) { LogRecHdr rechdr; /* Logging record header */ rechdr.log_type = (Byte)LOG_DISK_ERROR; rechdr.log_len = sizeof( Errno ); logPutRec( &rechdr, (Byte *)(&errno) ); } /* logDiskError() */ #endif /************************************************************************/ /* Function : isLogged */ /* Purpose : Determine whether a given record number is in log memory*/ /* Inputs : Log Pointer */ /* Outputs : LogRtn code */ /* Comment : If block is not in memory but is on disk, get it */ /************************************************************************/ LogRtn isLogged( LogPtr *lp ) { Reg LogBlk reqBlk, curBlk; /* Block to check, current log blk */ LogRecNum numRcds; /* Nmbr records in block */ Reg Errno rtn; /* Return code from diskReadBlk() */ reqBlk = lp->lp_blk; /* Get blk nmbr to check */ curBlk = nextFreeLog.lp_blk; /* Get current log block */ if ( reqBlk > curBlk ) /* If blk nmbr too high, */ return( LOG_BAD_BLK ); /* not logged yet */ if ( (curBlk - reqBlk) < MEMBLKS_USED ) lp->lp_memblk = MemBlk( reqBlk ); /* Blk is in memory */ #ifdef DISK else if ( reqBlk == diskBlk ) /* If in disk buffer block */ lp->lp_memblk = DISK_BLK; /* just show that */ else if ( (rtn = diskReadBlk(reqBlk, DISK_BLK)) == OK ) { /* Blk on disk. Get it. */ lp->lp_memblk = DISK_BLK; /* Show where it is */ diskBlk = reqBlk; /* Remember which disk blk */ } else { logDiskError( rtn ); /* If can't read disk, error*/ return( LOG_BAD_BLK ); /* Log it and return error */ } #else else /* If no disk */ return( LOG_BAD_BLK ); /* return error */ #endif bankCopy( Bank(lp->lp_memblk, 0), Addr(0), (Byte *)(&numRcds), sizeof(LogRecNum) ); /* Get nmbr rcds in block */ if ( lp->lp_rcd < numRcds ) /* If rcd # ok, return OK */ return( LOG_OK ); return( LOG_BAD_RCD ); /* Rcd number too high */ } /* isLogged() */ /************************************************************************/ /* Function : logGet */ /* Purpose : Get raw bytes from Logging Memory */ /* Inputs : LogPtr to get from, where to put it, length */ /* Outputs : None */ /* Comments : Log address is lp->lp_blk & lp->lp_addr */ /************************************************************************/ Void logGet( LogPtr *lp, Byte *datp, Nat16 len ) { Reg Nat16 curlen, left; Reg LogAddr addr; Reg Byte *p; addr = lp->lp_addr; for( left = len, p = datp; left; left -= curlen ) { curlen = (LOG_RAMSIZE - (addr % LOG_RAMSIZE)); if ( curlen > left ) curlen = left; bankCopy( Bank(lp->lp_memblk, addr), Addr(addr), p, curlen ); addr += curlen; p += curlen; } } /* logGet() */ /************************************************************************/ /* Function : isLogRecHdr */ /* Purpose : See if we have a valid LogRecHdr */ /* Inputs : LogRecHdr to check */ /* Outputs : TRUE if OK, else FALSE */ /************************************************************************/ MBool isLogRecHdr( LogRecHdr *hdrp ) { if ( (hdrp->log_syncc == LOG_SYNC) && (hdrp->log_len <= MAXLOGSIZE) ) return( TRUE ); return( FALSE ); } /* isLogRecHdr() */ /************************************************************************/ /* Function : logSearch */ /* Purpose : Search for a record from log memory by number */ /* Inputs : LogPtr for record number to find */ /* Outputs : TRUE if found record, else FALSE */ /* Comments : Updates LogPtr address to point to record lp->lp_rcd */ /************************************************************************/ MBool logSearch( LogPtr *lp ) { LogRecHdr hdr; if ( isLogged(lp) != LOG_OK ) return( FALSE ); for ( lp->lp_addr = LOG_START_ADDR; lp->lp_addr < BLKSIZE; ) { logGet( lp, (Byte *)&hdr, sizeof(LogRecHdr) ); /* Get next record*/ if ( !isLogRecHdr(&hdr) ) /* If bad, return */ return( FALSE ); if ( hdr.log_rcd == lp->lp_rcd ) /* If found record*/ return( TRUE ); /* return */ lp->lp_addr += hdr.log_len + sizeof(LogRecHdr); dispatch(); } return( FALSE ); } /* logSearch() */ /************************************************************************/ /* Function : logGetRec */ /* Purpose : Get a Record from Logging Memory */ /* Inputs : LogPtr in log memory to get record from, ptr to put rcd*/ /* Outputs : TRUE if got record, else FALSE */ /* Comments : Gets record pointed to by lp->lp_blk and lp->lp_addr. */ /* If invalid, searches for record number lp->lp_rcd. */ /* Updates lp to point to next record. */ /* Writes to *lp and *logp, even if returns FALSE. */ /************************************************************************/ MBool logGetRec( LogPtr *lp, LogRec *logp ) { if ( isLogged(lp) != LOG_OK ) return( FALSE ); logGet( lp, (Byte *)logp, sizeof(LogRecHdr) ); if ( !isLogRecHdr((LogRecHdr *)logp) || (logp->log_hdr.log_rcd != lp->lp_rcd) ) { if ( logSearch(lp) ) logGet( lp, (Byte *)logp, sizeof(LogRecHdr) ); else return( FALSE ); } lp->lp_addr += sizeof(LogRecHdr); logGet( lp, logp->log_data, logp->log_hdr.log_len ); lp->lp_rcd++; lp->lp_addr += logp->log_hdr.log_len; return( TRUE ); } /* logGetRec() */ /************************************************************************/ /* Function : logNextBlk */ /* Purpose : Point to start of next log block */ /* Inputs : LogPtr */ /* Outputs : None */ /************************************************************************/ Void logNextBlk( LogPtr *lp ) { if ( lp->lp_blk != MAX_BLKNUM ) lp->lp_blk++; lp->lp_memblk = MemBlk(lp->lp_blk); lp->lp_addr = LOG_START_ADDR; lp->lp_rcd = 0; } /*logNextBlk() */ /************************************************************************/ /* Function : logPut */ /* Purpose : Put raw bytes into Logging Memory */ /* Inputs : Ptr to data, length */ /* Outputs : None */ /************************************************************************/ Void logPut( Byte *datp, Nat16 len ) { Reg Nat16 curlen, left; Reg LogAddr addr; Reg Byte *p; addr = nextFreeLog.lp_addr; for( left = len, p = datp; left; left -= curlen ) { curlen = (LOG_RAMSIZE - (addr % LOG_RAMSIZE)); if ( curlen > left ) curlen = left; bankCopy( Bank(nextFreeLog.lp_memblk, addr), p, Addr(addr), curlen ); addr += curlen; p += curlen; } nextFreeLog.lp_addr = addr; } /* logPut() */ /************************************************************************/ /* Function : adjustLog */ /* Purpose : Check if room in log memory for new record, and if not,*/ /* start a new log block */ /* Inputs : Log Record Header */ /* Outputs : None */ /************************************************************************/ Void adjustLog( LogRecHdr *hdrp ) { Reg LogAddr curAddr; Reg LogBlk curBlk; #ifdef DISK Reg Errno rtn; #endif curAddr = nextFreeLog.lp_addr; curBlk = nextFreeLog.lp_blk; if ( curAddr <= (BLKSIZE - hdrp->log_len - sizeof(LogRecHdr)) ) return; /* OK, there's room. */ /* No room. Go to next block. */ bankZero( Bank(curBlk, curAddr), Addr(curAddr), BLKSIZE - curAddr ); /* Zero out rest of block */ logNextBlk( &nextFreeLog ); /* Go to next log block */ #ifdef DISK /* See if time to write disk, do it*/ if ( (rtn = checkDiskWrite(curBlk)) != OK ) logDiskError( rtn ); /* If failed disk write, log failure*/ #endif } /* adjustLog() */ /************************************************************************/ /* Function : logPutRec */ /* Purpose : Put a Record into Logging Memory */ /* Inputs : Ptr to Log Hdr, Ptr to data */ /* Outputs : None */ /************************************************************************/ Void logPutRec( LogRecHdr *hdrp, Byte *dp ) { if ( hdrp->log_len > MAXLOGSIZE ) return; adjustLog( hdrp ); /* Make room for this rcd*/ hdrp->log_syncc = LOG_SYNC; /* Insert sync chr */ hdrp->log_rcd = nextFreeLog.lp_rcd++; /* Insert rcd nmbr & incr*/ hdrp->log_time = tod; /* Insert time */ logPut( (Byte *)hdrp, sizeof(LogRecHdr) ); /* Log the header */ logPut( dp, hdrp->log_len ); /* Log the data */ bankCopy( Bank(nextFreeLog.lp_memblk, 0), (Byte *)(&nextFreeLog.lp_rcd), Addr(0), sizeof(LogRecNum) ); /* Store nmbr rcds at start of blk*/ } /* logPutRec() */ /************************************************************************/ /* Function : logError */ /* Purpose : Log an error */ /* Inputs : Error vector */ /* Outputs : None */ /************************************************************************/ Void logError( Word vect ) { LogRecHdr rechdr; /* Logging record header */ rechdr.log_type = (Byte)LOG_ERROR; rechdr.log_len = sizeof( Word ); logPutRec( &rechdr, (Byte *)(&vect) ); } /* logError() */ /************************************************************************/ /* Function : logOasisStatus */ /* Purpose : Log OASIS on/off status */ /* Inputs : Status: 1 for on, 0 for off */ /* Outputs : None */ /************************************************************************/ Void logOasisStatus( Word onoff ) { LogRecHdr rechdr; /* Logging record header */ rechdr.log_type = (Byte)OASIS_STAT; rechdr.log_len = sizeof( Word ); logPutRec( &rechdr, (Byte *)(&onoff) ); } /* logOasisStatus() */ #ifdef LOGGER /************************************************************************/ /* Function : log_drv */ /* Purpose : Test Driver that simply logs comments */ /* Inputs : Driver Pointer */ /* Outputs : None */ /************************************************************************/ Void log_drv( Driver *dp ) { LogRecHdr hdr; Nat16 cntr; Reg char *p; char buff[48]; for ( cntr = 0; cntr < dp->drv_parms[PARM0]; cntr++ ) { hdr.log_type = dp->drv_parms[SAMPLE_TYPE]; bcopy( (Byte *)"Test Logger iteration ", (Byte *)buff, 32 ); p = decToAscii( buff + strlen(buff), dp->drv_cnt ); *p++ = ' '; decToAscii( p, cntr ); hdr.log_len = strlen( buff ); logPutRec( &hdr, (Byte *)buff ); task_delay( 1 ); } dp->drv_cnt++; } /* log_drv() */ #endif @