How to Run IoT.js on the Raspberry PI 0

IoT.js is a lightweight JavaScript platform for building Internet of Things devices; this article will show you how to run it on a few dollars worth of hardware. The First version of it was released last year for various platforms including Linux, Tizen, and NuttX (the base of Tizen:RT). The Raspberry Pi 2 is one of the reference targets, but for demo purposes we also tried to build for the Raspberry Pi Zero, which is the most limited and cheapest device of the family. The main difference is the CPU architecture, which is ARMv6 (like the Pi 1), while the Pi 2 is ARMv7, and the Pi 3 is ARMv8 (aka ARM64).

IoT.js upstream uses a python helper script to crossbuild for supported devices, but instead of adding support to new device I tried to build on the device using native tools with cmake and the default compiler options; it simply worked! While working on this, I decided to package iotjs for debian to see how well it will support other architectures (MIPS, PPC, etc), we will see.

Unfortunately, Debian armel isn’t optimized for ARMv6 and FPU, both of which are present on the Pi 1 and Pi 0, so the Raspbian project had to rebuild Debian for the ARMv6+VFP2 ARM variant to support all Raspberry Pi SBC’s.

In this article, I’ll share hints for running IoT.js on Raspbian: the OS officially supported by the Raspberry foundation; the following instructions will work on any Pi device since a portability strategy was preferred over optimization. I’ll demonstrate three separate ways to do this: from packages, by building on the device, and by building in a virtual machine. By the way, an alternative to consider is to rebuild Tizen Yocto for  the Pi 0, but I’ll leave that as an exercise for the reader, you can accomplish this with a bitbake recipe, or you can ask for more hints in the comments section.

How to Run IoT.js on the Raspberry PI 0 - tizen-pizero

Install from Packages

iotjs landed in Debian’s sid, and until it is in testing branch (and subsequently Raspbian and Ubuntu), the fastest way is to download it is via precompiled packages from my personal Raspbian repo

url='https://dl.bintray.com/rzr/raspbian-9-armhf'
source="/etc/apt/sources.list.d/bintray-rzr-raspbian-9-armhf.list"
echo "deb $url raspbian main" | sudo tee "$source"
sudo apt-get update
apt-cache search iotjs
sudo apt-get install iotjs
/usr/bin/iotjs
Usage: iotjs [options] {script | script.js} [arguments]

Use it

Usage is pretty straightforward, start with a hello world source:

echo 'console.log("Hello IoT.js !");' > example.js
iotjs  example.js 
Hello IoT.js !

More details about the current environment can be used (this is for iotjs-1.0 with the default built-in modules):

echo 'console.log(JSON.stringify(process));' > example.js
iotjs  example.js 
{"env":{"HOME":"/home/user","IOTJS_PATH":"","IOTJS_ENV":""},"native_sources":{"assert":true,"buffer":true,"console":true,"constants":true,"dns":true,"events":true,"fs":true,"http":true,"http_client":true,"http_common":true,"http_incoming":true,"http_outgoing":true,"http_server":true,"iotjs":true,"module":true,"net":true,"stream":true,"stream_duplex":true,"stream_readable":true,"stream_writable":true,"testdriver":true,"timers":true,"util":true},"platform":"linux","arch":"arm","iotjs":{"board":"\"unknown\""},"argv":["iotjs","example.js"],"_events":{},"exitCode":0,"_exiting":false} null 2

From here, you can look to use other built-in modules like http, fs, net, timer, etc.

Need More Features?

More modules can be enabled in the master branch, so I also built snapshot packages that can be installed to enable more key features like GPIO, I2C, and more. For your convenience, the snapshot package can be installed to replace the latest release:

root@raspberrypi:/home/user$ apt-get remove iotjs iotjs-dev iotjs-dbgsym iotjs-snapshot
root@raspberrypi:/home/user$ aptitude install iotjs-snapshot
The following NEW packages will be installed:
  iotjs-snapshot{b}
(...)
The following packages have unmet dependencies:
 iotjs-snapshot : Depends: iotjs (= 0.0~1.0+373+gda75913-0~rzr1) but it is not going to be installed
The following actions will resolve these dependencies:
     Keep the following packages at their current version:
1)     iotjs-snapshot [Not Installed]                     
Accept this solution? [Y/n/q/?] n
The following actions will resolve these dependencies:

     Install the following packages:                 
1)     iotjs [0.0~1.0+373+gda75913-0~rzr1 (raspbian)]
Accept this solution? [Y/n/q/?] y
The following NEW packages will be installed:
  iotjs{a} iotjs-snapshot 
(...)
Do you want to continue? [Y/n/?] y
(...)
  iotjs-snapshot https://dl.bintray.com/rzr/raspbian-9-armhf/iotjs-snapshot_0.0~1.0+373+gda75913-0~rzr1_armhf.deb
  iotjs https://dl.bintray.com/rzr/raspbian-9-armhf/iotjs_0.0~1.0+373+gda75913-0~rzr1_armhf.deb

Do you want to ignore this warning and proceed anyway?
To continue, enter "yes"; to abort, enter "no": yes
Get: 1 https://dl.bintray.com/rzr/raspbian-9-armhf raspbian/main armhf iotjs armhf 0.0~1.0+373+gda75913-0~rzr1 [199 kB]
Get: 2 https://dl.bintray.com/rzr/raspbian-9-armhf raspbian/main armhf iotjs-snapshot armhf 0.0~1.0+373+gda75913-0~rzr1 [4344 B]
(...)

If you the run console.log(process) again, you’ll see more interesting modules to use, like gpio, i2c, uart and more, and external modules can be also used; check on the work in progress for sharing modules to the IoT.js community. Of course, this can be reverted to the latest release by simply installing the iotjs package because it has higher priority than the snapshot version.

root@raspberrypi:/home/user$ apt-get install iotjs
(...)
The following packages will be REMOVED:
  iotjs-snapshot
