# HG changeset patch # User Windel Bouwman # Date 1375633924 -7200 # Node ID 225f444019b1550f5a436d3452f0b7faf17eb9f3 # Parent 7416c923a02a65952d68c761e4128214a5a69468 Added build and flash menu option diff -r 7416c923a02a -r 225f444019b1 README.md --- a/README.md Sun Aug 04 15:10:10 2013 +0200 +++ b/README.md Sun Aug 04 18:32:04 2013 +0200 @@ -1,7 +1,7 @@ # Project goals -* To write a microkernel sort of OS. -* Write the kernel in C ('cos') +* To write a microkernel OS. +* Write the kernel in C3 ('cos') * Write a kernel in oberon like language and be able to compile this with the ide. * Create python scripts that form the major part of the OS. * Make IDE in python that can compile the OS. @@ -19,7 +19,12 @@ # How to start the IDE cd python - python runide.py + python ide.py + +# Run unittests + + cd python + python -m unittest [![Build Status](https://drone.io/bitbucket.org/windel/lcfos/status.png)](https://drone.io/bitbucket.org/windel/lcfos/latest) diff -r 7416c923a02a -r 225f444019b1 python/astviewer.py --- a/python/astviewer.py Sun Aug 04 15:10:10 2013 +0200 +++ b/python/astviewer.py Sun Aug 04 18:32:04 2013 +0200 @@ -3,19 +3,22 @@ from c3 import Visitor, astnodes class AstModelBuilder: - def __init__(self): + def __init__(self): self.functionIco = QIcon(QPixmap('icons/functionicon.png').scaled(32, 32)) self.variableIco = QIcon(QPixmap('icons/variableicon.png').scaled(32, 32)) self.model = QStandardItemModel() self.model.setHorizontalHeaderLabels(['Object', 'Type']) - def build(self, pkg): - #self.model.clear() - c = self.model.rowCount() - self.model.removeRows(0, c) - self.curItem = self.model.invisibleRootItem() - visitor = Visitor() - visitor.visit(pkg, self.p1, self.p2) - def p1(self, node): + + def build(self, pkg): + #self.model.clear() + c = self.model.rowCount() + self.model.removeRows(0, c) + self.curItem = self.model.invisibleRootItem() + if pkg: + visitor = Visitor() + visitor.visit(pkg, self.p1, self.p2) + + def p1(self, node): if type(node) is astnodes.Variable: i = QStandardItem(self.variableIco, str(node)) elif type(node) is astnodes.Function: @@ -30,25 +33,26 @@ i.setData(node) self.curItem.appendRow([i, ti]) self.curItem = i - def p2(self, node): + + def p2(self, node): if type(node) in [astnodes.Variable, astnodes.Function, astnodes.Package]: self.curItem = self.curItem.parent() # The actual widget: class AstViewer(QTreeView): - sigNodeSelected = pyqtSignal(object) - def __init__(self, parent=None): + sigNodeSelected = pyqtSignal(object) + def __init__(self, parent=None): super(AstViewer, self).__init__(parent) self.clicked.connect(self.selectHandler) self.modelBuilder = AstModelBuilder() self.setModel(self.modelBuilder.model) - def setAst(self, ast): - """ Create a new model and add all ast elements to it """ - self.modelBuilder.build(ast) - self.expandAll() + def setAst(self, ast): + """ Create a new model and add all ast elements to it """ + self.modelBuilder.build(ast) + self.expandAll() - def selectHandler(self, index): + def selectHandler(self, index): if not index.isValid(): return model = self.model() diff -r 7416c923a02a -r 225f444019b1 python/codeedit.py --- a/python/codeedit.py Sun Aug 04 15:10:10 2013 +0200 +++ b/python/codeedit.py Sun Aug 04 18:32:04 2013 +0200 @@ -36,24 +36,24 @@ self.t.start() def updateCursor(self): - self.blinkcursor = not self.blinkcursor - self.update() - #self.update(self.cursorX, self.cursorY, self.charWidth, self.charHeight) + self.blinkcursor = not self.blinkcursor + self.update() + #self.update(self.cursorX, self.cursorY, self.charWidth, self.charHeight) def setSource(self, src): - self.src = src - self.adjust() + self.src = src + self.adjust() def getSource(self): - return self.src + return self.src def setErrors(self, el): - self.errorlist = el - self.update() + self.errorlist = el + self.update() def setCursorPosition(self, c): - self.cursorPosition = clipVal(c, 0, len(self.src)) - self.update() + self.cursorPosition = clipVal(c, 0, len(self.src)) + self.update() CursorPosition = property(lambda self: self.cursorPosition, setCursorPosition) @@ -95,42 +95,51 @@ def showRow(self, r): self.scrollArea.ensureVisible(self.xposTXT, r * self.charHeight, 4, self.charHeight) + # Annotations: def addAnnotation(self, row, col, ln, msg): pass + # Text modification: def getChar(self, pos): pass + def insertText(self, txt): - self.setSource(self.src[0:self.CursorPosition] + txt + self.src[self.CursorPosition:]) - self.CursorPosition += len(txt) - self.textChanged.emit() + self.setSource(self.src[0:self.CursorPosition] + txt + self.src[self.CursorPosition:]) + self.CursorPosition += len(txt) + self.textChanged.emit() + def deleteChar(self): - self.setSource(self.src[0:self.CursorPosition] + self.src[self.CursorPosition+1:]) - self.textChanged.emit() + self.setSource(self.src[0:self.CursorPosition] + self.src[self.CursorPosition+1:]) + self.textChanged.emit() + def GotoNextChar(self): - if self.src[self.CursorPosition] != '\n': - self.CursorPosition += 1 + if self.src[self.CursorPosition] != '\n': + self.CursorPosition += 1 + def GotoPrevChar(self): - if self.src[self.CursorPosition - 1] != '\n': - self.CursorPosition -= 1 + if self.src[self.CursorPosition - 1] != '\n': + self.CursorPosition -= 1 + def GotoNextLine(self): - curLine = self.CurrentLine - c = self.CursorCol - 1 # go to zero based - self.CursorPosition += len(curLine) - c + 1 # line break char! - curLine = self.CurrentLine - if len(curLine) < c: - self.CursorPosition += len(curLine) - else: - self.CursorPosition += c - self.showRow(self.CursorRow) + curLine = self.CurrentLine + c = self.CursorCol - 1 # go to zero based + self.CursorPosition += len(curLine) - c + 1 # line break char! + curLine = self.CurrentLine + if len(curLine) < c: + self.CursorPosition += len(curLine) + else: + self.CursorPosition += c + self.showRow(self.CursorRow) + def GotoPrevLine(self): - c = self.CursorCol - 1 # go to zero based - self.CursorPosition -= c + 1 # line break char! - curLine = self.CurrentLine - if len(curLine) > c: - self.CursorPosition -= len(curLine) - c - self.showRow(self.CursorRow) + c = self.CursorCol - 1 # go to zero based + self.CursorPosition -= c + 1 # line break char! + curLine = self.CurrentLine + if len(curLine) > c: + self.CursorPosition -= len(curLine) - c + self.showRow(self.CursorRow) + def paintEvent(self, event): # Helper variables: er = event.rect() @@ -209,25 +218,26 @@ self.update() def mousePressEvent(self, event): - pos = event.pos() - if pos.x() > self.xposTXT and pos.x(): - c = round((pos.x() - self.xposTXT) / self.charWidth) - r = int(pos.y() / self.charHeight) + 1 - self.setRowCol(r, c) + pos = event.pos() + if pos.x() > self.xposTXT and pos.x(): + c = round((pos.x() - self.xposTXT) / self.charWidth) + r = int(pos.y() / self.charHeight) + 1 + self.setRowCol(r, c) + super().mousePressEvent(event) def adjust(self): - metrics = self.fontMetrics() - self.charHeight = metrics.height() - self.charWidth = metrics.width('x') - self.charDescent = metrics.descent() - self.xposERR = GAP - self.xposLNA = self.xposERR + GAP + self.errorPixmap.width() - self.xposTXT = self.xposLNA + 4 * self.charWidth + GAP - self.xposEnd = self.xposTXT + self.charWidth * 80 - self.setMinimumWidth(self.xposEnd) - txt = self.src.split('\n') - self.setMinimumHeight(self.charHeight * len(txt)) - self.update() + metrics = self.fontMetrics() + self.charHeight = metrics.height() + self.charWidth = metrics.width('x') + self.charDescent = metrics.descent() + self.xposERR = GAP + self.xposLNA = self.xposERR + GAP + self.errorPixmap.width() + self.xposTXT = self.xposLNA + 4 * self.charWidth + GAP + self.xposEnd = self.xposTXT + self.charWidth * 80 + self.setMinimumWidth(self.xposEnd) + txt = self.src.split('\n') + self.setMinimumHeight(self.charHeight * len(txt)) + self.update() class CodeEdit(QScrollArea): def __init__(self): @@ -248,6 +258,7 @@ def setFocus(self): self.ic.setFocus() + super().setFocus() def setFileName(self, fn): self.filename = fn diff -r 7416c923a02a -r 225f444019b1 python/codegenarm.py --- a/python/codegenarm.py Sun Aug 04 15:10:10 2013 +0200 +++ b/python/codegenarm.py Sun Aug 04 18:32:04 2013 +0200 @@ -62,6 +62,8 @@ self.align() self.outs.backpatch() self.outs.backpatch() + code = self.outs.getSection('code').to_bytes() + self.logger.info('Generated {} bytes code'.format(len(code))) def dcd(self, x): self.emit(arm.dcd_ins(Imm32(x))) diff -r 7416c923a02a -r 225f444019b1 python/icons/info.png Binary file python/icons/info.png has changed diff -r 7416c923a02a -r 225f444019b1 python/icons/warning.png Binary file python/icons/warning.png has changed diff -r 7416c923a02a -r 225f444019b1 python/ide.py --- a/python/ide.py Sun Aug 04 15:10:10 2013 +0200 +++ b/python/ide.py Sun Aug 04 18:32:04 2013 +0200 @@ -16,12 +16,13 @@ import zcc import outstream +logformat='%(asctime)s|%(levelname)s|%(name)s|%(msg)s' class BuildOutput(QTextEdit): """ Build output component """ def __init__(self, parent=None): super(BuildOutput, self).__init__(parent) - fmt = logging.Formatter(fmt='%(asctime)s %(levelname)s %(name)s %(msg)s') + fmt = logging.Formatter(fmt=logformat) class MyHandler(logging.Handler): def emit(self2, x): self.append(str(fmt.format(x))) @@ -57,11 +58,11 @@ self.model.appendRow([item, irow, icol]) def itemSelected(self, index): - if not index.isValid(): - return - item = self.model.itemFromIndex(index) - err = item.data() - self.sigErrorSelected.emit(err) + if not index.isValid(): + return + item = self.model.itemFromIndex(index) + err = item.data() + self.sigErrorSelected.emit(err) class AboutDialog(QDialog): @@ -87,7 +88,7 @@ class Ide(QMainWindow): def __init__(self, parent=None): super(Ide, self).__init__(parent) - + self.to_open_files = [] self.setWindowTitle('LCFOS IDE') icon = QIcon('icons/logo.png') @@ -103,6 +104,7 @@ self.mdiArea = QMdiArea() self.mdiArea.setViewMode(QMdiArea.TabbedView) self.mdiArea.setTabsClosable(True) + self.mdiArea.setTabsMovable(True) self.setCentralWidget(self.mdiArea) # Create components: @@ -147,6 +149,7 @@ addMenuEntry("Open", self.fileMenu, self.openFile, shortcut=QKeySequence(QKeySequence.Open)) addMenuEntry("Save", self.fileMenu, self.saveFile, shortcut=QKeySequence(QKeySequence.Save)) addMenuEntry("Build", self.fileMenu, self.buildFile, shortcut=QKeySequence("F7")) + addMenuEntry("Build and flash", self.fileMenu, self.buildFileAndFlash, shortcut=QKeySequence("F8")) self.helpAction = QAction('Help', self) self.helpAction.setShortcut(QKeySequence('F1')) @@ -217,8 +220,13 @@ self.restoreGeometry(self.settings.value('mainwindowgeometry')) if self.settings.contains('lastfiles'): lfs = self.settings.value('lastfiles') - for lf in lfs: - self.loadFile(lf) + self.to_open_files.extend(lfs) + + def showEvent(self, ev): + super().showEvent(ev) + while self.to_open_files: + fn = self.to_open_files.pop(0) + self.loadFile(fn) def closeEvent(self, ev): self.settings.setValue('mainwindowstate', self.saveState()) @@ -282,6 +290,18 @@ ce.setErrors(self.diag.diags) return + def buildFileAndFlash(self): + ce = self.activeMdiChild() + if not ce: + return + self.diag.clear() + outs = outstream.TextOutputStream() + if not zcc.zcc(ce.Source, outs, self.diag, do_optimize=True): + # Set errors: + self.builderrors.setErrorList(self.diag.diags) + ce.setErrors(self.diag.diags) + return + code_s = outs.getSection('code') self.debugInfo = code_s.debugInfos() if self.ctrlToolbar.device: @@ -291,10 +311,12 @@ stl = self.ctrlToolbar.device.iface stl.reset() stl.halt() + stl.run() logging.info('Done!') + if __name__ == '__main__': - logging.basicConfig(format='%(asctime)s %(levelname)s %(name)s %(message)s', level=logging.DEBUG) + logging.basicConfig(format=logformat, level=logging.DEBUG) app = QApplication(sys.argv) ide = Ide() ide.show() diff -r 7416c923a02a -r 225f444019b1 python/ir/function.py --- a/python/ir/function.py Sun Aug 04 15:10:10 2013 +0200 +++ b/python/ir/function.py Sun Aug 04 18:32:04 2013 +0200 @@ -38,14 +38,12 @@ bb.check() def call(self, *args): - print(args) varmap = {} bb = self.Entry ip = 0 while True: i = bb.Instructions[ip] ip += 1 - print(i) return diff -r 7416c923a02a -r 225f444019b1 python/stm32.py --- a/python/stm32.py Sun Aug 04 15:10:10 2013 +0200 +++ b/python/stm32.py Sun Aug 04 18:32:04 2013 +0200 @@ -1,4 +1,5 @@ import time +import logging from devices import Device, registerDevice, STLinkException, Interface import stlink @@ -100,7 +101,7 @@ self.unlockFlashIf() self.writeFlashCrPsiz(2) # writes are 32 bits aligned self.setFlashCrPg() - self.logger.info('writing {0} bytes'.format(len(content)), end='') + self.logger.info('writing {0} bytes'.format(len(content))) offset = 0 t1 = time.time() while offset < len(content): @@ -113,10 +114,10 @@ # Use simple mem32 writes: self.iface.write_mem32(address + offset, chunk) offset += size - print('.', end='', flush=True) + self.logger.info('.') t2 = time.time() - print('Done!') - print('Speed: {0} bytes/second'.format(len(content)/(t2-t1))) + self.logger.info('Done!') + self.logger.info('Speed: {0} bytes/second'.format(len(content)/(t2-t1))) self.lockFlash() # verfify program: self.verifyFlash(address, content) @@ -135,12 +136,14 @@ self.waitFlashBusy() self.clearFlashCrMer() self.lockFlash() + def verifyFlash(self, address, content): device_content = self.readFlash(address, len(content)) ok = content == device_content - print('Verify:', ok) + self.logger.info('Verify: {}'.format(ok)) + def readFlash(self, address, size): - print('Reading {1} bytes from 0x{0:X}'.format(address, size), end='') + self.logger.info('Reading {1} bytes from 0x{0:X}'.format(address, size)) offset = 0 tmp_size = 0x1800 t1 = time.time() @@ -159,14 +162,14 @@ image += mem[:tmp_size] # indicate progress: - print('.', end='', flush=True) + self.logger.info('.') # increase for next piece: offset += tmp_size t2 = time.time() assert size == len(image) - print('Done!') - print('Speed: {0} bytes/second'.format(size/(t2-t1))) + self.logger.info('Done!') + self.logger.info('Speed: {0} bytes/second'.format(size/(t2-t1))) return image def waitFlashBusy(self): diff -r 7416c923a02a -r 225f444019b1 python/stm32f4/burn.c3 --- a/python/stm32f4/burn.c3 Sun Aug 04 15:10:10 2013 +0200 +++ b/python/stm32f4/burn.c3 Sun Aug 04 18:32:04 2013 +0200 @@ -10,9 +10,11 @@ import stm32f4xx; +/* function void init() { } +*/ function void main() { diff -r 7416c923a02a -r 225f444019b1 python/testir.py --- a/python/testir.py Sun Aug 04 15:10:10 2013 +0200 +++ b/python/testir.py Sun Aug 04 18:32:04 2013 +0200 @@ -1,6 +1,9 @@ import unittest, os import sys -import c3, ppci, ir, x86, transform +import c3 +import ppci +import ir, x86, transform +import optimize class IrCodeTestCase(unittest.TestCase): def setUp(self): @@ -117,7 +120,7 @@ diag.printErrors(testsrc) ir.check() ir.dump() - transform.optimize(ir) + optimize.optimize(ir) print('dump IR') print('dump IR') print('dump IR')