X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=tools%2Ftinyos%2Fmisc%2Ftos-storage-stm25p.in;h=ed9eb63aa6c65acc36a61bd2a61e4b406feb9941;hb=005f20955c13e13ea1ab79aec8b8f0b18f128838;hp=c26793be078dd0d3429101d86cf787fa8b905f99;hpb=1ba974b83d19fc41bf80acd52726f36f7f1df297;p=tinyos-2.x.git diff --git a/tools/tinyos/misc/tos-storage-stm25p.in b/tools/tinyos/misc/tos-storage-stm25p.in index c26793be..ed9eb63a 100644 --- a/tools/tinyos/misc/tos-storage-stm25p.in +++ b/tools/tinyos/misc/tos-storage-stm25p.in @@ -29,76 +29,245 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE # +# Copyright (c) 2006-2007 Intel Corporation +# All rights reserved. +# +# This file is distributed under the terms in the attached INTEL-LICENSE +# file. If you do not find these files, copies can be found by writing to +# Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, +# 94704. Attention: Intel License Inquiry. + # @author Jonathan Hui +# @author David Gay +# @author Kevin Klues +# @author R. Steve McKown # # $Revision$ # $Date$ # +from __future__ import with_statement # Does this require too new a python? + +import os +import re from re import match from sys import * -from xml.dom import minidom +from xml.dom import * +from xml.dom.minidom import * +from subprocess import Popen, PIPE + +from getopt import * +import string +import commands +#New way of handling arguments........ +try: + opts, args = getopt(argv[1:], "t", []) +except GetoptError, err: + print str(err) # will print something like "option -a not recognized" + stderr.write( "Usage: tos-storage-stm25p [-t] \n" ) + +if len( args ) == 1: + platformdir = args[0] + # This gives the whole string when there's no / in platformdir + platform = platformdir[platformdir.rfind( "/" ) + 1:] +elif len( args ) == 0: + platformdir = "" + platform = "" +else: + stderr.write( "Usage: tos-storage-stm25p [-t] \n" ) + +cthreads = False +for o, a in opts: + if o == "-t": + cthreads = True + else: + assert False, "unhandled option" + +def error_exit( s ): + stderr.write( "ERROR: " + s + "\n" ) + exit( 2 ) + +def expand_path( path ): + substrs = path.split( "%" ) + path = substrs[0] + i = 1 + while i < len( substrs ): + if substrs[i] == "": + # There was a %%, leading to a blank substring, and the next string + # should just be appended + path += "%" + i = i + 1 + if i < len( substrs ): + path += substrs[i] + else: + # The first character of the string is the one that followed % + c = substrs[i][0] + if c == 'p': + sub = platform + elif c == 'P': + sub = platformdir + elif c == 'T': + sub = Popen( ["ncc", "-print-tosdir"], stdout=PIPE ).communicate( )[0] + sub = sub[:-1] # remove newline + else: + nfail( "unknown include-path substitution character " + c ) + path += sub + path += substrs[i][1:] + i = i + 1 + return path -NUM_SECTORS = 16 -SECTOR_SIZE = 65536 + +HEADER_FILE = 'Stm25p.h' +NUM_SECTORS = 0 +SECTOR_SIZE = 0 + +def parseHeader( dotplatform ): + """ Return an ordered list of paths from the dotplatform file """ + paths = [] + inArray = False + p = re.compile('push\s*\(\s*@includes,\s*qw\s*\('); + q = re.compile('\)\s*\)\s*;'); + try: + with open(dotplatform, 'r') as file: + for line in file: + path = line.strip() + if path: + if p.match(path): + inArray = True + elif q.match(path): + inArray = False + elif inArray == True: + paths.append(path) + return paths + except: + return None + +def findFile( paths, filename ): + """ Find the first occurrence of 'filename' in the list of paths given. """ + for path in paths: + rpath = expand_path(path) + try: + for file in os.listdir(rpath): + if file == filename: + return rpath + '/' + filename + except OSError: + None + return None + +def findVars( path, vars ): + """ Finds values for the variables already present in vars from path """ + inEnum = False + p = re.compile('enum\s.*{'); + q = re.compile('}s*;'); + r = re.compile('^\s*([A-Z0-9_]*)\s*=\s*([^,]*)'); + with open(path, 'r') as file: + for line in file: + line = line.strip() + if line: + if p.match(line): + inEnum = True + elif q.match(line): + inEnum = False + elif inEnum == True: + m = r.search(line) + if vars.has_key(m.group(1)): + vars[m.group(1)] = m.group(2) + +paths = parseHeader(platformdir + '/.platform') +if paths: + path = findFile(paths, HEADER_FILE) + if path: + enums = {} + enums["STM25P_NUM_SECTORS"] = 0 + enums["STM25P_SECTOR_SIZE_LOG2"] = 0 + findVars(path, enums) + NUM_SECTORS = int(enums["STM25P_NUM_SECTORS"]) + SECTOR_SIZE = 2**int(enums["STM25P_SECTOR_SIZE_LOG2"]) +if NUM_SECTORS == 0 or SECTOR_SIZE == 0: + stderr.write( "tos-storage-stm25p: no valid Stm25p.h found.\n\t" + "Check @includes in the platform's .platform file\n" ) + exit(2) volumes = {} volumeNames = [] volumeSizes = [] volumeOffsets = [] +volumeTypes = dict() +volumeOptions = dict() freeSectors = NUM_SECTORS*[ True ] -def error_exit( s ): - stderr.write( "ERROR: " + s + "\n" ) - exit( 2 ) +def volumeparse( file, fname, depth ): + if depth > 10: + error_exit( "include nesting too deep - check for cycles" ) + try: + dom = parse( file ) + except xml.parsers.expat.ExpatError: + error_exit( fname + " is not a valid input file" ) + except IOError: + error_exit( "couldn't open file " + fname ) -try: - dom = minidom.parse( stdin ) -except xml.parsers.expat.ExpatError: - error_exit( "input invalid" ) - -# extract information -for volume in dom.documentElement.getElementsByTagName( "volume" ): - name = volume.getAttribute( "name" ) - size = volume.getAttribute( "size" ) - base = volume.getAttribute( "base" ) - if name == "": - error_exit( "volume has no name" ) - elif not match( "^[a-zA-Z0-9_]+$", name ): - error_exit( "volume has invalid name '%s'" % name ) - elif volumes.has_key( name ): - error_exit( "duplicate volume definition '%s'" % name ) - else: - volumes[ name ] = "blah" - - if size == "": - error_exit( "volume '%s' has no size" % name ) - try: - size = int( size ) - except ValueError: - error_exit( "volume '%s' has invalid size" % name ) - if base != "": - try: - base = int( base ) - except ValueError: - error_exit( "volume '%s' has invalid base" % name ) - if ( size & ( SECTOR_SIZE - 1 ) ) != 0: - error_exit( "size of volume '%s' is not a multiple of %d" % \ - ( name, SECTOR_SIZE ) ) - if base != "" and ( base & ( SECTOR_SIZE - 1 ) ) != 0: - error_exit( "base of volume '%s' is not a multiple of %d" % \ - ( name, SECTOR_SIZE ) ) - - volumeNames.append( "VOLUME_" + name ) - volumeSizes.append( size / SECTOR_SIZE ) - if base == "": - volumeOffsets.append( -1 ) + # extract information + for volume in dom.documentElement.getElementsByTagName( "volume" ): + name = volume.getAttribute( "name" ) + size = volume.getAttribute( "size" ) + base = volume.getAttribute( "base" ) + type = string.lower(volume.getAttribute("type")) + isCircular = string.upper(volume.getAttribute("circular")) + if isCircular == "": + isCircular = "FALSE" + + if name == "": + error_exit( "volume has no name" ) + elif not match( "^[a-zA-Z0-9_]+$", name ): + error_exit( "volume has invalid name '%s'" % name ) + elif volumes.has_key( name ): + error_exit( "duplicate volume definition '%s'" % name ) + else: + volumes[ name ] = "blah" + + if size == "": + error_exit( "volume '%s' has no size" % name ) + try: + size = int( size ) + except ValueError: + error_exit( "volume '%s' has invalid size" % name ) + if base != "": + try: + base = int( base ) + except ValueError: + error_exit( "volume '%s' has invalid base" % name ) + if ( size & ( SECTOR_SIZE - 1 ) ) != 0: + error_exit( "size of volume '%s' is not a multiple of %d" % \ + ( name, SECTOR_SIZE ) ) + if base != "" and ( base & ( SECTOR_SIZE - 1 ) ) != 0: + error_exit( "base of volume '%s' is not a multiple of %d" % \ + ( name, SECTOR_SIZE ) ) + + volumeNames.append( "VOLUME_" + name ) + volumeSizes.append( size / SECTOR_SIZE ) + volumeTypes["VOLUME_" + name] = type + volumeOptions["VOLUME_" + name] = isCircular + + if base == "": + volumeOffsets.append( -1 ) + else: + base = base / SECTOR_SIZE + size = size / SECTOR_SIZE + volumeOffsets.append( base ) + for i in range( size ): + freeSectors[ i + base ] = False + + for include in dom.documentElement.getElementsByTagName( "include" ): + included = include.firstChild + if included != None and included.nodeType == included.TEXT_NODE: + included = expand_path( included.data ) + volumeparse( included, "(file %s)" % included, depth + 1 ) else: - base = base / SECTOR_SIZE - volumeOffsets.append( base ) - for i in range( size ): - freeSectors[ i + base ] = False + error_exit( "invalid include directive " + fname ) + dom.unlink( ) + +volumeparse( stdin, "(standard input)", 0 ) # allocate with first fit policy for i in range( len( volumeOffsets ) ): @@ -139,3 +308,50 @@ print "};" print "" print "#endif" + +# output nc file for threads +if cthreads == True: + outFile = open(commands.getstatusoutput("pwd")[1] + "/VolumeMapC.nc", "w") + outFile.write("#include \"StorageVolumes.h\" \n") + outFile.write("\n") + outFile.write("configuration VolumeMapC { \n") + outFile.write(" provides { \n") + outFile.write(" interface BlockRead[uint8_t volume_id]; \n") + outFile.write(" interface BlockWrite[uint8_t volume_id]; \n") + outFile.write(" interface LogRead[uint8_t volumeId]; \n") + outFile.write(" interface LogWrite[uint8_t volumeId]; \n") + outFile.write(" interface Mount[uint8_t volumeId]; \n") + outFile.write(" interface ConfigStorage[uint8_t volumeId]; \n") + outFile.write(" } \n") + outFile.write("} \n") + outFile.write("\n") + outFile.write("implementation { \n") + outFile.write(" components VolumeMapP; \n") + outFile.write("\n") + outFile.write(" BlockRead = VolumeMapP; \n") + outFile.write(" BlockWrite = VolumeMapP; \n") + outFile.write(" LogRead = VolumeMapP; \n") + outFile.write(" LogWrite = VolumeMapP; \n") + outFile.write(" Mount = VolumeMapP; \n") + outFile.write(" ConfigStorage = VolumeMapP; \n") + + for i in range(len(volumeNames)): + if volumeTypes[volumeNames[i]] == "block": + outFile.write("\n") + outFile.write(" components new BlockStorageC(" + volumeNames[i] + ") as BlockStorageC_" + volumeNames[i] + "; \n") + outFile.write(" VolumeMapP.SubBlockRead[" + volumeNames[i] + "] -> BlockStorageC_" + volumeNames[i] + "; \n") + outFile.write(" VolumeMapP.SubBlockWrite[" + volumeNames[i] + "] -> BlockStorageC_" + volumeNames[i] + "; \n") + outFile.write("\n") + + elif volumeTypes[volumeNames[i]] == "log": + outFile.write("\n") + outFile.write(" components new LogStorageC(" + volumeNames[i] + ", " + volumeOptions[volumeNames[i]] + ") as LogStorageC_" + volumeNames[i] + "; \n") + outFile.write(" VolumeMapP.SubLogRead[" + volumeNames[i] + "] -> LogStorageC_" + volumeNames[i] + "; \n") + outFile.write(" VolumeMapP.SubLogWrite[" + volumeNames[i] + "] -> LogStorageC_" + volumeNames[i] + "; \n") + outFile.write("\n") + + elif volumeTypes[volumeNames[i]] == "config": + outFile.write(" components new ConfigStorageC(" + volumeNames[i] + ") as ConfigStorageC_" + volumeNames[i] + "; \n") + outFile.write(" Mount[" + volumeNames[i] + "] = ConfigStorageC_" + volumeNames[i] + "; \n") + outFile.write(" ConfigStorage[" + volumeNames[i] + "] = ConfigStorageC_" + volumeNames[i] + "; \n") + outFile.write("} \n")