The following packages will be upgraded:
  iotjs
(...)
Do you want to continue? [Y/n] y
(...)

Build on the Device

It’s also possible to build the snapshot package from source with extra packaging patches, found in the community branch of IoT.js (which can be rebased on upstream anytime).

sudo apt-get install git time sudo
git clone https://github.com/tizenteam/iotjs
cd iotjs
./debian/rules
sudo debi

On the Pi 0, it took less than 30 minutes over NFS for this to finish. If you want to learn more you can follow similar instructions for building IoTivity on ARTIK;
it might be slower, but it will extend life span of your SD Cards.

Build on a Virtual Machine

A faster alternative that’s somewhere between building on the device and setting up a cross build environment (which always has a risk of inconsistencies) is to rebuild IoT.js with QEMU, Docker, and binfmt.

First install docker (I used 17.05.0-ce and 1.13.1-0ubuntu6), then install the remaining tools:

sudo apt-get install qemu qemu-user-static binfmt-support time
sudo update-binfmts --enable qemu-arm

docker build 'http://github.com/tizenteam/iotjs.git'

It’s much faster this way, and took me less than five minutes. The files are inside the container, so they need to be copied back to host. I made a helper script for setup and to get the deb packages ready to be deployed on the device (sudo dpkg -i *.deb) :

curl -sL https://rawgit.com/tizenteam/iotjs/master/run.sh | bash -x -
./tmp/out/iotjs/iotjs-dbgsym_0.0-0_armhf.deb
./tmp/out/iotjs/iotjs-dev_0.0-0_armhf.deb
./tmp/out/iotjs/iotjs_0.0-0_armhf.deb

I used the Resin/rpi-raspbian docker image (thanks again Resin!). Finally, I want to also thank my coworker Stefan Schmidt for the idea after he setup a similar trick for EFL’s CI.

Further Reading

If you want to learn more, here are some additional resources to take your understanding further.

Raspberry Pi is a trademark of the Raspberry Pi Foundation\

Building IoTivity for ARM on ARTIK Devices

There are several options to build IoTivity for ARM targets or any non x86 hardware, but first you have to decide which operating system you want to use. In this article, I won’t compare OS or devices; instead, I’ll give a couple of hints that apply to ARTIK 5, 7, and 10 devices (not the ARTIK 0 family, which run TizenRT). These steps can also be applied to other single board computers like the Raspberry PI.

Build for Tizen with GBS

The first and easiest way to build IoTivity is for Tizen, using GBS. This process was explained in a previous article.

For your knowledge, GBS was inspired by Debian’s git-build-package and uses an ARM toolchain that runs in a chrooted ARM environment using QEMU. Both ARTIK boards and the Raspberry Pi are used as Tizen reference platforms.

Build for Yocto with Bitbake

The second option is to crossbuild with the Yocto toolchain. Theoretically, it should be the fastest way, but in practice it might be the opposite because external packages will be rebuilt from scratch if the project doesn’t provide a Yocto SDK; this can be a long, resource consuming process.

Anyway, this is what is used in some OSS automotive projects (like AGL or GENIVI); the following slides provide a tutorial to get familiar with bitbake and OE layers (like meta-oic for IoTivity).

This can then be deployed to ARTIK 5 or 10 using meta-artik (ARTIK7 might need extra patches).

Cross Building Manually

Another option is to setup your toolchain with the scons environment, but I would not recommend it because you’ll probably lack tracking or control (output binaries will not be packaged) and risk consistency issues. If you choose this method, refer to IoTivity’s wiki page about crossbuilding.

Build on the Device

The last and most obvious option is to build on the device itself; this takes a bit longer, but is totally possible assuming your device has the resources (it worked for me on the RPI3 and ARTIK10). For this to work cleanly I suggest you build system package if your distro is supports it it (.rpm, .deb etc). This way you can track the different build configurations and avoid mistakes caused by manual operations.

Build on ARTIK10

ARTIK 10 supports building with Fedora 22, RPM packages can be built from Tizen’s spec file plus a handful of patches (I needed to use scons install and avoid duplication of packaging efforts). This work is still under review in the master branch, and will be backported to 1.3-rel branch once 1.3.1 is released. Meanwhile, you can clone my sandbox branch.

mkdir -p ${HOME}/rpmbuild/SOURCES/
git clone http://github.com/tizenteam/iotivity -b sandbox/pcoval/on/next/fedora
cd iotivity
git archive HEAD | gzip - > ${HOME}/rpmbuild/SOURCES/iotivity-1.3.1.tar.gz
rpmbuild -ba tools/tizen/iotivity.spec -D "_smp_mflags -j1" 

This is easy because the ARTIK10 has a lot of eMMC and RAM. The 8-core CPU is nice, but it won’t help because parallelizing too much will eat all of the device’s RAM. To be ensure reproductibility use -j1, but if you’re in a hurry you can try -j2 or more.

Build on ARTIK7

The next challenge is the ARITK710 which less powerful than ARTIK10 (RAM=1GB , eMMC=4GB) and uses Fedora 24. This is a slightly less favorable case because there are some extra steps due to the RAM and disk space being more limited. We’ll use extra storage to add a memory swap and mock: a nice Fedora tool to build RPM from git sources (it’s very similar to pbuilder for Debian). Extra storage can be connected to the board via SD or USB bus, but I prefer to use NFS; it’s not optimal, but it works.

Setup NFS

First, setup NFS on your development host and share a directory on the LAN; mine is Debian based:

sudo apt-get install nfs-kernel-server
mkdir -p /tmp/srv/nfs
ifconfig # Note interface IP to be used later

cat /etc/exports
# TODO: LAN's IP might be adjusted here:
/tmp/srv/nfs 192.0.0.0/255.0.0.0(rw,sync,no_root_squash,no_subtree_check)

Use NFS

Now, login to the target and install NFS and the other tools we’ll use:

dnf remove iotivity # Uninstall previous version if present
dnf install nfs-utils mock-scm mock rpm-build screen

