lib_xcore¶
lib_xcore is a system library that provides a C API for the underlying hardware features of an xcore tile. A header file is provided for each functional area, and can be included with a line such as:
#include <xcore/port.h>
By default, lib_xcore is automatically added to the list of libraries for
linking, so there is no need to use xcc -l
.
API Details¶
xcore/assert.h¶
Provides assertions similar to those defined by the standard C assert.h.
Assertions provided by this header are intended by behave similarly to the C standard assert. However by default, when enabled, these macros will expand to ‘hardware assisted’ assertions which cause processor exceptions upon failure. ‘Hardware assisted’ assertions can execute quickly and do not print any diagnostic information. This makes these assertions suitable for applications where small code size is desirable.
The behaviour of the (expansion of) macros defined in this header varies depending on the macros defined at the point it is first included. Specifically:
If
NDEBUG
is defined all assertions will expand to((void)0)
;Otherwise, if
LIBXCORE_XASSERT_IS_ASSERT
is not defined then the assertions will be ‘hardware assisted’ and will trap on failure without printing any diagnostic information;Otherwise (i.e.
LIBXCORE_XASSERT_IS_ASSERT
is defined andNDEBUG
is not) the assertions will be implemented in terms of the C standard libraryassert
.
Defines
-
_XCORE_XASSERT_EMPTY
¶
-
_XCORE_XASSERT_HIDE
(_X)¶
-
_XCORE_XASSERT_NOT_AFTER
(_C)¶
-
_XCORE_XASSERT_TRUE
(_CONDITION)¶
-
_XCORE_XASSERT_FALSE
(_CONDITION)¶
-
xassert
(__condition)¶ Assert that a given expression evaluates true.
Asserts that condition is true (nonzero). The actual behaviour when condition is false depends on the which configuration macros are defined.
- Attention
condition should not have side effects as these will not be executed when assertions are ineffective.
- Parameters
__condition – The expression which is expected to evaluate true
-
xassert_not
(__condition)¶ Assert that a given expression evaluates false.
Asserts that condition is false (0). The actual behaviour when condition is true depends on the which configuration macros are defined.
- Attention
condition should not have side effects as these will not be executed when assertions are ineffective.
- Parameters
__condition – The expression which is expected to evaluate true
-
xassert_not_after
(__timestamp)¶ Assert that the given timestamp is not in the past.
On XS2 and onwards this macro implements a timing assertion based on the reference clock. When
LIBXCORE_XASSERT_IS_ASSERT
is defined an approximation of the ‘hardware’ assert’s condition is used however this may be less accurate as checking the timestamp cannot be performed as a single instruction.The macro LIBXCORE_HAS_TIMING_ASSERTIONS will be defined if and only if this assertion can be effective on the current platform.
- Attention
timestamp should not have side effects as these will not be executed when assertions are ineffective (including when timing assertions are not available on the current platform).
Warning
On XS1 devices this assertion will have no effect.
- Parameters
__timestamp – The timestamp which is expected not to be in the past
xcore/chanend.h¶
Low level channel end API.
- Attention
It is strongly recommended that higher-level ‘channel’ protocols are used e.g. xcore/channel.h or xcore/channel_streaming.h
Typedefs
-
typedef resource_t
chanend_t
¶ Opaque channel end type for use in C/C++ code.
- Attention
Users must not access its raw underlying type.
Functions
-
inline chanend_t
chanend_alloc
()¶ Allocate a single chanend.
If there are no channel ends available the function returns 0.
Note
When the channel end is no longer required, chanend_free() should be called to deallocate it.
- Returns
Allocated chanend (0 if none are available)
-
inline void
chanend_free
(chanend_t __c)¶ Deallocate a single chanend.
- Attention
The last transfer on the chanend must have been a CT_END token.
- Parameters
__c – chanend to free.
- Throws
ET_ILLEGAL_RESOURCE – not an allocated chanend, an input/output is pending, or it has not received/sent a CT_END token.
ET_RESOURCE_DEP – another core is actively using the chanend.
-
inline void
chanend_set_dest
(chanend_t __c, chanend_t __dst)¶ Set the destination of a chanend.
- Parameters
__c – chanend to set.
__dst – Destination chanend.
- Throws
ET_ILLEGAL_RESOURCE – not an allocated chanend.
ET_RESOURCE_DEP – another core is actively using the chanend.
-
inline void
chanend_out_end_token
(resource_t __c)¶
-
inline void
chanend_check_end_token
(resource_t __c)¶
xcore/channel_streaming.h¶
Streaming channel API.
Functions
-
inline streaming_channel_t
s_chan_alloc
()¶ Allocate a streaming channel by allocating two hardware chan-ends and joining them.
If there are not enough chan-ends available the function returns a streaming_channel_t with both fields set to 0.
- Attention
The chan-ends must be accessed on the same tile
Note
When the streaming_channel_t is no longer required, s_chan_free() should be called to deallocate it.
- Returns
streaming_channel_t variable holding the two initialised and joined chan-ends or 0s.
-
inline void
s_chan_free
(streaming_channel_t __c)¶ Deallocate a streaming_channel_t by freeing its two hardware chan-ends.
- Parameters
__c – streaming_channel_t to free.
- Throws
ET_LINK_ERROR – a chan-end destination is not set.
ET_ILLEGAL_RESOURCE – not an allocated channel, or an input/output is pending.
ET_RESOURCE_DEP – another core is actively using the channel.
-
inline void
s_chan_out_word
(chanend_t __c, uint32_t __data)¶ Output a word over a streaming_channel_t.
- Parameters
__c – The streaming chan-end
__data – The word to be output
- Throws
ET_LINK_ERROR – chan-end destination is not set.
ET_ILLEGAL_RESOURCE – not an allocated chan-end.
ET_RESOURCE_DEP – another core is actively using the chan-end.
-
inline void
s_chan_out_byte
(chanend_t __c, uint8_t __data)¶ Output an byte over a streaming_channel_t.
- Parameters
__c – The streaming chan-end
__data – The byte to be output
- Throws
ET_LINK_ERROR – chan-end destination is not set.
ET_ILLEGAL_RESOURCE – not an allocated chan-end.
ET_RESOURCE_DEP – another core is actively using the chan-end.
-
inline void
s_chan_out_buf_word
(chanend_t __c, const uint32_t __buf[], size_t __n)¶ Output a block of data over a streaming_channel_t.
- Parameters
__c – The streaming chan-end
__buf – A pointer to the buffer containing the data to send
__n – The number of words to send
- Throws
ET_LINK_ERROR – chan-end destination is not set.
ET_ILLEGAL_RESOURCE – not an allocated chan-end.
ET_RESOURCE_DEP – another core is actively using the chan-end.
ET_LOAD_STORE – invalid buf[] argument.
-
inline void
s_chan_out_buf_byte
(chanend_t __c, const uint8_t __buf[], size_t __n)¶ Output a block of data over a streaming_channel_t.
- Parameters
__c – The streaming chan-end
__buf – A pointer to the buffer containing the data to send
__n – The number of bytes to send
- Throws
ET_LINK_ERROR – chan-end destination is not set.
ET_ILLEGAL_RESOURCE – not an allocated chan-end.
ET_RESOURCE_DEP – another core is actively using the chan-end.
ET_LOAD_STORE – invalid buf[] argument.
-
inline uint32_t
s_chan_in_word
(chanend_t __c)¶ Input a word from a streaming_channel_t.
- Parameters
__c – The streaming chan-end
- Throws
ET_ILLEGAL_RESOURCE – not an allocated chan-end, or has pending control token.
ET_RESOURCE_DEP – another core is actively using the chan-end.
- Returns
The word read from the channel
-
inline uint8_t
s_chan_in_byte
(chanend_t __c)¶ Input a byte from a streaming_channel_t.
- Parameters
__c – The streaming chan-end
- Throws
ET_ILLEGAL_RESOURCE – not an allocated chan-end, or has pending control token.
ET_RESOURCE_DEP – another core is actively using the chan-end.
- Returns
The byte read from the channel
-
inline void
s_chan_in_buf_word
(chanend_t __c, uint32_t __buf[], size_t __n)¶ Input a block of data from a streaming_channel_t.
- Parameters
__c – The streaming chan-end
__buf – A pointer to the memory region to fill
__n – The number of words to receive
- Throws
ET_ILLEGAL_RESOURCE – not an allocated chan-end, or has pending control token.
ET_RESOURCE_DEP – another core is actively using the chan-end.
ET_LOAD_STORE – invalid buf[] argument.
-
inline void
s_chan_in_buf_byte
(chanend_t __c, uint8_t __buf[], size_t __n)¶ Input a block of data from a streaming_channel_t.
- Parameters
__c – The streaming chan-end
__buf – A pointer to the memory region to fill
__n – The number of bytes to receive
- Throws
ET_ILLEGAL_RESOURCE – not an allocated chan-end, or has pending control token.
ET_RESOURCE_DEP – another core is actively using the chan-end.
ET_LOAD_STORE – invalid buf[] argument.
-
struct
streaming_channel_t
¶ - #include <channel_streaming.h>
xcore/channel_transaction.h¶
API for transaction-based channel communications.
Typedefs
-
typedef __xcore_transacting_chanend_t
transacting_chanend_t
¶ An opaque type for handling transactions.
Users must not access its raw underlying type.
Functions
-
inline transacting_chanend_t
chan_init_transaction_master
(chanend_t __c)¶ Start a transaction (master).
This initiates a transaction on a channel.
A transacting_chanend_t is used to temporarily open a transaction route through a channel. During the transaction, you can use transaction channel operations for increased efficiency. You can create a transacting chanend from a normal chanend using chan_init_transaction_master() and chan_init_transaction_slave().
This called must be matched by a call to chan_init_transaction_slave() on the other end of the channel.
Note
A transaction must be closed with chan_complete_transaction().
- Parameters
__c – chan-end to initialize the transaction on.
- Throws
ET_LINK_ERROR – chan-end destination is not set.
ET_ILLEGAL_RESOURCE – not an allocated chan-end.
ET_RESOURCE_DEP – another core is actively using the chan-end.
- Returns
the intialized master transacting_chanend_t
-
inline transacting_chanend_t
chan_init_transaction_slave
(chanend_t __c)¶ Start a transaction (slave).
This call must be matched by a call to chan_init_transaction_master() on the other end of the channel.
Note
A transaction must be closed with chan_complete_transaction().
Warning
The original channed c must not be used until the transaction is closed.
- Parameters
__c – chan-end to initialize the transaction on. chanend is invalidated
- Throws
ET_ILLEGAL_RESOURCE – not an allocated chan-end, or does not contain CT_END token.
ET_RESOURCE_DEP – another core is actively using the chan-end.
- Returns
the intialized slave transacting_chanend_t
-
inline chanend_t
chan_complete_transaction
(transacting_chanend_t __tc)¶ Completes a transaction. After this call the route between the two ends of the channel is freed allowing other channels to use the communication network.
Whilst the transacting_chanend_t is now invalid, the channel remains allocated, awaiting another transaction or deallocation.
Note
This call must be accompanied by a call to chan_complete_transaction() on the other end of the channel.
- Parameters
__tc – Transacting chan-end to close.
- Throws
ET_LINK_ERROR – chan-end destination is not set.
ET_ILLEGAL_RESOURCE – not an allocated chan-end, or channel handshaking corrupted.
ET_RESOURCE_DEP – another core is actively using the chan-end.
- Returns
The original chan-end which is valid once again.
-
inline void
t_chan_out_word
(transacting_chanend_t *__tc, uint32_t __data)¶ Output a word over a transacting chan-end.
- Parameters
__tc – [inout] Transacting chan-end
__data – Word to be output
- Throws
ET_LINK_ERROR – chan-end destination is not set.
ET_ILLEGAL_RESOURCE – not an allocated chan-end, or channel handshaking corrupted.
ET_RESOURCE_DEP – another core is actively using the chan-end.
ET_LOAD_STORE – invalid tc argument.
-
inline void
t_chan_out_byte
(transacting_chanend_t *__tc, uint8_t __data)¶ Output an byte over a transacting chan-end.
- Parameters
__tc – [inout] Transacting chan-end
__data – Byte to be output
- Throws
ET_LINK_ERROR – chan-end destination is not set.
ET_ILLEGAL_RESOURCE – not an allocated chan-end, or channel handshaking corrupted.
ET_RESOURCE_DEP – another core is actively using the chan-end.
ET_LOAD_STORE – invalid tc argument.
-
inline void
t_chan_out_buf_word
(transacting_chanend_t *__tc, const uint32_t __buf[], size_t __n)¶ Output a block of data over a transacting chan-end.
- Parameters
__tc – [inout] Transacting chan-end
__buf – [in] Pointer to the buffer containing the data to send
__n – Number of words to send
- Throws
ET_LINK_ERROR – chan-end destination is not set.
ET_ILLEGAL_RESOURCE – not an allocated chan-end, or channel handshaking corrupted.
ET_RESOURCE_DEP – another core is actively using the chan-end.
ET_LOAD_STORE – invalid tc or buf[] argument.
-
inline void
t_chan_out_buf_byte
(transacting_chanend_t *__tc, const uint8_t __buf[], size_t __n)¶ Output a block of data over a transacting chan-end.
- Parameters
__tc – [inout] Transacting chan-end
__buf – [in] Pointer to the buffer containing the data to send
__n – Number of bytes to send
- Throws
ET_LINK_ERROR – chan-end destination is not set.
ET_ILLEGAL_RESOURCE – not an allocated chan-end, or channel handshaking corrupted.
ET_RESOURCE_DEP – another core is actively using the chan-end.
ET_LOAD_STORE – invalid tc or buf[] argument.
-
inline uint32_t
t_chan_in_word
(transacting_chanend_t *__tc)¶ Input a word from a transacting chan-end.
- Parameters
__tc – [inout] Transacting chan-end
- Throws
ET_LINK_ERROR – chan-end destination is not set.
ET_ILLEGAL_RESOURCE – not an allocated chan-end, or channel handshaking corrupted.
ET_RESOURCE_DEP – another core is actively using the chan-end.
ET_LOAD_STORE – invalid tc argument.
- Returns
Word read from tc
-
inline uint8_t
t_chan_in_byte
(transacting_chanend_t *__tc)¶ Input a byte from a transacting chan-end.
- Parameters
__tc – [inout] Transacting chan-end
- Throws
ET_LINK_ERROR – chan-end destination is not set.
ET_ILLEGAL_RESOURCE – not an allocated chan-end, or channel handshaking corrupted.
ET_RESOURCE_DEP – another core is actively using the chan-end.
ET_LOAD_STORE – invalid tc or data argument.
- Returns
Byte read from tc
-
inline void
t_chan_in_buf_word
(transacting_chanend_t *__tc, uint32_t __buf[], size_t __n)¶ Input a block of data from a transacting chan-end.
- Parameters
__tc – [inout] Transacting chan-end
__buf – [in] Pointer to the memory region to fill
__n – The number of words to receive
- Throws
ET_LINK_ERROR – chan-end destination is not set.
ET_ILLEGAL_RESOURCE – not an allocated chan-end, or channel handshaking corrupted.
ET_RESOURCE_DEP – another core is actively using the chan-end.
ET_LOAD_STORE – invalid tc or buf[] argument.
-
inline void
t_chan_in_buf_byte
(transacting_chanend_t *__tc, uint8_t __buf[], size_t __n)¶ Input a block of data from a transacting chan-end.
- Parameters
__tc – [inout] Transacting chan-end
__buf – [in] Pointer to the memory region to fill
__n – The number of bytes to receive
- Throws
ET_LINK_ERROR – chan-end destination is not set.
ET_ILLEGAL_RESOURCE – not an allocated chan-end, or channel handshaking corrupted.
ET_RESOURCE_DEP – another core is actively using the chan-end.
ET_LOAD_STORE – invalid __tc or __buf argument.
xcore/channel.h¶
API for channel communications.
Typedefs
-
typedef streaming_channel_t
channel_t
¶ Helper type for passing around both ends of a channel.
Functions
-
inline channel_t
chan_alloc
()¶ Allocates a channel by allocating two hardware chan-ends and joining them.
If there are not enough chan-ends available the function returns a channel_t with both fields set to 0.
Note
When the channel_t is no longer required, chan_free() should be called to deallocate it.
Warning
The chan-ends must be accessed on the same tile.
- Returns
The channel_t (both fields will be 0 if allocation was not possible)
-
inline void
chan_free
(channel_t __c)¶ Deallocate a channel by freeing its constituent chan-ends.
- Parameters
__c – channel_t to free
- Throws
ET_ILLEGAL_RESOURCE – not an allocated chan-end, or channel handshaking corrupted.
ET_RESOURCE_DEP – another core is actively using the chanend.
-
inline void
chan_out_word
(chanend_t __c, uint32_t __data)¶ Output a word over a channel.
- Parameters
__c – The chan-end
__data – The word to be output
- Throws
ET_LINK_ERROR – chan-end destination is not set.
ET_ILLEGAL_RESOURCE – not an allocated chan-end, or channel handshaking corrupted.
ET_RESOURCE_DEP – another core is actively using the chan-end.
-
inline void
chan_out_byte
(chanend_t __c, uint8_t __data)¶ Output a byte over a channel.
- Parameters
__c – The chan-end
__data – The byte to be output
- Throws
ET_LINK_ERROR – chan-end destination is not set.
ET_ILLEGAL_RESOURCE – not an allocated chan-end, or channel handshaking corrupted.
ET_RESOURCE_DEP – another core is actively using the chan-end.
-
inline void
chan_out_buf_word
(chanend_t __c, const uint32_t __buf[], size_t __n)¶ Output a block of data over a channel.
- Parameters
__c – The chan-end
__buf – [in] A pointer to the buffer containing the data to send
__n – The number of words to send
- Throws
ET_LINK_ERROR – chan-end destination is not set.
ET_ILLEGAL_RESOURCE – not an allocated chan-end, or channel handshaking corrupted.
ET_RESOURCE_DEP – another core is actively using the chan-end.
ET_LOAD_STORE – invalid buf[] argument.
-
inline void
chan_out_buf_byte
(chanend_t __c, const uint8_t __buf[], size_t __n)¶ Output a block of data over a channel.
- Parameters
__c – The chan-end
__buf – [in] A pointer to the buffer containing the data to send
__n – The number of bytes to send
- Throws
ET_LINK_ERROR – chan-end destination is not set.
ET_ILLEGAL_RESOURCE – not an allocated chan-end, or channel handshaking corrupted.
ET_RESOURCE_DEP – another core is actively using the chan-end.
ET_LOAD_STORE – invalid buf[] argument.
-
inline uint32_t
chan_in_word
(chanend_t __c)¶ Input a word from a channel.
- Parameters
__c – The chan-end
- Throws
ET_ILLEGAL_RESOURCE – not an allocated chan-end, or channel handshaking corrupted.
ET_RESOURCE_DEP – another core is actively using the chan-end.
ET_LOAD_STORE – invalid **data* argument.
- Returns
The word which was read from the channel
-
inline uint8_t
chan_in_byte
(chanend_t __c)¶ Input a byte from a channel.
- Parameters
__c – The chan-end
- Throws
ET_ILLEGAL_RESOURCE – not an allocated chan-end, or channel handshaking corrupted.
ET_RESOURCE_DEP – another core is actively using the chan-end.
ET_LOAD_STORE – invalid **data* argument.
- Returns
The byte which was read from the channel
-
inline void
chan_in_buf_word
(chanend_t __c, uint32_t __buf[], size_t __n)¶ Input a block of data from a channel.
- Parameters
__c – The chan-end
__buf – [out] A pointer to the memory region to fill
__n – The number of words to receive
- Throws
ET_ILLEGAL_RESOURCE – not an allocated chan-end, or channel handshaking corrupted.
ET_RESOURCE_DEP – another core is actively using the chan-end.
ET_LOAD_STORE – invalid buf[] argument.
-
inline void
chan_in_buf_byte
(chanend_t __c, uint8_t __buf[], size_t __n)¶ Input a block of data from a channel.
- Parameters
__c – The chan-end
__buf – [out] A pointer to the memory region to fill
__n – The number of bytes to receive
- Throws
ET_ILLEGAL_RESOURCE – not an allocated chan-end, or channel handshaking corrupted.
ET_RESOURCE_DEP – another core is actively using the chan-end.
ET_LOAD_STORE – invalid buf[] argument.
xcore/clock.h¶
Hardware clock API.
Typedefs
-
typedef resource_t
xclock_t
¶ Clock handle type.
Functions
-
inline void
clock_enable
(xclock_t __id)¶ Enables a specified clock block so that it may be used.
Should be called before any other operations are performed on the given
id
. When the clock is no longer required is should be disabled again with clock_disable().- Parameters
__id – The id of the clock to enable
- Throws
ET_ILLEGAL_RESOURCE – not a valid clock.
ET_RESOURCE_DEP – another core is actively changing the clock.
-
inline void
clock_disable
(xclock_t __clk)¶ Disable a clock.
/note Once disabled, a the clock must be re-enabled using clock_enable() before it can be used again.
- Parameters
__clk – The clock to be disabled
- Throws
ET_ILLEGAL_RESOURCE – not a valid clock.
ET_RESOURCE_DEP – another core is actively changing the clock.
-
inline void
clock_start
(xclock_t __clk)¶ Start a clock.
- Parameters
__clk – The clock to start running
- Throws
ET_ILLEGAL_RESOURCE – not a valid clock.
ET_RESOURCE_DEP – another core is actively changing the clock.
-
inline void
clock_stop
(xclock_t __clk)¶ Stop a clock.
Waits until the clock is low and then pauses a clock.
- Parameters
__clk – The clock to stop
- Throws
ET_ILLEGAL_RESOURCE – not a valid clock.
ET_RESOURCE_DEP – another core is actively changing the clock.
-
inline void
clock_set_source_port
(xclock_t __clk, resource_t __p)¶ Configure a clock’s source to a 1-bit port.
A clock can be a 1-bit port, the reference clock or the xCORE clock. Note that if the xCORE clock is used then a non-zero divide must be used for ports to function correctly.
- Parameters
__clk – The clock to configure
__p – The 1-bit port to set as the clock input. Attempting to set a port which is not 1-bit as the input will cause an exception.
- Throws
ET_ILLEGAL_RESOURCE – not a valid clock or port, or the clock is running, or p not a one bit port.
ET_RESOURCE_DEP – another core is actively changing the clock.
-
inline void
clock_set_source_clk_ref
(xclock_t __clk)¶ Configure a clock’s source to be the 100MHz reference clock.
- Parameters
__clk – The clock to configure
- Throws
ET_ILLEGAL_RESOURCE – not a valid clock, or the clock is running.
ET_RESOURCE_DEP – another core is actively changing the clock.
-
inline void
clock_set_source_clk_xcore
(xclock_t __clk)¶ Configure a clock’s source to be the xCORE clock.
Note
When using the xCORE clock as the clock input a divide of > 0 must be used for the ports to function correclty.
- Parameters
__clk – The clock to configure
- Throws
ET_ILLEGAL_RESOURCE – not a valid clock, or the clock is running.
ET_RESOURCE_DEP – another core is actively changing the clock.
-
inline void
clock_set_divide
(xclock_t __clk, uint8_t __divide)¶ Configure the divider for a clock.
A clock can divide its input signal by an integer value which this function specifies. The XS2 architecture supports dividing the signal from a 1-bit port while the XS1 architecture will raise a trap if a non-zero divide is used with a 1-bit port input.
If the divide is 0 then the value signal will be passed through the clock. If the value is non-zero then the clock output will be divided by 2*divide.
Warning
If the clock has been started then this will raise a trap.
- Parameters
__clk – The clock to configure
__divide – The divide value
- Throws
ET_ILLEGAL_RESOURCE – not a valid clock, or the clock is running.
ET_RESOURCE_DEP – another core is actively changing the clock.
-
inline void
clock_set_ready_src
(xclock_t __clk, resource_t __ready_source)¶ Sets a clock to use a 1-bit port for the ready-in signal.
If the port is not a 1-bit port then an exception is raised. The ready-in port controls when data is sampled from the pins.
- Parameters
__clk – The clock to configure.
__ready_source – The 1-bit port to use for the ready-in signal.
- Throws
ET_ILLEGAL_RESOURCE – not a valid clock, or ready_source not a one bit port.
ET_RESOURCE_DEP – another core is actively changing the clock.
xcore/hwtimer.h¶
API for using hardware timers to measure and wait time.
Typedefs
-
typedef resource_t
hwtimer_t
¶ brief Hardware timer handle type.
Functions
-
inline void
hwtimer_free_xc_timer
(void)¶ Deallcoates the hardware timer automatically allocated.
for xC use. Each logical core is allocated a hardware timer that is multiplexed and used by the xC ‘timer’ interface. This multiplexed timer is not accessible from C. If the logical core is not running any xC code, or any xC code is not making use of the ‘timer’ resource type, the allocated hardware timer may be retrieved for use as a hwtimer_t.
Note
This call must be paired with a call to hwtimer_realloc_xc_timer() prior to the logical core completing its tasks.
Note
The xScope link also requires a hardware timer.
- Throws
ET_ILLEGAL_RESOURCE – timer has already been deallocated.
-
inline void
hwtimer_realloc_xc_timer
(void)¶ Reallcoates a logical core’s xC hardware timer that was.
deallocated by a call to hwtimer_free_xc_timer().
- Attention
There must be an available hw timer when this call is made, otherwise a trap will be raised.
- Throws
ET_ECALL – no available hw timer, reallocation failed.
-
inline hwtimer_t
hwtimer_alloc
(void)¶ Allocates a hardware timer.
If there are no timers available then 0 is returned.
Note
When the timer is no longer required, hwtimer_free() should be called to deallocate it.
- Returns
Timer handle to the allocated timer
-
inline void
hwtimer_free
(hwtimer_t __t)¶ Deallocate a timer.
- Parameters
__t – The timer to be freed
- Throws
ET_ILLEGAL_RESOURCE – not an allocated timer.
ET_RESOURCE_DEP – another core is actively using the timer.
-
inline uint32_t
hwtimer_get_time
(hwtimer_t __t)¶ Get the current time from the timer.
If there is a trigger time setup, the call will stall until after the trigger time. For select and interrupt event, calling hwtimer_get_time() will clear the event.
- Parameters
__t – The timer to read
- Throws
ET_ILLEGAL_RESOURCE – not an allocated timer.
ET_RESOURCE_DEP – another core is actively using the timer.
- Returns
The time value (a 32-bit value)
-
inline uint32_t
hwtimer_get_trigger_time
(hwtimer_t __t)¶ Get the trigger time value.
The trigger time value is set using hwtimer_set_trigger_time(). The trigger may be cleared using hwtimer_clear_trigger_time().
- Parameters
__t – The timer whose time value is requested.
- Throws
ET_ILLEGAL_RESOURCE – not a valid timer.
ET_RESOURCE_DEP – another core is actively using the timer.
- Returns
The time value
-
inline void
hwtimer_set_trigger_time
(hwtimer_t __t, uint32_t __time)¶ Setup an event trigger on a timer.
Note
This will cause hwtimer_get_time() to pause until the specified time. The trigger may be cleared using hwtimer_clear_trigger_time().
Note
hwtimer_wait_until(), hwtimer_delay(), hwtimer_setup_select() and hwtimer_setup_select_callback() call hwtimer_set_trigger_time()
- Parameters
__t – The timer to setup a event trigger on.
__time – The time at which the timer will trigger an event. The default timer ticks are at a 10ns resolution.
- Throws
ET_ILLEGAL_RESOURCE – not a valid timer.
ET_RESOURCE_DEP – another core is actively using the timer.
-
inline void
hwtimer_change_trigger_time
(hwtimer_t __t, uint32_t __time)¶ Change the time at which a timer trigger will fire.
This function modifies the time at which a previously setup trigger fires. It is used to set a new trigger time after a select or interrupt event has occurred.
- Parameters
__t – The timer to change
__time – The time at which the timer will trigger an event. The default timer ticks are at a 10ns resolution.
- Throws
ET_ILLEGAL_RESOURCE – not a valid timer.
ET_RESOURCE_DEP – another core is actively using the timer.
-
inline void
hwtimer_clear_trigger_time
(hwtimer_t __t)¶ Clear an event trigger on a timer.
Makes sure no triggers are setup on a timer. Should be called when a timer is no longer being used for select and interrupt events.
Note
Both hwtimer_wait_until() and hwtimer_delay() call hwtimer_clear_trigger_time().
- Parameters
__t – The timer to tear down events on
- Throws
ET_ILLEGAL_RESOURCE – not a valid timer.
ET_RESOURCE_DEP – another core is actively using the timer.
-
inline uint32_t
hwtimer_wait_until
(resource_t __t, uint32_t __until)¶ Wait until after a specified time.
- Attention
This will destroy any select or interrupt event triggers set on this resource.
- Parameters
__t – The timer to use for timing
__until – The time to wait until
- Throws
ET_ILLEGAL_RESOURCE – not an allocated timer.
ET_RESOURCE_DEP – another core is actively using the timer.
- Returns
The time we actually waited until
-
inline void
hwtimer_delay
(resource_t __t, uint32_t __period)¶ Delay for a specified time using a specific timer.
- Attention
This will destroy any select or interrupt event triggers set on this resource
- Parameters
__t – The timer resource to use
__period – The amount of time to wait (in reference time ticks, usually 10ns steps)
- Throws
ET_ILLEGAL_RESOURCE – not an allocated timer.
ET_RESOURCE_DEP – another core is actively using the timer.
ET_LOAD_STORE – invalid **now* argument.
-
inline uint32_t
get_reference_time
(void)¶ get the chip reference time
Gets the current reference time without requiring an allocated timer on chips where a reference time is available. This can be tested with LIBXCORE_HWTIMER_HAS_REFERENCE_TIME which will be defined if and only if a refence time is available. If no reference time is available then 0 is returned.
- Returns
The reference time
xcore/interrupt_wrappers.h¶
Helpers for implementing interrupt-enabled functions.
Defines
-
LIBXCORE_KSTACK_WORDS
¶ Specify the minimum kernel stack size the interrupt permitting function should create.
The user may specify a minimum kstack size by setting the LIBXCORE_KSTACK_WORDS define in their Makefile. This should be done when the kstack is being used by more than interrupt_callback_t functions.
-
DEFINE_INTERRUPT_PERMITTED
(__group, __ret, __root_function, ...)¶ Define a function that allows interrupts to occur within its scope.
This macro will define two functions for you:
An ordinary function that may be called directly Its signature will be
( ... )
A function that will also reserve space for and set up a stack for handling interrupts. The function name is accessed using the INTERRUPT_PERMITTED() macro
You would normally use this macro on the definition of the root function which will be called in a par statement. The interrupt stack (kernel stack) is created on the core’s stack with the ksp and sp being modified as necessary. When the functions exits, neither the kernel stack nor ksp is valid.
The kernel stack allocated has enough space for the interrupt_callback_t function (+callees) in the given group. The use of the group identifier allows a kernel stack to be no larger than that required by its greediest member.
The user may specify a larger kernel stack by defining LIBXCORE_KSTACK_WORDS.
Example usage:
DEFINE_INTERRUPT_PERMITTED(groupA, int, rootfunc, chanend c, int i) { // This is the body of 'int rootfunc(chanend c, int i)' }
Warning
The kernel stack is not re-entrant so kernel mode must not be masked from within an interrupt_callback_t
- Parameters
__group – this is the group of interrupt_callback_t function that may be safely enabled - see DEFINE_INTERRUPT_CALLBACK()
__ret – the return type of the ordinary function
__root_function – the name of the ordinary function
... – the arguments of the ordinary function
-
DECLARE_INTERRUPT_PERMITTED
(__ret, __root_function, ...)¶ Declare an interrupt permitting function.
Use this macro when you require a declaration of your interrupt permitting function types
Example usage:
// In another file: // DEFINE_INTERRUPT_PERMITTED(groupA, int, rootfunc, chanend c, int i) // DEFINE_INTERRUPT_PERMITTED(groupB, void, anotherfunc, void) DECLARE_INTERRUPT_PERMITTED(int, rootfunc, chanend c, int i); DECLARE_INTERRUPT_PERMITTED(void, anotherfunc, void); ... par { int ret = INTERRUPT_PERMITTED(rootfunc)(c,i); // kstack for groupA. INTERRUPT_PERMITTED(anotherfunc)(); // kstack for groupB.
- Parameters
__ret – the return type of the ordinary function
__root_function – the name of the ordinary function
... – the arguments of the ordinary function
-
INTERRUPT_PERMITTED
(__root_function)¶ The name of the defined interrupt permitting function.
Use this macro for retriving the name of the declared interrupt function. This is the name used to invoke the function.
- Returns
the name of the defined interrupt permitting function
-
DEFINE_INTERRUPT_CALLBACK
(__group, __intrpt, __data)¶ Define an interrupt handling function.
This macro will define two functions for you:
An ordinary function that may be called directly Its signature will be
void ( void* )
An interrupt_callback_t function for passing to a res_setup_interrupt_callback function. The interrupt_callback_t function name is accessed using the INTERRUPT_CALLBACK() macro
Example usage:
DEFINE_INTERRUPT_CALLBACK(groupA, myfunc, arg) { // This is the body of 'void myfunc(void* arg)' }
Warning
The kernel stack is not re-entrant so kernel mode must not be masked from within an interrupt_callback_t
- Parameters
__group – the group of interrupt_callback_t function we belong to see DEFINE_INTERRUPT_PERMITTED()
__intrpt – this is the name of the ordinary function
__data – the name to use for the void* argument
-
DECLARE_INTERRUPT_CALLBACK
(__intrpt, __data)¶ Declare an interrupt handling function.
Use this macro when you require a declaration of your interrupt function types
Example usage:
DECLARE_INTERRUPT_CALLBACK(myfunc, arg); chanend_setup_interrupt_callback(c, 0 , INTERRUPT_CALLBACK(myfunc));
- Parameters
__intrpt – this is the name of the ordinary function
__data – the name to use for the void* argument
-
INTERRUPT_CALLBACK
(__intrpt)¶ The name of the defined
interrupt_callback_t
function.Use this macro for retriving the name of the declared interrupt callback function. This is the name that is passed to
*_setup_interrupt_callback
() for registration.- Returns
the name of the defined interrupt_callback_t function
xcore/interrupt.h¶
API for configuring interrupts.
Functions
-
inline void
interrupt_mask_all
(void)¶ Mask all interrupts on this logical core.
Prevent any enabled triggerable_setup_interrupt_callback() functions from triggering. This has no effect on TRIGGERABLE_SETUP_EVENT_VECTOR() triggering. They can be restored by using interrupt_unmask_all().
-
inline void
interrupt_unmask_all
(void)¶ Unmask all interrupts on this logical core.
Allow triggerable_setup_interrupt_callback() functions to trigger. They can be suppressed by using interrupt_mask_all().
xcore/lock.h¶
provides hardware-based locking
Typedefs
-
typedef resource_t
lock_t
¶ Hardware lock handle type.
Functions
-
inline lock_t
lock_alloc
()¶ Allocates a lock.
If there are no locks availble the function returns 0.
Note
When the lock is no longer required, lock_free() must be called to deallocate it.
- Returns
handle for the allocated lock, 0 is no locks were available
-
inline void
lock_free
(lock_t __l)¶ Deallocates a given lock.
The lock must be released prior to calling this function.
- Parameters
__l – The lock_t to be freed
- Throws
ET_ILLEGAL_RESOURCE – not an allocated lock, or the lock has not been released.
ET_RESOURCE_DEP – another core is actively changing the lock.
ET_LOAD_STORE – invalid l argument.
-
inline void
lock_acquire
(lock_t __l)¶ Acquire a lock.
Only one core at a time can acquire a lock. This provides a hardware mutex which have very low overheads. If another thread has already acquired this lock then this function will pause until the lock is released and this core becomes the owner.
- Parameters
__l – The lock_t to acquire
- Throws
ET_ILLEGAL_RESOURCE – not an allocated lock.
ET_RESOURCE_DEP – another core is actively changing the lock.
-
inline void
lock_release
(lock_t __l)¶ Release a lock.
Releases the lock and allocates the next owner from the list of waiting cores in round-robin manner.
Note
There are no checks that the core releasing the lock is the current owner.
- Parameters
__l – The lock_t to use release
- Throws
ET_ILLEGAL_RESOURCE – not an allocated lock.
ET_RESOURCE_DEP – another core is actively changing the lock.
xcore/minicache.h¶
Cache maintenance interface for the XS3 MiniCache.
The minicache is fully associative and consists of a small number of naturally aligned lines. The minicache caches all reads and writes to and from software memory and external RAM. A single read or write can cause up to two lines to be filled or evicted (in the case that the address range affected spans multiple lines). When there are insufficient lines free to service a fill then allocated lines will be evicted, up to the number of lines to be filled. Evicted lines are chosen based a ‘psuedo leaast recently used’ algorithm.
Flush and invlidate operations queue until the cache is idle (i.e. until all ongoing fills and evicts have finished). During this wait, and whilst the operation completes, all new loads and stores through the cache will block.
This header is only available when targeting platforms with a compatible cache.
Functions
-
inline void
minicache_prefetch
(volatile const void *__address)¶ Prefetch an address into the cache without blocking.
Begins filling a cache line corresponding to the given __address. The address must be word-aligned and within a read-enabled region. If the region is an ‘uncached’ one (e.g. RAM) then this has no effect. If the address is cache line-aligned then a single line will be filled, otherwise the line corresponding to the address will be prefetched and additionally the next line in the address space (if such a line would have a valid address).
For each line prefetched:
If the address is already in the cache then no action is taken;
Otherwise, a fill is started for that line;
If there is not an available (unallocated) cache line, then an allocated one will be evicted before the fill can begin.
If the address does not correspond to a valid region, is not word aligned, or is within a region for which filling is disabled then a trap will occur.
- Parameters
__address – The address to prefetch
-
inline void
minicache_flush
(void)¶ Flush all dirty data in the cache back to its respective memory.
Sets a flush operation waiting on the cache. This will wait for all ongoing fills and then write all dirty lines back to their respective memories. The data remains in the cache, however its dirty state is cleared. During the flush operation (and whilst waiting to start it) all access to cached memory is blocking.
Note
If an invalidate operation is already waiting when a flush is queued, it is unspecified which will execute first.
-
inline void
minicache_invalidate
(void)¶ Invalidates all data in the cache.
Sets a flush operation waiting on the cache. This will wait for all ongoing fills and then write all dirty lines back to their respective memories. The data remains in the cache however its dirty state is cleared. During the flush operation (and whilst waiting to start it) all access to cached memory is blocking.
/note If a flush is queued before an invlidate has completed it is unspecified which will execute first.
/warning This may cause the observed value at a cached address to change.
xcore/parallel.h¶
Helper macros for fork/join style parallel execution.
Defines
-
PAR_FUNCS
(...)¶ Calls a list of
void (void*)
functions with each utilising a different hardware thread.Expands to a block which evaluates each of the given function call descriptions such that each runs in a different thread. For each
PFUNC
, a stack ofSTACK_SIZE
words will be allocated from the current stack and used to callFUNCTION
withARGUMENT
as its sole argument. The block is blocking until all function calls have returned.
Example:
PAR_FUNCS(PFUNC(my_print_function, "Hello 1"), PFUNC(my_print_function, "Hello 2"));
- See
Note
One function call will be evaluated in the current thread.
- Parameters
... – Functions to call, each the result of expanding
PFUNC
-
PFUNC
(_FUNCTION, _ARGUMENT)¶ Specifies a parallelised function call.
Expands to a function call desciption which can be used as an argument to PAR_FUNCS.
- See
- Parameters
_FUNCTION – a function with siganture
void (void *)
_ARGUMENT – the argument to pass to _FUNCTION - must be implicitly convertible to
void *
-
DECLARE_JOB
(_NAME, _ARG_TYPES_PACK)¶ Declare a
void
function with arbitrary functions which can be dispatched in another thread.Expands to the declaration of a function named _NAME
and additional definitions required to execute that function in a different thread.
The
_ARG_TYPES_PACK parameter must be a comma-separated sequence of permitted types, permitted types may be:A type specifier with optional qualification (e.g.
int
,const unsigned
,enum my_enum
). In the case of an enum, union or struct a declaration list must not be included.An (optionally qualified) pointer to a permitted type.
void
in which case this must be the only parameter and the parameter pack must be exactly(void) (i.e. an alias of
void
must not be used).Example:
DECLARE_JOB(thread_sum, (const unsigned *, size_t, unsigned long *)); void thread_sum(const unsigned * const ints, const size_t number, unsigned long * const result) { unsigned long sum = 0; for (size_t i = 0; i < number; i += 1) { sum += ints[i]; } *result = sum; }
Note
These restrictions mean that array types and pointer-to-function types may not appear in a parameter pack. However, typedefs of these types are allowed.
- Parameters
_NAME – Name of function to declare
_ARG_TYPES_PACK – A pack of type specifiers which form the parameter part of the function signature (must not include names)
-
PAR_JOBS
(...)¶ Calls a list of functions declared using DECLARE_JOB in parallel.
Expands to a block which executes each of the given function call specifications such that each call takes place in a different hardward thread. Each call specification should be the result of expanding PJOB and the
FUNCTION
should be one which was declared using DECLARE_JOB. Each thread’s stack will beSSIZE
words (as passed to DECLARE_JOB) in size and will be allocated from the current stack. Each function will execute as if calledFUNCTION
ARGPACK
; had been executed in its assigned thread. The block is blocking until all functions have returned.Example:
unsigned long sum1, sum2; PAR_JOBS(PJOB(thread_sum, (ints1, ints1_length, &sum1)), PJOB(thread_sum, (ints2, ints2_length, &sum2)));
- See
Note
One function call will be evaluated in the current thread.
- Parameters
... – Function call specifications as expanded from PJOB.
-
PJOB
(_FUNCTION, _ARGPACK)¶ Specifies a parallelised call of a function declared with DECLARE_JOB.
Expands to a function call desciption which can be used as an argument to PAR_JOBS.
- See
- Parameters
_FUNCTION – a function which was declared using DECLARE_JOB
_ARGPACK – pack of the arguments to pass to _FUNCTION - each must be implicitly convertible to its respective parameter type. E.g.
(5, NULL)
forvoid(int, int *)
xcore/port_protocol.h¶
Helper functions for port usage patterns.
Functions
-
inline void
port_protocol_in_handshake
(port_t __p, port_t __readyin, port_t __readyout, xclock_t __clk)¶ Configure a port to be a clocked input port in handshake mode.
If the ready-in or ready-out ports are not 1-bit ports, an exception is raised. The ready-out port is asserted on the falling edge of the clock when the port’s buffer is not full. The port samples its pins on its sampling edge when both the ready-in and ready-out ports are asserted.
By default the port’s sampling edge is the rising edge of clock. This can be changed by the function port_set_sample_falling_edge().
Note
A handshaken port must be buffered, so this function will also make the port buffered.
- Parameters
__p – The port to configure
__readyin – A 1-bit port to use for the ready-in signal
__readyout – A 1-bit port to use for the ready-out signal
__clk – The clock used to configure the port
- Throws
ET_ILLEGAL_RESOURCE – not a valid port/clock or clock is running, or readyin/readyout not a one bit port.
ET_RESOURCE_DEP – another core is actively changing a port/clock
-
inline void
port_protocol_out_handshake
(port_t __p, port_t __readyin, port_t __readyout, xclock_t __clk, uint32_t __initial)¶ Configures a port to be a clocked output port in handshake mode.
If the ready-in or ready-out ports are not 1-bit ports an exception is raised. the port drives the initial value on its pins until an output statement changes the value driven.
The ready-in port is read on the sampling edge of the port. outputs are driven on the next falling edge of the clock where the previous value read from the ready-in port was high.
On the falling edge of the clock the ready-out port is driven high if data is output on that edge, otherwise it is driven low.
By default the port’s sampling edge is the rising edge of clock. this can be changed by the function port_set_sample_falling_edge().
Note
A handshaken port must be buffered, so this function will also make the port buffered.
- Parameters
__p – the port to configure
__readyin – a 1-bit port to use for the ready-in signal
__readyout – a 1-bit port to use for the ready-out signal
__clk – the clock used to configure the port
__initial – the initial value to output on the port
- Throws
ET_ILLEGAL_RESOURCE – not a valid port/clock or clock is running, or readyin/readyout not a one bit port.
ET_RESOURCE_DEP – another core is actively changing a port/clock
-
inline void
port_protocol_in_strobed_master
(port_t __p, port_t __readyout, xclock_t __clk)¶ Configures a port to be a clocked input port in strobed master mode.
If the ready-out port is not a 1-bit port, an exception is raised. the ready-out port is asserted on the falling edge of the clock when the port’s buffer is not full. the port samples its pins on its sampling edge after the ready-out port is asserted.
By default the port’s sampling edge is the rising edge of clock. this can be changed by the function set_port_sample_delay().
Note
A strobed port must be buffered, so this function will also make the port buffered.
- Parameters
__p – the port to configure
__readyout – a 1-bit port to use for the ready-out signal
__clk – the clock used to configure the port
- Throws
ET_ILLEGAL_RESOURCE – not a valid port/clock or clock is running, or readyout not a one bit port.
ET_RESOURCE_DEP – another core is actively changing a port/clock
-
inline void
port_protocol_out_strobed_master
(port_t __p, port_t __readyout, xclock_t __clk, uint32_t __initial)¶ Configures a port to be a clocked output port in strobed master mode.
If the ready-out port is not a 1-bit port, an exception is raised. the port drives the initial value on its pins until an output statement changes the value driven. outputs are driven on the next falling edge of the clock. on the falling edge of the clock the ready-out port is driven high if data is output on that edge, otherwise it is driven low.
Note
A strobed port must be buffered, so this function will also make the port buffered.
- Parameters
__p – the port to configure
__readyout – a 1-bit port to use for the ready-out signal
__clk – the clock used to configure the port
__initial – the initial value to output on the port
- Throws
ET_ILLEGAL_RESOURCE – not a valid port/clock or clock is running, or readyout not a one bit port.
ET_RESOURCE_DEP – another core is actively changing a port/clock
-
inline void
port_protocol_in_strobed_slave
(port_t __p, port_t __readyin, xclock_t __clk)¶ Configures a port to be a clocked input port in strobed slave mode.
If the ready-in port is not a 1-bit port, an exception is raised. the port samples its pins on its sampling edge when the ready-in signal is high. by default the port’s sampling edge is the rising edge of clock. this can be changed by the function set_port_sample_delay().
Note
A strobed port must be buffered, so this function will also make the port buffered.
- Parameters
__p – the port to configure
__readyin – a 1-bit port to use for the ready-in signal
__clk – the clock used to configure the port
- Throws
ET_ILLEGAL_RESOURCE – not a valid port/clock or clock is running, or readyin not a one bit port.
ET_RESOURCE_DEP – another core is actively changing a port/clock
-
inline void
port_protocol_out_strobed_slave
(port_t __p, port_t __readyin, xclock_t __clk, uint32_t __initial)¶ Configures a port to be a clocked output port in strobed slave mode.
If the ready-in port is not a 1-bit port, an exception is raised. the port drives the initial value on its pins until an output statement changes the value driven. the ready-in port is read on the port’s sampling edge. outputs are driven on the next falling edge of the clock where the previous value read from the ready-in port is high. by default the port’s sampling edge is the rising edge of clock. this can be changed by the function set_port_sample_delay().
Note
A strobed port must be buffered, so this function will also make the port buffered.
- Parameters
__p – the port to configure
__readyin – a 1-bit port to use for the ready-in signal
__clk – the clock used to configure the port
__initial – the initial value to output on the port
- Throws
ET_ILLEGAL_RESOURCE – not a valid port/clock or clock is running, or readyin not a one bit port.
ET_RESOURCE_DEP – another core is actively changing a port/clock
xcore/port.h¶
API for IO using ports.
Defines
-
PORT_TIMESTAMP_MIN
¶ Lowest legal value for a port timestamp.
-
PORT_TIMESTAMP_MAX
¶ Largest legal value for a port timestamp.
Typedefs
-
typedef resource_t
port_t
¶ Port handle type.
-
typedef uint32_t
port_timestamp_t
¶ Integer type capable of holding all possible values of a port timestamp.
Note
The actual valid range of timestamps is given by PORT_TIMESTAMP_MIN and PORT_TIMESTAMP_MAX which are the lowest and highest valid timestamps respectively.
Enums
Functions
-
inline void
port_enable
(port_t __p)¶ Enables a port.
Either this function or port_start_buffered() must be called once for each variable of type
port
before use. port_disable() must be called afterwards.The port’s state is set to: input, unbuffered, inout_data, no_invert, rising_edge, master, no_ready, no triggers, clocked by XS1_CLKBLK_REF.
- See
port_enable_buffered
- Parameters
__p – The port to enable
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline void
port_reset
(port_t __p)¶ Reset a port.
Clears a ports settings back to the default state at port_enable().
- Parameters
__p – The port to be reset
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline void
port_start_buffered
(port_t __p, size_t __transfer_width)¶ Allocates a port to buffer and serialise/deserialise data.
Either this function or port_enable() must be called once for each port_t before it is used.
- See
- Parameters
__p – Value that identifies which port to drive
__transfer_width – Number of bits to serialise; must be 1, 4, 8, or 32. The number of bits must be >= to the physical port width.
- Throws
ET_ILLEGAL_RESOURCE – not a valid port, or is not legal width for the port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline void
port_disable
(port_t __p)¶ Disable a port.
Disables the port so it is no longer ready for use. It must be re-enabled if it is used again.
- Parameters
__p – The port to be disabled
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline void
port_set_transfer_width
(port_t __p, size_t __transfer_width)¶ Change the transfer width of a port.
The default transfer width is the same as the physical port width.
- Attention
A port must have been set to buffered if the width is different from the physical port width
- Parameters
__p – The port to change the transfer width of
__transfer_width – Number of bits to serialise; must be 1, 4, 8, or 32. The number of bits must be >= to the physical port width.
- Throws
ET_ILLEGAL_RESOURCE – not a valid port, or is not legal width for the port, or the port is unbuffered.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline void
port_set_buffered
(port_t __p)¶ Sets a port to be buffered.
Configures a port into buffered mode where it can automatically serialise or deserialise data.
- Parameters
__p – The port to set as buffered
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline void
port_set_unbuffered
(port_t __p)¶ Sets a port to be unbuffered (default state).
Configures a port into unbuffered mode. Note that before this is called, a a port needs to have its transfer width equal to the port width and be configured as a master port.
- Parameters
__p – The port to set as unbuffered
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline void
port_write_control_word
(port_t __p, uint32_t __word)¶ Configure the port with a platform-specific value.
Uses the value of __word to configure the port. The effect of this is platform dependent.
- Parameters
__p – The port to configure
__word – The config word to set on the port
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port or __word is not valid
-
inline void
port_set_clock
(port_t __p, xclock_t __clk)¶ Set the clock clocking a port.
Changes the clock used for a port’s control functions. The default clock is XS1_CLKBLK_REF.
- Parameters
__p – Port whose clock is being changed.
__clk – Clock to attach to the port.
- Throws
ET_ILLEGAL_RESOURCE – not a valid port/clock, or clock is running.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline void
port_set_inout_data
(port_t __p)¶ Set a port drive out the data value (default state).
- Parameters
__p – Port to change the mode of.
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline void
port_set_out_clock
(port_t __p)¶ Set a port to drive out its clocking signal.
Configures the port to drive the clock signal instead of its own data values. The clock signal that is driven out is configured using the port_set_clock() function.
- Parameters
__p – Port to change the mode of.
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline void
port_set_out_ready
(port_t __p, port_t __ready_source)¶ Set a port to drive out the ready signal of another port.
Configures the port to drive the ready signal of another port instead of its own data values.
- Parameters
__p – Port to change the mode of. This must be a 1-bit port or this function will trap.
__ready_source – The port whose ready signal will be output.
- Throws
ET_ILLEGAL_RESOURCE –
not a valid port
p not a one bit port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline void
port_set_invert
(port_t __p)¶ Set the port to invert its data.
Configures a port to invert the data on the pin. This can be reverted by calling port_set_no_invert().
- Parameters
__p – Port to set its data to be inverted. This must be a 1-bit port or a trap will be raised.
- Throws
ET_ILLEGAL_RESOURCE –
not a valid port
p not a one bit port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline void
port_set_no_invert
(port_t __p)¶ Set the port to not invert its data (default state).
Configures a port to not invert the data on the pin.
- Parameters
__p – Port to set the data to not be inverted.
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline void
port_set_sample_falling_edge
(port_t __p)¶ Set the port to sample on the falling edge.
The default is for a port to sample data on the rising edge of the clock. This function changes the port to sample on the falling edge instead. This change can be reverted by calling port_set_sample_rising_edge().
- Parameters
__p – Port to change its sampling edge.
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline void
port_set_sample_rising_edge
(port_t __p)¶ Set the port to sample on the rising edge (default state).
Restores a port to sampling data on the rising edge of the clock.
- Parameters
__p – Port to change its sampling edge.
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline void
port_set_master
(port_t __p)¶ Set the port to master mode (default state).
Configures a port to be a master. This is only relevant when using ready signals (port_set_ready_strobed() / port_set_ready_handshake()).
- See
xcore/port_protocol.h
Note
It is highly recommended to use the
port_protocol_*
functions to put a port into its desired mode as the order of operations is critical.- Parameters
__p – Port to set as a master
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline void
port_set_slave
(port_t __p)¶ Set the port to slave mode.
Configures a port to be a master. This is only relevant when using a ready strobe (port_set_ready_strobed())
- Attention
the port must be set to use a ready strobe, otherwise this function will raise an exception.
- See
xcore/port_protocol.h
Note
It is highly recommended to use the
port_protocol_*
functions to put a port into its desired mode as the order of operations is critical.- Parameters
__p – Port to set as a slave
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline void
port_set_no_ready
(port_t __p)¶ Set the port to use no ready signals (default state).
Changes a port to not use ready signals. A port can be configured to use strobes or handshaking signals using port_set_ready_strobed() or port_set_ready_handshake().
- Attention
the port must be a
master
port otherwise this function will raise an exception.- See
xcore/port_protocol.h
Note
It is highly recommended to use the
port_protocol_*
functions to put a port into its desired mode as the order of operations is critical.- Parameters
__p – Port to change to not use ready signals
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline void
port_set_ready_strobed
(port_t __p)¶ Set the port to use a single strobe.
Changes a port to not use ready signals. A port can be configured to use strobes or handshaking signals using port_set_ready_strobed() or port_set_ready_handshake().
- Attention
the port must be a buffered port otherwise this function will raise an exception.
- See
xcore/port_protocol.h
Note
It is highly recommended to use the
port_protocol_*
functions to put a port into its desired mode as the order of operations is critical.- Parameters
__p – Port to change to not use ready signals
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline void
port_set_ready_handshake
(port_t __p)¶ Set the port to be fully handshaken.
Changes a port to use both a ready input and drive a ready output in order to control when data is sampled or written.
- Attention
the port must be a master buffered port otherwise this function will raise an exception.
- See
xcore/port_protocol.h
Note
It is highly recommended to use the
port_protocol_*
functions to put a port into its desired mode as the order of operations is critical.- Parameters
__p – Port to change to not use ready signals
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline port_timestamp_t
port_get_trigger_time
(port_t __p)¶ Gets the timestamp of the last input or output operation on a port.
Note
The returned timestamp will be a valid timestamp no less than PORT_TIMESTAMP_MIN and no greater than PORT_TIMESTAMP_MAX.
- Parameters
__p – The port to get the timestamp from
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
- Returns
The timestamp of the last operation
-
inline void
port_set_trigger_time
(port_t __p, port_timestamp_t __t)¶ Set the timestamp at which the port will input/output data.
Sets the time condition for the next input or output on a port. If the port is unbuffered or the buffer is empty/full a call to port_in() or port_out() will pause until the specified time. The trigger is cleared by a input/output or by calling port_clear_trigger_time(). The given timestamp must be a valid port timestamp no less than PORT_TIMESTAMP_MIN and no greater than PORT_TIMESTAMP_MAX.
- Parameters
__p – The port to set the condition on
__t – The port timestamp to match
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively using the port.
-
inline void
port_clear_trigger_time
(port_t __p)¶ Clear the timestamp trigger on a port.
Clears any trigger_time condition on the port so the next input or output will happen unconditionally in respect to the timestamp. This function does not clear the trigger_in condition on the port.
- Parameters
__p – The port to clear the trigger_time on
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline void
port_set_trigger_in_equal
(port_t __p, uint32_t __v)¶ Setup an event to trigger on a port when its input value matches.
On a unbuffered port the trigger will apply to all future inputs until the trigger is set again. On an buffered port the trigger will only hold for the next input after which the trigger_in_equal will be cleared.
- Parameters
__p – The port to set the trigger on
__v – The value to match
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline void
port_set_trigger_in_not_equal
(port_t __p, uint32_t __v)¶ Setup an event to trigger on a port when its input value does not matches.
On a unbuffered port the trigger will apply to all future inputs until the trigger is set again. On an buffered port the trigger will only hold for the next input after which the trigger_in_not_equal will be cleared.
- Parameters
__p – The port to set the trigger on
__v – The value to not match
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline void
port_clear_trigger_in
(port_t __p)¶ Clear the in trigger on a port.
Clears any trigger_in condition on the port so the next input will happen unconditionally in respect to the input value. This function does not clear the trigger_time condition on the port.
- Parameters
__p – The port to clear the trigger_in on
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline uint32_t
port_peek
(port_t __p)¶ Peek at the value on a port.
Peeking a port returns the current value on the pins of a port, regardless of whether the port is an output or input and without affecting its direciton. Peek will not pause, regardless of any triggers that have been set.
- Parameters
__p – Port to be peeked
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
- Returns
The current value on the pins
-
inline void
port_out
(port_t __p, uint32_t __data)¶ Outputs a value onto a port.
In the case of an unbuffered port, the value will be driven on the pins on the next clock cycle. In the case of a buffered port, the data will be stored in the buffer, and be serialised onto the output pins.
If there is a time trigger setup and the port is unbuffered or the buffer is full the call will pause until the specified time.
- Parameters
__p – Port to output to
__data – Value to output
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline uint32_t
port_in
(port_t __p)¶ Input a value from a port.
For unbuffered port with no trigger, the data will be whatever is on the input pins. For unbuffered port with a trigger, the data will be the value read when the trigger fired. The call will pause if the trigger has not yet fired. For buffered port, this function will pause until the buffer is filled up with deserialised data.
- Parameters
__p – Port to input from
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
- Returns
The inputted data
-
inline uint32_t
port_out_shift_right
(port_t __p, uint32_t __data)¶ Outputs a value onto a port and shift the output data.
In the case of an unbuffered port, the value will be driven on the pins on the next clock cycle. In the case of a buffered port, the data will be stored in the buffer, and be serialised onto the output pins.
If there is a time trigger setup and the port is unbuffered or the buffer is full the call will pause until the specified time.
- Parameters
__p – Port to output to
__data – data is shifted right by the transfer width of the port, with the bits shifting out onto the port.
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
- Returns
The remaining shifted bits of data
-
inline uint32_t
port_in_shift_right
(port_t __p, uint32_t __data)¶ Input a value from a port and shift the data.
For unbuffered port with no trigger, the data will be whatever is on the input pins. For unbuffered port with a trigger, the data will be the value read when the trigger fired. The call will pause if the trigger has not yet fired. For buffered port, this function will pause until the buffer is filled up with deserialised data.
- Parameters
__p – Port to input from
__data – Initial value to shift input data into
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
- Returns
Result of shifting data right by the port width and storing the input data in the most significant bits
-
inline void
port_out_at_time
(port_t __p, port_timestamp_t __t, uint32_t __data)¶ Outputs a value onto a port at a specified port timestamp.
In the case of an unbuffered port, the value will be driven on the pins when on the clock cycle that moves the port timestamp to the specified time. In the case of a buffered port, the data will be stored in the buffer, and be serialised onto the output pins at the point that the time is reached. The given timestamp must be a valid port timestamp no less than PORT_TIMESTAMP_MIN and no greater than PORT_TIMESTAMP_MAX.
- Parameters
__p – Port to output to
__t – The timestamp to do the output on
__data – Value to output
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline uint32_t
port_in_at_time
(port_t __p, port_timestamp_t __t)¶ Input data from a port when its counter is at a specific time.
In the case of an unbuffered port, the data will be inputted when the counter reaches time t. In the case of a buffered port, an input will wait until the given time and then will start capturing data, returning a value when the buffer is full. The given timestamp must be a valid port timestamp no less than PORT_TIMESTAMP_MIN and no greater than PORT_TIMESTAMP_MAX.
- Parameters
__p – Port to input from
__t – The timestamp to do input on
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
- Returns
The inputted data
-
inline uint32_t
port_out_shift_right_at_time
(port_t __p, port_timestamp_t __t, uint32_t __data)¶ Outputs a value onto a port at a specified time and shifts the output data.
In the case of an unbuffered port, the value will be driven on the pins when on the clock cycle that moves the port counter to the specified time. In the case of a buffered port, the data will be stored in the buffer, and be serialised onto the output pins at the point that the time is reached. The given timestamp must be a valid port timestamp no less than PORT_TIMESTAMP_MIN and no greater than PORT_TIMESTAMP_MAX.
- Parameters
__p – Port to output to
__t – The timestamp of the output
__data – data is shifted right by the transfer width of the port, with the bits shifting out onto the port.
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
- Returns
The remaining shifted bits
-
inline uint32_t
port_in_shift_right_at_time
(port_t __p, port_timestamp_t __t, uint32_t __data)¶ Input data from a port at a specific time and shift the data.
In the case of an unbuffered port, the data will be inputted when the counter reaches time t. In the case of a buffered port, an input will wait until the given time and then will start capturing data, returning a value when the buffer is full. The given timestamp must be a valid port timestamp no less than PORT_TIMESTAMP_MIN and no greater than PORT_TIMESTAMP_MAX.
- Parameters
__p – Port to input from
__t – The timestamp to do input on
__data – Initial value to shift input data into
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
- Returns
Result of shifting data right by the port width and storing the input data in the most significant bits
-
inline uint32_t
port_in_when_pinseq
(port_t __p, port_type_t __pt, uint32_t __value)¶ Input data from a port when its pins match a specific value.
In the case of an unbuffered port, the data inputted be identical to the value. In the case of a buffered port, an input will wait until the value appears on the pins and then return that value and some previous values that have been deserialised.
- Parameters
__p – Port to input from
__pt – If port is buffered or unbuffered.
__value – The value to match against the pins
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
- Returns
The inputted data
-
inline uint32_t
port_in_when_pinsneq
(port_t __p, port_type_t __pt, uint32_t __value)¶ Input data from a port when its pins do not match a specific value.
In the case of an unbuffered port, the inputted data will be the non-matching pin values. In the case of a buffered port, this function will wait until a non matching value appears on the pins, and then return that value and previous values that have been deserialised.
- Parameters
__p – Port to input from
__pt – If port is buffered or unbuffered.
__value – The value to match against the pins
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
- Returns
The inputted data
-
inline uint32_t
port_in_shift_right_when_pinseq
(port_t __p, port_type_t __pt, uint32_t __value, uint32_t __data)¶ Input data from a port when its pins match a specific value and shift the data.
In the case of an unbuffered port, the data inputted be identical to the value. In the case of a buffered port, an input will wait until the value appears on the pins and then return that value and some previous values that have been deserialised.
- Parameters
__p – Port to input from
__pt – If port is buffered or unbuffered.
__value – The value to match against the pins
__data – Initial value to shift input data into
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
- Returns
Result of shifting data right by the port width and storing the input data in the most significant bits
-
inline uint32_t
port_in_shift_right_when_pinsneq
(port_t __p, port_type_t __pt, uint32_t __value, uint32_t __data)¶ Input data from a port when its pins do not match a specific value and shift the data.
In the case of an unbuffered port, the inputted data will be the non-matching pin values. In the case of a buffered port, this macro will wait until a non matching value appears on the pins, and then return that value and previous values that have been deserialised.
- Parameters
__p – Port to input from
__pt – If port is buffered or unbuffered.
__value – The value to match against the pins
__data – Initial value to shift input data into
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
- Returns
Result of shifting data right by the port width and storing the input data in the most significant bits
-
inline void
port_clear_buffer
(port_t __p)¶ Clears the buffer used by a port.
Any data sampled by the port which has not been input by the processor is discarded. Any data output by the processor which has not been driven by the port is discarded. If the port is in the process of serialising output, it is interrupted immediately. If a pending output would have caused a change in direction of the port then that change of direction does not take place. If the port is driving a value on its pins when this function is called then it continues to drive the value until an output statement changes the value driven.
- Parameters
__p – The port whose buffer is to be cleared
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
-
inline size_t
port_endin
(port_t __p)¶ Ends the current input on a buffered port.
The number of bits sampled by the port but not yet input by the processor is returned. This count includes both data in the transfer register and data in the shift register used for deserialisation. Subsequent inputs on the port return transfer-width bits of data until there is less than one transfer-width bits of data remaining. Any remaining data can be read with one further input, which returns transfer-width bits of data with the remaining buffered data in the most significant bits of this value.
- Parameters
__p – The port to end the current input on
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
- Returns
The number of bits of data remaining
-
inline size_t
port_force_input
(port_t __p, uint32_t *__data)¶ Force an input on a buffered port.
Perform an input on a buffered port even if the buffer is only partially full.
- Parameters
__p – The port to do the input on
__data – [out] The inputted data
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively changing the port.
ET_LOAD_STORE – invalid data argument.
- Returns
The number of bits input
-
inline void
port_set_trigger_value
(port_t __p, uint32_t __value)¶ Sets the trigger value for a port with a configured trigger.
Changes only the trigger value of a port which has already been configured to trigger on a value using port_set_trigger_in_equal() or port_set_trigger_in_not_equal().
- Parameters
__p – The port to change the trigger value of
__value – The new trigger value to set
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively using the port.
-
inline void
port_sync
(port_t __p)¶ Synchronise with the port to ensure all data has been output.
Block until all data has been shifted out of the port, with the final port-width bits being held for one clock period.
- Parameters
__p – The port to synchronise
- Throws
ET_ILLEGAL_RESOURCE – not a valid port.
ET_RESOURCE_DEP – another core is actively using the port.
-
inline void
port_set_shift_count
(port_t __p, uint32_t __sc)¶ Set the port shift count for input and output operations.
- Parameters
__p – The port to set the shift count for
__sc – Shift count to set
- Throws
ET_ILLEGAL_RESOURCE – Not a valid buffered port, or the shift count is not valid for the port width.
ET_RESOURCE_DEP – another core is actively using the port.
-
inline void
port_out_part_word
(port_t __p, uint32_t __d, uint32_t __bitp)¶ Output a part word to a port.
Writes a specified number of bits of a given value to the a buffered port
Note
This is equivalent to using port_shift_count_set() followed by port_out()
- Parameters
__p – The port to output to
__d – The word to take the part word from
__bitp – The number of bits of __d to output. Valid values are 1,2,3,4,5,6,7,8,16,24,32
- Throws
ET_ILLEGAL_RESOURCE – Not a valid buffered port, the port is busy, or an invalid part-word width has been used.
ET_RESOURCE_DEP – another core is actively using the port.
xcore/select.h¶
Macros for efficiently handling events from multiple resources.
Provides macros which expand to code for efficiently waiting for events on an arbitrary group of resources (analogous to a socket select
). The general form of user code is:
SELECT_MACRO(CASE_MACRO([...,] CASE_LABEL) [, ...])
// "select block":
{
CASE_LABEL:
[...;]
CASE_TERMINATOR;
[...;]
} // End of select block
Where:
SELECT_MACRO
defines the how the checking of events is implemented and is one of:
SELECT_RES() - Repeatedly wait for an event on an arbitrary set of resources.
SELECT_RES_ORDERED() - Repeatedly wait for an event on an arbitrary set of events giving priority to resources based on order.
CASE_MACRO
determines the condition under which a case label will be jumped to and is one of: CASE_THEN() - Unconditionally wait for an event on a given resource.
CASE_GUARD_THEN() - Wait for an event on a given resource if a condition evaluates true.
CASE_NGUARD_THEN() - Wait for an event on a given resource is a condition evaluates false.
DEFAULT_THEN() - Defines a label to jump to if no enabled resource events are ready.
DEFAULT_GUARD_THEN() - Defines a label to jump to if no enabled resource events are ready and a condition evaluates true.
DEFAULT_NGUARD_THEN() Defines a label to jump to if no enabled resource events are ready and a condition evaluates false.
CASE_LABEL
is a label inside the ‘select block’
The select block is compound statement consisting of sequences of statements prefixed with a CASE_LABEL
and followed by a CASE_TERMINATOR
CASE_TERMINATOR
determines whether control exits the select block or handles further events and is one of:
break
- Exits the select blockcontinue
- Waits for/handles another event or defaultSELECT_CONTINUE_RESET - Restores the configuration of the immediately enclosing select block and continues.
SELECT_CONTINUE_NO_RESET - Continues to handle another event in the immediately inclosing select block without applying global resource setup.
DEFAULT_*
macros. There may only be one default case; if more than one expansion of a DEFAULT_*
macro is passed to a SELECT_MACRO
then it is unspecified which one is effective, even if a condition means only one can ever be enabled. If the effective default case is expanded from DEFAULT_GUARD_THEN() and its condition is false or it is expanded from DEFAULT_NGUARD_THEN() and its condition is true, then the effect is as if there were no default case.
When the code expanded from a SELECT_MACRO
is executed, qualifying resources are checked for events. Qualifying resources are those which were passed to the immediately enclosing select block’s SELECT_MACRO:
By expanding CASE_THEN(); or
By expanding CASE_GUARD_THEN() and where the condition evaluates true; or
By expanding CASE_NGUARD_THEN() and where the conditional evaluates false.
CASE_MACRO
). If no such event is available then: If there is a default case (and it is not disabled by a condition) then control is transferred to the associated label;
Otherwise execution pauses until an event is available at which point control is transferred to its associated label.
CASE_TERMINATOR
is executed. At that point the behaviour depends on the terminator: If control reaches a
break
then control will exit the immediately enclosing select block.If control reaches the expansion of
SELECT_CONTINUE_NO_RESET
then the effect is as if control were transferred back to the beginning of the expansion of theSELECT_MACRO
, except that some setup is skipped. If an inner (i.e. nested)SELECT_MACRO
expansion has been executed (even as a result of calling a function), since control was transferred into the immediately enclosing select block by the immediately precedingSELECT_MACRO
expansion, then the use ofSELECT_CONTINUE_NO_RESET
to terminate the outer select construct has undefined behaviour.If control reaches the expansion of SELECT_CONTINUE_RESET then the effect is as if control were transferred to the beginning of the expansion of the
SELECT_MACRO
for the immediately enclosing select block. This effectively resets the select construct and makes ineffective any setup performed by any nestedSELECT_MACRO
which would affect the execution of the immediately enclosing one.If control reaches a
continue
then the effect is as if control had reached the expansion of SELECT_CONTINUE_RESET if a SELECT_MACRO expansion has been executed since since control was transferred into the immediately enclosing select block by the immediately precedingSELECT_MACRO
. Otherwise the effect is as if the expansion ofSELECT_CONTINUE_RESET
were executed.Note
This is intended to provide a safe means of handling further events if arbitrary code has been executed which may have used a select construct. Its use is likely to incur a runtime performance penalty compared to using the most appropriate of
SELECT_CONTINUE_RESET
andSELECT_CONTINUE_NO_RESET
.If control reaches the end of a select block without reaching a CASE_TERMINATOR then the behaviour will be as if a
CASE_TERMINATOR
had been reached but it is unspecified which one. (Thus this may result in undefined behaviour if a nested select construct has been executed.)
Executing the immediately preceding
SELECT_MACRO
expansion;Returning from a function call;
Executing a
CASE_TERMINATOR
. Additionally, transferring control out of a select block by any means other than calling a function or executingbreak
as aCASE_TERMINATOR
has undefined behaviour.
SELECT_MACRO
or a CASE_TERMINATOR
is executed and: There are no qualifying resources, and
There is no default case or the effective default case is disabled by a condition,
CASE_MACRO
(including default case) conditions are evaluated on initial entry to the SELECT_MACRO expansion and after each execution of a CASE_TERMINATOR
other than break
. If evaluation of a case condition has side effects then the behaviour is of the select construct is undefined.Note
Normal language rules apply - break
and continue
affect the relevant enclosing construct - so if they are nested within e.g. a loop then they will not terminate the select block. This also applies to other case terminators which must only appear within a select block. Thus it is impossible to exit a select block from a function.
If a CASE_LABEL
is placed within a select block such that it would be illegal to use goto
to jump to it from the point at which SELECT_MACRO
is expanded, then the behaviour is undefined.
Each resource passed (though a CASE_MACRO
) to a SELECT_MACRO
must be unique within that SELECT_MACRO
expansion, otherwise the behaviour of the select construct is undefined. That is, the same resource must not be used for two different cases. This applies even if cases are guarded by mutually exclusive conditions.
Defines
-
SELECT_RES
(...)¶ Repeatedly wait for an event on an arbitrary set of resources.
Selects on one or more resources with an optional default. If more than one event is available then it is upspecified which one will be taken.
Example:
int button_up = 1; int button_event_count = 0; SELECT_RES( CASE_GUARD_THEN(button_chanend, button_event_count < 21, event_button_chanend), CASE_THEN(led_chanend, event_led_chanend), DEFAULT_NGUARD_THEN(button_up, default_label)) { default_label: puts("Button is still down!"); SELECT_RESET; event_button_chanend: { uint32_t tmp = chan_in_word(button_chanend); chan_out_word(led_chanend, tmp); button_up = tmp; } button_event_count += 1; continue; event_led_chanend: { uint32_t tmp = chan_in_word(led_chanend); chan_out_word(button_chanend, tmp); } continue; }
- Parameters
... – case specifications as expanded from the
CASE_*
orDEFAULT_*
macros
-
SELECT_RES_ORDERED
(...)¶ Repeatedly wait for an event on an arbitrary set of events giving priority to resources based on order.
Behaviour is like SELECT_RES() except that events are checked in the order their respective
CASE_*
expansions are passed. This can be used to ensure that high priority events are serviced before lower priority ones.If there is an event on the highest priority qualifying resource upon execution of the expansion of SELECT_RES_ORDERED(), or a select terminator within its immediately following select block, then if is guaranteed that event will be taken. For any other priority in this case (if it is the highest priority event) then it is guarateed that it will be taken, but only if no higher priority event becomes available (in which case the event taken is unspecified). If no event is available then the default case will be taken if there is a default case and it is enabled. If there is no default case or the default case is disabled by a condition then execution will pause and wait for an event on a qualifying resource - in this case prioties no longer apply and the first event which becomes available will be taken.
Note
There is a runtime overhead associated with checking events in order so it is suggested that SELECT_RES() be used whenever possible.
- Parameters
... – case specifications as expanded from the
CASE_*
orDEFAULT_*
macros
-
SELECT_CONTINUE_RESET
¶ Restores the configuration of the immediately enclosing select block and continues.
This may be used instead of
continue
as a select terminator if a different (to the immediately enclosing one) select construct has been executed. The effect is that the resource setup which happens at the start of the select construct is guaranteed to re-run so that the correct events will be enabled. Using this instead ofcontinue
(when required) is likely to result in a slight performance boost as it eliminates the need to check global state.
-
SELECT_CONTINUE_NO_RESET
¶ Continues to handle another event in the immediately inclosing select block without applying global resource setup.
This may be used in stead of
continue
as a select terminator if different select block has not been executed during handling of the previous event (or default). In the event that another select construct has executed this will have undefined behaviour.Using this instead of
continue
(when safe to do so) is likely to result in a slight performance improvement.
-
CASE_THEN
(_RES, _LABEL)¶ Unconditionally wait for an event on a given resource.
- Parameters
_RES – The resource to wait for an event on.
_LABEL – The label (within the following select block) to jump to when an event occurs on res.
-
CASE_GUARD_THEN
(_RES, _GUARD_EXPR, _LABEL)¶ Wait for an event on a given resource if a condition evaluates true.
- Parameters
_RES – The resource to wait for an event on.
_GUARD_EXPR – Expression to evaluate to determine if this case should be enabled. Must not have side effects.
_LABEL – The label (within the following select block) to jump to when an event occurs on res.
-
CASE_NGUARD_THEN
(_RES, _GUARD_EXPR, _LABEL)¶ Wait for an event on a given resource is a condition evaluates false.
- Parameters
_RES – The resource to wait for an event on.
_GUARD_EXPR – Expression to evaluate to determine if this case should be disabled. Must not have side effects.
_LABEL – The label (within the following select block) to jump to when an event occurs on res.
-
DEFAULT_THEN
(_LABEL)¶ Defines a label to jump to if no enabled resource events are ready.
- Parameters
_LABEL – The label (within the following select block) to jump to if there are no events to take.
-
DEFAULT_GUARD_THEN
(_GUARD_EXPR, _LABEL)¶ Defines a label to jump to if no enabled resource events are ready and a condition evaluates true.
- Parameters
_LABEL – The label (within the following select block) to jump to if there are no events to take.
_GUARD_EXPR – Expression to determine it the default case should be enabled.
-
DEFAULT_NGUARD_THEN
(_GUARD_EXPR, _LABEL)¶ Defines a label to jump to if no enabled resource events are ready and a condition evaluates false.
- Parameters
_LABEL – The label (within the following select block) to jump to if there are no events to take.
_GUARD_EXPR – Expression to determine it the default case should be disabled.
xcore/swmem_evict.h¶
API for implementing software memory fill (write)
Defines
-
SWMEM_EVICT_SIZE_WORDS
¶ Number of words which must be evicted per eviction request.
Typedefs
-
typedef resource_t
swmem_evict_t
¶ Handle type for a SwMem evict resource.
-
typedef const void *
evict_slot_t
¶ Pointer to an eviction slot - this is the lowest address which must be evicted.
-
typedef uint32_t
evict_mask_t
¶
Functions
-
inline swmem_evict_t
swmem_evict_get
(void)¶ Gets and enables a swmem evict resource.
The handle must be passed to swmem_evict_free() before this function is called again.
- Returns
The swmem evict handle.
-
inline void
swmem_evict_free
(swmem_evict_t __r)¶ Disables a swmem evict resource as returned by swmem_evict_get()
-
inline evict_slot_t
swmem_evict_in_address
(swmem_evict_t __r)¶ Returns the slot handle of the waiting swmem eviction request, blocks if there isn’t one.
When a eviction request is raised, the contents of the ‘eviction slot’ are available to be read until the request is completed. Fulfilling the request may unblock another thread which is attempting to write.
The handle returned is the lowest address in the eviction request; the length of the request is always SWMEM_EVICT_SIZE_WORDS words.
Words can be read from the eviction slot individually using swmem_evict_read_word(); once all required words have been read swmem_evict_read_word_done() should be called to complete the request. Alternatively, swmem_evict_to_buffer() may be used to read and complete the request in a single call.
- Parameters
__r – The swmem evict resource handle
- Returns
An eviction slot handle
-
inline uint32_t
swmem_evict_read_word
(swmem_evict_t __r, evict_slot_t __slot, unsigned __word_index)¶ Read a single word from an eviction slot.
Returns the word from the eviction slot at the given index. To complete the eviction swmem_evict_read_word_done() should be called.
- Parameters
__r – The swmem evict resource handle
__slot – The eviction slot to read from (returned by swmem_evict_in_address())
__word_index – The index of the word (must be less than SWMEM_EVICT_SIZE_WORDS)
- Returns
The word at the given __word_index within the evict slot
-
inline evict_mask_t
swmem_evict_get_dirty_mask
(swmem_evict_t __r, evict_slot_t __slot)¶ Gets the dirty mask for the current eviction.
The mask returned is a bytewise dirty mask with one bit per byte in the entire eviction slot. This must only be called before the eviction request has been completed - i.e. it must be called before swmem_evict_read_word_done() or swmem_evict_to_buffer() for a given eviction request.
A byte is dirty if it has been written since it was last filled, or if it has been written but has never been filled (see swmem_fill.h).
The least significant bit in the dirty mask corresponds to the lowest byte address in the fill slot and each subsequent byte address corresponds to the next least significant bit of the dirty mask.
- Parameters
__r – The evict resource
__slot – The current eviction slot
- Returns
A bytewise dirty mask for the given eviction on the given resource
-
inline void
swmem_evict_read_word_done
(swmem_evict_t __r, evict_slot_t __slot)¶ Complete an eviction and unblock waiting threads.
This should be called after swmem_evict_read_word() has been used to get all required words from the evict request.
Note
It is not necessary (or safe) to call this if the request is fulfilled by calling swmem_evict_to_buffer().
- Parameters
__r – The swmem evict resource handle
__slot – The evict slot for the current eviction requesst
-
inline void
swmem_evict_to_buffer
(swmem_evict_t __r, evict_slot_t __slot, uint32_t *__buf)¶ Evict a slot into a buffer.
For an evict slot returned by swmem_evict_in_address(), reads the eviction slot into the given buffer and completes the eviction.
Note
If the dirty mask is required for the data read then it should be retrieved prior to calling this function. (Since the eviction will be complete on return.)
- Parameters
__r – The swmem evict resource handle
__slot – The eviction slot to read (returned by swmem_evict_in_address())
__buf – Buffer of at least SWMEM_EVICT_SIZE_WORDS words to evict the slot to
xcore/swmem_fill.h¶
API for implementing software memory fill (read)
Defines
-
SWMEM_FILL_SIZE_WORDS
¶ Number of words which must be filled per fill request.
Typedefs
-
typedef uint32_t
swmem_fill_buffer_t
[SWMEM_FILL_SIZE_WORDS
]¶ Buffer type which holds the correct number of words for a complete fill.
-
typedef resource_t
swmem_fill_t
¶ Handle type for a SwMem fill resource.
-
typedef const void *
fill_slot_t
¶ Pointer to a fill slot - this is the lowest address which must be filled.
Functions
-
inline swmem_fill_t
swmem_fill_get
(void)¶ Gets and enables a swmem fill resource.
The handle must be passed to swmem_fill_free() before this function is called again.
- Returns
The swmem fill handle.
-
inline void
swmem_fill_free
(swmem_fill_t __r)¶ Disables a swmem fill resource as returned by swmem_fill_get()
-
inline fill_slot_t
swmem_fill_in_address
(swmem_fill_t __r)¶ Returns the slot handle of the waiting swmem fill request, blocks if there isn’t one.
When a fill request is raised, the complete ‘fill slot’ must be populated. There are two ways of doing this:
Passing a complete buffer of length SWMEM_FILL_SIZE_WORDS words to swmem_fill_populate_from_buffer()
Calling swmem_fill_populate_word() for each individual word in the fill slot (i.e. at least SWMEM_FILL_SIZE_WORDS times) and then calling swmem_fill_populate_word_done().
- Parameters
__r – The swmem fill resource handle
- Returns
A fill slot handle which must be populated
-
inline void
swmem_fill_populate_word
(swmem_fill_t __r, fill_slot_t __slot, unsigned __word_index, uint32_t __value)¶ Populate a single word in a fill slot.
Fills a single word in a fill slot for a waiting fill request. The fill slot must be the last one returned by swmem_fill_in_address() and the fill request must not have been completed either by calling swmem_fill_populate_word_done() or by calling swmem_fill_populate_from_buffer(). To fulfill a request this function should be called for each word in the fill slot (i.e. with word_index set to each of
[0, SWMEM_FILL_SIZE_WORDS)
. Once all words have been populated in the fill slot, swmem_fill_populate_word_done() should be called to complete the fulfillment of the request and unblock any threads waiting for the fill.Note
It is safe to call this multiple times for the same word_index of a fill request, but only the last such call will have any effect.
- Parameters
__r – The swmem fill resource handle
__slot – The fill slot to populate (returned by swmem_fill_in_address())
__word_index – The index of the word (must be less than SWMEM_FILL_SIZE_WORDS)
__value – The value to set at the given index
-
inline void
swmem_fill_populate_word_done
(swmem_fill_t __r, fill_slot_t __slot)¶ Complete a fill and unblock waiting threads.
This should be called after swmem_fill_populate_word() has been used to fill each word in the fill request.
Note
It is not necessary (or safe) to call this if the request is fulfilled by calling swmem_fill_populate_from_buffer().
- Parameters
__r – The swmem fill resource handle
__slot – The fill slot for the ongoing fill request
-
inline void
swmem_fill_populate_from_buffer
(swmem_fill_t __r, fill_slot_t __slot, const uint32_t *__source)¶ Service a fill request using data in a suitably sized buffer.
For a fill slot returned by swmem_fill_in_address(), services the waiting fill request using data from __source - this must point to a buffer of at least SWMEM_FILL_SIZE_WORDS words; source[0] will be used to fill the 0th word in the fill slot, and so on.
- Parameters
__r – The swmem fill resource handle
__slot – The fill slot to populate (returned by swmem_fill_in_address())
__source – Buffer of at least SWMEM_FILL_SIZE_WORDS words to fill the slot from
xcore/thread.h¶
Hardware-assisted threading support.
Typedefs
-
typedef resource_t
xthread_t
¶ Handle for a single joinable thread.
-
typedef resource_t
threadgroup_t
¶ Handle for a group of threads which are jointly joinable.
-
typedef void (*
thread_function_t
)(void*)¶ Callback type which can be executed in another thread.
Enums
-
enum
thread_mode_t
¶ Thread mode bits enumeration.
Mode bits which may be passed to local_thread_mode_set_bits() and local_thread_mode_clear_bits() or to interpret the result of calling local_thread_mode_get_bits().
Note
The effect of setting/clearing these bits is platform-dependent; setting/clearing a bit is not guaranteed to have any effect.
Values:
-
enumerator
thread_mode_fast
¶ Fast mode bit
-
enumerator
thread_mode_high_priority
¶ High priority mode bit
-
enumerator
Functions
-
inline threadgroup_t
thread_group_alloc
(void)¶ Allocates a hardware thread.
Attempts to allocate a thread group from the pool on the current tile.
Note
The thread group should be freed using thread_group_free() when it is no longer required. (Or freed as a consequence of calling thread_group_wait_and_free().)
- Returns
A thread group handle, or 0 if none were available.
-
inline void
thread_group_add
(const threadgroup_t __group, const thread_function_t __func, void *const __argument, void *const __stack_base)¶ Add a new task to a thread group.
Adds a thead function invocation to a thread group allocated using thread_group_alloc(). This configures a hardware thread to execute func with argument as its sole parameter and with its stack pointer initialised to stack_base. stack_base must be word aligned and point to the last word of a block of memory sufficient to satisfy
func
’s stack requirements. That is, for a stack requirement ofs
words,[stack_base-s*word_size, stack_base]
will be used as the thread’s stack and will be clobbered.Note
Execution of func will not begin until the group is started using thread_group_start().
- Parameters
__group – Thread group handle as returned by thread_group_alloc().
__func – Function to call in separate thread with siganture
void(void*)
.__argument – [in] Parameter to pass to func.
__stack_base – [in] Word aligned pointer to the last word of the region to use as a stack when calling func. Note that this can be calculated with stack_base().
-
inline __xcore_bool_t
thread_group_try_add
(const threadgroup_t __group, const thread_function_t __func, void *const __argument, void *const __stack_base)¶ Attempts to add a new task to a thread group.
As thread_group_add() except returns false if no threads are available. If false is returned, the thread group has not been modified and no new resources have been allocated. If the result is nonzero then the task was successfully added to the group and will be launched when the group is started.
- Parameters
__group – Thread group handle as returned by thread_group_alloc().
__func – Function to call in separate thread with siganture
void(void*)
.__argument – [in] Parameter to pass to func.
__stack_base – [in] Word aligned pointer to the last word of the region to use as a stack when calling func. Note that this can be calculated with stack_base().
-
inline void
thread_group_start
(const threadgroup_t __group)¶ Starts all threads in a group running.
Starts execution of the thread functions for each thread in the group (as added using thread_group_add()). This function will return immediately regardless of the state of the threads.
Note
Use thread_group_wait() or thread_group_wait_and_free() to wait for the thread group to finish.
- Parameters
__group – The thread group to start.
-
inline void
thread_group_free
(const threadgroup_t __group)¶ Frees a thread group.
Returns the thread group to the pool so that it may be allocated again. The group handle is invalid once passed to this function so must not be re-used.
- Attention
This function must not be called on a thread group which has been started but not waited upon, even if its constituent threads have finished executing.
- Parameters
__group – The group to free.
-
inline void
thread_group_wait
(const threadgroup_t __group)¶ Wait for all threads in a thread group to finish.
The group must have been started using thread_group_start(). Calls to this function will block until all threads in the group have finished executing. Upon return of this function, the group remains valid but will no longer have any threads associated with it. The group may be re-used but threads must be re-added to it.
Note
Since the group remains valid, it should be freed with thread_group_free() if no longer required.
- Parameters
__group – The group to wait for completion.
-
inline void
thread_group_wait_and_free
(const threadgroup_t __group)¶ Waits for a thread group to finish then frees it.
Helper to both wait for and free a thread group. The group must have been started using thread_group_start() and the group will be invalid once this function returns.
Calls
-
inline xthread_t
xthread_alloc_and_start
(const thread_function_t __func, void *const __argument, void *const __stack_base)¶ Runs a function in another thread and returns a waitable handle.
Starts executing func in a separate hardware thread with argument as its sole parameter and with its stack pointer initialised to stack_base. stack_base must be word aligned and point to the last word of a block of memory sufficient to satisfy
func
’s stack requirements. That is, for a stack requirement ofs
words,[stack_base-s*word_size, stack_base]
will be used as the thread’s stack and will be clobbered.Note
The thread will begin execution immediately and this function will return. The thread will not be returned to the pool upon completion - it is necessary to call xthread_wait_and_free() to free the thread so that it may be reused.
- Parameters
__func – Function to call in separate thread with siganture
void(void*)
.__argument – [in] Parameter to pass to func.
__stack_base – [in] Word aligned pointer to the last word of the region to use as a stack when calling func. Note that this can be calculated with stack_base().
- Returns
A waitable handle for the hardware thread, or zero if the thread resource could not be allocated.
-
inline void
xthread_wait_and_free
(const xthread_t __xthread)¶ Wait for a thread to finish and then free it.
thread must have been allocated and started using xthread_alloc_and_start(). Calls to this function will block until the function called by thread has returned and upon completion it will free the associated hardware thread. thread must not be re-used after it has been freed.
- Parameters
__xthread – The thread to wait on, as returned by xthread_alloc_and_start().
-
inline void
run_async
(const thread_function_t __func, void *const __argument, void *const __stack_base)¶ Runs a function in another hardware thread.
Starts executing func in a separate hardware thread with argument as its sole parameter and with its stack pointer initialised to stack_base. stack_base must be word aligned and point to the last word of a block of memory sufficient to satisfy
func
’s stack requirements. That is, for a stack requirement ofs
words,[stack_base-s*word_size, stack_base]
will be used as the thread’s stack and will be clobbered.Note
The associated hardware thread will be freed once func returns, but it is not trivially possible to determine wether or not this has happened from the calling thread. If it necessary to wait for the completion of func then xthread_alloc_and_start() and xthread_wait_and_free() should be used instead.
- Parameters
__func – Function to call in separate thread with siganture
void(void*)
.__argument – [in] Parameter to pass to func.
__stack_base – [in] Word aligned pointer to the last word of the region to use as a stack when calling func. Note that this can be calculated with stack_base().
-
inline void *
stack_base
(void *const __mem_base, size_t const __words)¶ Returns a stack pointer suitable for use as a
stack_base
argument given a base address and a size.Given a base pointer (e.g. as returned by malloc or found by taking the address of an object) and the size of the intended stack in words, returns a stack base pointer to the last word of the stack - which is suitable for passing to the
stack_base
arguments of xthread_alloc_and_start(), run_async() and thread_group_add(). The given base address must be suitably aligned as the resulting stack pointer is required to be aligned also. The alignment requirement is a multiple of the word size and is target dependent. The resulting pointer will be a valid stack pointer for a stackwords
words in size. If used as a stack pointer for a function with a stack requirement no greater thanwords
words then the memory region used as a stack by that function will not be beyond[mem_base, (char *)mem_base + words*WORD_SIZE)
in either direction.- Parameters
__mem_base – [in] The base (lowest) address of the object/region to use as a stack. Must be word aligned.
__words – Size of the stack the returned pointed will return to in words
- Returns
The stack pointer.
-
inline void
local_thread_mode_set_bits
(const thread_mode_t __mode)¶ Set mode bits for the current thread.
Sets platform-dependent mode bits for the calling thread given a mask of bits to set. The mode bits passed must be a value from thread_mode_t or the bitwise disjunuction of two or more such values. The actual effect of setting mode bits varies by target; no bit is guaranteed to have any particular effect or any effect whatsoever. This function can only set bits - using a mode value with a bit unset will not clear that bit in the local thread mode. Instead, local_thread_mode_clear_bits() must be used.
- Parameters
__mode – Mask of bits to set
-
inline thread_mode_t
local_thread_mode_get_bits
(void)¶ Get the current thread’s mode bits.
Gets the platform-dependent mode bits for the current thread. The value returned will be the bitwise disjunction of zero or more values from thread_mode_t, and those members may be used as masks to interpret the result of this function.
- Returns
The calling thread’s mode bits
-
inline void
local_thread_mode_clear_bits
(const thread_mode_t __mode)¶ Clear bits in the current thread’s mode.
Given a mask, clear any bits which are set in that mask in the current thread’s mode. The mask must be a value from thread_mode_t or the bitwise disjunction of two or more such values. This can be used to unset bits which were set using local_thread_mode_set_bits().
- Parameters
__mode – The mask of bits to clear
xcore/triggerable.h¶
Functions applicable to Chanends, Ports and Timers for configuring events and interrupts.
Low level API for handling events and interrupts. It is generally recommended to use the SELECT API instead.
Note
A resource may only be configured for interrupts or events at a given time. Configuring interrupts for a resource may overwrite any event configuration and configuring events may overwrite any interrupt configurataion. A trigger controls the condition for both interrups and for events (whichever is enabled for the resource).
- See
xcore/select.h
xcore/interrupt.h
Defines
-
TRIGGERABLE_EV_BASE
¶ Minimum event vector value Interrupt values passed as iunterrupt data must be no less than this value.
-
TRIGGERABLE_SETUP_EVENT_VECTOR
(__resource, __label)¶ Configure the vector which handles events on a given resource.
Expands to a statement which configures the event vector for the given resource such that handling an event on that resource causes control to transfer to the given label.
Note
This will overwrite any interrupt vector which has been set on the resource.
- Parameters
__resource – The resource to configure
__label – The label to jump to when an event is handled on resource
- Throws ET_ILLEGAL_RESOURCEET_ILLEGAL_RESOURCE
not a valid chanend, port or timer
- Throws ET_RESOURCE_DEPET_RESOURCE_DEP
another core is actively using the resource.
-
TRIGGERABLE_WAIT_EVENT
(__labels…)¶ Wait for a configured and enabled event to occur.
Expands to a statements which waits for a configured event to occur and jumps to its event vector. Note that any possible event vector which may be jumped to (i.e. the labels configured as event vectors on all resources where events are enabled and an event may occur) must be passed as arguments otherwise the effect is undefined. Passing labels which cannot be reached by an enabled event may be ill formed if jumping to that label would be ill formed and may result in sub-optimal performance.
For a resource to raise an event:
Its trigger must be enabled with triggerable_enable_trigger() or triggerable_set_trigger_enabled()
Its trigger must occur; for a chanend this happens when data is available to be read, for ports and timers this will depend on the trigger which has been configured using the respective API. If at the point an event occurs the event vector has not been configured using TRIGGERABLE_SETUP_EVENT_VECTOR() then handling the event will have undefined behaviour.
- Attention
The expansion of this macro will block until the trigger occurs on a resource where events are enabled. If no events are enabled then this can never complete.
- Parameters
__labels – The labels configured as event vectors for all events which may occur.
-
TRIGGERABLE_TAKE_EVENT
(__labels…)¶ Jump to an event vector if an event is ready.
Has the same effect as TRIGGERABLE_WAIT_EVENT() except that if no event is waiting then this expansion does not block.
- Parameters
__labels – Labels which may be jumped to if an event is ready
Typedefs
-
typedef __xcore_interrupt_callback_t
interrupt_callback_t
¶ Interrupt handler type.
Functions
-
inline void
triggerable_setup_interrupt_callback
(resource_t __res, void *__data, interrupt_callback_t __func)¶ Setup interrupt event on a resource.
Once the interrupts is setup you need to call port_enable_trigger() to enable it.
- Parameters
__res – The resource to setup the interrupt event on.
__data – [in] The value to be passed to the interrupt_callback_t function On XS1 bit 16 must be set (see TRIGGERABLE_EV_BASE)
__func – The interrupt_callback_t function to handle events
- Throws
ET_ILLEGAL_RESOURCE – not a valid chanend, port or timer
ET_RESOURCE_DEP – another core is actively using the resource.
ET_ECALL – when xassert enabled, on XS1 bit 16 not set in data.
-
inline void
triggerable_enable_trigger
(resource_t __res)¶ Enable the trigger for a given resource.
This will allow the resource the generate events or interrupts when its trigger occurs.
- Parameters
__res – Resource to enable the trigger of
- Throws
ET_ILLEGAL_RESOURCE – not a valid chanend, port or timer
ET_RESOURCE_DEP – another core is actively using the resource.
-
inline void
triggerable_disable_trigger
(resource_t __res)¶ Disable the trigger for a given resource.
This prevents the resource generating events or interrupts.
- Parameters
__res – Resource to disable the trigger of
- Throws
ET_ILLEGAL_RESOURCE – not a valid chanend, port or timer
ET_RESOURCE_DEP – another core is actively using the resource.
-
inline void
triggerable_set_trigger_enabled
(resource_t __res, int __enabled)¶ Set the trigger enabled or disabled on a given resource.
Has the same effect as calling triggerable_enable_trigger() or triggerable_disable_trigger() depending on the value of enabled. However, this may perform better when the value of enabled is not statically known.
- Parameters
__res – The resource to enaable or disable the trigger of
__enabled – State to set on the trigger - if true it is enabled, otherwise it is disabled
- Throws
ET_ILLEGAL_RESOURCE – not a valid chanend, port or timer
ET_RESOURCE_DEP – another core is actively using the resource.
-
inline void
triggerable_disable_all
(void)¶ Disables all triggers in the current thread and masks interrupts.
Disables the triggers on all resources in use by the current thread and disabled interrupts as if with interrupt_mask_all().