Beaglebone Black vs Realtime Fist

Hace poco me llego la nueva placa Beaglebone Black con Linux Angstrom. Se me ocurrió hacer algunas pruebas acerca de como se comportaría en aplicaciones que requiere tiempo real.

Para esto arme un ambiente de desarrollo C++ con Eclipse + RSE a fin de poder compilar y deployar los binarios en la placa BBB. El seteo del ambiente no esta dentro del alcance de este post, pero si quieren saber mas de como lo hice pueden visitar Setting up Eclipse on the Beaglebone for C++ Development.

Las pruebas las hice conectando 2 salidas de la GPIO a un osciloscopio digital de 25 mhz. La idea es medir tiempos de respuesta en la GPIO y la estabilidad de las mismas, solo de las salidas.

P1010794

Bonescript

Beaglebone viene con una librería de acceso a GPIO para Node.js. Es una librería muy interesante, muy simple, con un interfaz similar a la de Arduino. Por supuesto que al ser un script, interpretado el overhead de CPU de las instrucciones es mucho mas alto que el de C++ compilado. La idea es hacer una pruebas para entender en definitiva lo lejos que esta de poder ser utilizado en aplicaciones real-time.

Para realizar esta pruebo decargue https://github.com/jadonk/bonescript y tome como ejemplo /demos/blinckled.js

var b = require('bonescript');

var ledPin = "P9_14";
b.pinMode(ledPin, b.OUTPUT);

var state = b.LOW;

b.digitalWrite(ledPin, state);

while (true) {
if(state == b.LOW) state = b.HIGH;
else state = b.LOW;
b.digitalWrite(ledPin, state);
}

De esta forma el script solo alterna el valor de salida del pin P9_14.

 
P1010795
 
En la imagen se puede ver que la mínima amplitud lograda en un pulso es de 152 us. Y la frecuencia para un ciclo completo ronda lo 3290 Hz.  Ademas de ser lento, vemos que hay una gran cantidad de jitter que supera los 60 us. Sumado a repetidas interruociones aleatorias por segundo de varios pulso de longitud.
 
P1010796
P1010797
 

Máxima velocidad C++

Que tan rápido puedo alternar el valor en un pin de la GPIO utilizando C++.  Para poder realizar esta prueba utilizo un ejemplo de acceso de GPIO con C++ publicado por Derek Malloy en su post Beaglebone: GPIO Programming on ARM Embedded Linux. El repo https://github.com/derekmolloy/boneDeviceTree

Luego de unos cambios a /gpio/TestApplication.cpp, este el codigo que utilice para las pruebas:

#include <iostream>
#include <string>
#include <unistd.h>
#include "GPIO/SimpleGPIO.h"
#include <sys/time.h>

using namespace std;

unsigned int LEDGPIO = 60; // GPIO1_28 = (1x32) + 28 = 60


int main(int argc, char *argv[]){

cout << "Testing the GPIO Pins" << endl;

gpio_export(LEDGPIO);
gpio_set_dir(LEDGPIO, OUTPUT_PIN);

while(true)
{
gpio_set_value(LEDGPIO, HIGH);
//usleep(100);
for (int i =0; i<30000;i++);
gpio_set_value(LEDGPIO, LOW);
for (int i =0; i<30000;i++);
}

cout << "Finished Testing the GPIO Pins" << endl;
gpio_unexport(LEDGPIO); // unexport the LED
return 0;
}
 
En lugar de utilizar usleep, realizo un simple for para quitar de la ecuación posibles context switches debido a que duermo el thread. Las pruebas como se puede ver en el osciloscopio dieron un pulso de 390 us. Con algo de jitter de aproximadamente 50 us. En un pulso especifico, pero en la vista general si nos alejamos en la escala de tiempo comenzamos a ver huecos aleatorios, como rafagas de jitter que pueden alcanzar desde algunos pulso de longitud hasta 20 o 50. Sin duda un problema.
 
Veamos ahora que velocidad logro si remuevo los for (;;) y dejamos que el tiempo entre pulsos sea solo el overhead de las instrucciones gpio_set_value.
El pulso que logramos es de 60 us, es decir unos 16.67 KHz o unos 8.47 KHz ciclos. Una vez mas obtenemos jitter, esta vez de 10us, PERO! aun tengo estos glitches aleatorios que pueden durar varias decenas de ciclos.
 
P1010801
 
Luego de subir a categoria real-time el proceso en linux utilizando:
 
chrt -r -p 50 728
 
Donde 728 es el PID del proceso.  Obtengo picos de utilización del CPU de 99% y los cortes esporádicos no cesaron.

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
728 root -51 0 2916 864 764 R 99.9 0.2 8:20.18 test
 
(pronto el video 23)

Conclusión

bonescript es practico y sencillo,  y apto para aplicaciones donde el tiempo de respuesta no sea algo critico. Se me ocurre que puede utilizarse para rovers, automatizaciones, domotica, etc. Pero no es apto para aplicaciones de tiempo real.

En cuanto a C++ los tiempos mejoran sin duda duplicamos la performance de Node.js pero aun tenemos problemas de jitter. Sin duda en el caso de necesitar real-time, Angstrom requiere un patch de real time para el kernel o simplemente descartarlo y utilizar un port de FreeRTOS o QNX.

Un pensamiento en “Beaglebone Black vs Realtime Fist

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s