Mount a directory for the device:

mnt=/tmp/mnt/nfs/host/$(hostname)/
host=192.168.0.2 # TODO adjust with IP of your host
mkdir -p $mnt ; mount $host:/tmp/srv/nfs $mnt

Attach a swap file:

file="$mnt/swap.tmp"
dd if=/dev/zero of=$file bs=1k count=2097152 # 2GB

losetup /dev/loop0 "$file"
mkswap /dev/loop0
swapon /dev/loop0

Because the eMMC is also limited, the build will be done in remote storage too. This won’t use an NFS shared folder directly because mock doesn’t support it, so let’s cheat it by mounting an ext4 partition file over NFS, the same way we did above:

file="$mnt/ext4.tmp"
dd if=/dev/zero of=$file bs=1k count=2097152 # 2GB

losetup /dev/loop1 "$file"
mkfs.ext4 /dev/loop1

src=/dev/loop1
dst=/var/lib/mock/
mount $src $dst

Build IoTivity

Create a user to run mock on remote filesystem:

user=abuild # TODO change if needed
adduser $user
home="/home/$user"
mnt=/tmp/mnt/nfs/host/$(hostname)/
mkdir -p "$home" "$mnt$home"
chown -Rv $user $s "$home" "$mnt$home"
mount --bind "$mnt$home" "$home"

su -l $user

Mock is pretty straightforward, but here is an example of the upcoming 1.3.1 release with the patches I mentioned above. If necessary, you can rebase your own private repo on it.

package=iotivity
url="https://github.com/TizenTeam/iotivity.git"
branch="sandbox/pcoval/on/next/fedora"
conf="fedora-24-armhfp"
spec=./tools/tizen/iotivity.spec
  
time mock -r "$conf" \
    --scm-enable \
    --scm-option method=git \
    --scm-option package="${package}" \
    --scm-option git_get=set \
    --scm-option write_tar=True \
    --scm-option branch="${branch}" \
    --scm-option git_get="git clone $url" \
    --scm-option spec="${spec}" \
    --resultdir=${HOME}/mock \
    --define "_smp_mflags -j1" \
    #eol

Now wait and check log trace:

You are attempting to run "mock" which requires administrative
privileges, but more information is needed in order to do so.
Authenticating as "root"
Password: 
INFO: mock.py version 1.3.4 starting (python version = 3.5.3)...
(...)
Start: run
(... time to clone and build iotivity repo ...)
Finish: rpmbuild iotivity-1.3.1-0.src.rpm
Finish: build phase for iotivity-1.3.1-0.src.rpm
INFO: Done(/home/abuild/mock/iotivity-1.3.1-0.src.rpm) Config(fedora-24-armhfp) 116 minutes 1 seconds
INFO: Results and/or logs in: /home/abuild/mock
INFO: Cleaning up build root ('cleanup_on_success=True')
Start: clean chroot
Finish: clean chroot
Finish: run

Depending on network bandwidth, RPMs will be produced in a reasonable time (less than a night for sure).

You can now validate reference examples:

su root -c "dnf remove -y iotivity"
su root -c "dnf install -y --allowerasing ${HOME}/mock/iotivity*.arm*.rpm"

rpm -ql iotivity-test

cd /usr/lib/iotivity/resource/examples ; ./simpleserver 2 
# 2 is needed to enable security node.

In other session:

cd /usr/lib/iotivity/resource/examples ; ./simpleclient
GET request was successful
Resource URI: /a/light
Server format in GET response:10000
Server version in GET response:2048

Bringing it all Together

There has been one major relevant change since 1.2.x, the default build configuration is using secured mode (Tizen had it enabled for longer). For developers, this means that if your application is not configured to support security ACL, it won’t work, and you might expect this OC_STACK_UNAUTHORIZED_REQ error:

onGET Response error: 46

The following presentation provides some insight on the IoTivity security features.

The fall back option is to rebuild IoTivity without SECURITY enabled (using –define SECURED 0), but this won’t be certified as OCF compliant. Finally, these build steps can be replicated for other projects using IoTivity.

Join Us for the Tizen Developer Conference in San Francisco

The Tizen Developer Conference (TDC) is just around the corner; it will be held May 16 – 17 at the Hilton Union Square Hotel in San Francisco, CA. Our team contributes a ton of code to some of the critical open source software that makes up Tizen, so of course we’ll be spending some time there to network with app developers and device makers who work with Tizen.

What’s Happening with Tizen?

There has been quite a few exciting developments for Tizen over the last year; for starters Samsung joined forces with Microsoft to bring .NET to Tizen, allowing developers to build applications for Tizen using C# and Visual Studio. Additionally, Tizen has continued to show up on a growing number of consumer devices including the Gear S3, Z2Gear 360, AR9500M air conditioner, POWERbot VR7000, multiple smart TV’s, and more. Finally, Tizen RT was released last year, making it easier than ever to run Tizen on low-end devices with constrained memory requirements. All of these changes create a great environment to see some interesting new things at this conference.

These developments have made Tizen more accessible than ever for app developers and device manufacturers; now is a great time to get more deeply involved in this ecosystem. Take a look at the conference sponsors page to get an idea of what companies will be at TDC to show off their latest work.

What to Expect at a Tizen Event

TDC is a technical conference for Tizen developers, app developers, open source enthusiasts, platform designers, IoT device manufacturers, hardware and software vendors, ISVs, operators, OEMs, and anyone engaged in the Tizen ecosystem. It offers an excellent opportunity to learn from leading Tizen experts and expand your understanding of mobile, IoT, wearable tech, and IVI systems engineering and application development; events like this are the best way to network with the top companies working within the Tizen ecosystem.

Not to mention, Tizen events often include the unveiling of new devices, so visitors get to be some of the first people in the world to see the next greatest things for Tizen. The real cherry on top are the giveaways that accompany some of these announcements. Winning a new device more than makes up for the cost of admission :-)

