Merge branch 'master' into ble-profile
Conflicts: source/CMakeLists.txt source/MicroBit.cpp source/MicroBitFiber.cpp source/MicroBitMessageBus.cpp source/MicroBitSuperMain.cpp
This commit is contained in:
commit
80f79f7faf
18 changed files with 204 additions and 95 deletions
|
@ -136,7 +136,16 @@ ManagedType<T>::ManagedType(const ManagedType<T> &t)
|
|||
template<typename T>
|
||||
ManagedType<T>::~ManagedType()
|
||||
{
|
||||
if (--(*ref) == 0)
|
||||
// Special case - we were created using a default constructor, and never assigned a value.
|
||||
if (*ref == 0)
|
||||
{
|
||||
// Simply destroy our reference counter and we're done.
|
||||
free(ref);
|
||||
}
|
||||
|
||||
// Normal case - we have a valid piece of data.
|
||||
// Decrement our reference counter and free all allocated memory if we're deleting the last reference.
|
||||
else if (--(*ref) == 0)
|
||||
{
|
||||
delete object;
|
||||
free(ref);
|
||||
|
@ -152,7 +161,14 @@ ManagedType<T>& ManagedType<T>::operator = (const ManagedType<T>&t)
|
|||
if (this == &t)
|
||||
return *this;
|
||||
|
||||
if (--(*ref) == 0)
|
||||
// Special case - we were created using a default constructor, and never assigned a value.
|
||||
if (*ref == 0)
|
||||
{
|
||||
// Simply destroy our reference counter, as we're about to adopt another.
|
||||
free(ref);
|
||||
}
|
||||
|
||||
else if (--(*ref) == 0)
|
||||
{
|
||||
delete object;
|
||||
free(ref);
|
||||
|
|
|
@ -254,6 +254,14 @@ class MicroBit
|
|||
*/
|
||||
unsigned long systemTime();
|
||||
|
||||
/**
|
||||
* Determine the version of the micro:bit runtime currently in use.
|
||||
*
|
||||
* @return A textual description of the currentlt executing micro:bit runtime.
|
||||
* TODO: handle overflow case.
|
||||
*/
|
||||
char *systemVersion();
|
||||
|
||||
/**
|
||||
* Triggers a microbit panic where an infinite loop will occur swapping between the panicFace and statusCode if provided.
|
||||
*
|
||||
|
|
|
@ -149,7 +149,7 @@
|
|||
// This enables the standard BLE device information service.
|
||||
// Set '1' to enable.
|
||||
#ifndef MICROBIT_BLE_DEVICE_INFORMATION_SERVICE
|
||||
#define MICROBIT_BLE_DEVICE_INFORMATION_SERVICE 0
|
||||
#define MICROBIT_BLE_DEVICE_INFORMATION_SERVICE 1
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -289,6 +289,16 @@
|
|||
#define MICROBIT_HEAP_DBG 0
|
||||
#endif
|
||||
|
||||
// Versioning options.
|
||||
// We use semantic versioning (http://semver.org/) to identify differnet versions of the micro:bit runtime.
|
||||
// Where possible we use yotta (an ARM mbed build tool) to help us track versions.
|
||||
// if this isn't available, it can be defined manually as a configuration option.
|
||||
//
|
||||
#ifndef MICROBIT_DAL_VERSION
|
||||
#define MICROBIT_DAL_VERSION "unknown"
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// Helper macro used by the micro:bit runtime to determine if a boolean configuration option is set.
|
||||
//
|
||||
|
|
|
@ -85,8 +85,6 @@ enum DisplayMode {
|
|||
struct MatrixPoint {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
|
||||
MatrixPoint(uint8_t x, uint8_t y);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#define MICROBIT_FIBER_FLAG_FOB 0x01
|
||||
#define MICROBIT_FIBER_FLAG_PARENT 0x02
|
||||
#define MICROBIT_FIBER_FLAG_CHILD 0x04
|
||||
#define MICROBIT_FIBER_FLAG_DO_NOT_PAGE 0x08
|
||||
|
||||
/**
|
||||
* Thread Context for an ARM Cortex M0 core.
|
||||
|
@ -67,6 +68,7 @@ struct Fiber
|
|||
Fiber *next, *prev; // Position of this Fiber on the run queues.
|
||||
};
|
||||
|
||||
extern Fiber *currentFiber;
|
||||
|
||||
/**
|
||||
* Initialises the Fiber scheduler.
|
||||
|
@ -119,7 +121,6 @@ Fiber *create_fiber(void (*entry_fn)(void), void (*completion_fn)(void) = releas
|
|||
Fiber *create_fiber(void (*entry_fn)(void *), void *param, void (*completion_fn)(void *) = release_fiber);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Calls the Fiber scheduler.
|
||||
* The calling Fiber will likely be blocked, and control given to another waiting fiber.
|
||||
|
@ -227,10 +228,15 @@ void queue_fiber(Fiber *f, Fiber **queue);
|
|||
*/
|
||||
void dequeue_fiber(Fiber *f);
|
||||
|
||||
/**
|
||||
* Set of tasks to perform when idle.
|
||||
* Service any background tasks that are required, and attmept power efficient sleep.
|
||||
*/
|
||||
void idle();
|
||||
|
||||
/**
|
||||
* IDLE task.
|
||||
* Only scheduled for execution when the runqueue is empty.
|
||||
* Performs a procressor sleep operation, then returns to the scheduler - most likely after a timer interrupt.
|
||||
* Only scheduled for execution when the runqueue is empty. Typically calls idle().
|
||||
*/
|
||||
void idle_task();
|
||||
|
||||
|
|
|
@ -19,50 +19,50 @@
|
|||
|
||||
#if MICROBIT_DISPLAY_TYPE == MICROBUG_REFERENCE_DEVICE
|
||||
const MatrixPoint MicroBitDisplay::matrixMap[MICROBIT_DISPLAY_COLUMN_COUNT][MICROBIT_DISPLAY_ROW_COUNT] =
|
||||
{ {MatrixPoint(0,0),MatrixPoint(0,1),MatrixPoint(0,2), MatrixPoint(0,3), MatrixPoint(0,4)},
|
||||
{MatrixPoint(1,0),MatrixPoint(1,1),MatrixPoint(1,2), MatrixPoint(1,3), MatrixPoint(1,4)},
|
||||
{MatrixPoint(2,0),MatrixPoint(2,1),MatrixPoint(2,2), MatrixPoint(2,3), MatrixPoint(2,4)},
|
||||
{MatrixPoint(3,0),MatrixPoint(3,1),MatrixPoint(3,2), MatrixPoint(3,3), MatrixPoint(3,4)},
|
||||
{MatrixPoint(4,0),MatrixPoint(4,1),MatrixPoint(4,2), MatrixPoint(4,3), MatrixPoint(4,4)}
|
||||
{ {{0,0},{0,1},{0,2},{0,3},{0,4}},
|
||||
{{1,0},{1,1},{1,2},{1,3},{1,4}},
|
||||
{{2,0},{2,1},{2,2},{2,3},{2,4}},
|
||||
{{3,0},{3,1},{3,2},{3,3},{3,4}},
|
||||
{{4,0},{4,1},{4,2},{4,3},{4,4}}
|
||||
};
|
||||
#endif
|
||||
|
||||
#if MICROBIT_DISPLAY_TYPE == MICROBIT_3X9
|
||||
const MatrixPoint MicroBitDisplay::matrixMap[MICROBIT_DISPLAY_COLUMN_COUNT][MICROBIT_DISPLAY_ROW_COUNT] =
|
||||
{
|
||||
{MatrixPoint(0,4),MatrixPoint(0,3),MatrixPoint(1,1)},
|
||||
{MatrixPoint(1,4),MatrixPoint(4,2),MatrixPoint(0,1)},
|
||||
{MatrixPoint(2,4),MatrixPoint(3,2),MatrixPoint(4,0)},
|
||||
{MatrixPoint(3,4),MatrixPoint(2,2),MatrixPoint(3,0)},
|
||||
{MatrixPoint(4,4),MatrixPoint(1,2),MatrixPoint(2,0)},
|
||||
{MatrixPoint(4,3),MatrixPoint(0,2),MatrixPoint(1,0)},
|
||||
{MatrixPoint(3,3),MatrixPoint(4,1),MatrixPoint(0,0)},
|
||||
{MatrixPoint(2,3),MatrixPoint(3,1),MatrixPoint(NO_CONN,NO_CONN)},
|
||||
{MatrixPoint(1,3),MatrixPoint(2,1),MatrixPoint(NO_CONN,NO_CONN)}
|
||||
{{0,4},{0,3},{1,1}},
|
||||
{{1,4},{4,2},{0,1}},
|
||||
{{2,4},{3,2},{4,0}},
|
||||
{{3,4},{2,2},{3,0}},
|
||||
{{4,4},{1,2},{2,0}},
|
||||
{{4,3},{0,2},{1,0}},
|
||||
{{3,3},{4,1},{0,0}},
|
||||
{{2,3},{3,1},{NO_CONN,NO_CONN}},
|
||||
{{1,3},{2,1},{NO_CONN,NO_CONN}}
|
||||
};
|
||||
#endif
|
||||
|
||||
#if MICROBIT_DISPLAY_TYPE == MICROBIT_SB1
|
||||
const MatrixPoint MicroBitDisplay::matrixMap[MICROBIT_DISPLAY_COLUMN_COUNT][MICROBIT_DISPLAY_ROW_COUNT] =
|
||||
{
|
||||
{MatrixPoint(0,4), MatrixPoint(1,4), MatrixPoint(2,4), MatrixPoint(3,4), MatrixPoint(4,4), MatrixPoint(4,3), MatrixPoint(3,3), MatrixPoint(2,3), MatrixPoint(1,3)},
|
||||
{MatrixPoint(0,3), MatrixPoint(4,2), MatrixPoint(3,2), MatrixPoint(2,2), MatrixPoint(1,2), MatrixPoint(0,2), MatrixPoint(4,1), MatrixPoint(3,1), MatrixPoint(2,1)},
|
||||
{MatrixPoint(1,1), MatrixPoint(0,1), MatrixPoint(4,0), MatrixPoint(3,0), MatrixPoint(2,0), MatrixPoint(1,0), MatrixPoint(0,0), MatrixPoint(NO_CONN,NO_CONN), MatrixPoint(NO_CONN,NO_CONN)}
|
||||
{{0,4},{1,4},{2,4},{3,4},{4,4},{4,3},{3,3},{2,3},{1,3}},
|
||||
{{0,3},{4,2},{3,2},{2,2},{1,2},{0,2},{4,1},{3,1},{2,1}},
|
||||
{{1,1},{0,1},{4,0},{3,0},{2,0},{1,0},{0,0},{NO_CONN,NO_CONN},{NO_CONN,NO_CONN}}
|
||||
};
|
||||
#endif
|
||||
|
||||
#if MICROBIT_DISPLAY_TYPE == MICROBIT_SB2
|
||||
const MatrixPoint MicroBitDisplay::matrixMap[MICROBIT_DISPLAY_COLUMN_COUNT][MICROBIT_DISPLAY_ROW_COUNT] =
|
||||
{
|
||||
{MatrixPoint(0,0),MatrixPoint(4,2),MatrixPoint(2,4)},
|
||||
{MatrixPoint(2,0),MatrixPoint(0,2),MatrixPoint(4,4)},
|
||||
{MatrixPoint(4,0),MatrixPoint(2,2),MatrixPoint(0,4)},
|
||||
{MatrixPoint(4,3),MatrixPoint(1,0),MatrixPoint(0,1)},
|
||||
{MatrixPoint(3,3),MatrixPoint(3,0),MatrixPoint(1,1)},
|
||||
{MatrixPoint(2,3),MatrixPoint(3,4),MatrixPoint(2,1)},
|
||||
{MatrixPoint(1,3),MatrixPoint(1,4),MatrixPoint(3,1)},
|
||||
{MatrixPoint(0,3),MatrixPoint(NO_CONN,NO_CONN),MatrixPoint(4,1)},
|
||||
{MatrixPoint(1,2),MatrixPoint(NO_CONN,NO_CONN),MatrixPoint(3,2)}
|
||||
{{0,0},{4,2},{2,4}},
|
||||
{{2,0},{0,2},{4,4}},
|
||||
{{4,0},{2,2},{0,4}},
|
||||
{{4,3},{1,0},{0,1}},
|
||||
{{3,3},{3,0},{1,1}},
|
||||
{{2,3},{3,4},{2,1}},
|
||||
{{1,3},{1,4},{3,1}},
|
||||
{{0,3},{NO_CONN,NO_CONN},{4,1}},
|
||||
{{1,2},{NO_CONN,NO_CONN},{3,2}}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -179,7 +179,7 @@ class MicroBitMessageBus : public MicroBitComponent
|
|||
* uBit.MessageBus.ignore(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, onButtonBClick);
|
||||
* @endcode
|
||||
*/
|
||||
void ignore(int id, int value, void (*handler)(MicroBitEvent, void*), void* arg);
|
||||
void ignore(int id, int value, void (*handler)(MicroBitEvent, void*));
|
||||
|
||||
/**
|
||||
* Unregister a listener function.
|
||||
|
|
|
@ -11,7 +11,7 @@ void panic(int statusCode);
|
|||
* Resets the micro:bit.
|
||||
* @param statusCode the appropriate status code. Status codes must be in the range 0-255.
|
||||
*/
|
||||
void reset(int statusCode);
|
||||
void microbit_reset();
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -178,6 +178,11 @@ class MicroBitPin : public MicroBitComponent
|
|||
* @param period The new period for the analog output in milliseconds.
|
||||
*/
|
||||
void setAnalogPeriod(int period);
|
||||
|
||||
/**
|
||||
* Same thing as setAnalogPeriodUs, but with microseconds.
|
||||
*/
|
||||
void setAnalogPeriodUs(int period);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
17
module.json
17
module.json
|
@ -1,17 +1,24 @@
|
|||
{
|
||||
"name": "microbit-dal",
|
||||
"version": "0.0.1",
|
||||
"version": "1.2.2",
|
||||
"license": "Apache2",
|
||||
"description": "The runtime library for the BBC micro:bit, developed by Lancaster University",
|
||||
"keywords": ["mbed-classic", "microbit", "runtime", "library", "lancaster", "University"],
|
||||
"author": "James Devine <j.devine@lancaster.ac.uk (mailto:j.devine@lancaster.ac.uk) >",
|
||||
"keywords": [
|
||||
"mbed-classic",
|
||||
"microbit",
|
||||
"runtime",
|
||||
"library",
|
||||
"lancaster",
|
||||
"University"
|
||||
],
|
||||
"author": "Joe Finney <j.finney@lancaster.ac.uk (mailto:j.finney@lancaster.ac.uk) >",
|
||||
"homepage": "https://developer.mbed.org/teams/Lancaster-University/code/microbit/",
|
||||
"dependencies":{
|
||||
"dependencies": {
|
||||
"mbed-classic": "~0.0.4",
|
||||
"ble": "lancaster-university/BLE_API#master",
|
||||
"ble-nrf51822": "lancaster-university/nrf51822#master"
|
||||
},
|
||||
"extraIncludes":[
|
||||
"extraIncludes": [
|
||||
"inc"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -39,6 +39,19 @@ set(YOTTA_AUTO_MICROBIT-DAL_CPP_FILES
|
|||
"ble-services/MicroBitTemperatureService.cpp"
|
||||
)
|
||||
|
||||
execute_process(WORKING_DIRECTORY "../../yotta_modules/${PROJECT_NAME}" COMMAND "git" "log" "--pretty=format:%h" "-n" "1" OUTPUT_VARIABLE git_hash)
|
||||
execute_process(WORKING_DIRECTORY "../../yotta_modules/${PROJECT_NAME}" COMMAND "git" "rev-parse" "--abbrev-ref" "HEAD" OUTPUT_VARIABLE git_branch OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
if (${git_branch} STREQUAL "master")
|
||||
set(MICROBIT_DAL_VERSION_STRING "${YOTTA_MICROBIT_DAL_VERSION_STRING}")
|
||||
else()
|
||||
set(MICROBIT_DAL_VERSION_STRING "${YOTTA_MICROBIT_DAL_VERSION_STRING}-${git_branch}-g${git_hash}")
|
||||
endif()
|
||||
|
||||
set(MICROBIT_DAL_VERSION_FLAGS "-DMICROBIT_DAL_VERSION=\\\"${MICROBIT_DAL_VERSION_STRING}\\\"")
|
||||
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MICROBIT_DAL_VERSION_FLAGS}")
|
||||
|
||||
if (YOTTA_CFG_MICROBIT_CONFIGFILE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${YOTTA_FORCE_INCLUDE_FLAG} \"${YOTTA_CFG_MICROBIT_CONFIGFILE}\"")
|
||||
endif ()
|
||||
|
|
|
@ -6,7 +6,7 @@ char MICROBIT_BLE_DEVICE_NAME[] = "BBC micro:bit [xxxxx]";
|
|||
const char* MICROBIT_BLE_MANUFACTURER = "The Cast of W1A";
|
||||
const char* MICROBIT_BLE_MODEL = "BBC micro:bit";
|
||||
const char* MICROBIT_BLE_HARDWARE_VERSION = "1.0";
|
||||
const char* MICROBIT_BLE_FIRMWARE_VERSION = "1.1";
|
||||
const char* MICROBIT_BLE_FIRMWARE_VERSION = MICROBIT_DAL_VERSION;
|
||||
const char* MICROBIT_BLE_SOFTWARE_VERSION = NULL;
|
||||
#endif
|
||||
|
||||
|
@ -18,6 +18,16 @@ void panic(int statusCode)
|
|||
uBit.panic(statusCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a hard reset of the micro:bit.
|
||||
*/
|
||||
void
|
||||
microbit_reset()
|
||||
{
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback when a BLE GATT disconnect occurs.
|
||||
*/
|
||||
|
@ -232,7 +242,7 @@ ManagedString MicroBit::getSerial()
|
|||
*/
|
||||
void MicroBit::reset()
|
||||
{
|
||||
reset();
|
||||
microbit_reset();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -423,7 +433,7 @@ void MicroBit::removeIdleComponent(MicroBitComponent *component)
|
|||
{
|
||||
int i = 0;
|
||||
|
||||
while(idleThreadComponents[i] != component && i < MICROBIT_IDLE_COMPONENTS)
|
||||
while(idleThreadComponents[i] != component && i < MICROBIT_IDLE_COMPONENTS)
|
||||
i++;
|
||||
|
||||
if(i == MICROBIT_IDLE_COMPONENTS)
|
||||
|
@ -443,6 +453,18 @@ unsigned long MicroBit::systemTime()
|
|||
return ticks;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine the version of the micro:bit runtime currently in use.
|
||||
*
|
||||
* @return A textual description of the currentlt executing micro:bit runtime.
|
||||
* TODO: handle overflow case.
|
||||
*/
|
||||
char *MicroBit::systemVersion()
|
||||
{
|
||||
return MICROBIT_DAL_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers a microbit panic where an infinite loop will occur swapping between the panicFace and statusCode if provided.
|
||||
*
|
||||
|
|
|
@ -37,20 +37,20 @@ void string_reverse(char *s)
|
|||
void itoa(int n, char *s)
|
||||
{
|
||||
int i = 0;
|
||||
int sign = (n >= 0);
|
||||
int positive = (n >= 0);
|
||||
|
||||
// Record the sign of the number,
|
||||
// Ensure our working value is positive.
|
||||
if (!sign)
|
||||
if (positive)
|
||||
n = -n;
|
||||
|
||||
// Calculate each character, starting with the LSB.
|
||||
do {
|
||||
s[i++] = n % 10 + '0';
|
||||
} while ((n /= 10) > 0);
|
||||
s[i++] = abs(n % 10) + '0';
|
||||
} while (abs(n /= 10) > 0);
|
||||
|
||||
// Add a negative sign as needed
|
||||
if (!sign)
|
||||
if (!positive)
|
||||
s[i++] = '-';
|
||||
|
||||
// Terminate the string.
|
||||
|
|
|
@ -10,17 +10,6 @@
|
|||
|
||||
const float timings[MICROBIT_DISPLAY_GREYSCALE_BIT_DEPTH] = {0.000010, 0.000047, 0.000094, 0.000187, 0.000375, 0.000750, 0.001500, 0.003000};
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Create a Point representation of an LED on a matrix
|
||||
* Used to handle non-linear matrix layouts.
|
||||
*/
|
||||
MatrixPoint::MatrixPoint(uint8_t x, uint8_t y)
|
||||
{
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Create a representation of a display of a given size.
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
Fiber *currentFiber = NULL; // The context in which the current fiber is executing.
|
||||
Fiber *forkedFiber = NULL; // The context in which a newly created child fiber is executing.
|
||||
Fiber *idle = NULL; // IDLE task - performs a power efficient sleep, and system maintenance tasks.
|
||||
Fiber *idleFiber = NULL; // IDLE task - performs a power efficient sleep, and system maintenance tasks.
|
||||
|
||||
/*
|
||||
* Scheduler state.
|
||||
|
@ -159,10 +159,10 @@ void scheduler_init()
|
|||
|
||||
// Create the IDLE fiber.
|
||||
// Configure the fiber to directly enter the idle task.
|
||||
idle = getFiberContext();
|
||||
idle->tcb.SP = CORTEX_M0_STACK_BASE - 0x04;
|
||||
idle->tcb.LR = (uint32_t) &idle_task;
|
||||
|
||||
idleFiber = getFiberContext();
|
||||
idleFiber->tcb.SP = CORTEX_M0_STACK_BASE - 0x04;
|
||||
idleFiber->tcb.LR = (uint32_t) &idle_task;
|
||||
|
||||
// Flag that we now have a scheduler running
|
||||
uBit.flags |= MICROBIT_FLAG_SCHEDULER_RUNNING;
|
||||
}
|
||||
|
@ -618,7 +618,7 @@ void schedule()
|
|||
// We're in a normal scheduling context, so perform a round robin algorithm across runnable fibers.
|
||||
// OK - if we've nothing to do, then run the IDLE task (power saving sleep)
|
||||
if (runQueue == NULL || fiber_flags & MICROBIT_FLAG_DATA_READY)
|
||||
currentFiber = idle;
|
||||
currentFiber = idleFiber;
|
||||
|
||||
else if (currentFiber->queue == &runQueue)
|
||||
// If the current fiber is on the run queue, round robin.
|
||||
|
@ -628,18 +628,38 @@ void schedule()
|
|||
// Otherwise, just pick the head of the run queue.
|
||||
currentFiber = runQueue;
|
||||
|
||||
if (currentFiber == idleFiber && oldFiber->flags & MICROBIT_FIBER_FLAG_DO_NOT_PAGE)
|
||||
{
|
||||
// Run the idle task right here using the old fiber's stack.
|
||||
// Keep idling while the runqueue is empty, or there is data to process.
|
||||
|
||||
// Run in the context of the original fiber, to preserve state of flags...
|
||||
// as we are running on top of this fiber's stack.
|
||||
currentFiber = oldFiber;
|
||||
|
||||
do
|
||||
{
|
||||
idle();
|
||||
}
|
||||
while (runQueue == NULL || fiber_flags & MICROBIT_FLAG_DATA_READY);
|
||||
|
||||
// Switch to a non-idle fiber.
|
||||
// If this fiber is the same as the old one then there'll be no switching at all.
|
||||
currentFiber = runQueue;
|
||||
}
|
||||
|
||||
// Swap to the context of the chosen fiber, and we're done.
|
||||
// Don't bother with the overhead of switching if there's only one fiber on the runqueue!
|
||||
if (currentFiber != oldFiber)
|
||||
{
|
||||
// Special case for the idle task, as we don't maintain a stack context (just to save memory).
|
||||
if (currentFiber == idle)
|
||||
if (currentFiber == idleFiber)
|
||||
{
|
||||
idle->tcb.SP = CORTEX_M0_STACK_BASE - 0x04;
|
||||
idle->tcb.LR = (uint32_t) &idle_task;
|
||||
idleFiber->tcb.SP = CORTEX_M0_STACK_BASE - 0x04;
|
||||
idleFiber->tcb.LR = (uint32_t) &idle_task;
|
||||
}
|
||||
|
||||
if (oldFiber == idle)
|
||||
if (oldFiber == idleFiber)
|
||||
{
|
||||
// Just swap in the new fiber, and discard changes to stack and register context.
|
||||
swap_context(NULL, ¤tFiber->tcb, NULL, currentFiber->stack_top);
|
||||
|
@ -655,6 +675,25 @@ void schedule()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set of tasks to perform when idle.
|
||||
* Service any background tasks that are required, and attmept power efficient sleep.
|
||||
*/
|
||||
void idle()
|
||||
{
|
||||
// Service background tasks
|
||||
uBit.systemTasks();
|
||||
|
||||
// If the above did create any useful work, enter power efficient sleep.
|
||||
if(scheduler_runqueue_empty())
|
||||
{
|
||||
if (uBit.ble)
|
||||
uBit.ble->waitForEvent();
|
||||
else
|
||||
__WFI();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* IDLE task.
|
||||
* Only scheduled for execution when the runqueue is empty.
|
||||
|
@ -664,16 +703,7 @@ void idle_task()
|
|||
{
|
||||
while(1)
|
||||
{
|
||||
uBit.systemTasks();
|
||||
|
||||
if(scheduler_runqueue_empty())
|
||||
{
|
||||
if (uBit.ble)
|
||||
uBit.ble->waitForEvent();
|
||||
else
|
||||
__WFI();
|
||||
}
|
||||
|
||||
idle();
|
||||
schedule();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -350,12 +350,13 @@ void MicroBitMessageBus::ignore(int id, int value, void (*handler)(MicroBitEvent
|
|||
* uBit.MessageBus.ignore(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, onButtonBClick);
|
||||
* @endcode
|
||||
*/
|
||||
void MicroBitMessageBus::ignore(int id, int value, void (*handler)(MicroBitEvent, void*), void* arg)
|
||||
void MicroBitMessageBus::ignore(int id, int value, void (*handler)(MicroBitEvent, void*))
|
||||
{
|
||||
if (handler == NULL)
|
||||
return;
|
||||
|
||||
MicroBitListener listener(id, value, handler, arg);
|
||||
// The remove function is not comparing the [arg] anyhow.
|
||||
MicroBitListener listener(id, value, handler, NULL);
|
||||
remove(&listener);
|
||||
}
|
||||
|
||||
|
|
|
@ -241,11 +241,18 @@ int MicroBitPin::isTouched()
|
|||
* If this pin is not configured as an analog output, the operation
|
||||
* has no effect.
|
||||
*
|
||||
* @param period The new period for the analog output in milliseconds.
|
||||
*/
|
||||
void MicroBitPin::setAnalogPeriod(int period)
|
||||
* @param period The new period for the analog output in microseconds.
|
||||
*/
|
||||
void MicroBitPin::setAnalogPeriodUs(int period)
|
||||
{
|
||||
if (status & IO_STATUS_ANALOG_OUT)
|
||||
((DynamicPwm *)pin)->setPeriodUs(period*1000);
|
||||
|
||||
((DynamicPwm *)pin)->setPeriodUs(period);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same thing as setAnalogPeriodUs, but with milliseconds.
|
||||
*/
|
||||
void MicroBitPin::setAnalogPeriod(int period)
|
||||
{
|
||||
setAnalogPeriodUs(period*1000);
|
||||
}
|
||||
|
|
|
@ -9,28 +9,25 @@ InterruptIn resetButton(MICROBIT_PIN_BUTTON_RESET);
|
|||
|
||||
extern char* MICROBIT_BLE_DEVICE_NAME;
|
||||
|
||||
void
|
||||
reset()
|
||||
{
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
// Bring up soft reset button.
|
||||
resetButton.mode(PullUp);
|
||||
resetButton.fall(reset);
|
||||
resetButton.fall(microbit_reset);
|
||||
|
||||
#if CONFIG_ENABLED(MICROBIT_DBG)
|
||||
pc.baud(115200);
|
||||
|
||||
|
||||
// For diagnostics. Gives time to open the console window. :-)
|
||||
for (int i=3; i>0; i--)
|
||||
{
|
||||
pc.printf("=== SUPERMAIN: Starting in %d ===\n", i);
|
||||
wait(1.0);
|
||||
}
|
||||
|
||||
pc.printf("micro:bit runtime DAL version %s\n", MICROBIT_DAL_VERSION);
|
||||
|
||||
#endif
|
||||
|
||||
// Bring up our nested heap allocator.
|
||||
|
|
Loading…
Reference in a new issue