123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615 |
- #! /usr/bin/env python
- # -*- coding: UTF-8 -*-
- #———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
- import sys, interrupt_names_teensy_3_6
- #———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
- def ENDC () :
- return '\033[0m'
- #······················································································································*
- def RED () :
- return '\033[91m'
- #······················································································································*
- def BOLD () :
- return '\033[1m'
- #······················································································································*
- def BOLD_RED () :
- return BOLD () + RED ()
- #———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
- def asSeparator () :
- return "@" + ("-" * 119) + "\n"
- #———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
- def cppSeparator () :
- return "//" + ("-" * 118) + "\n"
- #———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
- def generateSVChandler ():
- sFile = asSeparator ()
- sFile += "@ S V C H A N D L E R ( D O U B L E S T A C K M O D E )\n"
- sFile += asSeparator ()
- sFile += "@\n"
- sFile += "@ PSP+32 -> | |\n"
- sFile += "@ |----------------------------| \\\n"
- sFile += "@ PSP+28 -> | xPSR | |\n"
- sFile += "@ |----------------------------| |\n"
- sFile += "@ PSP+24 -> | PC (after SVC instruction) | |\n"
- sFile += "@ |----------------------------| |\n"
- sFile += "@ PSP+20 -> | LR | |\n"
- sFile += "@ |----------------------------| |\n"
- sFile += "@ PSP+16 -> | R12 | | Saved by interrupt response\n"
- sFile += "@ |----------------------------| |\n"
- sFile += "@ PSP+12 -> | R3 | |\n"
- sFile += "@ |----------------------------| |\n"
- sFile += "@ PSP+8 -> | R2 | |\n"
- sFile += "@ |----------------------------| |\n"
- sFile += "@ PSP+4 -> | R1 | |\n"
- sFile += "@ |----------------------------| |\n"
- sFile += "@ /--- PSP ----> | R0 | |\n"
- sFile += "@ | |----------------------------| /\n"
- sFile += "@ | | |\n"
- sFile += "@ |\n"
- sFile += "@ | *---------------------*\n"
- sFile += "@ | | LR return code | +36 [ 9]\n"
- sFile += "@ | *---------------------*\n"
- sFile += "@ \----------------------------------------- | R13 (PSP) | +32 [ 8]\n"
- sFile += "@ *---------------------*\n"
- sFile += "@ | R11 | +28 [ 7]\n"
- sFile += "@ *---------------------*\n"
- sFile += "@ | R10 | +24 [ 6]\n"
- sFile += "@ *---------------------*\n"
- sFile += "@ | R9 | +20 [ 5]\n"
- sFile += "@ *---------------------*\n"
- sFile += "@ | R8 | +16 [ 4]\n"
- sFile += "@ *---------------------*\n"
- sFile += "@ | R7 | +12 [ 3]\n"
- sFile += "@ *---------------------*\n"
- sFile += "@ | R6 | + 8 [ 2]\n"
- sFile += "@ *---------------------*\n"
- sFile += "@ | R5 | + 4 [ 1]\n"
- sFile += "@ *------------------------------------* *---------------------*\n"
- sFile += "@ | var.running.task.control.block.ptr +------> | R4 | + 0 [ 0]\n"
- sFile += "@ *------------------------------------* *---------------------*\n"
- sFile += "@\n"
- sFile += asSeparator () + "\n"
- sFile += " .section .bss.var.background.task.context, \"aw\", %nobits\n"
- sFile += " .align 2\n\n"
- sFile += "var.background.task.context:\n"
- sFile += " .space 4\n\n"
- sFile += asSeparator () + "\n"
- sFile += " .section .text.interrupt.SVC, \"ax\", %progbits\n\n"
- sFile += " .global interrupt.SVC\n"
- sFile += " .type interrupt.SVC, %function\n\n"
- sFile += "interrupt.SVC:\n"
- sFile += "@----------------------------------------- Save preserved registers\n"
- sFile += " push {r4, lr}\n"
- sFile += "@----------------------------------------- R4 <- thread SP\n"
- sFile += " mrs r4, psp\n"
- sFile += "@----------------------------------------- Restore R0, R1, R2 and R3 from saved stack\n"
- sFile += " ldmia r4!, {r0, r1, r2, r3} @ R4 incremented by 16\n"
- sFile += "@----------------------------------------- R4 <- Address of SVC instruction\n"
- sFile += " ldr r4, [r4, #8] @ 8 : 2 stacked registers before saved PC\n"
- sFile += "@----------------------------------------- R12 <- bits 0-7 of SVC instruction\n"
- sFile += " ldrb r12, [r4, #-2] @ R12 is service call index\n"
- sFile += "@----------------------------------------- R4 <- address of dispatcher table\n"
- sFile += " ldr r4, =svc.dispatcher.table\n"
- sFile += "@----------------------------------------- R12 <- address of routine to call\n"
- sFile += " ldr r12, [r4, r12, lsl #2] @ R12 = R4 + (R12 << 2)\n"
- sFile += "@----------------------------------------- R4 <- calling task context\n"
- sFile += " ldr r4, =var.running.task.control.block.ptr\n"
- sFile += " ldr r4, [r4]\n"
- sFile += "@----------------------------------------- Call service routine\n"
- sFile += " blx r12 @ R4:calling task context address\n"
- sFile += "@--- Continues in sequence to handle.context.switch\n\n"
- sFile += asSeparator ()
- sFile += "@\n"
- sFile += "@ H A N D L E C O N T E X T S W I T C H ( D O U B L E S T A C K M O D E )\n"
- sFile += "@\n"
- sFile += "@ On entry:\n"
- sFile += "@ - R4 contains the runnning task save context address,\n"
- sFile += "@ - R4 and LR of running task have been pushed on handler stack.\n"
- sFile += "@\n"
- sFile += asSeparator () + "\n"
- sFile += "handle.context.switch:\n"
- sFile += "@----------------------------------------- Select task to run\n"
- sFile += " bl kernel.select.task.to.run\n"
- sFile += "@----------------------------------------- R0 <- calling task context, R1 <- new task context\n"
- sFile += " ldr r1, =var.running.task.control.block.ptr\n"
- sFile += " mov r0, r4\n"
- sFile += " ldr r1, [r1]\n"
- sFile += "@----------------------------------------- Restore preserved registers\n"
- sFile += " pop {r4, lr}\n"
- sFile += "@----------------------------------------- Running task did change ?\n"
- sFile += " cmp r0, r1 @ R0:calling task context, R1:new task context\n"
- sFile += " bne running.state.did.change\n"
- sFile += " bx lr @ No change\n"
- sFile += "@----------------------------------------- Save context of preempted task\n"
- sFile += "running.state.did.change:\n"
- sFile += " mrs r12, psp\n"
- sFile += " cbz r0, save.background.task.context\n"
- sFile += "@--- Save registers r4 to r11, PSP (stored in R12), LR\n"
- sFile += " stmia r0, {r4, r5, r6, r7, r8, r9, r10, r11, r12, lr}\n"
- sFile += " b perform.restore.context\n"
- sFile += "save.background.task.context:\n"
- sFile += " ldr r2, =var.background.task.context\n"
- sFile += " str r12, [r2]\n"
- sFile += "@----------------------------------------- Restore context of activated task\n"
- sFile += "perform.restore.context:\n"
- sFile += " cbz r1, restore.background.task.context\n"
- sFile += " ldmia r1, {r4, r5, r6, r7, r8, r9, r10, r11, r12, lr}\n"
- sFile += " msr psp, r12\n"
- sFile += " bx lr\n"
- sFile += "@----------------------------------------- Restore background task context\n"
- sFile += "restore.background.task.context:\n"
- sFile += " ldr r2, =var.background.task.context\n"
- sFile += " ldr r2, [r2]\n"
- sFile += " msr psp, r2\n"
- sFile += " bx lr\n\n"
- return sFile
- #———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
- def generateBreakpointHandler () :
- sFile = asSeparator ()
- sFile += "@\n"
- sFile += "@ B K P T H A N D L E R ( D O U B L E S T A C K M O D E )\n"
- sFile += "@\n"
- sFile += asSeparator ()
- sFile += "@\n"
- sFile += "@ | |\n"
- sFile += "@ PSP+32 -> |----------------------------| \\\n"
- sFile += "@ | xPSR | |\n"
- sFile += "@ PSP+28 -> |----------------------------| |\n"
- sFile += "@ | PC (BKPT instruction) | |\n"
- sFile += "@ PSP+24 -> |----------------------------| |\n"
- sFile += "@ | LR | |\n"
- sFile += "@ PSP+20 -> |----------------------------| |\n"
- sFile += "@ | R12 | | Saved by interrupt response\n"
- sFile += "@ PSP+16 -> |----------------------------| |\n"
- sFile += "@ | R3 | |\n"
- sFile += "@ PSP+12 -> |----------------------------| |\n"
- sFile += "@ | R2 | |\n"
- sFile += "@ PSP+8 -> |----------------------------| |\n"
- sFile += "@ | R1 | |\n"
- sFile += "@ PSP+4 -> |----------------------------| |\n"
- sFile += "@ | R0 | |\n"
- sFile += "@ PSP -> |----------------------------| /\n"
- sFile += "@\n"
- sFile += asSeparator () + "\n"
- sFile += " .section .text.interrupt.DebugMonitor, \"ax\", %progbits\n\n"
- sFile += " .global interrupt.DebugMonitor\n"
- sFile += " .type interrupt.DebugMonitor, %function\n\n"
- sFile += "interrupt.DebugMonitor:\n"
- sFile += "@--------------------- Save preserved registers\n"
- sFile += " push {r5, lr}\n"
- sFile += "@--------------------- R5 <- thread SP\n"
- sFile += " mrs r5, psp\n"
- sFile += " ldmia r5, {r0, r1, r2, r3}\n"
- sFile += "@--------------------- LR <- Address of BKPT instruction\n"
- sFile += " ldr lr, [r5, #24] @ 24 : 6 stacked registers before saved PC\n"
- sFile += "@--------------------- Set return address to instruction following BKPT\n"
- sFile += "@ adds lr, #2\n"
- sFile += "@ str lr, [r5, #24]\n"
- sFile += "@--------------------- R12 <- address of dispatcher\n"
- sFile += " ldr r12, =section.dispatcher.table\n"
- sFile += "@--------------------- LR <- bits 0-7 of BKPT instruction\n"
- sFile += " ldrb lr, [lr, #-2] @ LR is service call index\n"
- sFile += "@--------------------- r12 <- address of routine to call\n"
- sFile += " ldr r12, [r12, lr, lsl #2] @ R12 = [R12 + LR * 4]\n"
- sFile += "@--------------------- Call service routine\n"
- sFile += " blx r12\n"
- sFile += "@--------------------- Set return code (from R0 to R3) in stacked registers\n"
- sFile += " stmia r5!, {r0, r1, r2, r3}\n"
- sFile += "@--------------------- Restore preserved registers, return from interrupt\n"
- sFile += " pop {r5, pc}\n\n"
- return sFile
- #———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
- def generateBreakpointSection (sectionName, idx):
- sFile = asSeparator () + "\n"
- sFile += " .section .text." + section + ", \"ax\", %progbits\n"
- sFile += " .global " + section +"\n"
- sFile += " .align 1\n"
- sFile += " .type " + section +", %function\n\n"
- sFile += section +":\n"
- sFile += " .fnstart\n"
- sFile += " mrs r12, IPSR @ r12 <- 0x??????00 in thread mode, 0x??????nn, nn ≠ 0 in handler mode\n"
- sFile += " ands r12, #255\n"
- sFile += " bne section." + section + " @ in handler mode, call implementation routine directly\n"
- sFile += " bkpt #" + str (idx) + "\n"
- sFile += " bx lr\n\n"
- sFile += ".Lfunc_end_" + section +":\n"
- sFile += " .size " + section +", .Lfunc_end_" + section +" - " + section +"\n"
- sFile += " .cantunwind\n"
- sFile += " .fnend\n\n"
- return sFile
- #———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
- def generateSoftwareInterruptandler () :
- sFile = asSeparator ()
- sFile += "@\n"
- sFile += "@ SECTIONS: Software Interrupt Handler (two stack mode)\n"
- sFile += "@\n"
- sFile += asSeparator ()
- sFile += "@\n"
- sFile += "@ | |\n"
- sFile += "@ PSP+32 -> |----------------------------| \\\n"
- sFile += "@ | xPSR | |\n"
- sFile += "@ PSP+28 -> |----------------------------| |\n"
- sFile += "@ | PC | |\n"
- sFile += "@ PSP+24 -> |----------------------------| |\n"
- sFile += "@ | LR | |\n"
- sFile += "@ PSP+20 -> |----------------------------| |\n"
- sFile += "@ | R12 | | Saved by interrupt response\n"
- sFile += "@ PSP+16 -> |----------------------------| |\n"
- sFile += "@ | R3 | |\n"
- sFile += "@ PSP+12 -> |----------------------------| |\n"
- sFile += "@ | R2 | |\n"
- sFile += "@ PSP+8 -> |----------------------------| |\n"
- sFile += "@ | R1 | |\n"
- sFile += "@ PSP+4 -> |----------------------------| |\n"
- sFile += "@ | R0 | |\n"
- sFile += "@ PSP -> |----------------------------| /\n"
- sFile += "@\n"
- sFile += asSeparator () + "\n"
- sFile += " .section .text.interrupt.SWINT, \"ax\", %progbits\n\n"
- sFile += " .global interrupt.SWINT\n"
- sFile += " .type interrupt.SWINT, %function\n\n"
- sFile += "interrupt.SWINT:\n"
- sFile += "@--------------------- Save preserved registers\n"
- sFile += " push {r5, lr}\n"
- sFile += "@--------------------- R5 <- thread SP\n"
- sFile += " mrs r5, psp\n"
- sFile += "@--------------------- Restore R0, R1, R2 and R3 from saved stack\n"
- sFile += " ldmia r5, {r0, r1, r2, r3}\n"
- sFile += "@--------------------- R12 <- Address section routine\n"
- sFile += " ldr r12, [r5, #16] @ 16 : 4 stacked registers before saved R12\n"
- sFile += "@--------------------- Call section routine\n"
- sFile += " blx r12\n"
- sFile += "@--------------------- Set return code (from R0 to R3) in stacked registers\n"
- sFile += " stmia r5!, {r0, r1, r2, r3} @ R5 is thread SP\n"
- sFile += "@--------------------- Set R12 stacked register to 0\n"
- sFile += " mov r0, #0\n"
- sFile += " str r0, [r5]\n"
- sFile += "@--------------------- Restore preserved registers, return from interrupt\n"
- sFile += " pop {r5, pc}\n\n"
- sFile += asSeparator () + "\n"
- sFile += " .section .text.direct.call.or.call.software.interrupt, \"ax\", %progbits\n\n"
- sFile += " .type direct.call.or.call.software.interrupt, %function\n\n"
- sFile += "direct.call.or.call.software.interrupt: @ R12 contains the address of section implementation function\n"
- sFile += "@--------------------- Save preserved registers\n"
- sFile += " push {r6, r7}\n"
- sFile += " mrs r6, IPSR @ IPSR[8...0] ≠ 0 in handler mode, = 0 in thread mode\n"
- sFile += " mov r7, #511\n"
- sFile += " tst r6, r7\n"
- sFile += " bne direct.call\n"
- sFile += "@--------------------- Software interrupt\n"
- sFile += " ldr r6, = 0xE000EF00 @ Address of STIR control register\n"
- sFile += " movs r7, # (80 - 16) @ Software Interrupt has number #80\n"
- sFile += " str r7, [r6] @ Generate Software Interrupt\n"
- sFile += "@--------------------- Wait for the exception is carried out\n"
- sFile += "wait.software.interrupt.done: @ R12 is reset by interrupt handler\n"
- sFile += " cmp r12, #0\n"
- sFile += " bne wait.software.interrupt.done\n"
- sFile += "@--------------------- Restore preserved registers\n"
- sFile += " pop {r6, r7}\n"
- sFile += " bx lr\n"
- sFile += "@--------------------- Direct call\n"
- sFile += "direct.call:\n"
- sFile += " pop {r6, r7}\n"
- sFile += " bx r12 @ in handler mode, call implementation routine directly\n\n"
- return sFile
- #———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
- def generateSoftwareInterruptSection (sectionName, idx):
- sFile = asSeparator () + "\n"
- sFile += " .section .text." + sectionName + ", \"ax\", %progbits\n"
- sFile += " .global " + sectionName +"\n"
- sFile += " .align 1\n"
- sFile += " .type " + sectionName +", %function\n\n"
- sFile += sectionName +":\n"
- sFile += " .fnstart\n"
- sFile += " ldr r12, =section." + sectionName + "\n"
- sFile += " b direct.call.or.call.software.interrupt\n\n"
- sFile += ".Lfunc_end_" + sectionName +":\n"
- sFile += " .size " + sectionName +", .Lfunc_end_" + sectionName +" - " + sectionName +"\n"
- sFile += " .cantunwind\n"
- sFile += " .fnend\n\n"
- return sFile
- #———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
- def generateCppForBreakpointSection ():
- s = "#include \"all-headers.h\"\n\n"
- s += cppSeparator () + "\n"
- s += "static void enableDebugMonitorInterruption (BOOT_MODE) {\n"
- s += "//--- Enable DebugMonitor interrupt\n"
- s += " #define DEMCR (* ((volatile uint32_t *) 0xE000EDFC))\n"
- s += " DEMCR |= (1 << 16) ; // Set MON_EN\n"
- s += "}\n\n"
- s += cppSeparator () + "\n"
- s += "MACRO_BOOT_ROUTINE (enableDebugMonitorInterruption) ;\n\n"
- s += cppSeparator ()
- return s
- #———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
- def generateCppForSoftwareInterruptSection ():
- s = "#include \"all-headers.h\"\n\n"
- s += cppSeparator () + "\n"
- s += "static void enableSoftwareInterrupt (BOOT_MODE) {\n"
- s += "//--- Enable software interrupt\n"
- s += " NVIC_ENABLE_IRQ (ISRSlot::SWINT) ;\n"
- s += "//--- Make STIR register accessible in unprivileged mode\n"
- s += " #define CCR (* ((volatile uint32_t *) 0xE000ED14))\n"
- s += " CCR |= (1 << 1) ;\n"
- s += "}\n\n"
- s += cppSeparator () + "\n"
- s += "MACRO_BOOT_ROUTINE (enableSoftwareInterrupt) ;\n\n"
- s += cppSeparator ()
- return s
- #———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
- def generateDisableInterruptSection (sectionName):
- sFile = asSeparator ()
- sFile += "@ SECTION - " + sectionName + "\n"
- sFile += asSeparator () + "\n"
- sFile += " .section .text." + sectionName + ", \"ax\", %progbits\n"
- sFile += " .global " + sectionName +"\n"
- sFile += " .align 1\n"
- sFile += " .type " + sectionName +", %function\n\n"
- sFile += sectionName +":\n"
- sFile += " .fnstart\n"
- sFile += "@--- Save preserved registers\n"
- sFile += " push {r6, lr}\n"
- sFile += "@--- Save interrupt enabled state\n"
- sFile += " mrs r6, PRIMASK\n"
- sFile += "@--- Disable interrupt\n"
- sFile += " cpsid i\n"
- sFile += "@--- Call section, interrupts disabled\n"
- sFile += " bl section." + sectionName + "\n"
- sFile += "@--- Restore interrupt state\n"
- sFile += " msr PRIMASK, r6\n"
- sFile += "@--- Restore preserved registers and return\n"
- sFile += " pop {r6, pc}\n\n"
- sFile += ".Lfunc_end_" + sectionName +":\n"
- sFile += " .size " + sectionName +", .Lfunc_end_" + sectionName +" - " + sectionName +"\n"
- sFile += " .cantunwind\n"
- sFile += " .fnend\n\n"
- return sFile
- #———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
- # ENTRY POINT
- #———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
- #------------------------------ Interrupt dictionary
- interruptDictionary = interrupt_names_teensy_3_6.interruptNames ()
- # print "Dest " + destinationFile
- #------------------------------ Assembly destination file
- destinationCppFile = sys.argv [1]
- # print "Dest " + destinationAssemblerFile
- #------------------------------ Assembly destination file
- destinationAssemblerFile = sys.argv [2]
- # print "Dest " + destinationAssemblerFile
- #------------------------------ Service scheme
- serviceScheme = sys.argv [3]
- #------------------------------ Section scheme
- sectionScheme = sys.argv [4]
- #------------------------------ Header files
- headerFiles = []
- for i in range (5, len (sys.argv)):
- headerFiles.append (sys.argv [i])
- #print headerFiles
- #------------------------------ Destination file string
- cppFile = ""
- sFile = " .syntax unified\n"
- sFile += " .cpu cortex-m4\n"
- sFile += " .thumb\n\n"
- #------------------------------ Explore header files
- interruptServiceList = []
- interruptSectionList = []
- boolServiceSet = set ()
- serviceList = []
- sectionList = []
- for header in headerFiles:
- with open (header) as f:
- for line in f:
- splitStr = line.strip ().split ("//$interrupt-section ")
- if len (splitStr) == 2 :
- interruptName = splitStr [1].strip ()
- if interruptName in interruptDictionary :
- interruptSectionList.append (interruptName)
- del interruptDictionary [interruptName]
- else:
- print (BOLD_RED () + "Error, interrupt '" + interruptName + "' does not exist, or is already assigned." + ENDC ())
- sys.exit (1)
- splitStr = line.strip ().split ("//$interrupt-service ")
- if len (splitStr) == 2 :
- interruptName = splitStr [1].strip ()
- if interruptName in interruptDictionary :
- interruptServiceList.append (interruptName)
- del interruptDictionary [interruptName]
- else:
- print (BOLD_RED () + "Error, interrupt '" + interruptName + "' does not exist, or is already assigned." + ENDC ())
- sys.exit (1)
- splitStr = line.strip ().split ("//$service ")
- if len (splitStr) == 2 :
- serviceName = splitStr [1].strip ()
- serviceList.append (serviceName)
- splitStr = line.strip ().split ("//$bool-service ")
- if len (splitStr) == 2 :
- serviceName = splitStr [1].strip ()
- serviceList.append (serviceName)
- boolServiceSet.add (serviceName)
- splitStr = line.strip ().split ("//$section ")
- if len (splitStr) == 2 :
- sectionName = splitStr [1].strip ()
- sectionList.append (sectionName)
- #------------------------------ Has service ?
- if (len (serviceList) > 0) and (serviceScheme == "") :
- print (BOLD_RED ()
- + "As the project defines service(s), the makefile.json file should have a \"SERVICE-SCHEME\" "
- + "entry (asoociated value: \"svc\")"
- + ENDC ())
- sys.exit (1)
- #------------------------------ Has sections ?
- if (len (sectionList) > 0) and (sectionScheme == "") :
- print (BOLD_RED ()
- + "As the project defines section(s), the makefile.json file should have a \"SECTION-SCHEME\" "
- + "entry (possible associated value: \"disableInterrupt\", \"bkpt\", \"swint\")"
- + ENDC ())
- sys.exit (1)
- #------------------------------ Services
- if serviceScheme == "svc" :
- sFile += generateSVChandler ()
- del interruptDictionary ["SVC"]
- sFile += asSeparator ()
- sFile += "@ SERVICES\n"
- idx = 1
- for service in serviceList :
- sFile += asSeparator () + "\n"
- sFile += " .section .text." + service + ", \"ax\", %progbits\n"
- sFile += " .global " + service +"\n"
- sFile += " .align 1\n"
- sFile += " .type " + service +", %function\n\n"
- sFile += service +":\n"
- sFile += " .fnstart\n"
- sFile += " svc #" + str (idx) + "\n"
- if service in boolServiceSet :
- sFile += " b get.user.result\n\n"
- else:
- sFile += " bx lr\n\n"
- sFile += ".Lfunc_end_" + service +":\n"
- sFile += " .size " + service +", .Lfunc_end_" + service +" - " + service +"\n"
- sFile += " .cantunwind\n"
- sFile += " .fnend\n\n"
- idx += 1
- sFile += asSeparator ()
- sFile += "@ SERVICE DISPATCHER TABLE\n"
- sFile += asSeparator () + "\n"
- sFile += " .align 2\n"
- sFile += " .global svc.dispatcher.table\n\n"
- sFile += "svc.dispatcher.table:\n"
- sFile += " .word start.phase2 @ 0\n"
- idx = 1
- for service in serviceList :
- sFile += " .word service." + service + " @ " + str (idx) + "\n"
- idx += 1
- sFile += "\n"
- #------------------------------ Generate section handler
- if sectionScheme == "bkpt" :
- cppFile += generateCppForBreakpointSection ()
- sFile += generateBreakpointHandler ()
- del interruptDictionary ["DebugMonitor"]
- sFile += asSeparator ()
- sFile += "@ SECTIONS\n"
- idx = 0
- for section in sectionList :
- sFile += generateBreakpointSection (section, idx)
- idx += 1
- sFile += asSeparator ()
- sFile += "@ SECTION DISPATCHER TABLE\n"
- sFile += asSeparator () + "\n"
- sFile += " .global section.dispatcher.table\n\n"
- sFile += "section.dispatcher.table:\n"
- idx = 0
- for section in sectionList :
- sFile += " .word section." + section + " @ " + str (idx) + "\n"
- idx += 1
- sFile += "\n"
- elif sectionScheme == "swint" :
- cppFile += generateCppForSoftwareInterruptSection ()
- sFile += generateSoftwareInterruptandler ()
- del interruptDictionary ["SWINT"]
- sFile += asSeparator ()
- sFile += "@ SECTIONS\n"
- idx = 0
- for section in sectionList :
- sFile += generateSoftwareInterruptSection (section, idx)
- idx += 1
- elif sectionScheme == "disableInterrupt" :
- for section in sectionList :
- sFile += generateDisableInterruptSection (section)
- elif len (sectionList) > 0 :
- print (BOLD_RED ()
- + "In the makefile.json file, the \"SECTION-SCHEME\" key has an invalid \"" + sectionScheme + "\" value; "
- + "(possible value: \"disableInterrupt\", \"bkpt\", \"swint\")"
- + ENDC ())
- sys.exit (1)
- #------------------------------ Interrupts as service
- for interruptServiceName in interruptServiceList :
- sFile += asSeparator ()
- sFile += "@ INTERRUPT - SERVICE: " + interruptServiceName + "\n"
- sFile += asSeparator () + "\n"
- sFile += " .section .text.interrupt." + interruptServiceName + ", \"ax\", %progbits\n\n"
- sFile += " .align 1\n"
- sFile += " .global interrupt." + interruptServiceName + "\n"
- sFile += " .type interrupt." + interruptServiceName + ", %function\n\n"
- sFile += "interrupt." + interruptServiceName + ":\n"
- sFile += "@----------------------------------------- Save preserved registers\n"
- sFile += " push {r4, lr}\n"
- sFile += "@----------------------------------------- Activity led On\n"
- sFile += " ldr r0, =0x400FF084 @ Address of GPIOC_PSOR control register\n"
- sFile += " movs r1, # (1 << 5) @ Port D13 is PORTC:5\n"
- sFile += " str r1, [r0] @ turn on\n"
- sFile += "@----------------------------------------- R4 <- running task context\n"
- sFile += " ldr r4, =var.running.task.control.block.ptr\n"
- sFile += " ldr r4, [r4]\n"
- sFile += "@----------------------------------------- Call Interrupt handler\n"
- sFile += " bl interrupt.service." + interruptServiceName + "\n"
- sFile += "@----------------------------------------- Perform the context switch, if needed\n"
- sFile += " b handle.context.switch\n\n"
- #------------------------------ Interrupts as section
- for interruptSectionName in interruptSectionList :
- sFile += asSeparator ()
- sFile += "@ INTERRUPT - SECTION: " + interruptSectionName + "\n"
- sFile += asSeparator () + "\n"
- sFile += " .section .text.interrupt." + interruptSectionName + ", \"ax\", %progbits\n\n"
- sFile += " .align 1\n"
- sFile += " .global interrupt." + interruptSectionName + "\n"
- sFile += " .type interrupt." + interruptSectionName + ", %function\n\n"
- sFile += "interrupt." + interruptSectionName + ":\n"
- sFile += "@----------------------------------------- Activity led On\n"
- sFile += " ldr r0, =0x400FF084 @ Address of GPIOC_PSOR control register\n"
- sFile += " movs r1, # (1 << 5) @ Port D13 is PORTC:5\n"
- sFile += " str r1, [r0] @ turn on\n"
- sFile += "@----------------------------------------- Goto interrupt function\n"
- sFile += " b interrupt.section." + interruptSectionName + "\n\n"
- #------------------------------ Unused interrupts
- for unusedInterruptName in interruptDictionary.keys () :
- sFile += asSeparator ()
- sFile += "@ INTERRUPT - UNUSED: " + unusedInterruptName + "\n"
- sFile += asSeparator () + "\n"
- sFile += " .section .text.interrupt." + unusedInterruptName + ", \"ax\", %progbits\n\n"
- sFile += " .align 1\n"
- sFile += " .type interrupt." + unusedInterruptName + ", %function\n"
- sFile += " .global interrupt." + unusedInterruptName + "\n\n"
- sFile += "interrupt." + unusedInterruptName + ":\n"
- sFile += " movs r0, #" + str (interruptDictionary [unusedInterruptName]) + "\n"
- sFile += " b unused.interrupt\n\n"
- #------------------------------ Write destination file
- sFile += asSeparator ()
- f = open (destinationAssemblerFile, "wt")
- f.write (sFile)
- f.close()
- f = open (destinationCppFile, "wt")
- f.write (cppFile)
- f.close()
- #———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
|