Last but not least, the most valuable component of these events are the technical sessions that provide practical knowledge to help build better devices and apps. There are four session tracks to choose from:

  • Device Ecosystem – Learn how to create new devices with Tizen.
  • Application Ecosystem – Learn how to build apps for Tizen with .NET, Xamarin.Forms, Visual Studio, and more.
  • Platform Core – Learn about some of the platform components that make Tizen great for various use cases.
  • Product Experience – Learn about some of the interesting Tizen features that are being used to make products better.

TDC will conclude with an IoT hands-on lab that will provide training for using Tizen RT and ARTIK devices to build IoT products. This requires separate registration, so make sure to bring your laptop and coding skills so can take part in this wonderful opportunity to learn from experts.

Check out the entire conference schedule here.

What are You Waiting For?

Time is running out to plan your trip to this conference. Students can register for free (don’t forget your student ID when you come), and for everyone else, you can use the coupon code TIZSDP to get 50% off your registration fee. If you’ll be in the San Francisco area on May 16 and 17, don’t miss out on this great opportunity. Check out the registration page to learn more about attending this conference.

We hope to see you there!

How OCF is Creating the Connected Car

The Connected Car & Fragmentation

Traditional car manufacturers have begun including early iterations of touchscreen technology with access to media and apps that can also provide basic HVAC (Heating, Ventilation and A/C) controls for the vehicle. These features can often be accessed through mobile devices with tailor-made apps from each car maker. However, this has led to OEMs building their own ecosystem silos, similar to the trends observed in the smartphone industry. The lack of an open, standardized framework has resulted in a fragmented market, where experiences from one OEM won’t work with another in any streamlined way; consequently, developers aren’t thinking about how to provide a rich user experience that allows cars and drivers to work in unison; this is a huge missed opportunity.

Samsung OSG, OCF, and IoTivity

The Open Connectivity Foundation (OCF) is creating a specification and sponsoring the IoTivity open source project to deliver an open and secure connectivity and interoperability framework; this enables devices from multiple vendors that belong to multiple vertical domains to run on a variety of software and hardware platforms. Automotive is one key vertical where OCF can have a significant impact. The Samsung Open Source Group (OSG) has been playing a significant role in both the Open Connectivity Foundation (OCF) and IoTivity.

Collaboration with Genivi & W3C

The GENIVI Alliance, a community that’s developing open source software and standards for the connected car, and OCF are partnering to co-develop open standards for vehicle connectivity and vehicle data exchange, including a unified model for secure discovery and exchange of information between smart homes, connected cars, and other IoT devices. The joint effort will also address end-to-end security challenges to enable new opportunities across multiple verticals. Additionally, GENIVI and OCF will  closely collaborate with the W3C Automotive Working Group, which develops the Open Web Platform API specification to expose vehicle data to web application developers.

Proof of Concept

Through a broad collaboration spanning ten organizations, we were able to develop and showcase our demo at the OCF booth at CES 2017.  ETRI, Genivi Alliance, Honeywell, Intel, Jaguar Land Rover, OCF, Samsung, Tinnos, The Data Alliance, and W3C all collaborated on open specifications and open source software to realize numerous interesting connected car use cases and explore interoperability between smart home devices and the connected vehicle.

Source Code

If you are interested in recreating these demos, or would like to experiment with it, base of demo code have been shared on the Samsung OSG git repository. To get started with IoTivity on GENIVI, simply add the “meta-ocf-automotive” layer, which includes minimalistic examples that demonstrate IoTivity. You can use the following as a guideline, for Yocto based distros.

# Fist Setup yocto buildenv, then
git clone https://github.com/GENIVI/genivi-dev-platform 
cd genivi-dev-platform 
git clone http://git.s-osg.org/meta-ocf-automotive/ 
MACHINE=qemux86-64 # Or supported BSPs (raspberrypi, minnowboard, dragonboard...)
echo 'BBLAYERS += "${TOPDIR}/../meta-ocf-automotive"'  >> 'gdp-src-build/conf/templates/bblayers.inc' 
source ./init.sh $MACHINE bitbake genivi-dev-platform

Once booted on qemu or the Raspberry Pi 2/3, an IoTivity server can be started from “/opt/iotivity-example*” and example clients can be run on the same LAN, including localhost. These examples are part of our IoTivity example, and are ready to be forked to create your own IoT services. We hope it will inspire you and simplify integration; start learning! For support, check out the detailed instructions on IoTivity’s automotive wiki page. Since GENIVI’s development platform is now shipping iotivity-node, linking sensors to the cloud as shown at FOSDEM, can be done in a jiffy.

Working together across organizational boundaries has enabled us to realize these demonstrations with real devices that run open source software; hopefully this will help people understand the potential business opportunities of connected cars. Feel free to post a comment below if you have any questions or comments.

Additional Resources

[wp_biographia user="pcoval"]

[wp_biographia user="sanjeev"]

Ecore_Evas: Creating a Canvas for Wayland Applications

While there are some developers who are familiar with using Ecore_Evas to create a canvas for applications, we often find that new EFL users face some confusion when first trying to create an application. This article aims to provide a simple example of how to create your first EFL Wayland application.

For those not familiar with the Ecore_Evas library, it is a set of functions that make it easy to tie together Ecore’s main loop and input handling to Evas; as such, it’s a natural base for EFL applications. While this combination makes it easy to create the basic aspects all applications need, for normal applications (those that use buttons, checkboxes and layouts) one should consider using Elementary. Ecore_Evas is extremely well suited for applications that are not based on widgets. It has a main loop that delivers events, does basic window handling, and leaves all of the drawing up to the user. This works very well if used in conjunction with Edje or when doing custom drawing such as what’s done for games, for example.

A typical example of an Ecore_Evas application may look like this

