Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Embedded libiio + libtinyiiod #1128

Merged
merged 20 commits into from
Jan 30, 2024
Merged

Embedded libiio + libtinyiiod #1128

merged 20 commits into from
Jan 30, 2024

Conversation

pcercuei
Copy link
Contributor

This set of patches enables support for compiling Libiio + IIOD on no-OS embedded devices.

Libiio itself can now be compiled without threads, using the NO_THREADS CMake option. This conflicts with all current backends (local, serial, usb, network) so those have to be disabled.

For embedded use, the backend used should be the "external" backend - enabled using the WITH_EXTERNAL_BACKEND CMake option. The application then has the responsability to provide the Libiio backend itself (or through a board-specific external library).

The embedded applications can now also implement a IIOD interface, using "libtinyiiod" that can be enabled with the WITH_LIBTINYIIOD CMake option. The API is described in iiod/libtinyiiod.h; the application is responsible for providing the callbacks to read/write on the communication bus (which can also be provided by a board-specific external library).

@rgetz
Copy link
Contributor

rgetz commented Jan 24, 2024

I'm assuming that when this is included - we would deprecate

How does this implemntation compare in size (text and data, stripped) to the existing libtinyiiod?

What are the requirements for this implmentions "no-OS embedded devices." I assume any 32-bit MCU with enough internal memory?

Has this been tested to replace the use cases where the existing tinyiiod is being used? Maybe @dbogdan has some good ideas where this should be tested before merged.

@pcercuei
Copy link
Contributor Author

Don't know yet; @buha will play with it in the coming days/weeks.

@pcercuei pcercuei force-pushed the pcercuei/libtinyiiod branch 8 times, most recently from 75afaaf to 22ddfd4 Compare January 25, 2024 13:06
No-OS applications most likely don't have <net/if.h>. This header was
included from dns_sd.h, which was included in utilities.c.

utilities.c only needed dns_sd.h for the FQDN_LEN macro; so move this
macro to network.h instead, which does not include any non-standard
headers.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
The problem with starting the enqueue/dequeue tasks when enabling the
IIO buffer is that the blocks might not have been enqueued yet by the
time the buffer is enabled. By starting the enqueue/dequeue tasks when
creating the IIO buffer, the blocks are much more likely to have been
enqueued by the time the buffer is enabled (but still not guaranteed,
unfortunately).

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
IIOD uses the high-level API of Libiio, it can run on top of any backend
(even though it would typically use the local backend).

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Add support for having an external backend, which is provided by the
application linking to Libiio.

This is especially useful on embedded systems, which cannot provide a
dynamically-loaded module.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Add support for building a thread-less Libiio.

This disables all current backends, but applications are still free to
provide their own external backend. This is especially useful on
embedded, where threads generally aren't a thing.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
In thread-less mode, instead of having a thread process the task
entries, they will be processed in-line in iio_task_enqueue() if the
task is running, and in iio_task_start() otherwise.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
In thread-less mode, the main loop will be executed inside
iiod_responder_wait_done().

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
This field was not used anywhere.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
This function was not used anywhere.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Support the PRINT command sending an uncompressed XML string, instead of
requiring ZSTD compression.

This makes it easier for embedded tinyiiod applications, which then
don't need to duplicate the XML string (once in plain text to create the
Libiio context using the XML backend, and once ZSTD-compressed for
tinyiiod).

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
If ZSTD was not enabled during compilation, the PRINT command will
simply send the uncompressed XML string. The client can then detect and
use the uncompressed string directly.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
When running threadless, the enqueue/dequeue operations will be executed
in-line; therefore, the buffer must be enabled before the tasks are
executed, otherwise these tasks will block on iio_block_enqueue() or
iio_block_dequeue().

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
This permits to compile a thread-less IIOD by using the dummy iio-lock
implementation.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
These functions are used by both IIOD and tinyiiod, and there's no
convenient place to place them; so move them to a new rw.c file.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
It provides zalloc() and the enum iio_attr_type.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
No-OS programs likely don't have <poll.h>, and don't need poll_nointr()
anyway; so move that function out of the way to iiod.c.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Move the <sys/socket.h> to where it's actually required, in
interpreter.c.

Remove the <endian.h> include which doesn't seem to be needed at all.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Add a WITH_LIBTINYIIOD CMake option, which defaults to OFF.

When enabled, a libtinyiiod.a static library will be built. The
library's API is described in tinyiiod/tinyiiod.h.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Due to the fact that tinyiiod runs thread-less, it is not possible to
have a blocking read to iio_event_stream_read().

To handle event reads properly, tinyiiod based applications should
return -EAGAIN in the iio_backend_ops.read_ev() callback if there is no
event, and have the responsability to call iiod_set_event() when an
event (or error) do occur.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
@buha
Copy link

buha commented Jan 29, 2024

So regarding size, a simple embedded app that just initializes the UART and configures this new tinyiiod to use the UART for communicating with the client, uses up:

   text	   data	    bss	    dec	    hex	filename
  95820	   1860	   2052	  99732	  18594	build/tinyiiod_demo.elf

This is with optimizations turned off and with debugging at -g3. (With optimizations on and debugging symbols off, I suspect flash usage would be reduced by a factor of 2x maybe 3x, didn't try.)

This would mean that the flash size needs to be 100 kB or more to fit such a program which is a good start, given that most micros that we use have 256 kB or more flash.

Ram usage at initialization is negligible. Ram usage at runtime after library init and a few mallocs I have not investigated.

My interpretation is that in any case, the benefits of using a common tinyiiod code base outweigh the cost of not being to run on the tinyest microcontrollers. I should also add that the iiod that was embedded into no-OS was lacking features compared to this one.

Copy link

@buha buha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm approving this since I can already run this on an embedded target and have it communicate with a client. Not all features are yet tested, but it's a good start.

The previous string used to detect the XML header contained the
encoding hardcoded to "utf-8", which means that a XML string using the
"UTF-8" (or any other encoding really) wouldn't be recognized as a valid
XML string.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
@pcercuei pcercuei merged commit 26d5f6e into main Jan 30, 2024
22 of 25 checks passed
@pcercuei pcercuei deleted the pcercuei/libtinyiiod branch January 30, 2024 12:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants