MEM.py

Go to the documentation of this file.
00001 #!/usr/local/bin/python
00002 #
00003 #                               Copyright 2005
00004 #                                     by
00005 #                        The Board of Trustees of the
00006 #                     Leland Stanford Junior University.
00007 #                            All rights reserved.
00008 #
00009 
00010 __facility__ = "Online"
00011 __abstract__ = "MEM related mnemonics"
00012 __author__   = "Selim Tuvi <stuvi@slac.stanford.edu> SLAC - GLAST LAT I&T/Online"
00013 __date__     = "2005/07/23 00:08:27"
00014 __updated__  = "$Date: 2006/03/31 05:02:30 $"
00015 __version__  = "$Revision: 1.13 $"
00016 __release__  = "$Name: HEAD $"
00017 __credits__  = "SLAC"
00018 
00019 import LICOS.copyright_SLAC
00020 
00021 import struct
00022 import time
00023 import logging as log
00024 
00025 from LICOS.lib.cmdTlmDb.cmdTlmDb import CmdPkg
00026 from LICOS.lib.LATconstants import *
00027 from LICOS.lib.cmdTlmDb.TelemetryEvent import TelemetryEvent
00028 
00029 # boot modes
00030 MEMTOOL_MODE_PBC  = 0
00031 MEMTOOL_MODE_SBC  = 1
00032 
00033 DUMP_MNEMONICS = { FSW_UNIT_SIU : [ "LBTHKP",      "LMEMSIUDATA"  ],
00034                    FSW_UNIT_EPU0: [ "LBTEPU0HKP",  "LMEMEPU0DATA" ],
00035                    FSW_UNIT_EPU1: [ "LBTEPU1HKP",  "LMEMEPU1DATA" ],
00036                    FSW_UNIT_EPU2: [ "LBTEPU2HKP",  "LMEMEPU2DATA" ],
00037                    }
00038 DUMP_TLM_INFIX = { FSW_UNIT_SIU : [ "MEM",  "SIU"  ],
00039                    FSW_UNIT_EPU0: [ "0",    "EPU0" ],
00040                    FSW_UNIT_EPU1: [ "1",    "EPU1" ],
00041                    FSW_UNIT_EPU2: [ "2",    "EPU2" ],
00042                    }
00043 DUMP_POOL_MNEMS = ['LMEMTPOOLLATUNIT', 'LMEMTPOOLTRANID', 'LMEMTPOOLID', 'LMEMTPOOLFREBYT',
00044                    'LMEMTPOOLFREBLK', 'LMEMTPOOLMAXBLK', 'LMEMTPOOLALCBYT', 'LMEMTPOOLALCBLK' ]
00045 
00046 MEM_LOAD_FRAG_SIZE = 11
00047 
00048 
00049 class MEM(CmdPkg):
00050   """!\brief MEM telecommand package class
00051 
00052   Provides access to MEM telecommands.
00053   """
00054   def __init__(self, db):
00055     """!\brief MEM constructor.
00056 
00057     \param db  Wrapper database object for the generated module
00058               containing command and telemetry database classes.
00059     """
00060     CmdPkg.__init__(self, db)
00061     self.__primaryBoot=False
00062 
00063   def dumpMemory(self, unit, address, size, tranID, dest):
00064     """!\brief Dump a region of memory
00065 
00066     \param unit        LAT unit id to download
00067     \param address     starting address
00068     \param size        number of 32-bit words to dump
00069     \param tranid      transaction id
00070     \param dest        Memory dump destination (FSW_DEST_1553 or FSW_DEST_SSR)
00071 
00072     \return            Dumped memory value as packed string
00073     """
00074 
00075     try:
00076       md = self.DumpTool(self.getCmdDb(), unit, self.__primaryBoot)
00077       memory = md.dumpMemory(address, size, tranID, dest)
00078     except Exception, e:
00079       log.exception(e)
00080       memory = None
00081     return memory
00082 
00083   def loadMemory(self, unit, address, tranID, data):
00084     """!\brief Load data to a region of memory
00085 
00086     \param unit        LAT unit id to download
00087     \param address     Starting address
00088     \param tranid      Transaction id
00089     \param data        Packed string of 32-bit words to load
00090 
00091     \return            True if memory load was successful, False otherwise
00092     """
00093 
00094     try:
00095       ml = self.LoadTool(self.getCmdDb(), unit, self.__primaryBoot)
00096       status = ml.loadMemory(address, tranID, data)
00097     except Exception, e:
00098       log.exception(e)
00099       status = False
00100     return status
00101 
00102   def dumpPool(self, unit, tranID, poolID):
00103     dumpHdlr = TelemetryEvent(cmdDb.getVsc().getDiagHandler(),
00104                               [ cmdDb.getVsc().getTlmDb().getApidFromName('LMEMPOOLDATA')] )
00105     dumpHdlr.enable()
00106     self.LMEMDUMPPOOL( LMEMLATUNIT = unit,
00107                                 LMEMTRANID  = tranID,
00108                                 LMEMPOOLID  = poolID)
00109     status = self.__checkLastCommandStatus()
00110 
00111     plds = dumpHdlr.waitForPayload( DUMP_POOL_MNEMS, timeout = LONG_TIMEOUT )
00112     dumpHdlr.disable()
00113 
00114     return plds
00115 
00116   def dumpSymbol(self, unit, tranID, name):
00117 
00118     mnemDict = {}
00119     for i in xrange(48):
00120       mnem = 'LMEMNAME%02d' % i
00121       if i < len(name):
00122         mnemDict[mnem] = ord(name[i])
00123       else:
00124         mnemDict[mnem] = 0
00125 
00126     dumpHdlr = TelemetryEvent(cmdDb.getVsc().getDiagHandler(),
00127                               [ cmdDb.getVsc().getTlmDb().getApidFromName('LMEMSYMVAL')] )
00128     symMnems = ['LMEMTSYMNAME%02d' % i for i in xrange(48)]
00129 
00130     plds     = ['LMEMTSYMLATUNIT', 'LMEMTSYMTRANID', 'LMEMTSYMVALUE', 'LMEMTSYMNAMESIZE'] + \
00131                symMnems
00132 
00133     dumpHdlr.enable()
00134     self.LMEMDUMPSYMVAL( LMEMLATUNIT  = unit,
00135                          LMEMTRANID   = tranID,
00136                          LMEMNAMESIZE = len(name),
00137                          LMEMPAD      = 0,
00138                          **mnemDict)
00139     status = self.__checkLastCommandStatus()
00140 
00141     plds = dumpHdlr.waitForPayload( plds, timeout = LONG_TIMEOUT )
00142     dumpHdlr.disable()
00143 
00144     if plds is None:   # timed out?
00145       return plds
00146 
00147     siz      = plds[3]
00148     symName  = ''.join(map(chr, plds[4:4+siz]))
00149 
00150     return plds[0:3] + [symName]
00151 
00152   def dumpPCI(self, unit, tranID, bus, device, function):
00153     try:
00154       md = self.DumpTool(self.getCmdDb(), unit, self.__primaryBoot)
00155       memory = md.dumpPCIheader(bus, device, function, tranID)
00156     except Exception, e:
00157       log.exception(e)
00158       memory = None
00159     return memory
00160 
00161 
00162   def cancelDumpMemory(self, unit, tranID):
00163     self.LMEMDUMPCANCEL( LMEMLATUNIT  = unit,
00164                          LMEMTRANID   = tranID)
00165     status = self.__checkLastCommandStatus()
00166     return status
00167 
00168   def getPoolStatus(self, unit, tranID, poolID):
00169     # alternate interface to LMEMDUMPPOOL
00170     return self.dumpPool(unit, tranID, poolID)
00171 
00172   def __checkLastCommandStatus(self):
00173     # boilerplate code that waits for completion on a command
00174     #   and checks the completion status.  If bad, log a warning
00175     status = True
00176     if self.__primaryBoot:
00177       log.warn("Command completion disabled")
00178       import time
00179       time.sleep(1)
00180       return status
00181     app = self.getCmdDb()
00182     status = app.waitForConfirmation(timeout = LONG_TIMEOUT)
00183     statusMsg = app.getConfirmationMsg()
00184     if not app.getVsc().getTlmDb().msgIsSuccess(statusMsg):
00185       log.warning(app.getVsc().getTlmDb().msgByValue(statusMsg))
00186       status=False
00187     return status
00188 
00189   def setPrimaryBoot(self, bool):
00190     self.__primaryBoot = bool
00191 
00192 
00193   ##private
00194   class DumpTool(object):
00195     """!\brief Provide a private memory dumping class for fileTools.py
00196     """
00197     def __init__(self, cmdDb, unit, primaryBoot):
00198       self.__cmdDb = cmdDb
00199       self.__unit  = unit
00200       self.__primaryBoot = primaryBoot
00201       self.__frags = {}  # cache of dump fragments, keyed by memory loc
00202       self.__sizes = {}  # sizes of above, same keys
00203       self.__mode  = None
00204       self.__tlms = [ cmdDb.getVsc().getTlmDb().getApidFromName(n) for n in DUMP_MNEMONICS[unit] ]
00205       # 2 dump handlers because some telem can come back on telemetry line
00206       self.__dumpHdlr = TelemetryEvent(cmdDb.getVsc().getDiagHandler(),
00207                                        self.__tlms, self.dumpMem)
00208       self.__dumpHdlr2 = TelemetryEvent(cmdDb.getVsc().getTelemHandler(),
00209                                         self.__tlms, self.dumpMem)
00210 
00211     def dumpMem(self, telemetry):
00212       packet = self.__cmdDb.getVsc().getTlmDb().decodeTelemetry(telemetry)
00213       self.__mode = DUMP_MNEMONICS[self.__unit].index(packet.name)
00214       if self.__mode == 0:
00215         self.__parsePBC(packet)
00216       elif self.__mode == 1:
00217         self.__parseSBC(packet)
00218       else:
00219         raise "MemDump Can't Get To This Line"
00220 
00221     def __parsePBC(self, packet):
00222       mode = 0
00223       infix =  DUMP_TLM_INFIX[self.__unit][mode]
00224       pktStart = packet.get_payload( 'LPBC%sDUMPADDR' % infix )
00225       pktWords = packet.get_payload( 'LPBC%sDUMPWC' % infix )
00226 
00227       # For SIU payload is LPBCMEMDUMPDATxx,
00228       # for EPUs it is LPBCiDUMPDATAxx
00229       if self.__unit == FSW_UNIT_SIU:
00230         suffix = ""
00231       else:
00232         suffix = "A"
00233 
00234       # Primary boot telemetry comes out *constantly*  we must *check*
00235       if self.__address <= pktStart < self.__address+self.__size*4:
00236         dataMnems = [ 'LPBC%sDUMPDAT%s%02d' % (infix, suffix, i) for i in range(pktWords) ]
00237         dataStrs  = [ struct.pack('!I', datum) for datum in map(packet.get_payload, dataMnems) ]
00238         self.__frags[pktStart] = ''.join(dataStrs)
00239         self.__sizes[pktStart] = pktWords
00240 
00241 
00242     def __parseSBC(self, packet):
00243       mode = 1
00244       infix =  DUMP_TLM_INFIX[self.__unit][mode]
00245       pktStart = packet.get_payload( 'LMEMT%sADDRESS' % infix )
00246       pktWords = packet.get_payload( 'LMEMT%sWORDCNT' % infix )
00247 
00248       dataMnems = [ 'LMEMT%sDATA%d' % (infix, i) for i in range(pktWords) ]
00249       dataStrs  = [ struct.pack('!I', datum) for datum in map(packet.get_payload, dataMnems) ]
00250       self.__frags[pktStart] = ''.join(dataStrs)
00251       self.__sizes[pktStart] = pktWords
00252 
00253 
00254     def __retrieveData(self, size):
00255       # wait until we have everything, or timeout in LONG_TIMEOUT
00256       n = 0
00257       lastSum = 0
00258       while n < STANDARD_TIMEOUT:
00259         s = sum(self.__sizes.values())
00260         if s > lastSum:
00261           lastSum = s
00262           n = 0
00263         if s >= size: break
00264         time.sleep(1)
00265         n += 1
00266 
00267       memLocs = self.__frags.keys()
00268       memLocs.sort()
00269       memory = ''
00270       for item in memLocs:
00271         memory += self.__frags[item]
00272       return memory
00273 
00274     def dumpMemory(self, address, size, tranID, dest):
00275       # mem dump telecommand wants ushorts
00276       address_lo = address & 0x0000ffff
00277       size_lo    = size    & 0x0000ffff
00278       address_hi = address >> 16
00279       size_hi    = size    >> 16
00280 
00281       self.__address = address
00282       self.__size    = size
00283 
00284       self.__dumpHdlr.enable()
00285       self.__dumpHdlr2.enable()
00286       self.__cmdDb.MEM.LMEMDUMPMEM( LMEMLATUNIT   = self.__unit,
00287                                     LMEMTRANID    = tranID,
00288                                     LMEMDEST      = dest,
00289                                     LMEMPAD       = 0,
00290                                     LMEMADDRESSHI = address_hi,
00291                                     LMEMADDRESSLO = address_lo,
00292                                     LMEMSIZEHI    = size_hi,
00293                                     LMEMSIZELO    = size_lo)
00294       #JHP: remove command conf as this won't work in primary boot
00295       if not self.__primaryBoot:
00296         if not self.__cmdDb.waitForSuccessfulConfirmation():
00297           result = False
00298       memory = self.__retrieveData(size)
00299       self.__dumpHdlr.disable()
00300       self.__dumpHdlr2.disable()
00301       return memory
00302 
00303     def dumpPCIheader(self, bus, device, function, tranID):
00304       #
00305       pciHdrSize  = 64
00306       self.__dumpHdlr.enable()
00307       self.__cmdDb.MEM.LMEMDUMPPCI( LMEMLATUNIT     = self.__unit,
00308                                     LMEMTRANID      = tranID,
00309                                     LMEMPCIBUS      = bus,
00310                                     LMEMPCIDEVICE   = device,
00311                                     LMEMPCIFUNCTION = function,
00312                                     LMEMPAD         = 0)
00313       #JHP: remove command conf as this won't work in primary boot
00314       if not self.__primaryBoot:
00315         if not self.__cmdDb.waitForSuccessfulConfirmation():
00316           result = False
00317       header = self.__retrieveData(pciHdrSize)
00318       self.__dumpHdlr.disable()
00319 
00320       return header
00321 
00322   class LoadTool(object):
00323     """!\brief Provide a private memory dumping class for fileTools.py
00324     """
00325     def __init__(self, cmdDb, unit, primaryBoot):
00326       """!\brief LoadTool constructor.
00327 
00328       \param cmdDb       Command database
00329       \param unit        LAT unit id to load
00330       \param primaryBoot Flag indicating whether the unit is in primary boot or not
00331       """
00332       self.__cmdDb = cmdDb
00333       self.__unit  = unit
00334       self.__primaryBoot = primaryBoot
00335 
00336     def loadMemory(self, address, tranID, data):
00337       """!\brief Load a given memory address with data.
00338 
00339       \param address Starting address
00340       \param tranID  Transaction ID
00341       \param data    Packed string of 32-bit words to load
00342 
00343       \return        True if the load was successful, False otherwise.
00344       """
00345       result = True
00346 
00347       offset = 0
00348 
00349       size = len(data)
00350 
00351       if size % 4 != 0:
00352         raise ValueError, "Load memory data size has to be a multiple of 4"
00353 
00354       while offset < size:
00355 
00356         address_lo = (address + offset) & 0x0000ffff
00357         address_hi = (address + offset) >> 16
00358 
00359         if (size - offset) / 4 > MEM_LOAD_FRAG_SIZE:
00360           loadSize = MEM_LOAD_FRAG_SIZE
00361         else:
00362           loadSize = (size - offset) / 4
00363 
00364         dataFragments = ()
00365         for i in range(MEM_LOAD_FRAG_SIZE):
00366           if i < loadSize:
00367             datum = struct.unpack('!I', data[offset+(i<<2):offset+((i+1)<<2)])[0]
00368             data_hi = datum >> 16
00369             data_lo = datum & 0x0000ffff
00370           else:
00371             data_hi = 0
00372             data_lo = 0
00373 
00374           dataFragments += (data_hi, data_lo)
00375 
00376         self.__cmdDb.MEM.LMEMLOADMEM(self.__unit,
00377                                     tranID,
00378                                     loadSize,
00379                                     address_hi,
00380                                     address_lo,
00381                                     *dataFragments)
00382         if not self.__primaryBoot:
00383           if not self.__cmdDb.waitForSuccessfulConfirmation():
00384             result = False
00385             break
00386         offset += loadSize*4
00387       return result
00388 

Generated on Thu Apr 27 20:52:42 2006 for LICOS L02-01-00 by doxygen 1.4.6-NO