/**
 * Ecore example illustrating the basics of ecore evas usage.
 *
 * You'll need at least one Evas engine built for it (excluding the
 * buffer one). See stdout/stderr for output.
 *
 * @verbatim
 * gcc -o ecore_evas_basics_example ecore_evas_basics_example.c `pkg-config --libs --cflags ecore evas ecore-evas`
 * @endverbatim
 */

#include 
#include 
#include 

static Eina_Bool
_stdin_cb(void *data EINA_UNUSED, Ecore_Fd_Handler *handler EINA_UNUSED)
{
   Eina_List *l;
   Ecore_Evas *ee;
   char c;

   int ret = scanf("%c", &c);
   if (ret < 1) return ECORE_CALLBACK_RENEW;

   if (c == 'h')
     EINA_LIST_FOREACH(ecore_evas_ecore_evas_list_get(), l, ee)
       ecore_evas_hide(ee);
   else if (c == 's')
     EINA_LIST_FOREACH(ecore_evas_ecore_evas_list_get(), l, ee)
       ecore_evas_show(ee);

   return ECORE_CALLBACK_RENEW;
}

static void
_on_delete(Ecore_Evas *ee)
{
   free(ecore_evas_data_get(ee, "key"));
   ecore_main_loop_quit();
}

int
main(void)
{
   Ecore_Evas *ee;
   Evas *canvas;
   Evas_Object *bg;
   Eina_List *engines, *l;
   char *data;

   if (ecore_evas_init() <= 0)
     return 1;

   engines = ecore_evas_engines_get();
   printf("Available engines:\n");
   EINA_LIST_FOREACH(engines, l, data)
     printf("%s\n", data);
   ecore_evas_engines_free(engines);

   ee = ecore_evas_new(NULL, 0, 0, 200, 200, NULL);
   ecore_evas_title_set(ee, "Ecore Evas basics Example");
   ecore_evas_show(ee);

   data = malloc(sizeof(char) * 6);
   sprintf(data, "%s", "hello");
   ecore_evas_data_set(ee, "key", data);
   ecore_evas_callback_delete_request_set(ee, _on_delete);

   printf("Using %s engine!\n", ecore_evas_engine_name_get(ee));

   canvas = ecore_evas_get(ee);
   if (ecore_evas_ecore_evas_get(canvas) == ee)
     printf("Everything is sane!\n");

   bg = evas_object_rectangle_add(canvas);
   evas_object_color_set(bg, 0, 0, 255, 255);
   evas_object_resize(bg, 200, 200);
   evas_object_show(bg);
   ecore_evas_object_associate(ee, bg, ECORE_EVAS_OBJECT_ASSOCIATE_BASE);

   ecore_main_fd_handler_add(STDIN_FILENO, ECORE_FD_READ, _stdin_cb, NULL, NULL, NULL);

   ecore_main_loop_begin();

   ecore_evas_free(ee);
   ecore_evas_shutdown();

   return 0;
}

This example application will use the first available Ecore_Evas engine to create a canvas that contains a blue rectangle.

Ecore_Evas Creating a Canvas for Wayland Applications - shot-2016-12-13_08-42-35

While this is not a very exciting example, it does illustrate how to create a basic Ecore_Evas application quite well.

How to Use Wayland with Ecore_Evas

With a simple modification of one line, this example application can run in a Wayland environment. The following line is changed to facilitate this.

ee = ecore_evas_new(NULL, 0, 0, 200, 200, NULL);

To run in Wayland, it should read

ee = ecore_evas_new("wayland_shm", 0, 0, 200, 200, NULL);

This essentially tells ecore_evas to utilize the Wayland_Shm engine to create a new canvas; this is an Evas engine that uses Wayland and Shared-Memory for drawing. There are other Evas Wayland engines available, such as the "wayland_egl" engine which uses Hardware Accelerated drawing (namely EGL).

What many new EFL developers do not realize is that there is an even easier way to make this application run in a Wayland environment, without changing a single line of code! While running in a Wayland environment (Weston, Enlightenment-Wayland, Gnome-Wayland, etc) the following command should be run from the terminal

export ECORE_EVAS_ENGINE=wayland_shm

Then, the application can be run, and when ecore_evas_new executes it will check for the ECORE_EVAS_ENGINE environment variable and attempt to use the engine specified there.

This means application developers who utilize Ecore_Evas can easily make any application run in a Wayland environment. It's possible to choose to make it Wayland specific by modifying the function call that creates the canvas, or it's possible to simply export an environment variable to change the engine that's in use. Personally, I have always found it easier to set the environment variable because this makes it possible to test the application under various windowing systems (such as X11, Wayland, Framebuffer) without modifying and recompiling the code.

For more information on how to utilize Ecore_Evas to create a basic EFL application, please see the Ecore_Evas documentation.

Get Started with IoTivity Interactions on the ARTIK10 and Tizen

A curious mind recently asked me to share materials about the OCF SmartHome demo, or perhaps I should call it the “Minimalist Smart Switch” instead. The demo was displayed at the Embedded Linux Conference in Berlin, and featured IoTivity running on an ARTIK10 SoC that connected to a Tizen Gear S2 Smartwatch; both run Tizen OS.

Get Started with IoTivity Interactions on the ARTIK10 and Tizen - ocf

You will find more technical details in the following slide deck.

Install Tizen and IoTivity

If you want to run it this demo, you can download the system image and uncompress the archive directly to the SD card using QEMU tools.

lsblk # will list all your disks
disk=/dev/sdTODO # update with your disk id
file=tizen-common-artik10-20160801rzr.qcow2
sudo qemu-img convert -p "${file}" "${disk}"
sync 

Once this is completed, insert the SD card into the ARTIK10 and turn it on; it will boot Tizen and launch the IoTivity server. For more information about this, check out the previous blog posts about booting tizen on ARTIK and building software for Tizen OS. These will show you how to rebuild the latest version of IoTivity from scratch.

