A version of microbit-dal that builds with both gcc and armcc.

Check in the CMakeLists.txt with a custom hook so that the library can build
with both compilers regardless.
This commit is contained in:
Jonathan Protzenko 2015-08-24 10:33:30 -07:00
parent eaccb3cb4d
commit 63b62e533f
3 changed files with 288 additions and 48 deletions

53
source/CMakeLists.txt Executable file
View File

@ -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
)

View File

@ -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
swap_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.
@ Write our core registers into the TCB
@ First, store the general registers
swap_context
; 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

View File

@ -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