Now that we have developed the main application, what remains for us is to integrate it with our Yocto RPI environment.
The first step consists of integrating the nodejs
package (located at meta-openembedded/meta-oe/recipes-devtools/nodejs
) with the Raspberry Pi environment. For this, we have to add the following line to raspberry-pack-image
:
# Base this image on core-image-minimal include recipes-core/images/core-image-minimal.bb DESCRIPTION = "Image for raspberry-pi" IMAGE_FEATURES += "ssh-server-dropbear splash" # Include modules in rootfs IMAGE_INSTALL += " kernel-modules gpio-packt i2c-tools spitools nunchuck v4l-utils nodejs "
We have now integrated nodejs
with our Poky distro.
The second step consists of creating the recipe file; let's call this recipe webserver-packt_01.bb
.
The idea is to have the following architecture inside the recipes-custom
folder:
$ tree webserver-packt/ webserver-packt/ âââ webserver-packt â âââ server.tar.gz âââ webserver-packt_0.1.bb
To create this recipe, we will use the recipetool
command , as follows:
$ source oe-init-build-env rpi-build $ recipetool create -d -o webserver-packt_0.1.bb ../meta-packt_rpi/recipes-custom/webserver-packt/webserver-packt/ $ cp webserver-packt_0.1.bb ../meta-packt_rpi/recipes-custom/webserver-packt/
The complete documentation of recipetool
command is online at
http://www.yoctoproject.org/docs/1.8/mega-manual/mega-manual.html#new-recipe-creating-the-base-recipe-using-recipetool
.
Now we just need to copy the entire archive (server.tar.gz
) containing the sources to ${datadir} (/usr/share/)
; this step is carried out in the do_install()
block, as shown here:
DESCRIPTION = "Panel to monitor rpi temperature" LICENSE = "GPLv2" LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.GPLv2;md5=751419260aa954499f7abaabaa882bbe" # Package Release PR = "r0" # Use local tarball SRC_URI = " file://server.tar.gz " RDEPENDS_${PN} += "bash" # Make sure our source directory (for the build) matches the directory structure in the tarball S = "${WORKDIR}" do_install() { install -d ${D}${datadir}/server-packt cp -a ${S}/server ${D}${datadir}/server-packt } # Package files FILES_${PN} += "${datadir}/server-packt"
Let's take a look at what the variables do:
RDEPENDS_{PN}
variable lists a package's runtime dependencies that must be installed in order for the built package to run correctly. In our case, bash is necessary for nodejs
.FILES_{PN}
variable contains the list of directories or files that are placed in the packages. In our case, server-packt
is necessary.We now have an environment ready to be used. If we want to deploy the application on our Raspberry Pi, we can do so with the following commands.
The host commands are as follows:
$ bitbake webserver-packt $ scp tmp/deploy/rpm/arm1176jzfshf_vfp/webserver-packt-0.1- r0.arm1176jzfshf_vfp.rpm root@ip_address_of_rpi:/home/
These are the Raspberry Pi commands:
$ rpm -ivh webserver-packt-0.1-r0.arm1176jzfshf_vfp.rpm $ rm webserver-packt-0.1-r0.arm1176jzfshf_vfp.rpm $ node /usr/share/server-packt/server/server.js
If we want to have a standalone application, it would be interesting if our application can start during the boot sequence of our Raspberry Pi. For this, we will use an init
script, inheriting directly from System V.
The first step is to create a .init
file within our structure. We will call this file server.init
. The tree will look like this:
$ tree webserver-packt/ webserver-packt/ âââ webserver-packt â âââ server.init â âââ server.tar.gz âââ webserver-packt_0.1.bb
So, the script will start the application automatically after the installation and every time the Raspberry Pi starts up. Here is the init
script from System V:
#!/bin/bash ### BEGIN INIT INFO # Provides: server.init # Required-Start: $remote_fs $syslog # Required-Stop:Ã $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start daemon at boot time # Description: Enable service provided by daemon. ### END INIT INFO DAEMON=node NAME=server.init DESC="Nodejs app" ARGS="/usr/share/server-packt/server/server.js" set -e usage() { echo "----------------------------------" echo "Usage: $0 (stop|start|restart)" echo "----------------------------------" } service_start() { echo -n "starting $DESC: $NAME... " start-stop-daemon -S -x $DAEMON -- $ARGS & echo "done." } echo "" service_stop() { echo -n "stopping $DESC: $NAME... " start-stop-daemon -K -x $DAEMON echo "done." } case $1 in stop) service_stop echo "" ;; start) service_start echo "" ;; restart) service_stop service_start echo "" ;; *) usage esac exit 0
Let's look at how the code works:
DAEMON
variable specifies the binary to launch (/usr/bin/node
)NAME
variable specifies the script nameDESC
variable contains some information about DAEMON (node)ARGS
variable contains the arguments to pass to DAEMON (node)If you want to test this script on the Raspberry Pi, use these commands:
$ scp server.init root@ip_address_of_rpi:/etc/init.d $ cd /etc/init.d $ update-rc.d server.init defaults
This command stops the application:
/etc/init.d/server.init stop
This one restarts it:
/etc/init.d/server.init restart
The inclusion of our init
file in our webserver-packt.bb
recipe consists of:
server.init
file to SRC_URI
.do_install()
to the step for our init
script.update-rc.d
. Adding this to Yocto is done by adding inherit update-rc.d
to our recipe.Here is webserver-packt.bb
after being updated:
DESCRIPTION = "Panel to monitor rpi temperature" LICENSE = "GPLv2" LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.GPLv2;md5=751419260aa954499f7abaabaa882bbe" # Package Release PR = "r0" # Use local tarball SRC_URI = " file://server.tar.gz file://server.init " RDEPENDS_${PN} += "bash" # Make sure our source directory (for the build) matches the directory structure in the tarball S = "${WORKDIR}" do_install() { install -d ${D}${datadir}/server-packt cp -a ${S}/server ${D}${datadir}/server-packt install -d ${D}${sysconfdir}/init.d/ install -m 0755 ${WORKDIR}/server.init ${D}${sysconfdir}/init.d/server-packt-init } # Package files FILES_${PN} += "${datadir}/server-packt" inherit update-rc.d INITSCRIPT_NAME = "server-packt-init" INITSCRIPT_PARAMS = "start 99 5 2 . stop 19 0 1 6 ."
Here is an explanation of our updated webserver-packt.bb
file:
INITSCRIPT_NAME
variable represents the filename of the initialization script, as installed to /etc/init.d
.INITSCRIPT_PARAMS
variable specifies the options to pass to update-rc.d
. In our case, the script has a runlevel
of 99
, is started at init levels 2 and 5, and is stopped at levels 0, 1, and 6.If you want more information about update-rc.d
, you can visit the official documentation of the Yocto Project: http://www.yoctoproject.org/docs/1.8/mega-manual/mega-manual.html#ref-classes-update-rc.d
3.145.178.240