Microvisor is in a pre-release phase and the information contained in this document is subject to change. Some features referenced below may not be fully available until Microvisor's General Availability (GA) release.
Microvisor system calls currently include the following functions to manage the application's access to the Internet:
All of the functions described below return a 32-bit integer that is one of the values from the standard Microvisor enumeration MvStatus
. All possible error values for a given system call are provided with each function's description.
Success is always signaled by a return value of zero (MV_STATUS_OKAY
).
Ask Microvisor to establish a primary network connection
1extern enum MvStatus mvRequestNetwork(const struct MvRequestNetworkParams *params,2MvNetworkHandle *handle);
Parameter | Description |
---|---|
params | A pointer to non-secure memory in which network configuration data is stored by the application |
handle | A pointer to non-secure memory into which the network handle will be written by Microvisor |
Error Value | Description |
---|---|
MV_STATUS_PARAMETERFAULT | params or handle does not reference memory accessible to the application; the number of handles already assigned is at maximum; or one of the properties of params is incorrect — see below |
MV_STATUS_UNSUPPORTEDSTRUCTUREVERSION | The version of the params structure is not supported by Microvisor |
This call, if successful, may subsequently yield any of the following notifications.
Notification Event Type | Description |
---|---|
MV_EVENTTYPE_NETWORKSTATUSCHANGED | Issued any time the network's status has changed. Applications should call mvGetNetworkStatus() to determine what has changed, but you should note that some changes may occur in rapid succession. Since network status values are not queued, a call to mvGetNetworkStatus() will obtain the instantaneous status at the time of the call, not a history of changes |
An application can call this function at any time to request that Microvisor establishes a connection to the Internet. Once the connection is in place, the application can use the returned network handle to establish data channels for the transfer of information.
Microvisor will maintain no more than 128 concurrent network handles, and will return an error if you request a further handle without first calling mvReleaseNetwork()
for an existing network handles.
The params
parameter takes a pointer to a MvRequestNetworkParams
structure:
1struct MvRequestNetworkParams {2uint32_t version;3union {4struct {5MvNotificationHandle notification_handle;6uint32_t notification_tag;7} v1;8};9};
These properties are:
version
— The system calls version. This should always be 1
.notification_handle
— The handle of the notification center you wish to dispatch notifications relating to the connection. The notification center must already have been instantiated. For more information, please see the Microvisor system calls overview and notification functions.notification_tag
— An arbitrary 32-bit value you can specify and which will then be included in all notifications relating to this connection. For more information, please see the Microvisor System Calls overview.Please see A Guide to Microvisor Networking for code samples.
Request the state of a specific network connection
1extern enum MvStatus mvGetNetworkStatus(MvNetworkHandle handle,2enum MvNetworkStatus *status);
Parameter | Description |
---|---|
handle | The required network's handle |
status | A pointer to non-secure memory into which the status value will be written by Microvisor |
Error Value | Description |
---|---|
MV_STATUS_PARAMETERFAULT | status references memory not accessible to the application |
MV_STATUS_INVALIDHANDLE | handle is invalid or does not identify an existing network connection |
Call this function to get an indication of the network connection's current state. The value written to the memory referenced by status
will be one of the following:
Status | Value | Description |
---|---|---|
MV_NETWORKSTATUS_DELIBERATELYOFFLINE | 0 | The device is not connected |
MV_NETWORKSTATUS_CONNECTED | 1 | The device is connected |
MV_NETWORKSTATUS_CONNECTING | 2 | The device is connecting to the Internet |
Please see A Guide to Microvisor Networking for code samples.
Relinquish access to a specified network connection
extern enum MvStatus mvReleaseNetwork(MvNetworkHandle *handle);
Parameter | Description |
---|---|
handle | A pointer to non-secure memory in which the required network's handle is stored by the application |
Error Value | Description |
---|---|
MV_STATUS_PARAMETERFAULT | handle references memory not accessible to the application |
MV_STATUS_INVALIDHANDLE | handle is invalid or does not identify an existing network connection |
An application can call this function at any time to relinquish access to a network connection that Microvisor has established for it. If the request is successful — the call does not return an error — then the network handle will be invalidated: Microvisor will zero the non-secure bytes in which the handle is stored. The network connection will be closed, i.e., the device disconnected, provided there are no other valid network handles in place and the connection is not in use by Microvisor.
Please see A Guide to Microvisor Networking for code samples.
Request information on the state of the Microvisor's network management system
1extern enum MvStatus mvGetNetworkReasons(enum MvNetworkReason *reasons,2uint32_t *current_handle_count);
Parameter | Description |
---|---|
reasons | A pointer to non-secure memory into which the network reasons bitfield will be written by Microvisor |
current_handle_count | A pointer to non-secure memory into which the number of extant handles will be written by Microvisor |
Error Value | Description |
---|---|
MV_STATUS_PARAMETERFAULT | reasons or current_handle_count references memory not accessible to the application |
Call this function to receive a snapshot of the state of Microvisor's networking subsystem rather than that of a specific network connection (cf. mvGetNetworkStatus()
). For instance, you can call mvGetNetworkReasons()
at any time and even if the application has not yet initiated a connection by calling mvRequestNetwork()
.
The value written to the memory referenced by reasons
will be a bitfield comprising any or all of the following flags:
Flag | Value | Description |
---|---|---|
MV_NETWORKREASON_NOTCONNECTING | 0x0000 | There are no pending connection attempts and connections not being prevented |
MV_NETWORKREASON_USINGNETWORK | 0x0001 | The application is using the network |
MV_NETWORKREASON_NEVERUSEDNETWORKAPI | 0x0002 | The application has not yet made use of the networking system calls. This will remain set until the application makes its first call to mvRequestNetwork() |
MV_NETWORKREASON_MINIMUMCHECKINEXPIRED | 0x0004 | Microvisor's minimum check-in period has expired |
MV_NETWORKREASON_RTCNOTSET | 0x0008 | The device RTC has not yet been set |
MV_NETWORKREASON_KERNELERROR | 0x0010 | A Microvisor error requires reporting |
MV_NETWORKREASON_APPLICATIONERROR | 0x0020 | An application error requires reporting |
MV_NETWORKREASON_COLDBOOTCONNECTION | 0x0040 | A connection was needed on cold boot in order to apply updates |
MV_NETWORKREASON_FETCHINGUPDATE | 0x0080 | An update is being fetched in the background |
MV_NETWORKREASON_DEBUGGERATTACHED | 0x0100 | A debugging session is attached to the device |
MV_NETWORKREASON_NOAPPLICATIONCODE | 0x0200 | No application code is present on the device |
MV_NETWORKREASON_ENHANCECALM | 0x8000 | Microvisor has been instructed by the server to make no further connection attempts for a time |
The value written to current_handle_count
will be the number of network handles Microvisor is currently maintaining, ie., from 0 to 128 inclusive.
Please see A Guide to Microvisor Networking for code samples.
Ask Microvisor to open a data transfer channel
1extern enum MvStatus mvOpenChannel(const struct MvOpenChannelParams *params,2MvChannelHandle *handle);
Parameter | Description |
---|---|
params | A pointer to non-secure memory in which channel configuration data is stored by the application |
handle | A pointer to non-secure memory into which the channel handle will be written by Microvisor |
Error Value | Description |
---|---|
MV_STATUS_PARAMETERFAULT | handle , params or a pointer in params references memory not accessible to the application |
MV_STATUS_INVALIDHANDLE | The value of notification_handle or network_handle in params is not a valid notification center handle |
MV_STATUS_INVALIDBUFFERSIZE | The value of send_buffer and/or receive_buffer buffer in params is mis-sized according to channel type |
MV_STATUS_INVALIDBUFFERALIGNMENT | The value of send_buffer and/or receive_buffer buffer in params is not suitably aligned according to channel type |
MV_STATUS_UNKNOWNCHANNELTYPE | The specified value of channel_type in params isn't recognized |
MV_STATUS_UNKNOWNENDPOINT | The value of endpoint in params isn't recognized |
MV_STATUS_NETWORKNOTCONNECTED | The network specified by network_handle in params isn't in the MV_NETWORKSTATUS_CONNECTED state |
MV_STATUS_TOOMANYCHANNELS | Opening this channel would exceed the number of simultaneously open channels |
This call, if successful, may subsequently yield any of the following notifications.
Notification Event Type | Description |
---|---|
MV_EVENTTYPE_CHANNELDATAREADABLE | Issued when data has been received by Microvisor and written to the channel's receive buffer. Microvisor will dispatch a further MV_EVENTTYPE_CHANNELDATAREADABLE notification every time mvReadChannel() is called and not all of the remaining data was read |
MV_EVENTTYPE_CHANNELDATAWRITESPACE | Issued when the amount of free space in the buffer increases. The application may use this as a signal to send more data, or to wait for data to be fully sent before closing the channel |
MV_EVENTTYPE_CHANNELNOTCONNECTED | Issued when the channel's line of communication is broken unintentionally, including by a call to mvReleaseNetwork() on the open channel's host network. Data written to the RX buffer is still available and can be read, but the application will receive an error if it attempts to write to the TX buffer after receiving this notification. Instead, the application should read any remaining data and call mvCloseChannel() to explicitly invalidate the channel handle |
The application makes use of channels to transfer data over a network connection established by Microvisor. Think of the network as the transport layer and a channel as a data-exchange protocol operating via that transport. The network must be connected for the channel to be opened. Up to four channels can be opened at any one time on a given network connection.
Channels are bi-directional and maintain flow control: if you don't read incoming data, the receive buffer will fill, and no more incoming data will be accepted until space is made for it.
The channel will be available to write to and read from as soon as mvOpenChannel()
returns no error, but that doesn't mean that the target is ready or has accepted the channel — your code will need to ensure it can communicate before attempting to do so.
You configure the channel by providing a pointer to a MvOpenChannelParams
structure:
1struct MvOpenChannelParams {2uint32_t version;3union {4struct {5MvNotificationHandle notification_handle;6uint32_t notification_tag;7MvNetworkHandle network_handle;8uint8_t *receive_buffer;9uint32_t receive_buffer_len;10uint8_t *send_buffer;11uint32_t send_buffer_len;12enum MvChannelType channel_type;13struct MvSizedString endpoint;14} v1;15};16};
These properties are:
version
— The system calls version. This should always be 1.notification_handle
— The handle of the notification center you wish to dispatch notifications relating to the channel. The notification center must already have been instantiated. For more information, please see the Microvisor system calls overviewnotification_tag
— An arbitrary 32-bit value you can specify and which will then be included with all notifications relating to this channel. For more information, please see the Microvisor system calls overview.network_handle
— A pointer to non-secure memory in which the host network's handle is stored by the application.receive_buffer
, send_buffer
— Pointers to RX and TX buffers — see below.receive_buffer_len
, send_buffer_len
— The size of the RX and TX buffers — see below.channel_type
— The protocol to be used — see below.endpoint
— A data structure comprising an endpoint identifier for cloud configuration in bytes and the number of bytes — see below.It is the responsibility of the application to provide memory for the channel's send and receive buffers. As with other Microvisor buffers, these are circular: Microvisor maintains a write pointer which is incremented as data is written but which will jump back to the start when the end of the backing store is reached.
For both the send and receive buffers, you specify their location in non-secure, i.e., application, memory and their sizes. Microvisor will write-protect the send buffers when the channel is opened. The send buffer must be a multiple of 512 bytes in size and its address must be 512-byte aligned. For example:
static volatile uint8_t http_rx_buffer[HTTP_RX_BUFFER_SIZE_B] __attribute__((aligned(512)));
The same is true of the receive buffer if you are working with HTTP channels. Beyond this limit, you're free to choose any size and non-secure location for the receive buffer, but you should ensure you have sufficient capacity for a response's headers and data. You will receive an MV_HTTPRESULT_RESPONSETOOLARGE
error — via mvReadHttpResponseData()
— if the received headers and data are too large for the buffer size you have chosen.
Once a channel is open, it isn't possible to resize the buffers or change their addresses. While buffers are in use, the application must not write to them or use their memory for other purposes. In fact, attempts to write to the send buffer will trigger an application crash. When the channel is closed, Microvisor zeroes the send buffer contents and removes the write protection.
Microvisor will support a number of channel types: protocols by which data can be exchanged with remote services. Currently, Microvisor supports only the transmission and reception of HTTP — channel type MV_CHANNELTYPE_HTTP
. We expect to support MQTT transfers in due course.
The channel type MV_CHANNELTYPE_OPAQUEBYTES
is now deprecated and should not be used. It is expected to be removed before Microvisor reaches General Availability (GA).
The endpoint
property is expected to be used to specify the name of a cloud-stored configuration record. This configuration will indicate a channel's target end server and the credentials required to access that resource. This will be done to ensure that the application code need hold high-value credentials.
This functionality is not yet implemented.
Please see A Guide to Microvisor Networking for code samples.
Read a number of bytes from the channel's RX buffer
This call has been deprecated and should not be used. It is expected to be removed before Microvisor reaches General Availability (GA).
1extern enum MvStatus mvReadChannel(MvChannelHandle handle,2uint8_t **read_pointer,3uint32_t *length);
Parameter | Description |
---|---|
handle | The specified channel's handle |
read_pointer | A pointer to non-secure memory into which Microvisor will write a pointer to the new data |
length | A pointer to non-secure memory in which the amount of data that can be read will be written by Microvisor |
Error Value | Description |
---|---|
MV_STATUS_PARAMETERFAULT | length does not reference memory accessible to the application |
MV_STATUS_INVALIDHANDLE | handle is invalid or does not identify an existing channel |
MV_STATUS_CHANNELCLOSED | The specified channel has already been closed |
When data has been received through a channel, Microvisor dispatches an MV_EVENTTYPE_CHANNELDATAREADABLE
notification. The application can read the data now or later, but when it does so, it calls mvReadChannel()
to learn how many bytes to read and where those bytes are located. This is done by setting read_pointer
and writing the size to length
.
The application doesn't need to read all the available data in one go. When it has read any of the data, or no longer requires it, it must call mvReadChannelComplete()
to inform Microvisor that some bytes are now available to take fresh incoming data.
Please see A Guide to Microvisor Networking for code samples.
Inform Microvisor the application has read a number of bytes from the RX buffer
This call has been deprecated and should not be used. It is expected to be removed before Microvisor reaches General Availability (GA).
1extern enum MvStatus mvReadChannelComplete(MvChannelHandle handle,2uint32_t consumed);
Parameter | Description |
---|---|
handle | The specified channel's handle |
consumed | The number of buffer bytes processed by the application |
Error Value | Description |
---|---|
MV_STATUS_INVALIDHANDLE | handle is invalid or does not identify an existing channel |
MV_STATUS_CHANNELCLOSED | The specified channel has already been closed |
When the application reads from a channel's RX buffer using mvReadChannel()
, it should call mvReadChannelComplete()
when it has finished reading. It specifies the number of bytes consumed, whether that's all of the received bytes or just some of them. This ensures that Microvisor knows how much space has been freed for further incoming data.
Please see A Guide to Microvisor Networking for code samples.
Write bytes to a channel's TX buffer
This call has been deprecated and should not be used. It is expected to be removed before Microvisor reaches General Availability (GA).
1extern enum MvStatus mvWriteChannel(MvChannelHandle handle,2const uint8_t *data,3uint32_t length,4uint32_t *available);
Parameter | Description |
---|---|
handle | The specified channel's handle |
data | A pointer to the data to be written to the buffer |
length | The number of bytes to be written |
available | A pointer to non-secure memory into which the number of free bytes in the buffer after the write operation will be written by Microvisor |
Error Value | Description |
---|---|
MV_STATUS_PARAMETERFAULT | data or available does not reference memory accessible to the application |
MV_STATUS_INVALIDHANDLE | handle is invalid or does not identify an existing channel |
MV_STATUS_INVALIDBUFFERSIZE | No data was consumed because it does not all fit into the channel's send buffer |
MV_STATUS_LATEFAULT | written is not a valid pointer, but data has been written to the channel |
MV_STATUS_CHANNELCLOSED | The specified channel has already been closed |
To write data to the channel's TX buffer, pass a pointer to the data and indicate its length. Microvisor will check that there is sufficient free space in the buffer. If there is, it will copy the data into the buffer and then write the number of free bytes remaining to the memory referenced by available
.
If the buffer has insufficient space for the data, Microvisor will write the number of free bytes to the memory referenced by available
and return an error. It does not copy any of the data to the buffer to allow the application to decide what action to take: to re-call mvWriteChannel()
with sufficient data to fill the available space, for example.
To avoid this decision, applications can call mvWriteChannel()
with length
set to zero: this causes Microvisor just to return the buffer's count of available bytes. The application can use that value to fill or partially fill the free space in the buffer. Applications can flush the TX buffer by writing exactly the number of bytes needed to fill the buffer.
Please see A Guide to Microvisor Networking for code samples.
Write to a channel in streaming mode
This call has been deprecated and should not be used. It is expected to be removed before Microvisor reaches General Availability (GA).
1extern enum MvStatus mvWriteChannelStream(MvChannelHandle handle,2const uint8_t *data,3uint32_t length,4uint32_t *written);
Parameter | Description |
---|---|
handle | The specified channel's handle |
data | A pointer to the data to be written to the buffer |
length | The number of bytes to be written |
written | A pointer to non-secure memory into which the number of bytes written will be output by Microvisor |
Error Value | Description |
---|---|
MV_STATUS_PARAMETERFAULT | data or writtem does not reference memory accessible to the application |
MV_STATUS_INVALIDHANDLE | handle is invalid or does not identify an existing channel |
MV_STATUS_LATEFAULT | written is not a valid pointer, but data has been written to the channel |
MV_STATUS_CHANNELCLOSED | The specified channel has already been closed |
mvWriteChannelStream()
allows applications to treat the channel as a byte-oriented stream. In this case, it is not an error if Microvisor doesn't have space to write all or any of the data: it will just write what it can. The amount of data consumed by Microvisor is passed back to the application through the written
pointer, allowing it to keep the stream fed.
Contrast this with mvWriteChannel()
, which adopts a message-centric approach.
Please see A Guide to Microvisor Networking for code samples.
Instruct Microvisor to shut down a channel
extern enum MvStatus mvCloseChannel(MvChannelHandle *handle);
Parameter | Description |
---|---|
handle | A pointer to non-secure memory in which the channel's handle is stored by the application |
Error Value | Description |
---|---|
MV_STATUS_PARAMETERFAULT | handle does not reference memory accessible to the application |
MV_STATUS_INVALIDHANDLE | handle is invalid or does not identify an existing channel |
MV_STATUS_CHANNELCLOSED | The specified channel has already been closed |
When the application has finished with a channel, it can call mvCloseChannel()
to end communication and free the resources used by it. Microvisor also zeroes the handle store and removes write protection from the send buffer. Once the call has returned — and only after the call has returned — the application can reallocate buffer memory as it sees fit.
Application crashes or restarts should be treated as implicit channel closures.
Please see A Guide to Microvisor Networking for code samples.
Determine why a channel was closed
1extern enum MvStatus mvGetChannelClosureReason(MvChannelHandle handle,2enum ClosureReason *reason);
Parameter | Description |
---|---|
handle | The specified channel's handle |
reason | A pointer to the non-secure memory into which the channel closure reason code will be written by Microvisor |
Error Value | Description |
---|---|
MV_STATUS_PARAMETERFAULT | reason does not reference memory accessible to the application |
MV_STATUS_INVALIDHANDLE | handle is invalid or does not identify an existing channel |
If the application receives an MV_EVENTTYPE_CHANNELNOTCONNECTED
notification, it can call mvGetChannelClosureReason()
to find out why the channel was closed. It should do so before mvCloseChannel()
is called, or the channel's handle will be invalidated and made inaccessible. It is good practice to call mvCloseChannel()
on unexpectedly closed channels in order to invalidate the handle and ensure the channel is not used inadvertently.
When mvGetChannelClosureReason()
is called, Microvisor writes a reason code to the memory referenced by reason
. It will be one of the following:
Constant | Code Value | Description |
---|---|---|
MV_CLOSUREREASON_NONE | 0 | The channel is not closed, or the closure reason is not known |
MV_CLOSUREREASON_CHANNELCLOSEDBYSERVER | 1 | The channel was closed by the server |
MV_CLOSUREREASON_CHANNELRESETBYSERVER | 2 | The server reset the channel |
MV_CLOSUREREASON_NETWORKDISCONNECTED | 3 | The channel was closed because the network was disconnected |
MV_CLOSUREREASON_CONNECTIONTERMINATED | 4 | The connection to the server was terminated due to an error |
MV_CLOSUREREASON_NOTYETOPEN | 5 | The application has not yet called mvOpenChannel() or the call failed |
MV_CLOSUREREASON_CLOSEDBYAPPLICATION | 6 | The application has called mvCloseChannel() |
MV_CLOSUREREASON_UNEXPECTEDLYTERMINATED | 7 | The channel was terminated, but the reason is unknown |
Please see A Guide to Microvisor Networking for code samples.