Of course, this can be adapted to other hardware like the ARTIK5 and maybe the ARTIK7 too, it would be a good idea to bookmark this page as a reference for Tizen on ARTIK. If you run into issues, feel free to ask about them in the ARTIK forums.

Note, You can also do it again on Yocto OS using meta-artik too, but using Tizen will save you the time and resources to rebuild everything.

Setup the Tizen Clients

For IoTivity clients on mobile devices, like the Samsung Z1, or smartwatches, such as the Samsung GearS2, the clients need a little preparation. Most of it’s documented in the Tizen page on the IoTivity wiki. I will also be personally available to assist developers at next the Tizen community meeting (2016-11-28 09h@UTC), which has more details on the Wiki’s Meeting page.

What’s Next for Tizen and IoTivity?

Micro-controllers have recently been a focus of some of my work. I shared some hints are shared in the following presentation “From Arduino Microcontrollers to Tizen using IoTivity” which I presented at IoT With the Best 2016.

Others at the Samsung Open Source Group have worked on more constrained devices by bridging different technologies together, including JerryScript, 6LoWPAN, and more. This was demonstrated at the recent Samsung Open Source Conference .

One likely challenge for ARTIK0 owners will be running iotivity-constrained on operating systems Iotivity supports, such as RIOT, Zephyr, and Tizen RT. If you’re one of these people, please keep us updated in the Tizen IRC channel, or the mailing lists!

Get Started with IoTivity Interactions on the ARTIK10 and Tizen - lfelc

Thanks to Luis De Bethencourt for helping me with the pictures of the Gear S2 on my wrist :-)

Ecore_Wl2: An EFL Library for Wayland Applications

Throughout the years of developing Wayland support for EFL, few EFL libraries have had as much impact on EFL Wayland applications as the Ecore_Wayland library has. This library was one of the first to make it possible to truly run EFL applications in a Wayland environment. As the years progressed, it became apparent that Ecore_Wayland had some shortcomings; this blog post will introduce you to the replacement for Ecore_Wayland, called Ecore_Wl2.

Ecore_Wayland’s Shortcomings

While testing our first Wayland implementation, it became apparent that the initial implementation of the Ecore_Wayland library had some drawbacks. Publicly exposed structures could not be changed easily without breaking existing applications, and any changes to existing Wayland protocols would require significant changes to our Ecore_Wayland library. It was also discovered that when an EFL Wayland application creates a new window, the backend library also creates an entirely new display and connection to the Wayland server. This resulted in high memory usage in EFL applications.

Due to these shortcomings, the community decided that EFL should have a better library for integrating with Wayland, and thus Ecore_Wl2 was born. Determined not to repeat the mistakes of the past, I began the long and arduous task of giving birth to a new library.

Building a More Capable Library

One of the first tasks with the new library was to move structures fields out of the public API so they could later be changed without breaking existing applications. As a result, in Ecore_Wl2 there are some publicly exposed structures (via Ecore_Wl2.h header file), however, the individual fields of these structures are not directly accessible. There are now public API functions to retrieve structure members to allow some access to these fields; this makes it possible to make necessary changes in the future while also maintaining existing applications.

The next area of focus for the new library was to reduce memory usage. In the older library, every window of every application would create it’s own Ecore_Wayland_Display: a huge waste of resources. I decided to implement display caching; this means the library code now maintains a cache of existing displays. When an application requests a display it calls ecore_wl2_display_connect():

EAPI Ecore_Wl2_Display *
ecore_wl2_display_connect(const char *name)

However, behind the scenes the library checks for any existing displays in the cache that match the given display name and return it. If no display is found in the internal cache, a new one is created and cached. This allows for display reuse without added memory overhead, especially for an application that intends to create more than one window. Since we use this new library in the server implementation, caching server displays has also been implemented.

While this blog post has briefly touched on the new Ecore_Wl2 library, I invite everyone to keep an eye open for another upcoming post concerning the Ecore_Wl2 library. It will go into more detail related to the improvements the library provides and how to make use of it.

Ecore_Drm2: How to Use Atomic Modesetting

In a previous article, I briefly discussed how the Ecore_Drm2 library came into being. This article will expand on that article and provide a brief introduction to the Atomic Modesetting and Nuclear Pageflip features inside the new Ecore_Drm2 library.

What Makes Atomic Modesetting and Nuclear Pageflip so Great?

For those that are unaware of what “modesetting” is, you may read more about it here. Atomic Modesetting is a feature that allows for output modes (resolutions, refresh rate, etc) to be tested in advance on a single screen or on multiple outputs. A benefit of this feature is that the given mode may be tested prior to being applied. If the test of a given output mode fails, the screen image doesn’t need to be changed to confirm a given mode works or not, thus reducing screen flickering.

Atomic/Nuclear Pageflipping allows for a given scanout framebuffer object and/or one or more hardware plane framebuffers to be updated in a single atomic operation. This means that updates to the screen output, whether they be updates of a given hardware plane, updates to a CRTC framebuffer, or even updates to rotation can happen in a single vblank interrupt. For the end user, this provides a much more friendly screen update by reducing redraws and flicker.

One of the things we strive to do with EFL is to keep our API simple to use. With that in mind, you will not notice any new API functions related to using Atomic Modesetting or Nuclear Pageflipping inside the Ecore_Drm2 library. You may be asking yourself right now: “Well, how do I make use of this then?” I have great news, you may already be using it :-). Rather than add new API functions, which need to be explicitly called for these features, I decided early that these benefits should come without any cost so that existing applications can make use of them without having to be modified.

The Technical Details

Inside the Ecore_Drm2 library there are various API functions that allow for setting output modes, or even sending a framebuffer object to scanout. These existing API functions have been modified to make use of Atomic Modesetting/Nuclear Pageflipping automatically where applicable. This means applications that are already using the various APIs of the Ecore_Drm2 library do not need to be changed.

