RactJS on the BeagleBone

If you want to access a ReactJS app on the BeagleBone you will have to provided a web server. I used NodeJS for that. The idea here is to just pass every request on to the React app. You can do this after setting up the server with this command:

const app = express();

// Serve static assets; This navigates to the build folder generated by webpack
app.use(express.static(path.resolve(__dirname, '..', '..', 'build')));

// Always return the main index.html, so react-router render the route in the client
app.get('*', (req, res) => {
    // __dirname will get the directory name of the file, not the directory where React was started
    res.sendFile(path.resolve(__dirname, '..', '..', 'build', 'index.html'));
});

I am using expect here to achieve the desired effect. To finally run the app on the BeagleBone you can just launch the server. Make sure that webpack bundles only your client code, not your server side code. The index.html includes the bundle.js script generated by webpack, redirecting requests from the server to the client enables ReactJS to handle the routing itself.

As a side note, I use Babel with webpack to generate a backwards compatible bundle.js file. Here is the code: https://github.com/ordsen/gsoc-preparation/tree/master/reactjs_example/frontend

RactJS on the BeagleBone

Rest API with NodeJS

To create a rest API from an Express NodeJS app just add a new js file to the routes folder, e.g. rest.js and add a call to to the app.js file:

var express = require('express');
var app = express();

app.use("/rest", rest.js)
app.use('/rest', rest);

To create a function which is first called on all requests add the following:

/* executed on all requests */
router.use(function(req, res, next) {
    console.log("There was a new request");

    // pass request on to our api
    next();
});

To create a GET method at /rest/yourMethod add the following to your rest.js file:

router.get('/yourMethod', function(req, res, next) {
    res.send('A return value');
});

Parameters can be read with req.params.your_param and the rest call needs to be modified for this to match something like this: ‘/yourMethod/:your_param’

To create a POST method at /rest/yourMethod:

router.post('/putPayload', function(req, res, next) {
    console.log(req.body.your_post_param);
    res.json( {result: "OK"} );
});

Note that req.body.your_post_param reads the parameter named your_post_param from the POST request.

A full example can be found on GitHub: https://github.com/ordsen/gsoc-preparation/tree/master/nodejs_server_example/interface

.

Rest API with NodeJS

NodeJS to C Binding

To call methods written in C/C++ from NodeJS you need to accomplish several tasks as stated here. I am not aware of a solution to talk directly to a C library, so I will create a C++ binding which behaves like a wrapper for the C functions. I will summarize here  how this works, please see the Github repo and the provided links for more details: https://github.com/ordsen/gsoc-preparation/tree/master/nodejs_server_example/interface

Continue reading “NodeJS to C Binding”

NodeJS to C Binding

NodeJS and Express

To create a new express app with (creation of express apps with IntelliJ currently seems not to work properly) ejs use

express --ejs name_of_your_project
cd name_of_your_project && npm install

To give you a basic overview: In your Express project, the bin/www file starts everything up. The app.js file is where everything app related happens. in the “views” folder you can find your html pages (which are ejs now) and in your “routes” folder you can put the logic for each page (e.g. index.js for the index page). And last but not least, you can add publicly available resources to the “public” folder. To include a new page, add the .ejs file to views, include it in app.js and add a .js file for that page to the roots directory. See my repo for an example.

NodeJS and Express

Results of serial port tests

I tested the serial ports with non-canonical and canonical input mode as well as synchronously and asynchronously. I did not encounter any heavy problems related to FIFO overflows, but there seems to be a limitation with canonical input mode:

Synchronous Serial Port Communication

Even when writing 20000 messages all at once with the maximum baud rate supported by the temios API (B230400) to all four serial ports there were no messages dropped! Reading from the port and writing to a log file all happens synchronously, but the driver seems to take care of pretty much everything. Reading one byte or multiple bytes from the serial buffer does not seem to make a difference and both perform good. I tested this with non-canonical input mode; with canonical input mode (see other branches) I was able to separate the log into single messages devided by their time stamps. When doing this it is easy to find out the limitations of the built in buffer: The serial device can send up to 4096 characters without a line break. But if it sends more, the first messages which arrived will be dropped as the buffer fills up. That makes sense, as one page is 4096 bytes large. To overcome this issue later the user of the serial terminal server should be able to select non-canonical mode. That way the buffer can be read in time. Another possibility would be to use non-canonical mode per default and divide the logs manually after each \n character.

Asynchronous Serial Port Communication

This was tested with canonical mode and led to the same results as with synchronous serial port communication. The same limits apply, but inputs can be handled without needing to spawn a new thread for I/O tasks. This can be an improvement for the serial terminal server implementation, as I would like to avoid blocking the UI thread.

Results of serial port tests

Accessing BeagleBone from mac

To SHH into your BeagleBone from OS X go to http://beagleboard.org/getting-started#step2 and download the drivers. I recommend to use the links on that web site, when I first did this I used the links provided by the on-board web site of the BeagleBone. That led to old drivers and thus SSH did not really work…

Anyway, after installing the drivers and rebooting your mac you can SSH into the BeagleBone. If there was already a connection any time before you will need to add the new SHA fingerprint to /Users/user/.ssh/known_hosts (where “user” is your user name). Simply open finder, tap CMD+SHIFT+G, paste /Users/user/.ssh/ and open the known_hosts file in an editor. Find the ip address of the BeagleBone (192.168.7.2) and add the new SHA fingerprint right behind it (separated by space). The fingerprint will be provided by the SSH command when it fails due to changed remote identification, so just copy it from there.

Accessing BeagleBone from mac

Writing Jessie to BeagleBone Black

My BeagleBone came with Debian 7 installed. To update it I accomplished the following steps:

1. Head over to https://beagleboard.org/latest-images and get the latest image
2. On macOS, install xz, unpack the ter.xz file and flash the SD card you want to use:

brew install xz
xz -d bone-debian-8.7-lxqt-4gb-armhf-2017-03-19-4gb.img.xz

#find the device name of the SD card
diskutiel -l
#in my case it was /dev/disk2; CHECK THIS FOR YOUR SYSTEM!
#umount the disk
diskutil umountDisk /dev/disk2
#flash the image. This took about 20 minutes on my computer
sudo dd bs=1m if="bone-debian-8.7-lxqt-4gb-armhf-2017-03-19-4gb.img" of=/dev/disk2

3. Eject the SD card and remove it from your PC. Make sure to power down your BeagleBone and remove all connections (power, ethernet, wires, etc)
4. Insert the micro SD card into the BeagleBone and apply power. It will boot from the SD card, wait for the boot process to finish
5. After SSH’ing into the BeagleBone uncomment the following line in /boot/uEnv.txt

sudo vim /boot/uEnv.txt
---------------------------------------------------------
##enable Generic eMMC Flasher:
##make sure, these tools are installed: dosfstools rsync
cmdline=init=/opt/scripts/tools/eMMC/init-eMMC-flasher-v3.sh

 

6. Shutdown the BeagleBone and remove the power cable. Before you plug in the power cabe press and hold the boot button (the one near the SD card slot). After plugging it in, wait for the led’s to flash. As soon as you let go the button the led’s should flash in a rhythmic pattern (from left to right and then from right to left and so on).

When the image is written to the eMMC all four led’s will be lit and the BeagleBone will shut down. As soon as all led’s turned off you can remove the SD card. When you boot the next time (without the SD card) you can check if everything worked with

lsb_release -a
Writing Jessie to BeagleBone Black