00001
00002
00003
00004
00005
00006
00007
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
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:
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
00170 return self.dumpPool(unit, tranID, poolID)
00171
00172 def __checkLastCommandStatus(self):
00173
00174
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
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 = {}
00202 self.__sizes = {}
00203 self.__mode = None
00204 self.__tlms = [ cmdDb.getVsc().getTlmDb().getApidFromName(n) for n in DUMP_MNEMONICS[unit] ]
00205
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
00228
00229 if self.__unit == FSW_UNIT_SIU:
00230 suffix = ""
00231 else:
00232 suffix = "A"
00233
00234
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
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
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
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
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