diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt new file mode 100755 index 0000000..f909545 --- /dev/null +++ b/source/CMakeLists.txt @@ -0,0 +1,53 @@ +# This file is no longer auto-generated to make the repository builds with GCC +# and ARMCC no matter what. + +cmake_minimum_required(VERSION 2.8.11) + +enable_language(ASM) + +set(YOTTA_AUTO_MICROBIT-DAL_CPP_FILES + "MicroBitSuperMain.cpp" + "MicroBitI2C.cpp" + "MicroBitMultiButton.cpp" + "MicroBitFont.cpp" + "MicroBit.cpp" + "MicroBitButton.cpp" + "MicroBitMessageBus.cpp" + "MicroBitCompass.cpp" + "MicroBitEventService.cpp" + "MicroBitEvent.cpp" + "MicroBitFiber.cpp" + "ManagedString.cpp" + "MicroBitAccelerometer.cpp" + "MicroBitDFUService.cpp" + "MicroBitIO.cpp" + "MicroBitCompat.cpp" + "MicroBitImage.cpp" + "MicroBitDisplay.cpp" + "DynamicPwm.cpp" + "MicroBitPin.cpp" + "MicroBitSerial.cpp" +) + +if(CMAKE_COMPILER_IS_GNUCC) + set(YOTTA_AUTO_MICROBIT-DAL_S_FILES + "CortexContextSwitch.s.gcc" + ) +else() + set(YOTTA_AUTO_MICROBIT-DAL_S_FILES + "CortexContextSwitch.s" + ) +endif() + +add_library(microbit-dal + ${YOTTA_AUTO_MICROBIT-DAL_CPP_FILES} + ${YOTTA_AUTO_MICROBIT-DAL_S_FILES} +) + +yotta_postprocess_target(LIBRARY microbit-dal) + +target_link_libraries(microbit-dal + mbed-classic + ble + ble-nrf51822 +) diff --git a/source/CortexContextSwitch.s b/source/CortexContextSwitch.s index 3e96f8c..090c95e 100644 --- a/source/CortexContextSwitch.s +++ b/source/CortexContextSwitch.s @@ -1,22 +1,20 @@ - .syntax unified - .cpu cortex-m0 - .thumb - .text - .align 2 + AREA asm_func, CODE, READONLY -@ Export our context switching subroutine as a C function for use in mBed - .global swap_context - .global save_context +; Export our context switching subroutine as a C function for use in mBed + EXPORT swap_context + EXPORT save_context -@ R0 Contains a pointer to the TCB of the fibre being scheduled out. -@ R1 Contains a pointer to the TCB of the fibre being scheduled in. -@ R2 Contains a pointer to the base of the stack of the fibre being scheduled out. -@ R3 Contains a pointer to the base of the stack of the fibre being scheduled in. + ALIGN + +; R0 Contains a pointer to the TCB of the fibre being scheduled out. +; R1 Contains a pointer to the TCB of the fibre being scheduled in. +; R2 Contains a pointer to the base of the stack of the fibre being scheduled out. +; R3 Contains a pointer to the base of the stack of the fibre being scheduled in. -swap_context: +swap_context - @ Write our core registers into the TCB - @ First, store the general registers + ; Write our core registers into the TCB + ; First, store the general registers STR R0, [R0,#0] STR R1, [R0,#4] @@ -27,7 +25,7 @@ swap_context: STR R6, [R0,#24] STR R7, [R0,#28] - @ Now the high general purpose registers + ; Now the high general purpose registers MOV R4, R8 STR R4, [R0,#32] MOV R4, R9 @@ -39,25 +37,25 @@ swap_context: MOV R4, R12 STR R4, [R0,#48] - @ Now the Stack and Link Register. - @ As this context is only intended for use with a fiber scheduler, - @ we don't need the PC. + ; Now the Stack and Link Register. + ; As this context is only intended for use with a fiber scheduler, + ; we don't need the PC. MOV R6, SP STR R6, [R0,#52] MOV R4, LR STR R4, [R0,#56] - @ Finally, Copy the stack. We do this to reduce RAM footprint, as stackis usually very small at the point - @ of sceduling, but we need a lot of capacity for interrupt handling and other functions. + ; Finally, Copy the stack. We do this to reduce RAM footprint, as stackis usually very small at the point + ; of sceduling, but we need a lot of capacity for interrupt handling and other functions. - MOVS R7, #0x20 @ Load R8 with top of System Stack space. + MOVS R7, #0x20 ; Load R8 with top of System Stack space. LSLS R7, #24 MOVS R4, #0x40 LSLS R4, #8 ORRS R7, R4 MOV R4, R7 -store_stack: +store_stack SUBS R4, #4 SUBS R2, #4 @@ -67,22 +65,22 @@ store_stack: CMP R4, R6 BNE store_stack - @ - @ Now page in the new context. - @ Update all registers except the PC. We can also safely ignore the STATUS register, as we're just a fiber scheduler. - @ + ; + ; Now page in the new context. + ; Update all registers except the PC. We can also safely ignore the STATUS register, as we're just a fiber scheduler. + ; LDR R4, [R1, #56] MOV LR, R4 LDR R6, [R1, #52] MOV SP, R6 - @ Copy the stack in. - @ n.b. we do this after setting the SP to make comparisons easier. + ; Copy the stack in. + ; n.b. we do this after setting the SP to make comparisons easier. - MOV R4, R7 @ Load R4 with top of System Stack space. + MOV R4, R7 ; Load R4 with top of System Stack space. -restore_stack: +restore_stack SUBS R4, #4 SUBS R3, #4 @@ -112,19 +110,19 @@ restore_stack: LDR R0, [R1, #0] LDR R1, [R1, #4] - @ Return to caller (scheduler). + ; Return to caller (scheduler). BX LR -@ R0 Contains a pointer to the TCB of the fibre to snapshot -@ R1 Contains a pointer to the base of the stack of the fibre being snapshotted +; R0 Contains a pointer to the TCB of the fibre to snapshot +; R1 Contains a pointer to the base of the stack of the fibre being snapshotted -save_context: +save_context - @ Write our core registers into the TCB - @ First, store the general registers + ; Write our core registers into the TCB + ; First, store the general registers STR R0, [R0,#0] STR R1, [R0,#4] @@ -135,7 +133,7 @@ save_context: STR R6, [R0,#24] STR R7, [R0,#28] - @ Now the high general purpose registers + ; Now the high general purpose registers MOV R4, R8 STR R4, [R0,#32] MOV R4, R9 @@ -147,25 +145,25 @@ save_context: MOV R4, R12 STR R4, [R0,#48] - @ Now the Stack and Link Register. - @ As this context is only intended for use with a fiber scheduler, - @ we don't need the PC. + ; Now the Stack and Link Register. + ; As this context is only intended for use with a fiber scheduler, + ; we don't need the PC. MOV R6, SP STR R6, [R0,#52] MOV R4, LR STR R4, [R0,#56] - @ Finally, Copy the stack. We do this to reduce RAM footprint, as stackis usually very small at the point - @ of sceduling, but we need a lot of capacity for interrupt handling and other functions. + ; Finally, Copy the stack. We do this to reduce RAM footprint, as stackis usually very small at the point + ; of sceduling, but we need a lot of capacity for interrupt handling and other functions. - MOVS R5, #0x20 @ Load R8 with top of System Stack space. + MOVS R5, #0x20 ; Load R8 with top of System Stack space. LSLS R5, #24 MOVS R4, #0x40 LSLS R4, #8 ORRS R5, R4 MOV R4, R5 -store_stack1: +store_stack1 SUBS R4, #4 SUBS R1, #4 @@ -175,13 +173,15 @@ store_stack1: CMP R4, R6 BNE store_stack1 - @ Restore scratch registers. + ; Restore scratch registers. LDR R7, [R0, #28] LDR R6, [R0, #24] LDR R5, [R0, #20] LDR R4, [R0, #16] - @ Return to caller (scheduler). + ; Return to caller (scheduler). BX LR - + + ALIGN + END \ No newline at end of file diff --git a/source/CortexContextSwitch.s.gcc b/source/CortexContextSwitch.s.gcc new file mode 100644 index 0000000..3e96f8c --- /dev/null +++ b/source/CortexContextSwitch.s.gcc @@ -0,0 +1,187 @@ + .syntax unified + .cpu cortex-m0 + .thumb + .text + .align 2 + +@ Export our context switching subroutine as a C function for use in mBed + .global swap_context + .global save_context + +@ R0 Contains a pointer to the TCB of the fibre being scheduled out. +@ R1 Contains a pointer to the TCB of the fibre being scheduled in. +@ R2 Contains a pointer to the base of the stack of the fibre being scheduled out. +@ R3 Contains a pointer to the base of the stack of the fibre being scheduled in. + +swap_context: + + @ Write our core registers into the TCB + @ First, store the general registers + + STR R0, [R0,#0] + STR R1, [R0,#4] + STR R2, [R0,#8] + STR R3, [R0,#12] + STR R4, [R0,#16] + STR R5, [R0,#20] + STR R6, [R0,#24] + STR R7, [R0,#28] + + @ Now the high general purpose registers + MOV R4, R8 + STR R4, [R0,#32] + MOV R4, R9 + STR R4, [R0,#36] + MOV R4, R10 + STR R4, [R0,#40] + MOV R4, R11 + STR R4, [R0,#44] + MOV R4, R12 + STR R4, [R0,#48] + + @ Now the Stack and Link Register. + @ As this context is only intended for use with a fiber scheduler, + @ we don't need the PC. + MOV R6, SP + STR R6, [R0,#52] + MOV R4, LR + STR R4, [R0,#56] + + @ Finally, Copy the stack. We do this to reduce RAM footprint, as stackis usually very small at the point + @ of sceduling, but we need a lot of capacity for interrupt handling and other functions. + + MOVS R7, #0x20 @ Load R8 with top of System Stack space. + LSLS R7, #24 + MOVS R4, #0x40 + LSLS R4, #8 + ORRS R7, R4 + MOV R4, R7 + +store_stack: + SUBS R4, #4 + SUBS R2, #4 + + LDR R5, [R4] + STR R5, [R2] + + CMP R4, R6 + BNE store_stack + + @ + @ Now page in the new context. + @ Update all registers except the PC. We can also safely ignore the STATUS register, as we're just a fiber scheduler. + @ + LDR R4, [R1, #56] + MOV LR, R4 + LDR R6, [R1, #52] + MOV SP, R6 + + @ Copy the stack in. + @ n.b. we do this after setting the SP to make comparisons easier. + + MOV R4, R7 @ Load R4 with top of System Stack space. + + +restore_stack: + SUBS R4, #4 + SUBS R3, #4 + + LDR R5, [R3] + STR R5, [R4] + + CMP R4, R6 + BNE restore_stack + + LDR R4, [R1, #48] + MOV R12, R4 + LDR R4, [R1, #44] + MOV R11, R4 + LDR R4, [R1, #40] + MOV R10, R4 + LDR R4, [R1, #36] + MOV R9, R4 + LDR R4, [R1, #32] + MOV R8, R4 + + LDR R7, [R1, #28] + LDR R6, [R1, #24] + LDR R5, [R1, #20] + LDR R4, [R1, #16] + LDR R3, [R1, #12] + LDR R2, [R1, #8] + LDR R0, [R1, #0] + LDR R1, [R1, #4] + + @ Return to caller (scheduler). + BX LR + + + + +@ R0 Contains a pointer to the TCB of the fibre to snapshot +@ R1 Contains a pointer to the base of the stack of the fibre being snapshotted + +save_context: + + @ Write our core registers into the TCB + @ First, store the general registers + + STR R0, [R0,#0] + STR R1, [R0,#4] + STR R2, [R0,#8] + STR R3, [R0,#12] + STR R4, [R0,#16] + STR R5, [R0,#20] + STR R6, [R0,#24] + STR R7, [R0,#28] + + @ Now the high general purpose registers + MOV R4, R8 + STR R4, [R0,#32] + MOV R4, R9 + STR R4, [R0,#36] + MOV R4, R10 + STR R4, [R0,#40] + MOV R4, R11 + STR R4, [R0,#44] + MOV R4, R12 + STR R4, [R0,#48] + + @ Now the Stack and Link Register. + @ As this context is only intended for use with a fiber scheduler, + @ we don't need the PC. + MOV R6, SP + STR R6, [R0,#52] + MOV R4, LR + STR R4, [R0,#56] + + @ Finally, Copy the stack. We do this to reduce RAM footprint, as stackis usually very small at the point + @ of sceduling, but we need a lot of capacity for interrupt handling and other functions. + + MOVS R5, #0x20 @ Load R8 with top of System Stack space. + LSLS R5, #24 + MOVS R4, #0x40 + LSLS R4, #8 + ORRS R5, R4 + MOV R4, R5 + +store_stack1: + SUBS R4, #4 + SUBS R1, #4 + + LDR R5, [R4] + STR R5, [R1] + + CMP R4, R6 + BNE store_stack1 + + @ Restore scratch registers. + + LDR R7, [R0, #28] + LDR R6, [R0, #24] + LDR R5, [R0, #20] + LDR R4, [R0, #16] + + @ Return to caller (scheduler). + BX LR +