Behind the scenes, the usage of Atomic Modesetting/Pageflipping is determined at runtime. This means that when the Ecore_Drm2 library gets initialized, it will make some checks to see if atomic usage is supported. Currently, these features are only supported on an Intel (i915) graphics card with a linux kernel version >= 4.8.0. If the Ecore_Drm2 initialization finds the proper driver and kernel version, it will then attempt to enable DRM_CLIENT_CAP_ATOMIC to support Atomic Modesetting/Pageflipping. If the client capability is successfully set, it will then attempt to enable DRM_CLIENT_CAP_UNIVERSAL_PLANES in order to enable hardware plane support.

Assuming all of the internal checks pass and the client capabilities are set successfully, the application will gain the added benefits of these features without any added work :-). There is one more thing that May be needed on some systems to get this working: it has been my experience that some boxes still need kernel boot-time options enabled for atomic to function. The necessary options (if required) are: drm.atomic=1, and i915.nuclear_pageflip=1.

While these features may not yet be available for all end-users to enjoy, the benefits they provide should be something that everyone can look forward to. With the continued hard work of linux kernel developers and graphics driver developers, we may all be able to enjoy these redraws soon :-)

Introducing the New & Improved Ecore_Drm2 Library

In the early days of developing Wayland support in EFL/Enlightenment, it was quickly apparent that EFL would need an abstraction library to interface with libdrm. We wanted users of EFL to be able to call simple functions without having to know about the underlying internals of libdrm, thus the original Ecore_Drm library was born. First, efforts to develop this library were undertaken with much enthusiasm and little fan-fare. After the birth of Ecore_Drm, we then proceeded to integrate it’s usage into some new Evas and Ecore_Evas engines so that the Enlightenment Desktop Shell could make use of it and render our first standalone Wayland desktop implementation.

After kicking the tires of our Wayland desktop for a while, we came to realize some shortcomings of the existing Ecore_Drm implementation. For starters, it would create it’s own Ecore_Drm_Device structure when launching the Enlightenment Wayland desktop (this structure was a representation of the physical connection to the /dev/dri card used in rendering). Along with this structure came lists of outputs, inputs, seats, planes, etc. In short, this structure was not very light and memory was being used up needlessly. Other shortcomings of the Ecore_Drm library included things such as structures being declared in public headers that couldn’t be easily changed, input device handling, systemd/logind support being coded directly into the library, and several other issues.

Redesigning From the Ground up

The community came to the easy decision that a better implementation was needed, thus we started efforts to create a new implementation and the Ecore_Drm2 library was born. This new library was developed slowly, while taking into account the shortcomings of the first iteration because we didn’t want to repeat the mistakes of the past. To help avoid these mistakes, the Ecore_Drm2 library API is currently marked as a ‘beta’ API which means it’s susceptible to changes at any time until the beta API marking is removed.

After several months of careful development and several months of testing, Ecore_Drm2 was deemed stable and complete enough to be pushed upstream. Efforts then ensued to modify the existing Evas and Ecore_Evas engines to use this shiny new library.

The new Ecore_Drm2 library fixes all of the shortcomings of the previous library. The community decided at inception that input handling should reside in it’s own library (thus the elput library was created). This removed a lot of internal overhead inside the Ecore_Drm2 library while also removing the need for the library itself to interface with systemd/logind. Public structures exposed via the Ecore_Drm2 library now have their actual implementations kept private so that changes could be made in the future if necessary. Internally, the size of the Ecore_Drm2_Device structure has been greatly reduced, saving memory.

While many improvements have been made to this new library (compared to the old one), one of the greatest overall improvements came as a result of it’s existence. With the new version of this library, we realized that the Evas and Ecore_Evas drm engines were also ripe for improvement. These rendering improvements did not happen by accident, but rather are the result of some great efforts, led by Derek Foreman, that provided tangible benefits by reducing tearing, decreasing time to first frame, improving rendering speed, and reducing memory usage. We believe we will see many more improvements just like this as a result of Ecore_Drm2.

An Introduction to Tizen Development on ARTIK

This article is a direct follow up of my previous post about booting Tizen on the ARTIK10. Before starting, you should bookmark this wiki page as an entry point for Tizen on ARTIK devices.

At the 2015 Tizen Developer Conference, I had the opportunity to present a tutorial about Tizen platform development; it’s still valid today. This article is very similar but is adapted for ARTIK10 and ARTIK5 configuration.

For some context, check out to the following slide deck along with the recorded video on how to patch Tizen and build with GBS for x86a as well as this page about Tizen:Common on VMware.

 

 

Tools Setup

If you’re familiar with Tizen you probably know about Git Build System (GBS): a very convenient tool to build packages. It’s adapted from Debian’s git-build-package to support zypper repos.

First, gbs and some other Tizen tools need to be installed on the host machine used for development; On a debian based distro this is trivial: add the proper apt source for your specific OS as listed in the tools folder.

For instance, edit and adapt:

# cat /etc/os-release # mine is NAME=Ubuntu VERSION_ID=14.04
# cat /etc/apt/sources.list.d/org_tizen.list # edit and adapt 

deb http://download.tizen.org/tools/latest-release/${NAME}_${VERSION_ID}/ /
deb-src http://download.tizen.org/tools/latest-release/${NAME}_${VERSION_ID}/

# sudo apt-get install gbs mic lthor sdb

Then, the configuration file ~/.gbs.conf must be created, it should contain something like the following:

# cat ~/.gbs.conf

[profile.tizen_common_3.0b_artik_armv7l]
repos=repo.tizen_base_armv7l,repo.tizen_common_3.0b_artik_armv7l
buildroot=~/tmp/gbs/tmp-GBS-tizen_common_3.0b_artik_armv7l/

[repo.tizen_base_armv7l]
url = http://download.tizen.org/snapshots/tizen/base/latest/repos/arm/packages/

[repo.tizen_common_3.0b_artik_armv7l]
url=http://download.tizen.org/snapshots/tizen/common_artik/latest/repos/arm-wayland/packages/

By the way, here is my current .gbs.conf, with more profiles:

