Introduction
μcuREST (micurest) is a C++11 library for implementing REST services on constrained platforms, such as bare metal applications on low-end MCUs. The library is platform-agnostic, zero-allocation, and has almost no external dependencies. It allows mapping hierarchically organized URIs to C/C++ variables, constants and methods, and exposing the URIs via HTTP protocol.
Architecture
Diagram on the left shows architecture of a RESTful application, implemented with μcuREST library. The latter facilitates the Core, a set of Content Providers and a set of Resource Mapping Templates. For some platforms, μcuREST also provide implementation of I/O stream interfaces to platform specific Transport Layer. The Application provides content (variables, functions, methods) and a Resource Map, which is the key part of application’s design. This map statically (at compile time) associates application content with URIs and content providers.
Transport Layer
An application, implementing HTTP RESTful services with μcuREST, needs a platform specific transport layer and a mediator (Session Layer in terms of OSI model) between μcuREST and the transport layer. The mediator must handle sessions and implement two interfaces: istream and ostream.
Resource Map
Resource map is defined with C++ language, using a set of templates. Example of a simple map is given on Example 1, a more complicated example available on Example 2.
/* map of URIs to application resources */ const directory& resourceMap() noexcept { return Root< resource::FileConstString<name::hello_html, hello_html_content, media::html>, resource::FileText<name::hello, sizeof(hello_text), hello_text>, resource::FileFunctions<name::led, bool, getLed, setLed> >(); }
/* map of URIs to application resources * D defines a directory, * E defines an entry with a name and content node * N defines a content node * F combines E and N in one for simple content, such as variables */ const directory& resourceMap() noexcept { return Root< /// this notation documents URI of the resource /* cost of adding another page: 190/28 */ /* first entry that matches accepted content is served by default */ E<name::io, Embed<io>>, /* directory d */ D<name::d, E<name::X, N<V<micurest::accessor::vector<byte, digital_read, digital_write, digital_has>>>>, E<identity::numeric, N<micurest::accessor::vector<byte, digital_read, digital_write, digital_has>>>>, /* directory r */ D<name::r, E<name::X, N<V<micurest::accessor::vector<byte, relay_read, relay_write, relay_has>>>>, E<identity::numeric, N<micurest::accessor::vector<byte, relay_read, relay_write, relay_has>>>>, /* directory a */ D<name::a, E<name::X, N<V<micurest::accessor::bunch<int, analog_read, analog_has>>>>, E<identity::numeric, N<micurest::accessor::bunch<int, analog_read, analog_has>>>>, /* directory in */ D<name::in, E<name::X, N<V<micurest::accessor::bunch<byte, interrupt_read, interrupt_has>>>>, E<identity::numeric, N<micurest::accessor::bunch<byte, interrupt_read, interrupt_has>>>>, E<name::X, json_node>, F<name::blob,&blob_length, sizeof(blob), blob>, F<name::mode, pointer<enums::mode_t, &mode>>, E<name::modes, N<enums::list<enums::mode_names>>>, E<name::ip, N<V<ip_addr, &ip>>>, E<name::mac, N<V<mac_addr, &mac>>>, E<name::rtc, Object<datetime>>, E<name::demo, Embed<demo>>, F<name::natural, pointer<unsigned, &natural>>, F<name::logical, pointer<bool, &logical>>, F<name::text, countof(text), text> >(); }
Limitations
μcuREST implements a minimal subset of HTTP specification, sufficient for serving GET requests from browsers, GET/PUT/POST requests from JavaScript via XMLHttpRequest and simple machine-to-machine communications. Only normalized case-sensitive URIs are supported. Query strings, cookies, absolute URLs, cache control, transfer encoding, and many other HTTP features are not supported. Support for authentication is currently in consideration.
Depending on the transport layer in use and the mediator implementation, HTTM message size could be limited to the size of one MTU (~1460 bytes).
Principle of Operation
Requirements
- Compiler: μcuREST sources need a C++11 enabled compiler, such as g++-4.8 and up.
- Library: libstdc++ v3 highly desirable. But if not available a workaround exists
- Transport layer: A platform specific transport layer, such as TCP/IP, is required for implementing HTTP REST services.
- ROM/RAM space: on AVR platform μcuREST core takes 6K of ROM and 100 bytes of RAM. Size of the resource map starts with 3K/200 and grows with its complexity, taking in average 750 bytes of ROM and 250 bytes of RAM per entry.
Screenshots
Below you may find screenshots of web pages, implemented in examples for Controllino MAXI, ESP8266 NodeMCU and Particle Photon
Post a Comment