OpenEmbedded, IOTA CClient and a Raspberry Pi

The full article was originally published by Bernardo Rodrigues on Medium. Read the full article here.

This is my second article for the IOTA community. It presents the possibilities of the meta-iota OpenEmbedded layer with a hands-on tutorial that acts as a proof-of-concept. In the first article, I talked about how to run IOTA cIRI on a BeagleBone Black with Yocto Project and OpenEmbedded. It showed how the meta-iota layer can help with the cross-compilation of an embeddable IOTA node.

This time, I want to focus on the client side of things. The repository c-iota-workshop, has practical examples of how to use the CClient library to write C applications and interact with the Tangle. Although both the enTangled and the c-iota-workshop repositories provide the possibility of building with Bazel, which in theory allows cross-compilation for a Raspberry Pi, I want to show how to do that with BitBake. This tutorial can be easily translated into several different boards, as long as there is an OpenEmbedded BSP layer supporting it.


First, let’s take a look at the contents of c-iota-workshop. It contains 6 examples, namely:

These examples show how C code can be used to write Client applications to interact with the Tangle. There are, however, some restrictions. Many parameters (such as SEED, RECEIVER_ADDR, ADDR_HASH and TLS_CERTIFICATE_PEM) are hard-coded, and real production applications should handle them differently (especially the seed, which is the most critical information of a client and should never be revealed). Nevertheless, these are still extremely useful references to understand how the CClient API should be manipulated.

Now, let’s take a look at the BitBake repice ( that cross-compiles these examples:

SUMMARY = "C IOTA workshop"
DESCRIPTION = "Some simple examples to get you started on developing with IOTA using C."
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"



S = “${WORKDIR}/git”

DEPENDS = ” libcclient uthash keccak logger”

${CC} -I${S} ${CFLAGS} ${LDFLAGS} -o iota_c_hello_world examples/e01_hello_world.c iota_client_service/client_service.c -lcclient -lcommon -lcjson -lkeccak -lmbedtls -lmbedcrypto -lmbedx509 -lhttp_parser -llogger -pthread
${CC} -I${S} ${CFLAGS} ${LDFLAGS} -o iota_c_send_hello examples/e02_send_hello.c iota_client_service/client_service.c -lcclient -lcommon -lcjson -lkeccak -lmbedtls -lmbedcrypto -lmbedx509 -lhttp_parser -llogger -pthread -lm
${CC} -I${S} ${CFLAGS} ${LDFLAGS} -o iota_c_receive_hello examples/e03_receive_hello.c iota_client_service/client_service.c -lcclient -lcommon -lcjson -lkeccak -lmbedtls -lmbedcrypto -lmbedx509 -lhttp_parser -llogger -pthread
${CC} -I${S} ${CFLAGS} ${LDFLAGS} -o iota_c_generate_address examples/e04_generate_address.c iota_client_service/client_service.c -lcclient -lcommon -lcjson -lkeccak -lmbedtls -lmbedcrypto -lmbedx509 -lhttp_parser -llogger -pthread
${CC} -I${S} ${CFLAGS} ${LDFLAGS} -o iota_c_check_balance examples/e05_check_balance.c iota_client_service/client_service.c -lcclient -lcommon -lcjson -lkeccak -lmbedtls -lmbedcrypto -lmbedx509 -lhttp_parser -llogger -pthread
${CC} -I${S} ${CFLAGS} ${LDFLAGS} -o iota_c_send_tokens examples/e06_send_tokens.c iota_client_service/client_service.c -lcclient -lcommon -lcjson -lkeccak -lmbedtls -lmbedcrypto -lmbedx509 -lhttp_parser -llogger -pthread -lm

install -m 0755 -d ${D}${bindir}
install -m 0755 ${S}/iota_c_hello_world ${D}${bindir}
install -m 0755 ${S}/iota_c_send_hello ${D}${bindir}
install -m 0755 ${S}/iota_c_receive_hello ${D}${bindir}
install -m 0755 ${S}/iota_c_generate_address ${D}${bindir}
install -m 0755 ${S}/iota_c_check_balance ${D}${bindir}
install -m 0755 ${S}/iota_c_send_tokens ${D}${bindir}

Here, the variable DEPENDS is telling BitBake what are the other recipes that need to be compiled before it starts with this one. That is necessary so the recipe’s sysroot is correctly set up with the necessary libs and headers. The dependency list should actually be much bigger, but luckily already declares most of them, and because our recipe depends on it, its dependencies also come into our sysroot.

Then, the do_compile() task is defined. We are not using Make, CMake, Bazel or any other tool to coordinate the compilation. Each one of the 6 examples is explicitly compiled with the invocation of ${CC}, which is the BitBake variable that represents the C Cross Compiler. All the libraries are listed for linking.

Finally, the do_install() task is responsible for placing the executable binaries into the destination directory, represented by the ${D} variable. The ${bindir} variable means that the binaries will reside in the /usr/binpath of the final rootfs. The -m parameter of the install command is meant to set the appropriate file permissions (-rwxr-xr-x) of each executable.

Read the full Article

The full article was originally published by Bernardo Rodrigues on Medium, where people are continuing the conversation by highlighting and responding to this story.

You might also like

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. AcceptRead More