wget -O ~/.gbs.conf https://notabug.org/tizen/tizen-helper/raw/master/config/gbs.conf

Hello Tizen Source

Here, is the “helloworld project” and the packaging file needed to create a minimal platform package.

# mkdir -p tizen-example/packaging
# cd tizen-example
# cat main.c

#include "stdio.h"
void main()
{
    printf("Hello Tizen!\n");
}

A trivial makefile is needed to install it, as GNU make will guess how to build it (note, tabs are used not spaces) :

# cat Makefile

prefix?=/usr

install: main
    install -d ${DESTDIR}${prefix}/bin/
    install main ${DESTDIR}${prefix}/bin/

Finally write a minimal RPM spec file, like on any RPM based distribution (Red Hat, SUSE, Mer, etc):

# cat packaging/tizen-example.spec

Name: tizen-example
Version: 0
Release: 0
Summary: example
Source: %{name}-%{version}.tar.gz
License: TODO
BuildRequires: make
%description
Basic hello world example
%prep
%setup -q -n %{name}-%{version}
%build
%install 
%make_install
%clean
%files
%{_bindir}/*

Then commit those files into a newly created git project:

git init
git add .
git commit -sam 'Import'

Build the Software

The next step is to build it with this single command line:

gbs build -P "tizen_common_3.0b_artik_armv7l" --arch armv7l --include-all

It will download dependencies and eventually produce an RPM file; the contents can be listed with this command line:

rpm -qlp ~/tmp/gbs/tmp-GBS-tizen_common_3.0b_artik_armv7l/local/repos\
tizen_common_3.0b_artik_armv7l/armv7l/RPMS/rzr-example-0-0.armv7l.rpm

/usr/bin/main

Deploy to Target Device

At this stage, the package can be uploaded using scp, but let’s use an alternate way: Tizen’s Smart debug bridge (sdb) which was installed earlier.

On the target side, the SDB daemon should be already running:

# systemctl status sdbd    

sdbd.service - sdbd
   Loaded: loaded (/usr/lib/systemd/system/sdbd.service; disabled; vendor preset: enabled)
   Active: active (running) since Mon 2016-07-25 10:03:00 PDT; 7min ago
  (...)

If not, (re)start it:

# systemctl restart sdbd

# ifconfig -a 

Take note of the target’s IP address. Back on the host, use the sdb client to connect to it.

# sdb connect  192.168.0.42
connecting to 192.168.0.42:26101 ...
connected to 192.168.0.42:26101

# sdb devices
List of devices attached 
192.168.0.42:26101     device          artik

Perfect! Now files can be pushed or pulled just like the Tizen SDK IDE, but this has the benefit of providing shell access with su supported:

# sdb shell

sh-3.2$ pwd
/opt/home/owner

Now, we’re ready to upload our built RPM and install it with rpm running as root:

# sdb push ~/tmp/gbs/tmp-GBS-tizen_common_3.0b_artik_armv7l/local/repos/tizen_common_3.0b_artik_armv7l/armv7l/RPMS /opt/home/owner/RPMS
pushed   tizen-example-0-0.armv7l.rpm   100%          3KB
(...)

# sdb shell
sh-3.2$ su
Password: # tizen
bash-3.2# rpm -i /opt/home/owner/RPMS/tizen-example-*.rpm

bash-3.2# /usr/bin/main
Hello Tizen!

It’s not rocket science, but this is enough to validate the Tizen toolchain.

Setting up a private repo

Note: a quick tip for deploying is to setup an HTTP repo on the host machine and pull packages with zypper.

On the host machine, execute the following:

sudo apt-get install apache2
sudo a2enmode userdir
mkdir -p ~/public_html/tmp/
ln -fs ~/tmp/gbs  ~/public_html/tmp/gbs
ifconfig -a # note host_ip for later ie: 192.168.0.154

Then, some variables need to be adapted on the target side.

# sdb shell # or ssh root@$target_ip
# su # password=tizen
# host_ip=192.168.0.154 # adapt
# user=pcoval # adapt
# profile=tizen_common_3.0b_artik_armv7l
# url="http://${host_ip}/~${user}/tmp/gbs/tmp-GBS-${profile}/local/repos/${profile}/armv7l/"
#
# zypper removerepo ${user}
Repository 'pcoval' not found by alias, number or URI.

# zypper addrepo ${url} ${user} 
Adding repository 'pcoval' ...............................................[done]
Repository 'pcoval' successfully added
Enabled: Yes
Autorefresh: No
GPG check: Yes
URI: http://192.168.0.154/~pcoval/tmp/gbs/tmp-GBS-tizen_common_3.0b_artik_armv7l/local/repos/tizen_common_3.0b_artik_armv7l/armv7l/

# zypper repos
# | Alias                   | Name                                  | Enabled | Refresh
--+-------------------------+---------------------------------------+---------+--------
1 | Tizen_Base              | Bootstrap Project of Tizen  (arm)     | Yes     | No     
2 | Tizen_Common_3.0b_artik | Tizen:Common:3.0b:artik (arm-wayland) | Yes     | No     
3 | pcoval                  | pcoval                                | Yes     | No     

By the way, here are some zypper commands, you will probably use:

# zypper
# zypper refresh -r ${user} 
# zypper repos -r ${user} 
# zypper update -r  ${user} 
# zypper clean -r ${user} 
# zypper install --force -r ${user} ${package}

What’s Next ?

This should have summed up all that is needed to get into Tizen platform development on ARTIK devices. Now there are many new possibilities open for things like IoT development; let us know about your plans or join existing discussions about hardware support related to things like Graphics, Bluetooth/BLE, or maybe try to compare the results of this with Yocto’s meta-artik or other Operating Systems.

Remember, we also plan to have a quick chat about ARTIK at next Tizen Community Online Meeting, I hope to see you there! As a parting gift, here are some extra hints about packaging new software for the Tizen contrib repo.