From c49d769e462f03ed82cecab77f0e44856cbd397a Mon Sep 17 00:00:00 2001 From: George Wort Date: Mon, 10 Jun 2019 12:51:40 +0100 Subject: [PATCH 1/3] Allow armcc and armclang to compile. --- inc/bluetooth/MicroBitBLEManager.h | 6 +- .../MicroBitPartialFlashingService.h | 8 +- inc/core/MicroBitHeapAllocator.h | 24 ++ inc/core/MicroBitUtil.h | 2 +- inc/drivers/MicroBitMemoryMap.h | 2 +- inc/drivers/MicroBitQuadratureDecoder.h | 12 +- .../TOOLCHAIN_ARM_STD/CortexContextSwitch.s | 293 ++++++++++++++++++ .../TOOLCHAIN_GCC_ARM/CortexContextSwitch.s | 292 +++++++++++++++++ source/bluetooth/MicroBitBLEManager.cpp | 6 +- .../MicroBitPartialFlashingService.cpp | 5 + source/bluetooth/MicroBitUARTService.cpp | 21 +- source/core/MicroBitHeapAllocator.cpp | 18 +- source/drivers/MicroBitAccelerometer.cpp | 2 +- source/drivers/MicroBitCompassCalibrator.cpp | 12 +- source/drivers/MicroBitFile.cpp | 8 +- source/drivers/MicroBitMemoryMap.cpp | 1 + source/drivers/MicroBitQuadratureDecoder.cpp | 9 +- source/drivers/MicroBitSerial.cpp | 16 +- source/types/MicroBitImage.cpp | 16 +- 19 files changed, 706 insertions(+), 47 deletions(-) create mode 100644 source/asm/TOOLCHAIN_ARM_STD/CortexContextSwitch.s create mode 100644 source/asm/TOOLCHAIN_GCC_ARM/CortexContextSwitch.s diff --git a/inc/bluetooth/MicroBitBLEManager.h b/inc/bluetooth/MicroBitBLEManager.h index 5645d548..0cb12c22 100644 --- a/inc/bluetooth/MicroBitBLEManager.h +++ b/inc/bluetooth/MicroBitBLEManager.h @@ -221,7 +221,7 @@ class MicroBitBLEManager : MicroBitComponent void stopAdvertising(); /** - * A member function used to defer writes to flash, in order to prevent a write collision with + * A member function used to defer writes to flash, in order to prevent a write collision with * softdevice. * @param handle The handle offered by soft device during pairing. * */ @@ -312,7 +312,7 @@ class MicroBitBLEManager : MicroBitComponent void showManagementModeAnimation(MicroBitDisplay &display); #define MICROBIT_BLE_DISCONNECT_AFTER_PAIRING_DELAY 500 - unsigned long pairing_completed_at_time; + unsigned long pairing_completed_at_time; int pairingStatus; ManagedString passKey; @@ -322,7 +322,7 @@ class MicroBitBLEManager : MicroBitComponent * Default to Application Mode * This variable will be set to MICROBIT_MODE_PAIRING if pairingMode() is executed. */ - uint8_t currentMode = MICROBIT_MODE_APPLICATION; + uint8_t currentMode; }; diff --git a/inc/bluetooth/MicroBitPartialFlashingService.h b/inc/bluetooth/MicroBitPartialFlashingService.h index 64a1d5bb..a0e5f4c7 100644 --- a/inc/bluetooth/MicroBitPartialFlashingService.h +++ b/inc/bluetooth/MicroBitPartialFlashingService.h @@ -97,13 +97,13 @@ class MicroBitPartialFlashingService void flashData(uint8_t *data); // Ensure packets are in order - uint8_t packetCount = 0; - uint8_t blockPacketCount = 0; + uint8_t packetCount; + uint8_t blockPacketCount; // Keep track of blocks of data uint32_t block[16]; - uint8_t blockNum = 0; - uint32_t offset = 0; + uint8_t blockNum; + uint32_t offset; }; diff --git a/inc/core/MicroBitHeapAllocator.h b/inc/core/MicroBitHeapAllocator.h index 10aa5c94..115a2511 100644 --- a/inc/core/MicroBitHeapAllocator.h +++ b/inc/core/MicroBitHeapAllocator.h @@ -52,6 +52,7 @@ DEALINGS IN THE SOFTWARE. #define MICROBIT_HEAP_ALLOCTOR_H #include "MicroBitConfig.h" +#include // The maximum number of heap segments that can be created. #define MICROBIT_MAXIMUM_HEAPS 2 @@ -85,4 +86,27 @@ struct HeapDefinition int microbit_create_heap(uint32_t start, uint32_t end); void microbit_heap_print(); +/** + * Attempt to allocate a given amount of memory from any of our configured heap areas. + * + * @param size The amount of memory, in bytes, to allocate. + * + * @return A pointer to the allocated memory, or NULL if insufficient memory is available. + */ +void *_microbit_malloc(size_t size); +void* _microbit_calloc (size_t num, size_t size); +void* _microbit_realloc (void* ptr, size_t size); + +/** + * Release a given area of memory from the heap. + * + * @param mem The memory area to release. + */ +void _microbit_free(void *mem); + +#define malloc _microbit_malloc +#define free _microbit_free +#define calloc _microbit_calloc +#define realloc _microbit_realloc + #endif diff --git a/inc/core/MicroBitUtil.h b/inc/core/MicroBitUtil.h index d9fc5f74..087cf8d4 100644 --- a/inc/core/MicroBitUtil.h +++ b/inc/core/MicroBitUtil.h @@ -32,7 +32,7 @@ DEALINGS IN THE SOFTWARE. #include "MicroBitConfig.h" -#define CREATE_KEY_VALUE_TABLE(NAME, PAIRS) const KeyValueTable NAME { PAIRS, sizeof(PAIRS) / sizeof(KeyValueTableEntry) }; +#define CREATE_KEY_VALUE_TABLE(NAME, PAIRS) const KeyValueTable NAME = { PAIRS, sizeof(PAIRS) / sizeof(KeyValueTableEntry) }; /** * Provides a simple key/value pair lookup table with range lookup support. diff --git a/inc/drivers/MicroBitMemoryMap.h b/inc/drivers/MicroBitMemoryMap.h index 6494c85c..b2b6803c 100644 --- a/inc/drivers/MicroBitMemoryMap.h +++ b/inc/drivers/MicroBitMemoryMap.h @@ -70,7 +70,7 @@ class MicroBitMemoryMap Region memoryMap[NUMBER_OF_REGIONS]; }; - uint8_t regionCount = 0; + uint8_t regionCount; public: diff --git a/inc/drivers/MicroBitQuadratureDecoder.h b/inc/drivers/MicroBitQuadratureDecoder.h index 6416095b..6af28c0f 100644 --- a/inc/drivers/MicroBitQuadratureDecoder.h +++ b/inc/drivers/MicroBitQuadratureDecoder.h @@ -42,13 +42,13 @@ DEALINGS IN THE SOFTWARE. class MicroBitQuadratureDecoder : public MicroBitComponent { protected: - int64_t position = 0; // Absolute position + int64_t position; // Absolute position MicroBitPin& phaseA, // Phase A input for decoding phaseB; // Phase B input for decoding MicroBitPin* LED; // LED output to assert while decoding - uint32_t samplePeriod = 128; // Minimum sampling period allowed - uint16_t faults = 0; // Double-transition counter - uint8_t LEDDelay = 0; // power-up time for LED, in microseconds + uint32_t samplePeriod; // Minimum sampling period allowed + uint16_t faults; // Double-transition counter + uint8_t LEDDelay; // power-up time for LED, in microseconds uint8_t flags; public: @@ -172,9 +172,9 @@ class MicroBitQuadratureDecoder : public MicroBitComponent * * Ensures that stop() gets called if necessary. */ - virtual ~MicroBitQuadratureDecoder() override; + virtual ~MicroBitQuadratureDecoder(); - virtual void systemTick() override; + virtual void systemTick(); }; #endif diff --git a/source/asm/TOOLCHAIN_ARM_STD/CortexContextSwitch.s b/source/asm/TOOLCHAIN_ARM_STD/CortexContextSwitch.s new file mode 100644 index 00000000..bd7deecc --- /dev/null +++ b/source/asm/TOOLCHAIN_ARM_STD/CortexContextSwitch.s @@ -0,0 +1,293 @@ +; The MIT License (MIT) + +; Copyright (c) 2016 British Broadcasting Corporation. +; This software is provided by Lancaster University by arrangement with the BBC. + +; Permission is hereby granted, free of charge, to any person obtaining a +; copy of this software and associated documentation files (the "Software"), +; to deal in the Software without restriction, including without limitation +; the rights to use, copy, modify, merge, publish, distribute, sublicense, +; and/or sell copies of the Software, and to permit persons to whom the +; Software is furnished to do so, subject to the following conditions: + +; The above copyright notice and this permission notice shall be included in +; all copies or substantial portions of the Software. + +; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +; THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +; DEALINGS IN THE SOFTWARE. + + AREA asm_func, CODE, READONLY + +; Export our context switching subroutine as a C function for use in mbed + EXPORT swap_context + EXPORT save_context + EXPORT save_register_context + EXPORT restore_register_context + + 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 + + ; Write our core registers into the TCB + ; First, store the general registers + + ; Skip this is we're given a NULL parameter for the TCB + CMP R0, #0 + BEQ store_context_complete + + 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] + +store_context_complete + ; Finally, Copy the stack. We do this to reduce RAM footprint, as stack is usually very small at the point + ; of scheduling, but we need a lot of capacity for interrupt handling and other functions. + + ; Skip this is we're given a NULL parameter for the stack. + CMP R2, #0 + BEQ store_stack_complete + + LDR R4, [R0,#60] ; Load R4 with the fiber's defined stack_base. +store_stack + SUBS R4, #4 + SUBS R2, #4 + + LDR R5, [R4] + STR R5, [R2] + + CMP R4, R6 + BNE store_stack + +store_stack_complete + + ; + ; 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. + + ; Skip this is we're given a NULL parameter for the stack. + CMP R3, #0 + BEQ restore_stack_complete + + LDR R4, [R1,#60] ; Load R4 with the fiber's defined stack_base. + +restore_stack + SUBS R4, #4 + SUBS R3, #4 + + LDR R5, [R3] + STR R5, [R4] + + CMP R4, R6 + BNE restore_stack + +restore_stack_complete + 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. + + LDR R4, [R0,#60] ; Load R4 with the fiber's defined stack_base. + +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 + + +; R0 Contains a pointer to the TCB of the fiber to snapshot +save_register_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 Pointer and Link Register. + ; As this context is only intended for use with a fiber scheduler, + ; we don't need the PC. + MOV R4, SP + STR R4, [R0,#52] + MOV R4, LR + STR R4, [R0,#56] + + ; Restore scratch registers. + LDR R4, [R0, #16] + + ; Return to caller (scheduler). + BX LR + + +restore_register_context + + ; + ; 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, [R0, #56] + MOV LR, R4 + LDR R4, [R0, #52] + MOV SP, R4 + + ; High registers... + LDR R4, [R0, #48] + MOV R12, R4 + LDR R4, [R0, #44] + MOV R11, R4 + LDR R4, [R0, #40] + MOV R10, R4 + LDR R4, [R0, #36] + MOV R9, R4 + LDR R4, [R0, #32] + MOV R8, R4 + + ; Low registers... + LDR R7, [R0, #28] + LDR R6, [R0, #24] + LDR R5, [R0, #20] + LDR R4, [R0, #16] + LDR R3, [R0, #12] + LDR R2, [R0, #8] + LDR R0, [R0, #0] + LDR R1, [R0, #4] + + ; Return to caller (normally the scheduler). + BX LR + + ALIGN + END diff --git a/source/asm/TOOLCHAIN_GCC_ARM/CortexContextSwitch.s b/source/asm/TOOLCHAIN_GCC_ARM/CortexContextSwitch.s new file mode 100644 index 00000000..84247b45 --- /dev/null +++ b/source/asm/TOOLCHAIN_GCC_ARM/CortexContextSwitch.s @@ -0,0 +1,292 @@ +@ The MIT License (MIT) + +@ Copyright (c) 2016 British Broadcasting Corporation. +@ This software is provided by Lancaster University by arrangement with the BBC. + +@ Permission is hereby granted, free of charge, to any person obtaining a +@ copy of this software and associated documentation files (the "Software"), +@ to deal in the Software without restriction, including without limitation +@ the rights to use, copy, modify, merge, publish, distribute, sublicense, +@ and/or sell copies of the Software, and to permit persons to whom the +@ Software is furnished to do so, subject to the following conditions: + +@ The above copyright notice and this permission notice shall be included in +@ all copies or substantial portions of the Software. + +@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +@ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +@ DEALINGS IN THE SOFTWARE. + + .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 + .global save_register_context + .global restore_register_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 + + @ Skip this is we're given a NULL parameter for the TCB + CMP R0, #0 + BEQ store_context_complete + + 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] + +store_context_complete: + @ Finally, Copy the stack. We do this to reduce RAM footprint, as stack is usually very small at the point + @ of scheduling, but we need a lot of capacity for interrupt handling and other functions. + + @ Skip this is we're given a NULL parameter for the stack. + CMP R2, #0 + BEQ store_stack_complete + + LDR R4, [R0,#60] @ Load R4 with the fiber's defined stack_base. +store_stack: + SUBS R4, #4 + SUBS R2, #4 + + LDR R5, [R4] + STR R5, [R2] + + CMP R4, R6 + BNE store_stack + +store_stack_complete: + + @ + @ 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. + + @ Skip this is we're given a NULL parameter for the stack. + CMP R3, #0 + BEQ restore_stack_complete + + LDR R4, [R1,#60] @ Load R4 with the fiber's defined stack_base. + +restore_stack: + SUBS R4, #4 + SUBS R3, #4 + + LDR R5, [R3] + STR R5, [R4] + + CMP R4, R6 + BNE restore_stack + +restore_stack_complete: + 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. + + LDR R4, [R0,#60] @ Load R4 with the fiber's defined stack_base. + +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 + + +@ R0 Contains a pointer to the TCB of the fiber to snapshot +save_register_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 Pointer and Link Register. + @ As this context is only intended for use with a fiber scheduler, + @ we don't need the PC. + MOV R4, SP + STR R4, [R0,#52] + MOV R4, LR + STR R4, [R0,#56] + + @ Restore scratch registers. + LDR R4, [R0, #16] + + @ Return to caller (scheduler). + BX LR + + +restore_register_context: + + @ + @ 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, [R0, #56] + MOV LR, R4 + LDR R4, [R0, #52] + MOV SP, R4 + + @ High registers... + LDR R4, [R0, #48] + MOV R12, R4 + LDR R4, [R0, #44] + MOV R11, R4 + LDR R4, [R0, #40] + MOV R10, R4 + LDR R4, [R0, #36] + MOV R9, R4 + LDR R4, [R0, #32] + MOV R8, R4 + + @ Low registers... + LDR R7, [R0, #28] + LDR R6, [R0, #24] + LDR R5, [R0, #20] + LDR R4, [R0, #16] + LDR R3, [R0, #12] + LDR R2, [R0, #8] + LDR R0, [R0, #0] + LDR R1, [R0, #4] + + @ Return to caller (normally the scheduler). + BX LR diff --git a/source/bluetooth/MicroBitBLEManager.cpp b/source/bluetooth/MicroBitBLEManager.cpp index 07a517f1..e247369c 100644 --- a/source/bluetooth/MicroBitBLEManager.cpp +++ b/source/bluetooth/MicroBitBLEManager.cpp @@ -226,6 +226,7 @@ static void securitySetupCompletedCallback(Gap::Handle_t handle, SecurityManager */ MicroBitBLEManager::MicroBitBLEManager(MicroBitStorage &_storage) : storage(&_storage) { + currentMode = MICROBIT_MODE_APPLICATION; manager = this; this->ble = NULL; this->pairingStatus = 0; @@ -242,6 +243,7 @@ MicroBitBLEManager::MicroBitBLEManager(MicroBitStorage &_storage) : storage(&_st */ MicroBitBLEManager::MicroBitBLEManager() : storage(NULL) { + currentMode = MICROBIT_MODE_APPLICATION; manager = this; this->ble = NULL; this->pairingStatus = 0; @@ -271,7 +273,7 @@ void MicroBitBLEManager::advertise() } /** - * A member function used to defer writes to flash, in order to prevent a write collision with + * A member function used to defer writes to flash, in order to prevent a write collision with * softdevice. * @param handle The handle offered by soft device during pairing. * */ @@ -643,7 +645,7 @@ void MicroBitBLEManager::pairingMode(MicroBitDisplay &display, MicroBitButton &a { // Do not page this fiber! currentFiber->flags |= MICROBIT_FIBER_FLAG_DO_NOT_PAGE; - + ManagedString namePrefix("BBC micro:bit ["); ManagedString namePostfix("]"); ManagedString BLEName = namePrefix + deviceName + namePostfix; diff --git a/source/bluetooth/MicroBitPartialFlashingService.cpp b/source/bluetooth/MicroBitPartialFlashingService.cpp index b0f1c42a..dac1973d 100644 --- a/source/bluetooth/MicroBitPartialFlashingService.cpp +++ b/source/bluetooth/MicroBitPartialFlashingService.cpp @@ -41,6 +41,11 @@ DEALINGS IN THE SOFTWARE. MicroBitPartialFlashingService::MicroBitPartialFlashingService(BLEDevice &_ble, EventModel &_messageBus) : ble(_ble), messageBus(_messageBus) { + packetCount = 0; + blockPacketCount = 0; + blockNum = 0; + offset = 0; + // Set up partial flashing characteristic uint8_t initCharacteristicValue = 0x00; GattCharacteristic partialFlashCharacteristic(MicroBitPartialFlashingServiceCharacteristicUUID, &initCharacteristicValue, sizeof(initCharacteristicValue), diff --git a/source/bluetooth/MicroBitUARTService.cpp b/source/bluetooth/MicroBitUARTService.cpp index c6b984df..b98b3b9d 100644 --- a/source/bluetooth/MicroBitUARTService.cpp +++ b/source/bluetooth/MicroBitUARTService.cpp @@ -279,18 +279,19 @@ int MicroBitUARTService::send(const uint8_t *buf, int length, MicroBitSerialMode int size = txBufferedSize(); - uint8_t temp[size]; + uint8_t *temp = new uint8_t[size]; memclr(&temp, size); circularCopy(txBuffer, txBufferSize, temp, txBufferTail, txBufferHead); - if(mode == SYNC_SLEEP) fiber_wake_on_event(MICROBIT_ID_NOTIFY, MICROBIT_UART_S_EVT_TX_EMPTY); ble.gattServer().write(txCharacteristic->getValueAttribute().getHandle(), temp, size); + delete[] temp; + if(mode == SYNC_SLEEP) schedule(); else @@ -398,7 +399,7 @@ int MicroBitUARTService::read(uint8_t *buf, int len, MicroBitSerialMode mode) */ ManagedString MicroBitUARTService::read(int len, MicroBitSerialMode mode) { - uint8_t buf[len + 1]; + uint8_t *buf = new uint8_t[len + 1]; memclr(&buf, len + 1); @@ -407,7 +408,11 @@ ManagedString MicroBitUARTService::read(int len, MicroBitSerialMode mode) if(ret < 1) return ManagedString(); - return ManagedString((const char *)buf); + ManagedString string((const char *)buf); + + delete[] buf; + + return string; } /** @@ -467,7 +472,7 @@ ManagedString MicroBitUARTService::readUntil(ManagedString delimeters, MicroBitS //calculate our local buffer size int localBuffSize = (preservedTail > foundIndex) ? (rxBufferSize - preservedTail) + foundIndex : foundIndex - preservedTail; - uint8_t localBuff[localBuffSize + 1]; + uint8_t *localBuff = new uint8_t[localBuffSize + 1]; memclr(&localBuff, localBuffSize + 1); @@ -476,7 +481,11 @@ ManagedString MicroBitUARTService::readUntil(ManagedString delimeters, MicroBitS //plus one for the character we listened for... rxBufferTail = (rxBufferTail + localBuffSize + 1) % rxBufferSize; - return ManagedString((char *)localBuff, localBuffSize); + ManagedString string((char *)localBuff, localBuffSize); + + delete[] localBuff; + + return string; } return ManagedString(); diff --git a/source/core/MicroBitHeapAllocator.cpp b/source/core/MicroBitHeapAllocator.cpp index c42b3daa..0fd0c6c1 100644 --- a/source/core/MicroBitHeapAllocator.cpp +++ b/source/core/MicroBitHeapAllocator.cpp @@ -59,7 +59,13 @@ DEALINGS IN THE SOFTWARE. // A list of all active heap regions, and their dimensions in memory. HeapDefinition heap[MICROBIT_MAXIMUM_HEAPS] = { }; uint8_t heap_count = 0; -extern "C" int __end__; +#if defined __CC_ARM || defined __ARMCC_VERSION +#define HEAP_START Image$$RW_IRAM1$$ZI$$Limit +#else +#define HEAP_START __end__ +#endif + +extern "C" int HEAP_START; #if CONFIG_ENABLED(MICROBIT_DBG) && CONFIG_ENABLED(MICROBIT_HEAP_DBG) // Diplays a usage summary about a given heap... @@ -271,7 +277,7 @@ void *microbit_malloc(size_t size, HeapDefinition &heap) * * @return A pointer to the allocated memory, or NULL if insufficient memory is available. */ -void *malloc(size_t size) +void *_microbit_malloc(size_t size) { static uint8_t initialised = 0; void *p; @@ -280,7 +286,7 @@ void *malloc(size_t size) { heap_count = 0; - if(microbit_create_heap((uint32_t)(&__end__), (uint32_t)(MICROBIT_HEAP_END)) == MICROBIT_INVALID_PARAMETER) + if(microbit_create_heap((uint32_t)(&HEAP_START), (uint32_t)(MICROBIT_HEAP_END)) == MICROBIT_INVALID_PARAMETER) microbit_panic(MICROBIT_HEAP_ERROR); initialised = 1; @@ -319,7 +325,7 @@ void *malloc(size_t size) * * @param mem The memory area to release. */ -void free(void *mem) +void _microbit_free(void *mem) { uint32_t *memory = (uint32_t *)mem; uint32_t *cb = memory-1; @@ -351,7 +357,7 @@ void free(void *mem) microbit_panic(MICROBIT_HEAP_ERROR); } -void* calloc (size_t num, size_t size) +void* _microbit_calloc (size_t num, size_t size) { void *mem = malloc(num*size); @@ -361,7 +367,7 @@ void* calloc (size_t num, size_t size) return mem; } -void* realloc (void* ptr, size_t size) +void* _microbit_realloc (void* ptr, size_t size) { void *mem = malloc(size); diff --git a/source/drivers/MicroBitAccelerometer.cpp b/source/drivers/MicroBitAccelerometer.cpp index 7ab926be..b6256fb9 100644 --- a/source/drivers/MicroBitAccelerometer.cpp +++ b/source/drivers/MicroBitAccelerometer.cpp @@ -72,7 +72,7 @@ MicroBitAccelerometer::MicroBitAccelerometer(CoordinateSpace &cspace, uint16_t i * Device autodetection. Scans the given I2C bus for supported accelerometer devices. * if found, constructs an appropriate driver and returns it. * - * @param i2c the bus to scan. + * @param i2c the bus to scan. * @param id the unique EventModel id of this component. Defaults to: MICROBIT_ID_ACCELEROMETER * */ diff --git a/source/drivers/MicroBitCompassCalibrator.cpp b/source/drivers/MicroBitCompassCalibrator.cpp index 09f5f1b5..c4ae6ccc 100644 --- a/source/drivers/MicroBitCompassCalibrator.cpp +++ b/source/drivers/MicroBitCompassCalibrator.cpp @@ -68,7 +68,7 @@ MicroBitCompassCalibrator::MicroBitCompassCalibrator(MicroBitCompass& _compass, * @param compass The compass instance to calibrate. * @param accelerometer The accelerometer to gather contextual data from. * @param display The LED matrix to display user feedback on. - * @param storage The object to use for storing calibration data in persistent FLASH. + * @param storage The object to use for storing calibration data in persistent FLASH. */ MicroBitCompassCalibrator::MicroBitCompassCalibrator(MicroBitCompass& _compass, MicroBitAccelerometer& _accelerometer, MicroBitDisplay& _display, MicroBitStorage &storage) : compass(_compass), accelerometer(_accelerometer), display(_display) { @@ -95,7 +95,7 @@ MicroBitCompassCalibrator::MicroBitCompassCalibrator(MicroBitCompass& _compass, * @param data a collection of data points * @param samples the number of samples in the 'data' array * - * @return The deviation between the closest and further point in the data array from the point given. + * @return The deviation between the closest and further point in the data array from the point given. */ float MicroBitCompassCalibrator::measureScore(Sample3D &c, Sample3D *data, int samples) { @@ -186,7 +186,7 @@ CompassCalibration MicroBitCompassCalibrator::spherify(Sample3D centre, Sample3D scale = max(scale, s); // next, determine the scale effect this has on each of our components. - float dx = (data[i].x - centre.x); + float dx = (data[i].x - centre.x); float dy = (data[i].y - centre.y); float dz = (data[i].z - centre.z); @@ -226,8 +226,8 @@ CompassCalibration MicroBitCompassCalibrator::spherify(Sample3D centre, Sample3D Sample3D MicroBitCompassCalibrator::approximateCentre(Sample3D *data, int samples) { Sample3D c,t; - Sample3D centre = { 0,0,0 }; - Sample3D best = { 0,0,0 }; + Sample3D centre; + Sample3D best; float score; @@ -407,7 +407,7 @@ void MicroBitCompassCalibrator::calibrateUX(MicroBitEvent) remaining_scroll_time-=TIME_STEP; } - CompassCalibration cal = calibrate(data, samples); + CompassCalibration cal = calibrate(data, samples); compass.setCalibration(cal); if(this->storage) diff --git a/source/drivers/MicroBitFile.cpp b/source/drivers/MicroBitFile.cpp index 2b43312f..b3256638 100644 --- a/source/drivers/MicroBitFile.cpp +++ b/source/drivers/MicroBitFile.cpp @@ -160,7 +160,7 @@ int MicroBitFile::read(char *buffer, int size) */ ManagedString MicroBitFile::read(int size) { - char buff[size + 1]; + char *buff = new char[size + 1]; buff[size] = 0; @@ -169,7 +169,11 @@ ManagedString MicroBitFile::read(int size) if(ret < 0) return ManagedString(); - return ManagedString(buff,ret); + ManagedString string(buff,ret); + + delete[] buff; + + return string; } /** diff --git a/source/drivers/MicroBitMemoryMap.cpp b/source/drivers/MicroBitMemoryMap.cpp index 3462aa5c..070bdd6d 100644 --- a/source/drivers/MicroBitMemoryMap.cpp +++ b/source/drivers/MicroBitMemoryMap.cpp @@ -43,6 +43,7 @@ DEALINGS IN THE SOFTWARE. */ MicroBitMemoryMap::MicroBitMemoryMap() { + regionCount = 0; // Assumes PXT Built program // SD pushRegion(Region(0x00, 0x00, 0x18000, 0x00)); // Soft Device diff --git a/source/drivers/MicroBitQuadratureDecoder.cpp b/source/drivers/MicroBitQuadratureDecoder.cpp index 0abaeef5..cb9f38ef 100644 --- a/source/drivers/MicroBitQuadratureDecoder.cpp +++ b/source/drivers/MicroBitQuadratureDecoder.cpp @@ -46,11 +46,18 @@ DEALINGS IN THE SOFTWARE. MicroBitQuadratureDecoder::MicroBitQuadratureDecoder(MicroBitPin& phaseA_, MicroBitPin& phaseB_, MicroBitPin& LED_, uint8_t LEDDelay_, uint8_t flags_) : phaseA(phaseA_), phaseB(phaseB_), LED(&LED_), LEDDelay(LEDDelay_), flags(flags_) { + position = 0; + samplePeriod = 128; + faults = 0; } MicroBitQuadratureDecoder::MicroBitQuadratureDecoder(MicroBitPin& phaseA_, MicroBitPin& phaseB_, uint8_t flags_) : phaseA(phaseA_), phaseB(phaseB_), LED(NULL), flags(flags_) { + position = 0; + samplePeriod = 128; + faults = 0; + LEDDelay = 0; } /** @@ -205,7 +212,7 @@ void MicroBitQuadratureDecoder::poll() { NRF_QDEC->TASKS_READCLRACC = 1; position += (int32_t)NRF_QDEC->ACCREAD; - faults = min(UINT16_MAX, faults + NRF_QDEC->ACCDBLREAD); + faults = min(0xFFFF, faults + NRF_QDEC->ACCDBLREAD); } /** diff --git a/source/drivers/MicroBitSerial.cpp b/source/drivers/MicroBitSerial.cpp index 7fad4e00..ac279c77 100644 --- a/source/drivers/MicroBitSerial.cpp +++ b/source/drivers/MicroBitSerial.cpp @@ -585,7 +585,7 @@ int MicroBitSerial::read(MicroBitSerialMode mode) */ ManagedString MicroBitSerial::read(int size, MicroBitSerialMode mode) { - uint8_t buff[size + 1]; + uint8_t *buff = new uint8_t[size + 1]; memclr(&buff, size + 1); @@ -594,7 +594,11 @@ ManagedString MicroBitSerial::read(int size, MicroBitSerialMode mode) if(returnedSize <= 0) return ManagedString(); - return ManagedString((char *)buff, returnedSize); + ManagedString string((char *)buff, returnedSize); + + delete[] buff; + + return string; } /** @@ -778,7 +782,7 @@ ManagedString MicroBitSerial::readUntil(ManagedString delimeters, MicroBitSerial //calculate our local buffer size int localBuffSize = (preservedTail > foundIndex) ? (rxBuffSize - preservedTail) + foundIndex : foundIndex - preservedTail; - uint8_t localBuff[localBuffSize + 1]; + uint8_t *localBuff = new uint8_t[localBuffSize + 1]; memclr(&localBuff, localBuffSize + 1); @@ -789,7 +793,11 @@ ManagedString MicroBitSerial::readUntil(ManagedString delimeters, MicroBitSerial unlockRx(); - return ManagedString((char *)localBuff, localBuffSize); + ManagedString string((char *)localBuff, localBuffSize); + + delete[] localBuff; + + return string; } unlockRx(); diff --git a/source/types/MicroBitImage.cpp b/source/types/MicroBitImage.cpp index b3a19d42..db6b2064 100644 --- a/source/types/MicroBitImage.cpp +++ b/source/types/MicroBitImage.cpp @@ -789,7 +789,7 @@ ManagedString MicroBitImage::toString() int stringSize = getSize() * 2; //plus one for string terminator - char parseBuffer[stringSize + 1]; + char *parseBuffer = new char[stringSize + 1]; parseBuffer[stringSize] = '\0'; @@ -822,7 +822,11 @@ ManagedString MicroBitImage::toString() bitmapPtr++; } - return ManagedString(parseBuffer); + ManagedString string(parseBuffer); + + delete[] parseBuffer; + + return parseBuffer; } /** @@ -854,7 +858,7 @@ MicroBitImage MicroBitImage::crop(int startx, int starty, int cropWidth, int cro newHeight = getHeight(); //allocate our storage. - uint8_t cropped[newWidth * newHeight]; + uint8_t *cropped = new uint8_t[newWidth * newHeight]; //calculate the pointer to where we want to begin cropping uint8_t *copyPointer = getBitmap() + (getWidth() * starty) + startx; @@ -871,7 +875,11 @@ MicroBitImage MicroBitImage::crop(int startx, int starty, int cropWidth, int cro pastePointer += newHeight; } - return MicroBitImage(newWidth, newHeight, cropped); + MicroBitImage image(newWidth, newHeight, cropped); + + delete[] cropped; + + return image; } /** From 928cc5105fa24cf85efcefa311a3a3490a499ba4 Mon Sep 17 00:00:00 2001 From: George Wort Date: Wed, 12 Jun 2019 15:03:33 +0100 Subject: [PATCH 2/3] Use the .S file extension for CortexContextSwitch so that armclang interprets it correctly. --- .../{CortexContextSwitch.s => CortexContextSwitch.S} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename source/asm/TOOLCHAIN_ARM_STD/{CortexContextSwitch.s => CortexContextSwitch.S} (100%) diff --git a/source/asm/TOOLCHAIN_ARM_STD/CortexContextSwitch.s b/source/asm/TOOLCHAIN_ARM_STD/CortexContextSwitch.S similarity index 100% rename from source/asm/TOOLCHAIN_ARM_STD/CortexContextSwitch.s rename to source/asm/TOOLCHAIN_ARM_STD/CortexContextSwitch.S From 9d05b48e62b6155dd4ce06bd94310268600580a5 Mon Sep 17 00:00:00 2001 From: George Wort Date: Thu, 13 Jun 2019 12:17:47 +0100 Subject: [PATCH 3/3] Add .lib dependencies. --- BLE_API.lib | 1 + mbed-classic.lib | 1 + nRF51822.lib | 1 + nrf51-sdk.lib | 1 + 4 files changed, 4 insertions(+) create mode 100644 BLE_API.lib create mode 100644 mbed-classic.lib create mode 100644 nRF51822.lib create mode 100644 nrf51-sdk.lib diff --git a/BLE_API.lib b/BLE_API.lib new file mode 100644 index 00000000..dd4d041f --- /dev/null +++ b/BLE_API.lib @@ -0,0 +1 @@ +https://github.com/lancaster-university/BLE_API/#bbc2dc58f8da1d5a6d1882dddd5ce7399dc48889 diff --git a/mbed-classic.lib b/mbed-classic.lib new file mode 100644 index 00000000..64dda9ca --- /dev/null +++ b/mbed-classic.lib @@ -0,0 +1 @@ +https://github.com/geowor01/mbed-classic/#d20ce0213b3a8734477eff8c7d5c35189e695a30 \ No newline at end of file diff --git a/nRF51822.lib b/nRF51822.lib new file mode 100644 index 00000000..91d008f6 --- /dev/null +++ b/nRF51822.lib @@ -0,0 +1 @@ +https://github.com/lancaster-university/nRF51822/#040baa12c08b439f9a09f0c1594ac625e58e2ad1 diff --git a/nrf51-sdk.lib b/nrf51-sdk.lib new file mode 100644 index 00000000..08760c8b --- /dev/null +++ b/nrf51-sdk.lib @@ -0,0 +1 @@ +https://github.com/geowor01/nrf51-sdk/#ef7142f00d5d89b0c54862485c4a2c34eaee6a4b \ No newline at end of file