Bobot

De Proyecto Butiá
Revisión del 12:35 4 nov 2011 de Andres (Discusión | contribuciones) (Página creada con '== Bobot == Fig. 9.1 bobot logoFig. 9.2 Arquitectura del bobot[[Archivo:web_bobot.png|thumb|Fig. 9.3 Interacción c...')

(dif) ← Revisión anterior | Revisión actual (dif) | Revisión siguiente → (dif)
Saltar a: navegación, buscar

Bobot

Fig. 9.1 bobot logo
Fig. 9.2 Arquitectura del bobot
Fig. 9.3 Interacción con dispositivo USB4all de forma web

bobot-server (version 2) es un servicio que permite acceder a aplicaciones y usuarios interactuar con dispositivos USB4all. Consiste en un agente altamente portable y liviano, que exporta la funcionalidad de los dispositivos USB4all presentes de una forma fácil de usar. Ofrece dos métodos de acceso, uno optimizado para aplicaciones, basado en un socket y un protocolo fácilmente parseable, y otro optimizado para ser usado por humanos, mediante un sitio web hosteado en el propio agente, el cual atiende en el puerto 2010.
Bobot introduce el concepto de driver, en el cual se codifica el protocolo que utilizan los usermodules, de esta forma se exponen al usuario del sistema bobot los servicios que implementan los usermodules ocultando los detalles relacionados con el protocolo de intercambio de mensajes. Para desarrollar compatibilidad con un nuevo dispositivo electronico en la plataforma USB4all utilizando bobot para su control, primero se debe desarrollar el usermodule necesario como fue descripto en la sección: Escribiendo un usermodule luego se debe escribir el driver correspondiente a ese usermodule.

El driver se escribe en Lua, debe seguir un formato preestablecido y es implementado mediante el recurso de tablas que brinda Lua. Una característica de Lua es que las funciones son miembros de primer orden, esto permite (entre otras cosas) que una función pueda ser un tipo de datos válido, pasar funciones como argumento de funciones o como retorno de las mismas y almacenarla en una tabla. Esta capacidad permite que dentro de la tabla que representa un driver se puedan almacenar funciones asociadas para cada servicio expuesto por un módulo. Estas funciones son invocadas al solicitarse servicios desde la aplicación que utiliza la biblioteca.

Asociado a cada función se almacenan metadatos que describen los parámetros que la función recibe, su tipo, valor de retorno y valores aceptados. Mucha de ésta información es utilizada por el bobot para generar el sitio web mencionado anteriormente, como se muestra en la figura 9.3. Este sitio describe al módulo de usuario y se puede usar como documentación y mecanismo de prueba del mismo. A continuación se muestra un ejemplo de driver para el módulo de usuario presentado en la sección: Escribiendo un usermodule. En este driver podemos ver que se exportan los siguientes servicios:

  • read_version
  • prender
  • apagar
  • buzzer_corto
  • buzzer_triple

El siguiente código corresponde con la implementación de estos servicios en un driver bobot:

 
local device = _G
local RD_VERSION = string.char(0x00)
local PRENDER = string.char(0x01)
local APAGAR = string.char(0x02)
local BUZZER_CORTO = string.char(0x03)
local BUZZER_TRIPLE = string.char(0x04)

api={}
api.read_version = {}
api.read_version.parameters = {} --no parameters
api.read_version.returns = {[1]={rname="version", rtype="number"}} --one return
api.read_version.call = function ()
        local get_read_version = RD_VERSION 
        device:send(get_read_version)
        local version_response = device:read(2) 
        local raw_val = string.byte(version_response, 2) 
        --print("rawval, deg_temp: ", raw_val, deg_temp)
        return raw_val
end

api.prender = {}
api.prender.parameters = {} --no parameters
api.prender.returns = {} --no return
api.prender.call = function ()
    local write_res, err = device:send(PRENDER)
    if write_res then return true else return false end
end

api.apagar = {}
api.apagar.parameters = {} --no parameters
api.apagar.returns = {} --no return
api.apagar.call = function ()
    local write_res, err = device:send(APAGAR)
    if write_res then return true else return false end
end

api.buzzer_corto = {}
api.buzzer_corto.parameters = {[1]={rname="num", rtype="number"}} 
api.buzzer_corto.returns = {} --no return
api.buzzer_corto.call = function (num)
    local write_res, err = device:send(BUZZER_CORTO .. string.char(num))
    if write_res then return true else return false end
end

api.buzzer_triple = {}
api.buzzer_triple.parameters = {[1]={rname="tiempo1", rtype="number"}, [2]={rname="tiempo2", rtype="number"}, [3]={rname="tiempo3", rtype="number"}} 
api.buzzer_triple.returns = {} --no return
api.buzzer_triple.call = function (tiempo1, tiempo2, tiempo3)
    local write_res, err = device:send(BUZZER_TRIPLE .. string.char(tiempo1) .. string.char(tiempo2) .. string.char(tiempo3))
    if write_res then return true else return false end
end

En el ejemplo puede notarse al comparar con el usermodule presentado de ejemplo, como se realiza el pasaje de parámetros entre el driver y el usermodule, esto corresponde con el protocolo definido por el usuario para codificar los comandos del usermodule y el orden de los parámetros, este protocolo es llamado en la arquitectura USB4all como user protocol y responde al formato de < COMANDO [argumento1] [argumento2]...[argumentoN] > para el pedido y mensajes del tipo < COMANDO [resultado1] [resultado2]..[resultadoN] > para la respuesta.

Entre las características del bobot se encuentra la capacidad de abstraer al usuario del tipo de hardware de placa de E/S está conectada pudiendo ser placas que utilizan comunicación serial rs232c o USB u otra tecnología como también la cantidad de las mismas. En la figura 8.2 puede verse un caso posible, donde se encuentran diferentes usermodules cargados en una baseboard y ciertos drivers cargados en el bobot que van a permitir consumir los servicios expuestos por los usermodules.

Como se mencionó al comienzo de la sección, bobot expone un protocolo que puede utilizarse mediante conexiones TCP/IP, este protocolo se describe de esta forma:

   LIST
   DESCRIBE moduleName
   CALL moduleName operation param1, param2, ...,paramN
   OPEN moduleName
   CLOSEALL

Donde el comando:

  • LIST despliega la lista de módulos disponibles en la placa por su nombre.
  • DESCRIBE muestra la información de que servicios expone el módulo de nombre moduleName e información sobre los parámetros.
  • CALL es utilizado para invocar los servicios expuestos por un módulo.
  • OPEN se utiliza para abirir un módulo, a partir de ese momento el baseboard le asigna tiempo de CPU y recursos al usermodule, actualmente esta deprecado su uso ya que bobot se encarga de abrirlos de forma automática ante la primer invocación.
  • CLOSEALL cierra todos los módulos abiertos en la placa, llevandola a un estado conocido.


Puede descargarse bobot desde el git del proyecto butiá en sourceforge.