Expand description
Applet-side of the applet API.
This api
crate provides Rust bindings for the Wasm-side of the applet API.
Users should not directly use those bindings but instead use the prelude
crate
that provides higher-level and more convenient access.
The bindings in this crate are automatically generated from a proc-macro based
on a procedural description of the applet API defined in the api-desc
crate.
As such, they follow a precise convention:
- The module hierarchy in the applet API is mapped to the module hierarchy in this crate.
- Type definitions (like enums) are mapped to their definition. If an enum is
used as an error, it provides a
Error::to_result(isize) -> Result<usize, Error>
method to convert signed integer results into RustResult
. - Functions are mapped to their definition but also to a module of the same
name. This module defines 2 structs:
Params
for the parameters of the function andResults
for the results of the function. If a struct is empty, then it is not used. - All parameters and results are 32-bits integers mapping to the
i32
Wasm type, but their Rust type reflect their role. For example:usize
for unsigned integersisize
for signed integers (which may represent someResult<u31, u31>
where the error type may be converted to some enum)*const u8
and*mut u8
for opaque/polymorphic pointers*const T
and*mut T
for transparent pointers whereT
is recursively definedextern "C" fn(data: *const u8, ...)
for closures over some opaque data and possibly additional parameters
§WebAssembly-level documentation
§Applet functions
An applet must expose 3 functions to the platform:
init: () -> ()
called exactly once before anything else. It cannot call any platform function exceptdp
(akadebug::println()
).main: () -> ()
called exactly once afterinit
returns. It can call all platform functions.alloc: (size: u32, align: u32) -> (ptr: u32)
may be called during any platform function afterinit
returned. It cannot call any platform function. A return value of zero indicates an error and will trap the applet. The applet may assume thatsize
is a non-zero multiple ofalign
andalign
is either 1, 2, or 4.
§Platform functions
The platform exposes many functions. Each function comes with its own documentation, which may omit the following general properties.
§Parameters and result
At WebAssembly level, all functions use u32
(more precisely i32
) as
parameters and result (WebAssembly permits multiple results, but platform
functions never return more than one value). However, platform functions will be
documented with more specific types to better convey the intent.
Languages that compile to WebAssembly may use similar specific types when
binding platform functions. Those types should be compatible with u32
in
WebAssembly.
§Applet closures
Some functions (usually called register
) may register a closure. There is
usually an associated function (usually called unregister
) that unregisters
the registered closure. The register function takes fn { data: *const void, ... }
(usually called handler_func
) and a *const void
(usually called
handler_data
) as arguments. The unregister function (if it exists) doesn’t
have any particular parameters.
After the closure is registered (the register function is called) and as long as
it stays registered (the unregister function is not called), the platform may
call this closure any time sw
(aka scheduling::wait_for_callback()
) is
called. Note that if main
returns and there are registered closures, the
applet behaves as if sw
is called indefinitely.
An applet closure may call any platform function unless explicitly documented by the register function.
§Reading and writing memory
Some functions take pointers as argument (usually *const u8
or *mut u8
).
They either document the expected size or take an associated length argument.
The platform may read and write (only for *mut T
pointers) the designated
region of the WebAssembly memory during the function call. Otherwise (and by
default), platform functions don’t read or write the WebAssembly memory.
§Allocating memory
Finally, some functions take nested pointers as argument (usually *mut *mut u8
). They either return a usize
or take a *mut usize
as argument.
Those functions may call alloc
(at most once per such nested pointer argument)
with a dynamic size but fixed alignment (usually 1). If they do, they will store
the non-null result in the *mut *mut u8
argument. Regardless of whether they
allocate or not, they store the size in the *mut usize
argument (if it exists)
or return it (otherwise).
Note that alloc
will not be called with a size of zero. So if the size is zero
after the function returns, this signifies that alloc
was not called (and the
*mut *mut u8
not written) and the output is empty (unless otherwise documented
like in the case of an absence of output, in which case the size may not be
written).
The caller is responsible for managing the allocation after the function returns
and the size is non-zero. To avoid memory leaks, the applet should initialize
the *mut usize
argument (if it exists) to zero and consider having ownership
of the *mut *mut u8
pointee if the size is non-zero after the call.
Modules§
- button
- Button and touch operations.
- clock
- Clock operations.
- crypto
- Cryptographic operations.
- debug
- Debugging operations.
- fingerprint
- Fingerprint operations.
- gpio
- Low-level GPIO operations.
- led
- LED operations.
- platform
- Platform operations.
- rng
- Random number generators.
- scheduling
- store
- Persistent storage operations.
- timer
- Timer operations.
- uart
- usb
- USB operations.
- vendor
- Vendor interface.