Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce optional javascript semantics for event handling #418

Open
wants to merge 36 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
9dedea4
Introduce optional javascript semantics for event handling
finneyj Sep 27, 2018
69bf72e
Update string print() method to avoid unecessary delays
finneyj Feb 27, 2019
b1cb519
Simplify implementation of fiber_wake_on_event()
finneyj Feb 27, 2019
6112d74
MicroBitMessageBus::process() updated to pass events by value
finneyj Feb 27, 2019
ca43746
Ensure MicroBitDisplay::waitForFreeDisplay() is free of race conditions
finneyj Feb 27, 2019
31fea82
Change Fiber lists to be singly-linked
finneyj May 3, 2019
60d423e
Ignore .vscode metadata
finneyj May 3, 2019
1c1426f
Introduce FiberTable stucture
finneyj May 3, 2019
461fb33
Integrate optional fiber meta-data contributed in #424
finneyj May 7, 2019
07f07fb
Ensure Fiber stack allocation happens in the context of that Fiber
finneyj May 7, 2019
b71334e
Add user define limit to size of FiberPool
finneyj May 7, 2019
b9816a4
Reintroduce validation test in fiber_sleep()
finneyj May 7, 2019
226bf9c
Replace FiberTable with a list of all fibers to save memory
finneyj May 8, 2019
92c6cc6
Allow overriding of the heap allocator and getting heap sizes
finneyj May 8, 2019
7413352
Introduce optional javascript semantics for event handling
finneyj Sep 27, 2018
c9c98be
Update string print() method to avoid unecessary delays
finneyj Feb 27, 2019
b28dba4
MicroBitMessageBus::process() updated to pass events by value
finneyj Feb 27, 2019
77d679c
Ensure MicroBitDisplay::waitForFreeDisplay() is free of race conditions
finneyj Feb 27, 2019
c04b1fd
Merge branch 'js-event-semantics' of https://www.github.com/lancaster…
finneyj May 8, 2019
8075eab
.gitignore vscode metadata
finneyj Mar 24, 2020
25e1e10
Add Fiber->user_data and list_fiber()
mmoskal Jan 20, 2019
92d0cee
Allow overriding of the heap allocator and getting heap sizes
mmoskal Jan 20, 2019
415e5eb
Compilation fixes
mmoskal Jan 20, 2019
15ebed2
Add fiber_user_data to yotta mappings; fix some errors
mmoskal Jan 20, 2019
d823d4b
Rename list pointers in MicroBitFiber.h
finneyj Mar 25, 2020
c42776c
Merge branch 'pxtgc' into js-event-semantics
finneyj Mar 25, 2020
219feb8
Remove list_fibers API
finneyj Mar 25, 2020
3ed3674
Add CONFIG flag to indicate use of get_fiber_list() API
finneyj Mar 25, 2020
76538ef
Re-enumerate component ID values to align with CODAL
finneyj Mar 25, 2020
f96a390
Use schedule() not fiber_sleep(0) in MicroBitSerial.cpp (Fix #461)
finneyj Apr 1, 2020
dd339a7
Honour delay parameter in MicroBitDisplay::print(MicroBitImage)
finneyj Apr 1, 2020
0fd4a80
Correctly initialise animation timer for printChar() Fix #463
finneyj Apr 21, 2020
3bccdd6
Ensure consistent behaviour of MicroBitDisplay::print() operations
finneyj Apr 21, 2020
673228f
Align print() semantics with previous versions
finneyj Apr 24, 2020
2443beb
Align MICROBIT_PIN_EVENT_ON_* with codal
mmoskal Jun 8, 2020
e5b6741
Align allocateNotifyEvent() API with codal
finneyj Jul 31, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
build
.yotta.json
.vscode
yotta_modules
yotta_targets
*.swp
*~
Makefile
.vscode
79 changes: 38 additions & 41 deletions inc/core/MicroBitComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,47 +31,44 @@ DEALINGS IN THE SOFTWARE.
// Enumeration of core components.
#define MICROBIT_ID_BUTTON_A 1
#define MICROBIT_ID_BUTTON_B 2
#define MICROBIT_ID_BUTTON_RESET 3
#define MICROBIT_ID_ACCELEROMETER 4
#define MICROBIT_ID_COMPASS 5
#define MICROBIT_ID_DISPLAY 6

//EDGE connector events
#define MICROBIT_IO_PINS 20

#define MICROBIT_ID_IO_P0 7 //P0 is the left most pad (ANALOG/DIGITAL)
#define MICROBIT_ID_IO_P1 8 //P1 is the middle pad (ANALOG/DIGITAL)
#define MICROBIT_ID_IO_P2 9 //P2 is the right most pad (ANALOG/DIGITAL)
#define MICROBIT_ID_IO_P3 10 //COL1 (ANALOG/DIGITAL)
#define MICROBIT_ID_IO_P4 11 //BTN_A
#define MICROBIT_ID_IO_P5 12 //COL2 (ANALOG/DIGITAL)
#define MICROBIT_ID_IO_P6 13 //ROW2
#define MICROBIT_ID_IO_P7 14 //ROW1
#define MICROBIT_ID_IO_P8 15 //PIN 18
#define MICROBIT_ID_IO_P9 16 //ROW3
#define MICROBIT_ID_IO_P10 17 //COL3 (ANALOG/DIGITAL)
#define MICROBIT_ID_IO_P11 18 //BTN_B
#define MICROBIT_ID_IO_P12 19 //PIN 20
#define MICROBIT_ID_IO_P13 20 //SCK
#define MICROBIT_ID_IO_P14 21 //MISO
#define MICROBIT_ID_IO_P15 22 //MOSI
#define MICROBIT_ID_IO_P16 23 //PIN 16
#define MICROBIT_ID_IO_P19 24 //SCL
#define MICROBIT_ID_IO_P20 25 //SDA

#define MICROBIT_ID_BUTTON_AB 26 // Button A+B multibutton
#define MICROBIT_ID_GESTURE 27 // Gesture events

#define MICROBIT_ID_THERMOMETER 28
#define MICROBIT_ID_RADIO 29
#define MICROBIT_ID_RADIO_DATA_READY 30
#define MICROBIT_ID_MULTIBUTTON_ATTACH 31
#define MICROBIT_ID_SERIAL 32

#define MICROBIT_ID_IO_INT1 33 //INT1
#define MICROBIT_ID_IO_INT2 34 //INT2
#define MICROBIT_ID_IO_INT3 35 //INT3
#define MICROBIT_ID_PARTIAL_FLASHING 36
#define MICROBIT_ID_BUTTON_AB 3 // Button A+B multibutton
#define MICROBIT_ID_BUTTON_RESET 4
#define MICROBIT_ID_ACCELEROMETER 5
#define MICROBIT_ID_COMPASS 6
#define MICROBIT_ID_DISPLAY 7
#define MICROBIT_ID_THERMOMETER 8
#define MICROBIT_ID_RADIO 9
#define MICROBIT_ID_RADIO_DATA_READY 10
#define MICROBIT_ID_MULTIBUTTON_ATTACH 11
#define MICROBIT_ID_SERIAL 12
#define MICROBIT_ID_GESTURE 13 // Gesture events

#define MICROBIT_ID_IO_P0 100 //P0 is the left most pad (ANALOG/DIGITAL)
#define MICROBIT_ID_IO_P1 101 //P1 is the middle pad (ANALOG/DIGITAL)
#define MICROBIT_ID_IO_P2 102 //P2 is the right most pad (ANALOG/DIGITAL)
#define MICROBIT_ID_IO_P3 103 //COL1 (ANALOG/DIGITAL)
#define MICROBIT_ID_IO_P4 104 //BTN_A
#define MICROBIT_ID_IO_P5 105 //COL2 (ANALOG/DIGITAL)
#define MICROBIT_ID_IO_P6 106 //ROW2
#define MICROBIT_ID_IO_P7 107 //ROW1
#define MICROBIT_ID_IO_P8 108 //PIN 18
#define MICROBIT_ID_IO_P9 109 //ROW3
#define MICROBIT_ID_IO_P10 110 //COL3 (ANALOG/DIGITAL)
#define MICROBIT_ID_IO_P11 111 //BTN_B
#define MICROBIT_ID_IO_P12 112 //PIN 20
#define MICROBIT_ID_IO_P13 113 //SCK
#define MICROBIT_ID_IO_P14 114 //MISO
#define MICROBIT_ID_IO_P15 115 //MOSI
#define MICROBIT_ID_IO_P16 116 //PIN 16
#define MICROBIT_ID_IO_P19 119 //SCL
#define MICROBIT_ID_IO_P20 120 //SDA

#define MICROBIT_ID_IO_INT1 130 //INT1
#define MICROBIT_ID_IO_INT2 131 //INT2
#define MICROBIT_ID_IO_INT3 132 //INT3

// System Softwarre components
#define MICROBIT_ID_PARTIAL_FLASHING 200

#define MICROBIT_ID_MESSAGE_BUS_LISTENER 1021 // Message bus indication that a handler for a given ID has been registered.
#define MICROBIT_ID_NOTIFY_ONE 1022 // Notfication channel, for general purpose synchronisation
Expand Down
32 changes: 32 additions & 0 deletions inc/core/MicroBitConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,23 @@ extern uint32_t __etext;
#define SYSTEM_TICK_PERIOD_MS 6
#endif

// Enable used_data field in Fiber structure (for thread-local data)
#ifndef MICROBIT_FIBER_USER_DATA
#define MICROBIT_FIBER_USER_DATA 0
#endif

// Indicate get_fiber_list() API is supported
#ifndef MICROBIT_GET_FIBER_LIST_SUPPORTED
#define MICROBIT_GET_FIBER_LIST_SUPPORTED 1
#endif

// Maximum size of the FiberPool
// Defines the size that the pool of unused Fiber contexts is permitted to grow to. After this point, memory
// from unused Fiber contexts will be restored to the Heap Allocator.
#ifndef MICROBIT_FIBER_MAXIMUM_FIBER_POOL_SIZE
#define MICROBIT_FIBER_MAXIMUM_FIBER_POOL_SIZE 3
#endif

//
// Message Bus:
// Default behaviour for event handlers, if not specified in the listen() call
Expand All @@ -171,6 +188,21 @@ extern uint32_t __etext;
#define MESSAGE_BUS_LISTENER_MAX_QUEUE_DEPTH 10
#endif

//
// Define MESSAGE_BUS concurrency behaviour.
// Set to MESSAGE_BUS_CONCURRENT_LISTENERS to fire event handler
// concurrently when a given event is raised, and process events sequentially as they arrive (default micro:bit semantics).
// Set to MESSAGE_BUS_CONCURRENT_EVENTS to to fire event handlers sequentially for any given event, while still allowing
// concurrent processing of events.
//
//
// Permissable values are:
// 0: MESSAGE_BUS_CONCURRENT_LISTENERS
// 1: MESSAGE_BUS_CONCURRENT_EVENTS
//
#ifndef MESSAGE_BUS_CONCURRENCY_MODE
#define MESSAGE_BUS_CONCURRENCY_MODE MESSAGE_BUS_CONCURRENT_LISTENERS
#endif
//
// Core micro:bit services
//
Expand Down
30 changes: 29 additions & 1 deletion inc/core/MicroBitFiber.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ DEALINGS IN THE SOFTWARE.
#define MICROBIT_FIBER_FLAG_CHILD 0x04
#define MICROBIT_FIBER_FLAG_DO_NOT_PAGE 0x08

#if CONFIG_ENABLED(MICROBIT_FIBER_USER_DATA)
#define HAS_THREAD_USER_DATA (currentFiber->user_data != NULL)
#else
#define HAS_THREAD_USER_DATA false
#endif

/**
* Thread Context for an ARM Cortex M0 core.
*
Expand Down Expand Up @@ -88,7 +94,12 @@ struct Fiber
uint32_t context; // Context specific information.
uint32_t flags; // Information about this fiber.
Fiber **queue; // The queue this fiber is stored on.
Fiber *next, *prev; // Position of this Fiber on the run queue.
Fiber *qnext; // Position of this Fiber on its queue.
Fiber *next; // Position of this Fiber in the global list of fibers.

#if CONFIG_ENABLED(MICROBIT_FIBER_USER_DATA)
void *user_data; // Optional pointer to user defined data block.
#endif
};

extern Fiber *currentFiber;
Expand All @@ -111,6 +122,13 @@ void scheduler_init(EventModel &_messageBus);
*/
int fiber_scheduler_running();

/**
* Provides a list of all active fibers.
*
* @return A pointer to the head of the list of all active fibers.
*/
Fiber* get_fiber_list();

/**
* Exit point for all fibers.
*
Expand Down Expand Up @@ -364,6 +382,16 @@ inline int inInterruptContext()
return (((int)__get_IPSR()) & 0x003F) > 0;
}

/**
* Return all current fibers.
*
* @param dest If non-null, it points to an array of pointers to fibers to store results in.
*
* @return the number of fibers (potentially) stored
*/
int list_fibers(Fiber **dest);


/**
* Assembler Context switch routing.
* Defined in CortexContextSwitch.s.
Expand Down
34 changes: 34 additions & 0 deletions inc/core/MicroBitHeapAllocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,38 @@ struct HeapDefinition
int microbit_create_heap(uint32_t start, uint32_t end);
void microbit_heap_print();


/**
* Returns the size of a given heap.
*
* @param heap_index index between 0 and MICROBIT_MAXIMUM_HEAPS-1
*
* @return the size of heap in bytes, or zero if no such heap exists.
*/
uint32_t microbit_heap_size(uint8_t heap_index);

/**
* 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.
*/
extern "C" void* microbit_alloc(size_t size);

/**
* Release a given area of memory from the heap.
*
* @param mem The memory area to release.
*/
extern "C" void microbit_free(void *mem);

/**
* Copy existing contents of ptr to a new memory block of given size.
*
* @param ptr The existing memory block (can be NULL)
* @param size The size of new block (can be smaller or larger than the old one)
*/
extern "C" void* microbit_realloc(void* ptr, size_t size);

#endif
4 changes: 2 additions & 2 deletions inc/core/MicroBitListener.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ DEALINGS IN THE SOFTWARE.

#include "mbed.h"
#include "MicroBitConfig.h"
#include "MicroBitLock.h"
#include "MicroBitEvent.h"
#include "MemberFunctionCallback.h"
#include "MicroBitConfig.h"

// MicroBitListener flags...
#define MESSAGE_BUS_LISTENER_PARAMETERISED 0x0001
Expand Down Expand Up @@ -67,7 +67,7 @@ struct MicroBitListener

MicroBitEvent evt;
MicroBitEventQueueItem *evt_queue;

MicroBitLock lock;
MicroBitListener *next;

/**
Expand Down
66 changes: 66 additions & 0 deletions inc/core/MicroBitLock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
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.
*/

/**
* A simple lock, mostly used for mutual exclusion.
*/

#ifndef MICROBIT_LOCK_H
#define MICROBIT_LOCK_H

#include "MicroBitConfig.h"

class Fiber;

class MicroBitLock
{
private:
bool locked;
Fiber *queue;

public:

/**
* Create a new lock that can be used for mutual exclusion and condition synchronisation.
*/
MicroBitLock();

/**
* Block the calling fiber until the lock is available
**/
void wait();

/**
* Release the lock, and signal to one waiting fiber to continue
*/
void notify();

/**
* Release the lock, and signal to all waiting fibers to continue
*/
void notifyAll();
};

#endif
3 changes: 3 additions & 0 deletions inc/core/NotifyEvents.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,7 @@ DEALINGS IN THE SOFTWARE.
#define MICROBIT_SERIAL_EVT_TX_EMPTY 2
#define MICROBIT_UART_S_EVT_TX_EMPTY 3

// Any values after 1024 are available for application use
#define MICROBIT_NOTIFY_USER_EVENT_BASE 1024

#endif
44 changes: 41 additions & 3 deletions inc/drivers/MicroBitDisplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,15 +288,33 @@ class MicroBitDisplay : public MicroBitComponent
* @param s The string to display.
*
* @param delay The time to delay between characters, in milliseconds. Must be > 0.
* Defaults to: MICROBIT_DEFAULT_PRINT_SPEED.
*
* @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.
*
* @code
* display.printAsync("abc123",400);
* @endcode
*/
int printAsync(ManagedString s, int delay = MICROBIT_DEFAULT_PRINT_SPEED);
int printAsync(ManagedString s, int delay);

/**
* Prints the given ManagedString to the display, one character at a time.
* Returns immediately, and executes the animation asynchronously.
*
* If the string is greater than one charcter in length, the screen
* will be cleared after MICROBIT_DEFAULT_PRINT_SPEED milliseconds.
* Otherwise, that character will be left on the screen indefinitely.
*
* @param s The string to display.
*
* @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.
*
* @code
* display.printAsync("abc123");
* @endcode
*/
int printAsync(ManagedString s);


/**
* Prints the given image to the display, if the display is not in use.
Expand Down Expand Up @@ -352,7 +370,27 @@ class MicroBitDisplay : public MicroBitComponent
* display.print("abc123",400);
* @endcode
*/
int print(ManagedString s, int delay = MICROBIT_DEFAULT_PRINT_SPEED);
int print(ManagedString s, int delay);

/**
* Prints the given string to the display, one character at a time.
*
* Blocks the calling thread until all the text has been displayed.
*
* If the string is greater than one charcter in length, the screen
* will be cleared after MICROBIT_DEFAULT_PRINT_SPEED milliseconds.
* Otherwise, that character will be left on the screen indefinitely.
*
* @param s The string to display.
*
* @return MICROBIT_OK, MICROBIT_CANCELLED or MICROBIT_INVALID_PARAMETER.
*
* @code
* display.print("abc123");
* @endcode
*/
int print(ManagedString s);


/**
* Prints the given image to the display.
Expand Down
Loading