tabla de contenido - Pontificia Universidad Javeriana

Anuncio
BESA MICRO-EDITION, ARQUITECTURA DE SISTEMAS MULTIAGENTE PARA
MICROCONTROLADORES
T.G. 0505
DAVID MAGIN FLOREZ RUBIO
GUILLERMO ANDRES RODRÍGUEZ CANTOR
JUAN MANUEL ORTIZ GÓMEZ
PONTIFICIA UNIVERSIDAD JAVERIANA
FACULTAD DE INGENIERIA
CARRERA DE INGENIERIA ELECTRÓNICA
BOGOTÁ
2005
BESA MICRO-EDITION, ARQUITECTURA DE SISTEMAS MULTIAGENTE PARA
MICROCONTROLADORES
T.G. 0505
DAVID MAGIN FLOREZ RUBIO
GUILLERMO ANDRES RODRÍGUEZ CANTOR
JUAN MANUEL ORTIZ GÓMEZ
Informe Final
Director
ENRIQUE GONZALEZ
Ingeniero Eléctrico
PONTIFICIA UNIVERSIDAD JAVERIANA
FACULTAD DE INGENIERIA
CARRERA DE INGENIERIA ELECTRÓNICA
BOGOTÁ
2005
ii
TABLA DE CONTENIDO
INTRODUCCIÓN
1
1.
3
1.1.
1.2.
2.
2.1.
2.2.
2.2.1.
2.2.2.
2.3.
2.3.1.
2.3.2.
2.3.3.
2.3.4.
3.
3.1.
3.2.
3.2.1.
3.2.2.
3.2.3.
3.3.
3.3.1.
3.3.2.
3.3.3.
OBJETIVOS
OBJETIVO GENERAL
OBJETIVOS ESPECÍFICOS
3
3
MARCO TEÓRICO
5
SISTEMAS MULTI-AGENTE
Aplicaciones
ARQUITECTURA BESA DE SISTEMAS MULTI-AGENTE
DEFINICIÓN DE AGENTE
Estructura de un Agente (Canal – Comportamiento – Estado)
Definición de Contenedor
REQUERIMIENTOS DE BESA
Necesidades de Sincronización
Necesidades de Concurrencia
Comunicación entre Agentes
SISTEMAS OPERATIVOS
SISTEMAS OPERATIVOS EN TIEMPO REAL
PLANIFICACIÓN
MECANISMOS DE SINCRONIZACIÓN
Semáforos
Mensajes
MANEJO DE MEMORIA
DESARROLLO
5
5
6
6
7
8
9
9
10
10
11
12
13
15
16
17
18
21
REQUERIMIENTOS DE BESA
21
SELECCIÓN DEL RTOS Y DE LA FAMILIA DE MICROCONTROLADORES
21
BÚSQUEDA Y SELECCIÓN DEL RTOS
21
SELECCIÓN DE LA FAMILIA DE MICROCONTROLADORES
24
APROPIACIÓN DEL RTOS
26
Gestión de Memoria
26
Pruebas Realizadas
26
CONSTRUCCIÓN DEL MODELO BESA-ME
27
DESCRIPCIÓN GENERAL
27
NIVEL AGENTE
28
Estructuras Asociadas a la Identificación del Agente
29
Construcción del Canal
30
Construcción del Comportamiento
32
El Estado
33
Simulación del envío de un Evento al Canal y ejecución de sus Comportamientos 34
NIVEL SISTEMA
34
Creación del Contenedor
35
El Administrador Local en BESA-ME
37
Envío de Eventos BESA desde Interrupciones
37
Comunicación entre Agentes
39
iii
3.4.
3.4.1.
3.4.2.
4.
4.1.
4.1.1.
4.1.2.
4.2.
4.2.1.
4.2.2.
4.2.3.
PROTOCOLO DE COMUNICACIÓN EXTERNA
PROTOCOLO DE COMUNICACIÓN A NIVEL BYTE
Selección del Protocolo de Comunicación a Nivel Byte
Introducción al Funcionamiento del Protocolo I2C
Implementación del Protocolo de Comunicación a Nivel Byte
PROTOCOLO DE COMUNICACIÓN A NIVEL TRAMA
Trama Evento BESA
Trama Acknowledge BESA
Secuencia de Comunicación del Protocolo a Nivel Trama
PRUEBAS Y ANÁLISIS DE RESULTADOS
PROTOCOLO DE PRUEBAS
IDENTIFICACIÓN DE VARIABLES
Variables Independientes
Variables Intervinientes
Variables Dependientes
PRUEBAS A REALIZAR
Pruebas de Capacidad
Pruebas de Comunicación
Pruebas de Interrupciones
ANÁLISIS DE LOS RESULTADOS OBTENIDOS
PRUEBAS DE CAPACIDAD
Tamaño del Stack
Cantidad de Agentes por Contenedor
Cantidad de Comportamientos
Cantidad de Guardas
Cantidad de Puertos
Síntesis de Resultados Obtenidos
PRUEBAS DE COMUNICACIÓN
Envíos de Eventos por el Canal de Comunicación
Tiempos de Respuesta a Eventos
Tipos de Errores en la Comunicación Externa
PRUEBAS DE INTERRUPCIONES
40
40
40
41
43
46
46
47
48
61
61
61
61
63
63
64
64
64
65
65
65
66
66
68
69
69
70
70
71
74
77
81
5.
CONCLUSIONES
87
6.
BIBLIOGRAFIA
91
7.
ANEXOS
93
ANEXO A. MANUAL DEL USUARIO.
ANEXO B. CODIGO DE PROGRAMACION.
iv
93
94
INDICE DE FIGURAS
Figura 1.
Arquitectura interna de un agente. Tomado del artículo BESA.5
7
5
Figura 2.
Modelo del nivel de sistema BESA. Tomado de BESA.
9
Figura 3.
Modelo de Agente en BESA-ME
29
Figura 4.
Estructuras asociadas al Agente
29
Figura 5.
Estructura asociada al canal.
30
Figura 6.
Estructura asociada a los Puerto y a las Guardas.
31
Figura 7.
Estructura del Mensaje recibido por el Comportamiento.
31
Figura 8.
Estructura asociada al Comportamiento.
33
Figura 9.
Nivel Sistema en BESA-ME con el servicio de comunicación entre contenedores. El
administrador local se encarga del manejo de los eventos.
35
Figura 10.
Estructura asociada Contenedor.
36
Figura 11.
Estructura de los buffer de Transmisión y de Recepción para la comunicación entre
contenedores.
36
Figura 12.
BESA_DATA, Estructura en la que almacenan los datos de usuario.
37
Figura 13.
BESA_EVENT, Estructura en la que se almacena el tipo de evento y el
BESA_DATA.
Figura 14.
37
ISR_BESA_EVENT, Estructura en la que se almacena un BESA_EVENT cuando
quiere ser enviado desde una rutina de interrupción.
Figura 15.
Diagrama
de
bloques
del
tratamiento
de
eventos
38
desde
una
rutina
de
interrupción.
38
Figura 16.
Formato de tramas utilizadas para la comunicación entre Contenedores.
46
Figura 17.
Tipos de respuesta acknowledge en BESA-ME. Ejemplo del envío de un agente X a
un agente Z ubicados en distintos contenedores.
49
Figura 18.
Señales START, no Acknowledge Hardware y STOP.
54
Figura 19.
Señales presentes durante la comunicación exitosa desde un contenedor hacia otro
contenedor. Tamaño máximo de Datos igual a 6. DataSize igual a 8.
55
Figura 20.
Envío y recepción de eventos al bus I2C por medio de interrupciones.
56
Figura 21.
Diagrama de flujo de la comunicación entre agentes en BESA-ME.
60
Figura 22.
Envíos exitoso para diferentes frecuencias de envío y tamaño de cola igual a
uno.
Figura 23.
73
Envíos exitoso para diferentes frecuencias de envío y tamaño de cola igual a
dos.
Figura 24.
73
Envíos exitoso para diferentes frecuencias de envío y tamaño de cola igual a
tres.
Figura 25.
74
Tiempos de atención a eventos periódicos de envíos externos, desde los
comportamientos.
75
v
Figura 26.
Tiempos
de
atención
a
eventos
periódicos
de
envíos
locales,
comportamientos.
Figura 27.
desde
los
76
Envíos exitosos vs periodo de envío, para dos agentes ubicados en distintos
contenedores. Cada punto representa un grupo de 100 envíos
77
Figura 28.
Porcentaje de causas de error para un xDelayTime de 2ms.
78
Figura 29.
Porcentaje de causas de error para un xDelayTime de 11ms.
78
Figura 30.
Porcentaje de causas de error para un xDelayTime de 14ms.
78
Figura 31.
Porcentaje de causas de error para un xDelayTime de 20ms.
79
Figura 32.
Envíos exitosos vs periodo de envío, para 2 agentes productores y un
consumidor.
80
Figura 33.
Porcentaje de Causas de error para un xDelayTime de 3 ms.
80
Figura 34.
Porcentaje de Causas de error para un xDelayTime de 10 ms.
81
Figura 35.
Porcentaje de Causas de error para un xDelayTime de 14 ms.
81
Figura 36.
Envíos generados desde interrupciones periódicas.
83
Figura 37.
Distribución de los agentes y sus respectivos comportamientos para la aplicación
Figura 38.
de demostración.
85
Distribución de los agentes según los recursos físicos disponibles.
86
vi
INDICE DE TABLAS
Tabla 1.
Comparación de los recursos de memoria entre PIC18F452 y PIC18F8720.
Tabla 2.
Descripción de los bytes de la trama Event BESA para un Data Size de
tamaño
Tabla 3.
N.
25
47
Descripción de los bytes de la trama Ack BESA. Constante para cualquier tamaño
de datos.
48
Tabla 4.
Valores de los Stacks.
66
Tabla 5.
Tiempos de Respuesta para distintas cantidades de Agentes en un Contenedor.
Todos los tiempos en milisegundos.
Tabla 6.
67
Tiempos de Respuesta para distintas cantidades de Comportamientos en un
Contenedor.
68
Tabla 7.
Cantidad máxima de Guardas en un contenedor
69
Tabla 8.
Tiempos de respuesta a eventos con distintas cantidades de Puertos
69
Tabla 9.
Envíos de Eventos por el puerto I2C con diferentes tamaños de colas y periodos de
envío.
71
Tabla 10.
Tiempos de respuesta a un envío remoto por I2C.
74
Tabla 11.
Tiempos
de
atención
a
los
envíos
externos
de
eventos
periódicamente.
Tabla 12.
Tiempos
de
75
atención
a
los
periódicamente.
Tabla 13.
generados
envíos
locales
de
eventos
generados
76
Promedio de Envíos exitosos y fallidos generados desde una rutina de interrupción
a un agente local.
82
vii
INTRODUCCIÓN
En la cotidianidad se puede observar que para la solución eficiente de problemas complejos,
resulta conveniente dividirlos en tareas más simples que puedan ejecutarse por separado. Un
buen resultado depende de la coordinación entre ellas. Éste mismo concepto puede ser llevado a
la
industria, donde el avance de la tecnología plantea nuevos retos que requieren soluciones
rápidas y efectivas.
Existe un modelo que abstrae el concepto de tareas distribuidas y que propone un esquema para
la construcción de sistemas complejos.
Éste modelo es conocido como Sistema Multi-Agente
(SMA).
A partir de los desarrollos sobre SMA publicados por Jiming Liu, se puede obtener una visión
general del origen y justificación de este modelo. Sus desarrollos respondían a la pregunta de
por qué tener múltiples individuos afirmando: “por la misma razón que organizaciones como las
conformadas por abejas y hormigas están formadas por grupos de individuos nacidos con una
labor específica, los individuos se comunican entre sí, para entre todos, lograr un objetivo
común” 1 . De esta forma, se muestra la existencia de entidades (individuos) especializadas para
el desarrollo de determinadas labores y como a través de estas entidades, es posible distribuir
las tareas, disminuyendo la carga para cada uno de ellos y mejorando el resultado final.
Los SMA no sólo son una tecnología muy prometedora, también están emergiendo como una
nueva manera del pensamiento: un paradigma conceptual para analizar problemas y para el
diseño de sistemas; un medio para manejar la complejidad, distribución e interactividad, y
quizás una nueva perspectiva en las ciencias de la computación y la inteligencia artificial 2 .
El diseño de aplicaciones desde el concepto SMA presenta algunas dificultades tales como la falta
de herramientas para su desarrollo y su reducido uso industrial. Para darle solución a lo anterior
hemos desarrollado una herramienta de programación de alto nivel que facilita la distribución de
tareas y su aplicación en un entorno hardware, con la característica de permitir al diseñador
modificarlas en una forma eficiente, así como realizar labores de mantenimiento o actualización
del sistema (escalabilidad). Dado el extendido uso de los microcontroladores para aplicaciones
industriales y de investigación, la implementación de la herramienta se ha realizado sobre estos
dispositivos.
1
LIU, Jiming. “Multi – Agent Robotic Systems”. CRC Press, Boca Ratón, Fl. 2001
2
Robocup Federation, “RoboCup Home Page”. http://www. robocup.org.
1
Debido al enfoque Multi-Agente de la herramienta que fue implementada, este libro comienza
con un resumen de las generalidades y aplicaciones de los SMA. En el capítulo siguiente se
describe BESA, la arquitectura de SMA desarrollada en la Pontificia Universidad Javeriana, con
base en la cual se ha desarrollado la herramienta descrita en este trabajo y que da origen a su
nombre BESA Micro Edition (BESA-ME). Una vez identificadas las necesidades de este modelo de
SMA y su aplicación a microcontroladores, se muestra la necesidad de usar un Sistema
Operativo que las soporte, por lo cual continuamos con un capítulo donde se explican las
características generales y se describen más a fondo los Sistemas Operativos de tipo Tiempo
Real (RTOS por sus siglas en inglés). Luego, en el desarrollo, se sintetizan lo requerimientos de
ejecución de la arquitectura BESA, con base en estos se explica como se seleccionó el RTOS para
soportar el modelo y como fue construido el modelo BESA adaptado a las características de un
micro-controlador y a un ambiente distribuido de dos microcontroladores.
exponen las
Por último, se
pruebas y sus resultados, con los cuales se evaluaron las características de
capacidad y velocidad de la herramienta aplicada a una plataforma hardware específica.
BESA-ME es entonces una herramienta innovadora, económica y de gran facilidad de aplicación,
diseñada con posibilidades de ser actualizada a medida que los microcontroladores evolucionen.
2
1. OBJETIVOS
1.1. Objetivo General
Desarrollar una plataforma de software que implemente el modelo BESA para una familia de
microcontroladores, permitiendo la creación de aplicaciones con enfoque Multi-Agente.
1.2. Objetivos Específicos
1.
Seleccionar e implementar para una familia de microcontroladores, un sistema operativo ya
existente que posea las características de un RTOS y proporcione los servicios básicos de un
ambiente multitarea requeridos por el modelo BESA.
2.
Diseñar e implementar una plataforma de software basada en el modelo BESA que funcione
sobre el RTOS seleccionado e implementado y que soporte la creación de aplicaciones con
enfoque Multi-Agente.
3.
Desarrollar el servicio de comunicación entre agentes de dos microcontroladores de la misma
familia adecuado para el modelo BESA.
3
4
2. MARCO TEÓRICO
En este marco teórico se muestra un resumen de las generalidades y aplicaciones de los
Sistemas Multi-Agente. Con base en esto se describe el modelo abstracto de SMA planteado por
la arquitectura BESA.
Dadas las características que plantea este modelo y su aplicación a
microcontroladores, se muestra la necesidad de usar un Sistema Operativo Tiempo Real, sobre
el cual se profundiza también.
2.1. Sistemas Multi-agente
Un Sistema Multi-Agente (SMA) es un sistema computacional con características de autonomía,
es decir, capaz de ejecutar ciertas tareas dentro de un entorno determinado y modificarlo, según
la función especifica para la cual fue diseñado. Las funciones que puede realizar están definidas
por un conjunto de instrucciones que pueden ser ejecutadas o no. La arquitectura del sistema
determina la forma de comunicación entre agentes y la administración de los recursos 3 .
En la estandarización de estas arquitecturas de SMA, la fundación FIPA (Foundation for
Intelligent Physics Agents) ha creado ciertas directrices. Propone una plataforma de software
que contiene la definición de un lenguaje de comunicación entre agentes y los elementos básicos
para la construcción del sistema 4 .
Aplicaciones
Actualmente los Agentes y los sistemas multiagente son una de las tecnologías más prominentes
y atractivas de la ingeniería y la informática. Las tecnologías, métodos y teorías de sistemas
multiagentes están contribuyendo en diversos dominios de aplicación, tales como: recuperación
de información, diseño de interfases de usuario, robótica, juegos de computador, educación,
ambientes de entretenimiento, manejo y administración de proyectos, simulación social, realidad
virtual, etc.
En la solución de muchos de estos problemas se emplean mecanismos de control de software y
de
hardware,
como
algoritmos
computacionales
y
máquinas
dedicadas
que
utilizan
microcontroladores y DSP.
3
WEISS, Gerhard.
“Multiagent systems: A modern approach to Distributed Artificial Intelligence”.
Masachussets, U.S.A 1999.
4
Foundation For Intelligent Physical Agents, http://www.fipa.org, Noviembre 5 del 2004.
5
2.2. Arquitectura BESA de Sistemas Multi-Agente
BESA es una arquitectura para la construcción de Sistemas Multi-Agente, que implementa tres
conceptos principales en su modelo abstracto de SMA 5 , de los cuales se desprende la sigla
BESA:
•
Behavior – Oriented: Los agentes se descomponen modularmente en entidades más
simples, las cuales poseen ciertos comportamientos con una semántica asociada entre
ellos, que permite la cooperación. Un agente está compuesto por un conjunto de
comportamientos concurrentes.
•
Event – Driven: Los eventos que desencadenan la ejecución de comportamientos son
señales que pueden ser percibidas o usadas por los agentes y esta ejecución depende de un
mecanismo selector que evalúa el estado actual de la entidad y el estado de comunicación
asociado a la detección del evento.
•
Social – Based: El sistema se crea sobre una organización social de agentes, compuesta
en un conjunto de organizaciones de más bajo nivel, que conservan la estructura de un
agente y cuyos últimos eslabones son los agentes individuales.
2.2.1.
Definición de Agente
Un agente es la unidad abstracta fundamental a partir de la cual se conforma el sistema MultiAgente BESA.
A nivel social es la unidad más simple que sirve como base para construir
cualquier nivel superior.
Su arquitectura interna determina la estructura del sistema, los
mecanismos de interacción entre los mismos agentes y el tratamiento dado a los eventos con el
fin de obtener una respuesta.
Los agentes responden a eventos provenientes del entorno o de una tarea en ejecución.
Así
como el agente puede percibir eventos provenientes del entorno, también puede modificarlo.
Para esto, cada evento que se defina en el sistema debe tener un tratamiento asociado, de
manera que cuando el agente lo perciba ejecute un procedimiento y se obtenga un resultado.
Un agente debe además poder comunicarse con los demás agentes del sistema, pues es
fundamental la interacción entre ellos para lograr el objetivo esperado a través de la ejecución
concurrente de las tareas, el intercambio de eventos y la respuesta dada a los mismos.
5
GONZALEZ, Enrique, AVILA, Jamir, BUSTACARA, César. “BESA” Bogotá, Colombia. 2003.
6
Estructura de un Agente (Canal – Comportamiento – Estado)
La arquitectura interna de los agentes integra cuatro elementos importantes: una composición
modular de comportamientos, un canal compuesto por un buzón de recepción y un mecanismo
selector de eventos y un estado.
Figura 1.
Arquitectura interna de un agente. Tomado del artículo BESA.5
El canal y el comportamiento son las dos tareas por las cuales está compuesto un agente como
mínimo. En el canal se reciben los eventos; para cada tipo de evento debe existir un puerto al
cual se asigna el evento recibido para ser transferido a los comportamientos asociados. Allí se
almacenan y se ejecutan los procedimientos relacionados a cada evento.
Como se observa en la figura 1,
el canal está formado por un buzón de entrada, donde se
reciben los eventos direccionados al agente.
Mediante un mecanismo selector basado en
guardas los eventos que se reciben se transfieren al puerto correspondiente.
Los puertos al
igual que el buzón de entrada son colas, que permiten almacenar varios eventos de un mismo
tipo en un puerto específico.
La política implementada para el despacho de los eventos es FIFO (First in – First out), razón por
la cual por cada tipo de evento asignado a un agente, debe existir un puerto asociado, con el fin
de evitar el bloqueo entre eventos y que no se ejecuten los procedimientos relacionados en el
momento adecuado.
7
El evento almacenado en el puerto sólo se transfiere al comportamiento correspondiente cuando
se comprueba una condición booleana, que se puede ver afectada por el mismo evento o por
una variable que influye en la condición, disparando la guarda.
Los comportamientos son tareas que pueden ejecutarse en paralelo y deben estar asociados con
la guarda asociada al tipo de evento. Cada comportamiento tiene una cola para recibir eventos
provenientes de los puertos del canal; cuando llega el evento, el comportamiento ejecuta
automáticamente la función de tratamiento correspondiente.
Un sistema multitarea permite que varios procesos sean ejecutados al mismo tiempo,
compartiendo uno o más procesadores. BESA tiene la característica de ser una arquitectura
multitarea ya que debe coordinar concurrentemente el uso del canal de comunicación y la
ejecución de los comportamientos de los agentes en tiempo real. Tener más de un
comportamiento en la arquitectura de un agente permite el paralelismo en el sistema, es decir,
la ejecución de diferentes procedimientos en tiempo real, como respuesta a eventos que pueden
ser concurrentes o no.
Dentro de la arquitectura del agente existe un espacio denominado Estado (State) reservado
para guardar información acerca del contexto del agente, del entorno, de los demás agentes y
del sistema en general, según el tipo de información que el usuario final requiera.
El estado
puede ser accedido desde las funciones de tratamiento que se ejecutan en el comportamiento;
puede ser leído y modificado según se requiera, por lo que debe ser protegido para que sólo
pueda ser accedido por una tarea a la vez.
Definición de Contenedor
Un conjunto de agentes reunidos da origen a un nivel social más abstracto conocido como
sistema.
En BESA un sistema está formado por contenedores, que pueden funcionar en
diferentes máquinas físicas o virtuales.
Un contenedor es un espacio de ejecución donde los agentes habitan. Estos están manejados
por un administrador local que es el encargado de la gestión del ciclo de vida de los agentes y de
permitir la comunicación con agentes de otros contenedores.
8
Modelo del nivel de sistema BESA. Tomado de BESA.5
Figura 2.
Los agentes pertenecientes a un mismo contenedor interactúan directamente, a diferencia de los
agentes ubicados en distintos contenedores, los cuales se comunican entre si a través de un
único puerto compatible con FIPA, el cual recibe la comunicación y las consultas de otros
sistemas externos. (Ver Figura 2).
2.2.2.
Requerimientos de BESA
Necesidades de Sincronización
En la construcción del modelo de implementación (BESA-ME, BESA-Micro Edition) surge la
necesidad de proteger estructuras y variables que pueden ser accedidas por varias tareas al
mismo tiempo.
Si una tarea accede a determinada variable y está utilizando la información
contenida en ésta, ninguna otra tarea debe acceder a la misma variable hasta que no sea
liberada por la tarea anterior.
En el peor de los casos el acceso simultáneo por más de una
tarea a una variable podría causar que ésta sea modificada mientras está siendo accedida y
generar un error en la información o en la ejecución.
Para evitar que esto suceda es necesario contar con algún mecanismo de señalización que
proteja la variable a la que se accede y la información contenida en ella, de manera que en los
casos críticos en los que se requiera, sólo una tarea pueda acceder la variable a la vez.
La utilización de semáforos es seguramente la solución más adecuada para solucionar los
problemas de sincronización.
Cuando se va a acceder a una variable crítica, se baja el
semáforo, cuando se libera la variable se sube el semáforo y otra tarea puede accederla.
9
Necesidades de Concurrencia
Debido a que el modelo abstracto de BESA plantea la ejecución de los comportamientos en
paralelo, se requiere que la arquitectura BESA sea una arquitectura multitarea, creando cada
comportamiento y cada canal como una tarea del sistema operativo, lo que permite su ejecución
concurrente por parte del planificador del RTOS.
Cada agente puede tener más de un comportamiento, y a cada comportamiento le son
asignados eventos con sus respectivas funciones de tratamiento; las funciones deben ser
ejecutadas entonces simultáneamente para responder a los eventos en tiempo real a medida
que se vayan presentando. Puede ser útil entonces, el manejo de prioridades para asegurar la
ejecución de ciertos comportamientos críticos que requieran una acción inmediata, teniendo
presente que se debe evitar la inanición de las tareas de menor prioridad.
El hecho de que el canal sea una tarea que se ejecute paralelamente con los comportamientos,
asegura al máximo la recepción de los eventos que le sean dirigidos y su reenvío a los
comportamientos correspondientes.
Comunicación entre Agentes
BESA plantea un servicio de directorios que facilita la comunicación entre los agentes.
El
servicio tiene dos secciones principales: una de páginas blancas donde es posible ubicar los
agentes por una identificación dada en el momento de la creación; y otra de páginas amarillas
donde se puede localizar a un grupo de agentes que tengan ciertas características en común,
según su especialidad. Cada contenedor tiene su propio servicio de directorios.
La comunicación entre agentes se puede dar de dos maneras diferentes: entre agentes del
mismo contenedor o entre agentes de contenedores distintos.
Comunicación entre Agentes del Mismo Contenedor
Cuando un agente quiere comunicarse con otro, recurre entonces al servicio de directorios para
poder localizar el destinatario, ya sea por su identificación o por su especialidad. Si los agentes
pertenecen al mismo contenedor, la comunicación es directa, envían información de uno a otro,
sin que el administrador local del contenedor intervenga.
Comunicación entre Agentes de Distintos Contenedores
El agente acude al servicio de directorios para localizar al agente con el que se quiere comunicar.
Una vez localizado, la comunicación se realiza a través del puerto serial al que todos los
contenedores pueden acceder, el cual se encarga de transmitir y recibir la información
proveniente de otro contenedor y entregarla al agente correspondiente.
10
Los contenedores deben tener en su servicio de directorios la información correspondiente a los
agentes existentes en los demás contenedores.
Si un agente es creado o destruido, el
administrador local del contenedor debe informar a todos los otros contenedores del sistema,
con el fin de que sea actualizado su servicio de directorios.
Lo mismo debe hacerse en el
arranque del sistema para que cada contenedor conozca a de la existencia de otros
contenedores y agentes 6 .
2.3. Sistemas Operativos
Los Sistemas Operativos (SO) son uno de los más grandes logros en el desarrollo de software y
constituyen uno de los más complejos programas. La búsqueda por lograr una administración
eficiente y segura de los recursos de un computador ha llevado al desarrollo de los conceptos de
proceso, gestión de memoria, seguridad y protección de la información, planificación y gestión
de recursos, y estructura de sistema 7 .
El concepto de proceso es uno de lo grandes logros en el desarrollo de SO. Se define como la
mínima unidad de actividad; está caracterizada por una ejecución secuencial, por un estado
actual y por estar asociada a un conjunto de recursos. Está compuesto por una o más unidades
de trabajo conocidas como hilos, estos incluyen un contexto propio y áreas de datos propias, a
partir
de
las
cuales
se
logran
establecer
bifurcaciones
a
subrutinas,
es
decir,
son
interrumpibles y permiten que los procesos cedan y retomen el control del procesador (control
expropiativo), utilizando así, la técnica de multi-hilos para ejecutar varias tareas independientes
(multiproceso) 8 .
Para la administración del paso de ejecución de un proceso a otro y sus implicaciones existen
varios algoritmos de planificación. Esta administración parte de 5 posibles estados de los
procesos: Nuevo, Listo, Ejecutándose, Bloqueado y Terminado, según los cuales se deben tomar
las acciones determinadas por el algoritmo de planificación.
En la actualidad el estándar POSIX, define la interfaz que los sistemas operativos deben ofrecer
a las aplicaciones, así como la semántica de los servicios ofrecidos por esta interfaz.
6
GONZALEZ, Enrique, AVILA, Jamir, BUSTACARA, César. “BESA” Bogotá, Colombia. 2003.
7
STALLINGS, William. “Sistemas Operativos”. Prentice Hall. Madrid, España. 2001.
8
STALLINGS, William. “Sistemas Operativos”. Prentice Hall. Madrid, España. 2001.
11
2.3.1. Sistemas Operativos en Tiempo Real
Cuando un sistema computacional requiere dar respuesta a determinados dispositivos en tiempo
real, aspectos como la administración eficiente de la memoria y el aumento en la eficiencia de
utilización de la CPU se hacen secundarios, tal es el caso de las plataformas robóticas y mallas
de control industrial.
Esta necesidad ya ha sido detectada por empresas diseñadoras de
microcontroladores usados en aplicaciones de tiempo real y ha sido superada mediante el
desarrollo de sistemas operativos para estos dispositivos, son conocidos como sistemas
operativos en tiempo real (RTOS, siglas en inglés).
Los Sistemas Operativos Tiempo Real son diseñados para administrar la respuesta a sucesos o
eventos, de tal forma que se respeten ciertos rangos de tiempo de respuesta, los cuales, en el
caso de ser críticos para el sistema, requieren atención inmediata.
En todo caso el RTOS es
determinista, en consecuencia permite que el usuario prediga los tiempos de respuesta que el
RTOS proporcionará al sistema informático que administra. Estos eventos, normalmente se
producen en el entorno del sistema; estos llegan como interrupciones al procesador, ya sean por
software o hardware. Los RTOS deben atender ráfagas de miles de interrupciones que activan
diferentes procesos.
Para no perder ningún suceso recibido, el RTOS debe trabajar con la
técnica multiproceso, la cual ejecuta los procesos independientemente unos de otros, pero en
ciertas aplicaciones se deben tener estrategias para asignar prioridad a los procesos y
ejecutarlos según su importancia, lo cual se logra con una planificación expropiativa basada en
prioridades.
Algunas de las características más importantes de los RTOS son 9 :
-
La gestión de dispositivos críticos en tiempo.
-
Sofisticadas estrategias para la gestión de interrupciones.
-
Eficiente almacenamiento de E/S.
-
Permiten acceso desde los programas de usuario a los vectores de interrupción para
prestar servicio a los sucesos.
Otras áreas críticas en los RTOS son el determinismo, la sensibilidad, el control del usuario, la
gran fiabilidad y la tolerancia a los fallos. 10
Entre éste tipo de SO se encuentran muchas versiones comerciales de alto costo como URTX,
RTX, QNX, útiles para dispositivos de alto desempeño como los microprocesadores 80X86 y
9
MILENKOVICH, Milan. “Sistemas Operativos: Conceptos y Diseño”. Mc. Graw Hill, Madrid, España. 1998.
10
STALLINGS, William. “Sistemas Operativos”. Prentice Hall. Madrid, España. 2001.
12
algunos de libre distribución como SALVOTM y la migración del SO MartOS al MC68332 11 .
SALVOTM, con versiones para microcontroladores Microchip, TI y Motorola entre otros, soporta
multiproceso y en su versión de libre distribución soporta hasta tres tareas simultáneas12 .
2.3.2. Planificación
El planificador es un conjunto de políticas y mecanismos incorporados al Sistema Operativo que
gobiernan el orden en que se ejecutan las tareas en un sistema multiprogramado. El objetivo
primario de la planificación es optimizar el rendimiento del sistema de acuerdo con los criterios
considerados más importantes por los diseñadores.
Existen 3 clases de planificadores,
los
cuales se clasifican según la frecuencia con la que es invocado por el procesador; estas son
planificaciones a largo, mediano y corto plazo; este último es el único que se implementa en los
RTOS.
El planificador a corto plazo, también conocido como distribuidor (Dispacher), es el que toma
decisiones con una mayor frecuencia y detalle sobre la tarea que se ejecutará a continuación. Su
principal objetivo es maximizar el rendimiento del sistema de acuerdo con un conjunto de
criterios elegidos. El planificador a corto plazo debe ser ejecutado por lo tanto, cada vez que
una tarea se detenga (bloqueo), o cada vez que un suceso (interno o externo) ocurra. Éste es el
tipo de planificador que soportan los sistemas RTOS, ya que el tiempo de ejecución es el criterio
más importante a tener en cuenta. La suspensión, la terminación o aborto de una tarea en
ejecución, son también sucesos que pueden necesitar la llamada al planificador a corto plazo. 13
Los algoritmos o mecanismos de planificación se pueden dividir en dos grandes grupos,
expropiativos y no expropiativos. La no expropiación implica que cuando una tarea de mayor
prioridad aparece, la tarea actual en ejecución no se ve obligada a ceder la propiedad del
procesador, sino hasta que éste termine su ejecución. Con planificación expropiativa una tarea
en ejecución puede ser sustituida por una tarea de mayor prioridad en cualquier instante, lo que
implica entonces una mayor carga de trabajo para el planificador pero un menor tiempo de
respuesta a los eventos críticos. Las características que deben cumplir los RTOS son apoyadas
por el uso de planificación expropiativa.
Round Robin (RR),
planificación por turno rotatorio o también conocida como fracciones de
tiempo, presenta una apropiación del reloj de modo que se genera periódicamente una
interrupción indicando que la tarea que se encuentra en ejecución tiene que ser colocada en la
11
CASTO GUTIÉRREZ, Alberto, “Migración de un Sistema Operativo De Tiempo Real, MaRTE OS, a un
microcontrolador”, http://marte.unican.es/alberto_slides.ppt, Septiembre 5 de 2004.
12
SALVOTM, http://www.pumpkinc.com, Febrero 15 de 2004.
13
MILENKOVICH, Milan. “Sistemas Operativos: Conceptos y Diseño”. Mc. Graw Hill, Madrid, España. 1998.
13
cola de listas y se selecciona la siguiente, según un FIFO. El criterio de diseño es el tiempo de
duración de los cuantos (fracciones de tiempo) que se va a usar. Si el cuanto es muy pequeño,
las tareas cortas tendrán que pasar varias veces por el sistema antes de ser finalizados,
generando una sobrecarga en la gestión de recursos. Si el cuanto es muy grande, RR se
degenera en un simple FIFO donde las tareas cortas tienen que esperar mucho tiempo.
Existen otros algoritmos de planificación que presentan una serie de características más
complejas, impidiendo así cumplir con los criterios necesarios para la implementación de un
RTOS. Algunos de estos son SRT (Shortest Remaining Time), para el cual la tarea con menor
tiempo esperado de ejecución será la más prioritaria; Realimentación el cual presenta un
mecanismo dinámico de colas y prioridades. Cada cola representa un nivel de prioridad, y el más
alto es el de las tareas más nuevas. Una vez una tarea vuelve a su estado de Lista, luego de su
primera ejecución, es colocado en la segunda cola de menor prioridad. Después de cada
ejecución, la tarea Lista es degradada al nivel inmediatamente inferior de prioridad. Cada una de
estas colas funciona con la filosofía de FIFO, menos la última, que funciona con el mecanismo de
RR por no poder descender más; Planificación de colas multi-nivel (MLQ, Multiple-Level Queues),
el cual clasifica la carga de trabajo de acuerdo con sus características y mantiene colas de tareas
separadas servidas por diferentes planificadores. Una posible separación sería programas
interactivos, tareas del sistema y trabajos de lotes (simuladores). Estas asociaciones no son de
gran utilidad, para sistemas en tiempo real, por lo que no se suele implementar esta disciplina
en RTOS.
Un criterio más que debe cumplir un RTOS en el que se desee implementar en un sistema MultiAgente es el “tiempo de respuesta”, es decir, cualquier opción que presente una reducción en el
tiempo de procesamiento y de decisión, debe aparecer en las posibilidades de adopción para
éste proyecto.
La no utilización de planificadores a largo y mediano plazo es una decisión
evidente para cumplir con los parámetros necesarios, ya que el tiempo de procesamiento
requerido por cada uno de ellos, implica retardos indeseables. Por esta misma razón, los
algoritmos de planificación que requieren de cálculos complejos son desechados de las
posibilidades de implementación, como los son SPN (Shortest Process Next), SRT (Shortest
Remaining
Time),
Mayor
Tasa
De
Respuesta
y
Colas
Multi-Nivel,
métodos
descritos
anteriormente.
“La planificación dinámica del mejor resultado es el método utilizado en la mayoría de los
sistemas en tiempo real comercializados en la actualidad. Cuando llega una tarea, el sistema le
asigna una prioridad en función de sus características. Normalmente, se emplea alguna forma
de planificación por plazos, como puede ser la de primero el plazo más próximo. En general, las
tareas son aperiódicas, por lo que no es posible un análisis estático de planificación. Con este
tipo de planificación, no se sabe si se va a cumplir una restricción de tiempo hasta que vence el
14
plazo o la tarea termina.
Esta es la mayor desventaja de esta forma de planificación.
Su
ventaja está en la facilidad de implementación.”
El uso de múltiples colas, cada una de ellas de distintas prioridades (diferente al mecanismo de
Colas Multi-Nivel), recorridas con el mecanismo de turno rotatorio, se presenta como la mejor
opción de implementación para los requerimientos de BESA, ya que la característica de Event –
Driven requiere de una selección de tareas basada en prioridades, y de rotación equitativa,
además, su fácil implementación garantiza una rápida ejecución del planificador, evitando de
esta forma la inanición de procesos 14 .
2.3.3. Mecanismos de sincronización
Los sistemas operativos de tipo tiempo real (RTOS) soporten la concurrencia de tareas.
Esta
característica tiene varios niveles de complejidad dependiendo el tipo de relación que tienen
entre sí las tareas que requieren el uso del procesador, así: estas tareas pueden ser
independientes y no conocer la existencia de las otras (competencia), tener conocimiento
indirecto de las otras tareas (cooperación por compartimiento) o tener conocimiento directo de
las otras tareas (cooperación por comunicación). Las anteriores relaciones llevan a situaciones
de competencia y de cooperación que deben ser soportadas por el sistema operativo o tenidas
en cuenta por el programador.
Para que un sistema soporte la concurrencia sincronizada de tareas, en éste se deben realizar
dos acciones fundamentales: la Administración de recursos globales y la Gestión óptima de los
recursos.
Para llevarlas a cabo se han diseñado los mecanismos de sincronización.
Estos
permiten solucionar los tres problemas principales de la sincronización entre tareas: la exclusión
mutua, el inter-bloqueo y la inanición de las tareas.
El problema de la exclusión mutua se da cuando un recurso puede ser usado por una sola tarea
y no puede compartir su tiempo con otras hasta que la tarea salga de la sección de programa
que lo usa, estos recursos son llamados recursos críticos y la región del programa que los usa
son llamadas regiones críticas. El sistema operativo junto con otros servicios se deben encargar
de que sólo una tarea opere en su sección crítica a la vez. Por otro lado el inter-bloqueo se
presenta cuando dos tareas (o más) esperan la liberación de un recurso compartido, y a s vez,
esta espera retiene la liberación de otro recurso. Por último la inanición de una tarea se da
cuando el SO le concede el uso de un recurso a determinadas tareas periódicamente y se impide
que alguna o algunas tareas determinadas vuelvan a tomar el control del procesador, por
ejemplo por ser de baja prioridad.
14
MILENKOVICH, Milan. “Sistemas Operativos: Conceptos y Diseño”. Mc. Graw Hill, Madrid, España. 1998.
15
Los
problemas
de
sincronización
que
aparecen
por
la
concurrencia
de
tareas
son
fundamentalmente los mismos tanto para un sistema monoprocesador, donde se intercalan las
tareas,
como
para
un
sistema
multiprocesador,
donde
también
hay
superposición
(simultaneidad) en la ejecución de tareas.
Las soluciones a los anteriores problemas se pueden agrupar en tres tipos:
•
Por software, estas son implementadas en el código de programa de usuario.
Los
15
Algoritmos de Dekker y de Peterson ofrecen una solución de éste tipo .
•
Desde sistema operativo, a través de funcionalidades como los semáforos y los
mensajes.
•
Por Hardware, como, por ejemplo, el uso de inhabilitación por interrupciones.
El primer tipo es propenso a errores y a generar sobrecarga en el sistema. Las soluciones por
Hardware usan instrucciones de máquina por lo que no son soluciones generales.
Estos
problemas no se presentan en las soluciones implementadas como servicios del sistema
operativo o del lenguaje de programación, por esto y otras ventajas adicionales, se han
convertido en las estrategias de sincronización de más éxito. Dado que cubren las necesidades
de facilidad de programación y portabilidad, necesarias para el desarrollo del proyecto, serán las
óptimas para cumplir los objetivos planteados.
Explicamos su funcionamiento básico a
continuación.
Semáforos
El principio de los semáforos es la cooperación entre las tareas por medio de la generación de
señales y usados como mecanismos de sincronización permiten que se cumpla la exclusión
mutua entre tareas y evitan el interbloqueo. Los semáforos son variables que se modifican a
través de dos tipos de señales, una señal que indica que una tarea está esperando un resultado
y que llamaremos down y una señal que indica que se ha producido el resultado la cual
llamaremos up con la cual el semáforo debe “dejar pasar” una de las tareas que se encontraban
“esperando” en ese semáforo.
La variable semáforo puede iniciar en un valor no negativo y se debe disminuir en una unidad
cuando haya down y aumentar cuando se produzca up.
Si al llegar un down el valor del
semáforo se hace negativo entonces la tarea que generó el down se bloquea ya que dicho valor
indica que no hay resultados disponibles para la tarea que los solicita.
Ahora, cuando se
produce una señal up hacia cierto semáforo, significa que se produjo un resultado de interés
para las tareas que hayan estado esperando o para las que van a llegar a esperar, por lo cual se
incrementa en una unidad el valor del semáforo respectivo.
15
STALLINGS, William. “Sistemas Operativos”. Prentice Hall. Madrid, España. 2001.
16
Para decidir a cual de las tareas que produjeron un down en determinado semáforo se le debe
dar el control del procesador cuando ocurra el siguiente up (debido a la liberación de un recurso,
por ejemplo) se ha encontrado que la política más equitativa es FIFO, esta decisión es
independiente del mecanismo de planificación del sistema operativo.
FIFO es la política para
semáforos más apropiada para el RTOS a implementar ya que disminuirá el riesgo de inanición
de una tarea en el acceso a un recurso. Una vez una tarea haya solicitado acceso al semáforo
ninguna tarea de más prioridad podrá quitárselo.
Los semáforos permiten solucionar el problema de la exclusión mutua, mediante identificadores
que avisen con una señal down cuando se entra en la sección crítica de un programa. Sin
embargo, el éxito del uso de semáforos depende de su correcto manejo, debido a que la falta del
uso de alguna de estas dos señales puede llegar a bloquear el sistema.
Mensajes
El paso de mensajes entre procesos permite que las tareas cooperantes se sincronicen y que a
su vez intercambien información. El servicio de mensajería es útil en sistemas distribuidos, en
sistemas multiprocesador y monoprocesador de memoria compartida. Por lo cual será de gran
utilidad para la comunicación entre agentes.
Por un lado tenemos el intercambio de información. Para intercambiar información se necesita
al menos un sencillo protocolo de comunicación que permita la sincronización de los mensajes.
El esquema más sencillo consiste en el uso de las primitivas send y receive. Con estas primitivas
se pueden generar distintas configuraciones: bloqueo de la tarea tras generar send hasta que
reciba una respuesta, o no bloqueo, bloqueo tras generar receive hasta encontrar un mensaje o
no bloqueo. Según el tipo de sistema a desarrollar existen diferentes técnicas para solucionar
problemas como la pérdida de los mensajes o el bloqueo indefinido de las tareas al esperar un
mensaje que nunca llega.
Para enviar y recibir mensajes hacia y desde la tarea correcta se usa el direccionamiento directo
e indirecto, para cada primitiva. La primitiva send con direccionamiento directo requiere tener
identificadores para cada tarea, el cual debe ser enviado al llamar la primitiva. En el caso de
direccionamiento indirecto los mensajes se envían a una estructura de datos formada por colas
(denominada buzón), en las cuales se almacena temporalmente la información hasta que un
receptor la lee, es análogo a un arreglo de buzones donde cada uno ha sido creado para
establecer distintos tipos de relaciones entre las tareas.
Estas relaciones pueden ser de un
emisor a un receptor (comunicación punto a punto), de un emisor a muchos receptores o de
muchos emisores a un receptor, para éste último caso el buzón es denominado puerto.
17
La primitiva receive con direccionamiento directo requiere que cada tarea tenga conocimiento
anticipado sobre qué tarea o tareas le enviarán información, pero para los casos en que es
imposible predecir de qué tareas se va a recibir un mensaje en cada instante, se usa el
direccionamiento implícito, en éste, al ejecutar la primitiva receive, la tarea receptora espera el
identificador de la tarea que da origen al mensaje, proveniente de la ejecución de un send.
Cuando sucede un envío con exitosa recepción, el sistema puede realizar una copia del mensaje
en una cola o buzón, o simplemente transferir el apuntador a la información, lo cual la
convertiría en memoria compartida. Cuando se realiza copia del mensaje se asegura que no se
modificará indeseablemente el contenido de la información, sin embargo, éste método es lento,
ya que a medida que crece el tamaño de la información crece el tiempo de transferencia,
además utiliza más memoria para la creación de los buzones pero evita usar recursos adicionales
para proteger la información. El traslado del apuntador utiliza eficientemente la memoria, pero
se debe tener cuidado (usando los mecanismos adecuados) para no modificar los mensajes
originales en casos indeseados.
Cuando se quiere minimizar la carga de procesamiento y minimizar el coste de almacenamiento,
requerimientos de este proyecto, se usa un formato de mensajes de tamaño corto y fijo apoyado
en una organización de memoria por ejemplo pool de buffers, concepto que se ampliará en la
sección 2.3.4. En el formato del mensaje se incluye algunas veces información sobre la prioridad
del mensaje, para soportar el caso en el que no se desee tomar los mensajes de un buzón con
política FIFO. Por otro lado el paso de mensajes permite la sincronización respecto a los recursos
del sistema, es decir, soporta la exclusión mutua 16 .
2.3.4.
Manejo de memoria
Dadas las características de memoria de los microcontroladores actuales, se necesita una
estrategia para el manejo de memoria que no consuma muchos recursos del dispositivo y que no
sobre cargue el procesador.
La estrategia más sencilla es definir cuales son los tamaños de
palabra más útiles para el sistema operativo y crear arreglos de buffers de estos tamaños, y
solicitarlos al sistema a medida que se vayan necesitando.
La anterior estrategia es conocida como pool of buffers. Presenta la ventaja de requerir mínimo
sobre costo en el uso del procesador ya que elimina la búsqueda de espacios de memoria libres
al dejarlos de tamaño fijo.
Sin embargo puede llegar a ser ineficiente el uso de la memoria
cuando se reserva un espacio mayor al máximo de los buffers necesario o se usa menos espacio
que el menor de los reservados. Además, el programador debe ser muy cuidadoso de liberar los
16
MILENKOVICH, Milan. “Sistemas Operativos: Conceptos y Diseño”. Mc. Graw Hill, Madrid, España. 1998.
18
semáforos de protección una vez han sido usados los buffers, para permitir la posterior
reutilización de los mismos.
19
20
3. DESARROLLO
Se comenzó por analizar los requerimientos de la arquitectura BESA;
con base en estos se
explica como se seleccionó el RTOS para soportar la construcción y aplicación del modelo. Se
adaptó el modelo BESA a las características de un micro-controlador, luego se diseño y aplicó
un protocolo de comunicación para la extensión del modelo a un ambiente distribuido que usa
dos microcontroladores.
3.1. Requerimientos de BESA
En el capítulo 2 se describieron las características de Concurrencia, Sincronización y
Comunicación entre tareas como los principales requerimientos del modelo BESA.
Como se
mostró en el aparte de sistemas operativos, estas características son soportadas por los RTOS
actuales, pero adicional a estos requerimientos surge uno nuevo, ya que al ser implementado
sobre un microcontrolador se hace crítica la capacidad de memoria del hardware.
En
consecuencia es indispensable tener en cuenta que el modelo se pueda implementar sobre las
condiciones de memoria del dispositivo seleccionado.
3.2. Selección del RTOS y de la Familia de Microcontroladores
Se realizó una investigación sobre el funcionamiento de un RTOS en un micro controlador
desarrollando un kernel básico sobre un PIC18F452. Luego se buscaron los RTOS disponibles en
el mercado, buscando que tuvieran las características necesarias para implementar el modelo
BESA. Teniendo en cuenta criterios de bajo costo y facilidad de adaptación a nuestras
necesidades se seleccionó el RTOS freeRTOS y se estudiaron los posibles microcontroladores
sobre los cuales desarrollar la aplicación.
3.2.1. Búsqueda y Selección del RTOS
El Sistema Operativo necesario para la implementación de BESA debe ser como primera medida
de tiempo real, ya que se requiere dar respuesta a los eventos con la mayor rapidez posible y de
manera simultánea. Por esta razón el planificador debe dar tiempo de procesamiento a todas las
tareas que lo requieran, y contar con la característica de expropiación para permitir que tareas
de mayor prioridad tomen el control del procesador cuando lo necesiten. Además el SO debe
brindar un mecanismo para la creación y eliminación de tareas, y la posibilidad de suspenderlas
y reactivarlas, ya sea a una o a todas simultáneamente, en cualquier instante del
procesamiento.
21
El RTOS debe brindar la posibilidad de utilizar Semáforos, mecanismo seleccionado como la
mejor opción para solucionar los problemas de Sincronización, ya que permite el uso adecuado
de los espacios de memoria compartida a los que varias tareas (canal, comportamientos y otras)
pueden acceder, como el estado y los buffers utilizados para las transmisiones de un contenedor
a otro.
Un motivo por el cual una tarea puede llegar a bloquearse, es el envío no exitoso de un mensaje
a otra tarea; esta razón trae consigo la necesidad de un servicio de transmisión de mensajes
entre tareas, que permita la acumulación de mensajes cuando el planificador no permita su
inmediata recepción por tener bloqueada la tarea destino. Esto se logra por medio de colas tipo
buzón, en las cuales se puedan almacenar temporalmente eventos que serán atendidos una vez
la tarea destino sea desbloqueada y pueda recibir y dar tratamiento a los eventos enviados.
La búsqueda de un sistema operativo arrojó como resultados varios RTOS de libre distribución
desarrollados por distintas organizaciones y versiones de demostración de algunas empresas. De
todos estos destacamos aquí dos de los más sobresalientes y que más se acomodaban a
nuestras necesidades, SALVOTM y freeRTOSTM.
SALVOTM, del grupo PumpkincTM,
fue diseñado expresamente para sistema embebidos, cuyas
aplicaciones típicas usan entre 1 y 2K bytes de ROM, y entre 50 y 100 bytes de RAM. Cumple
con el criterio de multitarea cooperativa, servicio de eventos, bloqueo y suspensión de tareas, y
con muchos otros aspectos necesarios descritos anteriormente para el desarrollo del proyecto.
SALVOTM puede implementar en una gran cantidad de dispositivos, como son:
•
Familia 8051 y derivados.
•
ARClite microRISC.
•
ARM® ARM7TDMI®
•
Atmel® AVR® y MegaAVR™
•
Motorola M68HC11
•
TI's MSP430 Microcontriolador de baja potencia
•
Microchip PIC12|14000|16|17|18 PICmicro® MCUs
•
TI's TMS320C2000 DSPs
Sin embargo, la versión demo de SALVOTM que puede ser adquirida libremente permite crear
únicamente 3 tareas como máximo, lo que impediría en gran parte un buen aprovechamiento
del mismo 17 . La adquisición de la versión completa implica una inversión económica que no está
contemplada en el proyecto, razón de peso para desistir de este RTOS.
17
SALVOTM, http://www.pumpkinc.com, Febrero 15 de 2004.
22
FreeRTOSTM ofrece bajo consumo memoria RAM puesto que ha sido desarrollado específicamente
para aplicaciones con sistemas embebidos (microcontroladores). Presenta además tres modelos
posibles de asignación de memoria para la implementación de las aplicaciones. Utiliza un tipo de
planificación expropiativa que implementa colas por cada nivel de prioridad, recorridas cíclica y
equitativamente según el mecanismo FIFO; también ofrece un sistema de sincronización por
medio de semáforos binarios.
FreeRTOSTM es de libre distribución, es de fácil implementación y entendimiento gracias a que se
puede acceder libremente a su documentación. FreeRTOSTM también puede ser implementado
en una gran variedad de dispositivos 18 :
•
LPC2106, LPC2124 and LPC2129 (ARM7). Incluye código para el manejo de I2C. Renesas
H8S2329 (Hitachi H8/S) con un demo de EDK2329.
•
Atmel AT91SAM7 o las familias (AT91SAM7S32, AT91SAM7S64, AT91SAM7S128,
AT91SAM7S256). Incluye código para el manejo de USB para IAR Kickstart.
•
AT91FR40008 con demo de ATEB40X .
•
MSP430 con manejador de LCD.
•
HCS12 (MC9S12C32)
•
Cygnal 8051 / 8052
•
Microchip PICMicro (PIC18)
•
Atmel AVR (MegaAVR) con código de demostración STK500.
•
RDC8822 Microcontroller (AMD clon embebido del 186) con demo para Flashlite 186
SBC.
•
PC [corre con FreeDOS u otro DOS]
FreeRTOSv2.6.0 ofrece todas las características necesarias para la correcta implementación de
la arquitectura BESA, así como servicios que facilitaron las pruebas ejecutadas en el transcurso
del proyecto.
Los códigos y la documentación pueden ser descargados de Internet y traen
adjunto tres programas de demostración que sirven para familiarizarse con el RTOS, sirviendo
de punto de partida para nuevas aplicaciones. Se puede observar que este sistema operativo
tiene más oportunidades de migración a otros procesadores que los ofrecidos por SALVOTM, y por
consiguiente mayores aplicaciones posibles para el futuro de BESA-ME. Además cuenta con un
foro en la red donde es posible aclarar dudas y compartir inconvenientes y soluciones junto con
los demás usuarios y los desarrolladores del RTOS. Todas estas características llevaron a tomar
la decisión de implementar FreeRTOSTM como sistema operativo soporte a la plataforma BESAME desarrollada.
18
FreeRTOSTM, www.freertos.org. Mayo 25 de 2005.
23
3.2.2. Selección de la Familia de Microcontroladores
La familia de microcontroladores fue escogida con los siguientes criterios:
•
Debe ser soportada por el RTOS escogido. (freeRTOSTM)
•
Se analizó que tuviera la memoria suficiente para soportar el RTOS seleccionado y dejar
libre la memoria necesaria para el código BESA-ME.
•
El tercer criterio fue que ofreciera un módulo para la comunicación con otros dispositivos
microcontroladores, para permitir que agentes de distintos contenedores pueden
interactuar.
•
Para la generación de interrupciones interpretadas como eventos en el contesto BESAME y la interacción con otros dispositivos hardware como respuesta a estos, se observó
que ofreciera un número de puertos y periféricos considerable.
•
Finalmente se tuvo en cuenta la familia de microcontroladores más usados en el
contexto académico de los proyectos desarrollados en la Carrera de Ingeniería
Electrónica de la Pontificia Universidad Javeriana, en el cual se desarrolla BESA-ME.
Cualquiera de los sistemas embebidos que se desee implementar en la práctica, presentará
como criterio más crítico, la limitación de los recursos físicos. En éste caso, los requerimientos
de BESA indican que el recurso más limitado es el de memoria, pues esta arquitectura requiere
del uso constante de buzones para la recepción y envío de mensajes. Además, es necesaria la
asignación dinámica de segmentos de memoria que serán utilizados y reutilizados según la
aplicación implementada. El stack requerido por las tareas para guardar su información cuando
se produce un cambio de contexto, y las estructuras propias de BESA implican también un
espacio de memoria.
El continuo manejo de colas, (tanto para planificación de tareas, como
para los comportamientos y eventos del sistema) que serán modificadas y leídas por distintas
tareas (las colas son memoria compartida), implica también el manejo de semáforos, que
también consumen memoria, para la correcta sincronización en el acceso a los espacios de
memoria que lo necesiten. Todos estos aspectos demuestran porque el aprovechamiento de la
memoria al máximo es un aspecto crítico del presente proyecto.
De esta forma, los criterios de selección del microcontrolador para el proyecto, están ligados con
la selección del RTOS freeRTOS. Este RTOS presenta demostraciones específicas para el
microcontrolador PIC18F452 de microchip. Además, la universidad posee el hardware necesario
para la programación de estos dispositivos (ICD2 – In Circuit Debbuger), así como el software
de simulación y de programación (MPLAB).
Adicionalmente, la plataforma ROBOCOOP 19 que
sería un ambiente óptimo para la aplicación de BESA-ME usa el microcontrolador PIC18F452.
19
ROBOCOOP Es un proyecto de robótica distribuida, desarrollado en la Pontificia Universidad Javeriana.
24
El PIC18F452 se acomoda fácilmente a las necesidades de la arquitectura BESA gracias al
soporte que presta el sistema operativo a este dispositivo.
Sin embargo, no fue el
microcontrolador usado para finalizar el desarrollo de BESA-ME.
Luego de realizar la construcción del Nivel Agente, expuesto más adelante, se encontró que la
capacidad de memoria del PIC18F452 sólo permitía la creación de 1 agente
y 2
TM
comportamientos, razón por la cual se decidió realizar una migración de freeRTOS
microcontrolador de la misma familia pero con más capacidad de memoria.
a otro
Se escogió el
PIC18F8720, por las características que se muestran en la Tabla 1.
Para lograr esto fue necesario modificar el archivo p18f8720.lkr que viene incluido en los
archivos del compilador mcc18 de Microchip para el lenguaje de programación C.
Estas
modificaciones fueron necesarias debido a que el manejo de memoria que hace freeRTOSTM
requiere que se defina un gran bloque de memoria sobre el cual se separan los bytes de RAM a
medida que se solicitan (ver anexo C).
PIC18F452
20
PIC18F8720
Memoria de Programa (Bytes)
32K
128K
Memoria de Programa (Instrucciones)
16384
65536
Memoria de Datos (Bytes)
1536
3840
Memoria de Datos EEPROM (Bytes)
256
1024
Fuentes de Interrupciones
18
18
21
Tabla 1. Comparación de los recursos de memoria entre PIC18F452 y PIC18F8720.
Realizando esta migración de freeRTOS se demostró parte de la fácil implementación de la
arquitectura BESA-ME en una gran variedad de microcontroladores, ya que a Nivel de Agente la
migración sólo depende de que el RTOS, la capa inferior de la arquitectura, sea portada al
dispositivo deseado.
Esta familia de microcontroladores está siendo usada además en los
proyectos de investigación del grupo SIRP 22 de la Pontificia Universidad Javeriana.
P
De esta
forma, la plataforma BESA-ME será la base de futuras aplicaciones tanto para SIRP como para
aquellos estudiantes que deseen enfocar el desarrollo de sus proyectos por medio de sistemas
Multi-Agente.
20
MICROCHIP, PIC18FXX2 Data Sheet, Microchip Technology Inc 2002.
21
MICROCHIP, PIC18F6520/8520/6620/8620/6720/8720 Data Sheet, Microchip Technology Inc 2002.
22
SIRP, Sistemas inteligentes, Robótica y Percepción. Grupo de Investigación de la Facultad de Ingeniería
Electrónica, Pontifica Universidad Javeriana.
25
3.2.3. Apropiación del RTOS
FreeRTOSTM presenta tres programas de demostración que son descargados junto con el sistema
operativo.
Cada uno de estos demos presenta características distintas con el fin de que el
usuario se acomode a distintos aspectos del sistema. El circuito inicial creado para la realización
de las pruebas se basó completamente en las necesidades de dichos demos.
Gestión de Memoria
FreeRTOSTM presenta tres esquemas para el manejo de memoria. La asignación estática de
espacios de memoria se presenta como opción para sistemas en la cuales no se creará ni se
eliminarán dinámicamente tareas, colas o semáforos; de tal forma que esta distribución se
realiza sólo una vez en el sistema. El segundo esquema de planeación, asigna espacios de
memoria que luego podrán ser liberados, sin embargo puede llegar a se ineficiente en su
funcionamiento, si los tamaños asignados en la creación de diversas variables son distintos,
presentando indeseablemente segmentación de memoria. Y por último, el tercer esquema
maneja dinámicamente la asignación de la memoria RAM, pero se sugiere que sea utilizado
aplicaciones con computadores de escritorio, ya que requiere de mucho más procesamiento.
BESA-ME utilizará entonces el primer modelo de manejo de memoria, ya que no requiere la
liberación dinámica de espacios, puesto que las tareas creadas inicialmente, no serán destruidas
nunca. Además es el esquema de más fácil aplicación, y el que mejor se desempeña en
dispositivos microcontroladores.
Pruebas Realizadas
Luego de confirmar el correcto funcionamiento del RTOS, se procedió a realizar la primera
aproximación de las tareas necesarias para la implementación de los requerimientos de BESA.
Para esto se realizaron las siguientes pruebas:
1. Una tarea envía a otra un dato, éste dato es puesto en una cola compartida de tamaño
1. La tarea que envía el dato (productora)
se duerme durante un tiempo prudencial
para poder apreciar fácilmente el suceso (aproximadamente 500ms). Cuando la tarea
consumidora recibe el dato, lo muestra en el respectivo LED del puerto B, configurado
como salida. Cuando el productor se despierta, incrementa el valor anterior, y manda un
nuevo dato, para que el consumidor lo muestre.
2.
Ahora, aparece una tercera tarea que envía con una frecuencia menor, a la misma cola
un dato negativo, de tal forma que cada vez que llega un dato el consumidor
decrementa en uno el orden de muestra de los LEDs.
En esta segunda prueba, las
tareas funcionan perfectamente, no se pierden datos ni se alteran los mismos.
26
3. En la tercera prueba, una cuarta tarea aparece como productora, introduciendo un valor
constante de 2 que se suma al valor acumulado, dando la apariencia de un salto en la
secuencia de los LED. En esta última prueba todos los productores presentan la misma
prioridad, y el consumidor tiene una prioridad de cero. Con estas características, el
sistema no funciona correctamente, se pierden datos.
Sin embargo aumentando el
tamaño de la cola N (N = Número de productores), el sistema regresa a la normalidad.
Cuando el consumidor tiene mayor prioridad, ningún dato se pierde, aun cuando la cola
sea de tamaño unitario.
Una vez identificadas a plenitud las características de los métodos de envió y recepción de
mensajes por medio de colas, la creación y bloqueo de tareas con las primitivas del RTOS, se
procedió a la construcción del modelo abstracto de BESA.
3.3. Construcción del Modelo BESA-ME
Diseñado para ser implementado en un microcontrolador, en el modelo BESA-ME se modificaron
algunos servicios originales del modelo abstracto planteado por BESA, con el objetivo de ahorrar
memoria y mejorar velocidad de respuesta, pero conservando siempre la esencia de la
arquitectura.
3.3.1. Descripción General
Dentro de las características que fueron modificadas se encuentran las condiciones booleanas,
que se presentan en el mecanismo selector de guardas. Las condiciones booleanas ya no se
verificarán para la activación de los comportamientos asociados. Para éste proyecto, no son de
vital importancia. Su ausencia permitirá la reducción de gran parte el tiempo de filtrado de los
eventos en los puertos, y la minimización del uso de memoria para la ubicación de los eventos
que llegan a los puertos.
Igualmente el servicio de directorio de agentes, fue simplificado eliminando la sección de
páginas amarillas. En consecuencia, el usuario puede hacer envíos a un agente sólo si conoce el
nombre del agente, el cual es llamado alias en el contexto BESA-ME.
Los eventos recibidos por un agente, son almacenados directamente en una cola FIFO (tipo
buzón) de eventos entrantes, propia del canal de cada agente. Se decidió recibir estos eventos
por recopia y no por apuntador para garantizar la seguridad de la información pero en
detrimento de la velocidad de respuesta a los eventos.
Estos eventos son ubicados en los
puertos correspondientes según el tipo de evento al que pertenezca. Existen tantos puertos
como tipos de eventos declarados inicialmente. Cuando un evento llega a un puerto, se crea un
27
mensaje especial para ser enviado a los correspondientes comportamientos. Éste mensaje
contiene el apuntador a la función que se debe ejecutar, y el dato proveniente del evento BESA
inicial. Cuando el mensaje llega a la cola de recepción del comportamiento, éste se desbloquea,
e invoca a la función correspondiente mandándole como parámetro el dato asociado a evento
BESA. Esta función asociada, es la que el usuario final podrá programar directamente. En las
funciones asociadas también se pueden presentar envíos de datos a otros agentes, ya sean del
mismo contenedor o de otro.
En el modelo abstracto de BESA, a nivel social, existen agentes mediadores que pueden servir
como despachadores de eventos entrantes al contenedor, para distribuirlo a los agentes
destinatarios. Un agente mediador puede servir también para manejar mecanismos de
cooperación y asignación de tareas.
Sin embargo, el modelo de implementación BESA – ME no contiene en su sistema agentes
mediadores ya que la distribución de eventos, se realiza directamente a través del servicio de
envíos dentro del contenedor cuando son originados por otro agente, o desde una tarea
adaptador, encargada de recibir los eventos desde otro contenedor o desde las rutinas de
interrupción del microcontrolador, con el objetivo de repartirlos adecuadamente. Por tal razón en
lugar del nivel social, en BESA-ME hablaremos de nivel sistema.
Otra característica importante es que, tras analizar el concepto de contenedor de BESA, como el
espacio donde habitan y cumplen sus ciclos de vida los agentes, hemos decidido abstraer cada
microcontrolador como un contenedor.
El contenedor debe ser visto como el medio de
interacción local de los agentes.
Las estructuras y funciones de cada uno de los componentes del sistema BESA-ME se describirán
a continuación separadas en dos niveles: El nivel agente en el cual no existe el contenedor y el
nivel sistema donde inician las interacciones entre agentes.
3.3.2. Nivel Agente
La implementación del modelo de agente BESA-ME, requiere de mínimo dos tareas para cumplir
con el modelo BESA, estas son: la tarea encargada de cumplir las funcionalidades del canal y la
que ejecuta cada comportamiento. En el caso más sencillo de agente se debe tener mínimo un
comportamiento.
Además, ligados a la creación del agente, deben existir mecanismos de
identificación para ser usados por las tareas canal y comportamiento.
Estas tareas son re-entrantes, en consecuencia, el mismo código es usado cada vez que se crea
un agente o un comportamiento adicional, lo cual reduce la cantidad de memoria de programa
28
usada al escalar el sistema. En la Figura 3 se muestra la estructura implementada del agente,
que se explica a continuación.
AGENT
Port_1
Guard_1
CHANNEL
Guard_2
Behavior_1
Guard_X
Buzón
Port_2
Guard_1
Behavior_2
Guard_2
Action_1
Action_2
Guard_Y
Events
Behavior_N
Action_N
Port_M
Guard_1
Guard_2
Estado
Guard_Z
Beh_1
Beh_2
Beh_N
Figura 3.
Modelo de Agente en BESA-ME
Estructuras Asociadas a la Identificación del Agente
El agente esta constituido por sus dos tareas básicas (Canal y Comportamiento) y por dos
estructuras que permiten que el agente acceda a la información del sistema y que el sistema
obtenga información de él, estas estructuras son:
Figura 4.
Estructuras asociadas al Agente
Estructura Agente (stAgentBESA): Contiene datos como el estado del agente, el apuntador a la
estructura del canal asociado a dicho agente, una lista de los comportamientos que se
29
encuentran asociados a dicho agente, y por último una estructura stAgentHandler que contiene a
su vez el Alias y el AgentID, el cual para el caso de BESA-ME no es usado, ya que basta con el
Alias para identificar al agente, sin embargo éste se deja allí para futuras aplicaciones. También
está contenido aquí el apuntador a la cola de recepción del canal para la recepción de eventos.
Podemos ver entonces que con el conocimiento del Alias, se puede acceder a toda la información
relacionada con el agente. En la Figura 4 se observa el código con el que fue implementada.
Construcción del Canal
El canal es el encargado de recibir los eventos provenientes del entorno o de otros agentes, para
luego asociarlos al puerto correspondiente, de esta forma el dato es enviado a los
comportamientos indicados por la guarda asociada al puerto. Para esto, el canal debe contar,
como mínimo, con un buzón de entrada (cola de recepción), un puerto por cada tipo de evento y
una guarda que asocie el evento a un comportamiento.
Estructura Canal (stChannelBESA): Contiene un apuntador a la cola de recepción del canal
(xQueueRxChannel), un arreglo de apuntadores a los diferentes puertos que lo comprenden
(apChannelPorts) y una variable para indicar el número de puertos (número de eventos) que
tiene el canal (NumPortChannel).
En la Figura 5 se observa el código con el que fue
implementada.
Figura 5.
Estructura asociada al canal.
El tamaño del arreglo de apuntadores está definido por el máximo número de puertos que el
usuario haya establecido para el canal. Nótese que no se maneja un sistema de colas de
almacenamiento de eventos retenidos, debido a que no se implementaron las condiciones
booleanas de las guardas.
Estructura Puerto: (stPortBESA) Cada puerto contiene una constante que indica el tipo de evento
al que corresponde (xEventType), una variable que indica el número de asociaciones definidas
para el tipo de evento (NumBindGuards) y un arreglo de apuntadores a guardas que contienen
la información necesaria de cada asociación del puerto (apBindGuard).
Estructura Guarda: (stGuardBESA) Tiene un apuntador a la función de tratamiento asociada al
tipo de evento que debe ejecutarse en el comportamiento (*ActionFunction) y un apuntador a la
30
cola de recepción del comportamiento asociado (xQueueRxBehavior). En la Figura 6 se observa
el código con el que fue implementada la guarda BESA y el puerto BESA.
Figura 6.
Estructura asociada a los Puerto y a las Guardas.
Estructura Mensaje para el Comportamiento: (stMsgBehavior) Tiene un apuntador a los datos
que se envían en el evento (pEventData) y un apuntador a la función de tratamiento asociada al
tipo de evento (*ActionFunction) que debe ejecutarse en el comportamiento. De esta forma el
usuario sólo tendrá que realizar la programación correspondiente a las funciones asociadas, con
los datos entrantes al agente. En la Figura 7 se observa el código con el que fue implementado
el tipo Mensaje a comportamiento.
Figura 7.
Estructura del Mensaje recibido por el Comportamiento.
Para la ejecución del canal se creó una tarea a partir de los servicios del RTOS, la tarea asociada
al canal se denomina vChannel.
Esta es la encarga de revisar constantemente el buzón de
entrada de mensajes para saber si ha recibido un evento; si no hay un evento pendiente en la
cola, esta tarea se bloquea hasta que alguno llegue. Cuando se recibe un evento, la tarea debe
verificar el tipo de evento y compararlo con los puertos existentes; si no existe un puerto para
este tipo de evento el canal no ejecuta ninguna operación y el evento es ignorado; informándole
además al transmisor inicial
que el evento no pertenece al sistema. Al identificar el puerto
correspondiente, se evalúa el número de asociaciones existentes, para la correcta ubicación del
evento y se accede a las guardas para crear el mensaje y enviarlo al comportamiento indicado
por la guarda.
La tarea vChannel recibe como parámetro el apuntador a la estructura del canal pChannel, para
así poder tener acceso a las demás estructuras. Dentro de esta tarea se crea el mensaje que se
31
envía al comportamiento, como se muestra a continuación en pseudo código de la tarea
vChannel:
void vChannel (void *pvParameters)
{
Creación de los apuntadores a las estructuras stPort, stGuard, stChannel, stEvent y stMsgBehavior;
Asignación de los apuntadores a las estructuras creadas.
for( infinito )
{
if ( hay algún evento nuevo en la cola de recepción del canal? )
{
for ( Se recorre cada uno de los puertos del arreglo de puertos )
{
If ( el tipo de evento recibido es igual al tipo de evento del puerto actual?)
{
For ( Recorrer el arreglo de guardas para el puerto actual )
{
Armar el mensaje para el comportamiento indicado en la guarda;
Enviar el apuntador del mensaje a la cola de recepción del comportamiento indicado por
la guarda actual;
if ( envió no exitoso )
{
intentar de nuevo el envío;
}
}
}else
{
Aumentar la posición del apuntador para cambiar de posición en el arreglo de puertos;
}
}
}
}
Construcción del Comportamiento
El comportamiento es el encargado de recibir los mensajes que contienen el dato y el apuntador
a la función de tratamiento que haya sido determinada por el usuario para el tipo de evento.
Debe tener entonces una cola de recepción para almacenar los mensajes. Además es necesario
acceder al estado del agente para obtener información del estado y poder modificarlo.
La estructura asociada al Comportamiento es:
Estructura Comportamiento: Tiene un apuntador a la cola de recepción del comportamiento
(xQueueRxBehavior) y un apuntador al “Handler” del Agente (pAgentHandler) que permite
acceder a su estructura y por ende al estado del agente. La estructura de los comportamientos
se muestra en la figura 8.
32
Figura 8.
Estructura asociada al Comportamiento.
Para la ejecución del comportamiento se creó una tarea a partir de los servicios del RTOS, la
tarea asociada al comportamiento se llama vBehavior.
Es la encargada de revisar
constantemente su cola de recepción para verificar la llegada de mensajes.
Cuando llega un
mensaje, el comportamiento debe propiciar la ejecución de la función de tratamiento, la cual
debe recibir como entrada el apuntador al evento BESA que fue enviado en el mensaje y un
apuntador al Agente al cual pertenece el comportamiento, a través del cual puede acceder al
estado, si así lo requiere el usuario. A continuación se presenta el pseudo código de vBehavior:
void vBehavior ( void *pvParameters )
{
Creación de las las variables tipo stBehaviorBESA y stMsgBehavior;
Creación y asignación de los apuntadores a las estructuras creadas;
for ( infinito )
{
if ( llegó algún evento a la cola de recepción del comportamiento )
{
Se invoca la función de acción según lo indica el apuntador en el mensaje que
acaba de llegar y se le mandan los datos recibidos;
}
}
}
El Estado
El estado es un espacio de memoria compartida que sólo debe ser accedido desde las acciones
ligadas a los comportamientos.
A través del estado los comportamientos pueden actualizar
información relativa al agente y a los procesos que éste ejecuta.
Su implementación se realizó a través de una cola con capacidad para almacenar una apuntador
de tipo void. Se crearon las funciones TakeStateData y GiveStateData para permitir al usuario
modificar el estado en una forma segura. Su uso se explica en el manual del usuario que se
encuentra en el anexo A.
33
Simulación del Envío de un Evento al Canal y Ejecución de sus
Comportamientos
Para verificar el correcto funcionamiento de la estructura de un agente, antes de expandir el
modelo a más agentes y distintos contenedores, se realizó una prueba creando una tarea
adicional para enviar eventos al canal.
La tarea adicional llamada vPrueba envía al buzón del canal un determinado evento,
bloqueándose luego de esto por un tiempo determinado; luego se despierta para repetir el
envío. El canal recibe el evento, busca el puerto correspondiente y allí verifica la guarda para
crear el mensaje y enviarlo al comportamiento adecuado. Una vez el mensaje llega al buzón del
comportamiento, éste lo recibe y llama la función de tratamiento asociada para ejecutarla.
El correcto funcionamiento de está primera aproximación del agente se observó a través de la
ejecución de la función asociada, la cual conmutaba unos LED de acuerdo al dato recibido.
Luego de observar el correcto desempeño del agente, se procede a aumentar el número de
comportamientos asociados a un mismo tipo de evento. Prueba que arrojó resultados positivos
observando la conmutación correspondiente de los LED; la última fase de estas primeras
aproximaciones acerca de la configuración de un agente se basaron en la creación de distintos
tipos de eventos enviados a un mismo agente, el cual activa a su vez, luego del tratamiento
propio de cada entidad, los comportamientos asociados con sus respectivas funciones.
3.3.3. Nivel Sistema
Una vez la estructura de cada agente esta completa, es necesario establecer el nivel superior del
sistema BESA, es decir, el conjunto de varios agentes funcionando en el contexto de un
contenedor.
34
BUS SERIAL I2C
Contenedor A
Contenedor B
Contenedor C
Administrador
Local
Administrador
Local
Administrador
Local
Páginas
Blancas
Páginas
Blancas
Páginas
Blancas
Agentes
Sensor
Figura 9.
Agentes
Actuador
Sensor
Agentes
Actuador
Sensor
Actuador
Nivel Sistema en BESA-ME con el servicio de comunicación entre contenedores. El administrador
local se encarga del manejo de los eventos.
Un sistema de agentes implementado en BESA–ME se considera como un sistema distribuido
compuesto por uno o varios contenedores BESA, los cuales funcionan en diversas máquinas
físicas o virtuales, en este caso, cada contenedor esta ubicado en un microcontrolador
(contenedor físico).
La integración de mas de un contenedor y la posibilidad de comunicación entre los agentes
pertenecientes a éstos a través del protocolo serial I2C, completa el modelo BESA-Micro Edition
a nivel de sistema distribuido. En la figura 9 se observa una representación gráfica del modelo
implementado.
Creación del Contenedor
BESA-ME tiene estipulado, en su modelo de implementación, que cada contenedor esta
contenido en un microcontrolador, el cual para efectos de la comunicación necesitará un número
de identificación fijo, el cual está estipulado por una constante denominada CONTAINER_ID a la
cual se le deben asignar valores desde 01H hasta 80H, para un máximo de 127 contenedores.
El CONTAINER_ID es asignado por el usuario.
35
Figura 10.
Estructura asociada Contenedor.
Cada contenedor contiene una estructura necesaria para almacenar la información de los
agentes internos y los de otros contenedores, tal como se muestra en la Figura 10 (directorio de
páginas blancas de los agentes de todo el sistema). Además contendrá dos buffers para
almacenar temporalmente los datos entrantes y salientes de la comunicación entre distintos
contenedores. Esta utilización de espacios de memoria compartida (buffers, ver Figura 11) hace
necesario el uso de sistemas de sincronización que permitan el manejo seguro de estos espacios
de memoria. Se utilizan entonces dos semáforos propios de los servicios de freeRTOSTM, los
cuales serán explicados en la sección de comunicación entre contenedores.
Figura 11.
Estructura de los buffer de Transmisión y de Recepción para la comunicación entre contenedores.
El contenedor también contiene dos colas de recepción para manejar la información proveniente
de otros contenedores. Estas colas permiten un manejo seguro del protocolo de comunicación
entre contenedores. Hay otra cola más para la recepción de eventos BESA desde una rutina de
interrupción.
Los Eventos BESA en BESA-ME han sido implementados de tal forma que el usuario pueda crear
su propio tipo de eventos, de acuerdo a sus necesidades, siempre y cuando respete la sintaxis
explicada en el Manual del Programador (ver Anexo A).
36
Figura 12.
BESA_DATA, Estructura en la que almacenan los datos de usuario.
Como se observa en la figura 12, BESA_DATA cuenta con un campo data_size, en el cual se
debe almacenar el número de bytes del evento, este debe ser inicializado por el programador.
Figura 13.
BESA_EVENT, Estructura en la que se almacena el tipo de evento y el BESA_DATA.
A partir de BESA_DATA (Figura 12) se crea la estructura BESA_EVENT, en la cual, además,
existe el campo xEventType, en donde el programador debe poner el tipo de evento de la
estructura stEventBESA creada. (Figura 13).
En el microcontrolador se ha declarado sólo una estructura de tipo stContainerBESA, a la cual se
tiene acceso desde el apuntador pContainer, el cual es un apuntador de tipo global, en
consecuencia no ha sido necesario usarlo como parámetro de alguna función en BESA-ME.
El Administrador Local en BESA-ME
El administrador local en BESA-ME está formado por un conjunto de tareas y funciones que se
encargan de la administración de la comunicación entre agentes y la administración de los
eventos BESA generados desde rutinas de interrupción.
En este conjunto se encuentran
vAdaptor y SendAck las cuales han sido implementadas como tareas.
También están las
funciones SendEvent, SendEventFromISR, SendEventI2C e i2cISR (ver Anexo A- sección API).
Envío de Eventos BESA desde Interrupciones
Pensando en las diferentes aplicaciones que se pueden implementar, como las enfocadas al
control, se ha desarrollado un servicio especial para enviar eventos a los agentes desde una
rutina de interrupción. El servicio es accedido desde la función SendEventFromISR.
Cuando el envío del evento es generado desde una rutina de interrupción, se usa otro tipo de
evento cuya estructura es ISR_BESA_EVENT (Figura 14).
Este tipo de evento es usado
automáticamente por el administrador local cuando el programador hace uso de la función
SendEventFromISR. Los parámetros xEvent y alias son puestos en una misma estructura para
poder ser enviados a la cola de recepción de eventos provenientes de una rutina de interrupción.
37
Esta estructura es recibida en un cola tipo buzón por la tarea vAdaptor, que hace parte del
administrador local.
Figura 14.
ISR_BESA_EVENT, Estructura en la que se almacena un BESA_EVENT cuando quiere ser enviado
desde una rutina de interrupción.
Una vez ha recibido este evento, La tarea vAdaptor se encarga de traducir el envío de un evento
desde una rutina de interrupción a un envío desde una tarea tal como si fuera un envío desde un
comportamiento usando la función SendEvent (ver Figura 15). Esta estrategia brinda robustez a
la generación de eventos y brinda al programador una utilidad que le facilita el desarrollo de
aplicaciones sobre BESA-ME.
Figura 15.
Diagrama de bloques del tratamiento de eventos desde una rutina de interrupción.
El pseudo código del código implementado se presenta a continuación.
void vAdaptor(void * pvParameters)
{
Creación de la estructura del tipo stEventFromISR;
Creacion del contador i;
for(;;)
{
while(no llegue un evento a la cola xQueueRxFromISR, se espera máximo un tiempo
portMAX_DELAY){}
inicialización del contador i en cero;
while( el contador i sea menor a NUM_OF_ITERATIONS_IN_SEND_EVENT_FROM_ISR)
{
se envía el evento al alias, según el tipo de evento definido por el usuario
if( envío exitoso)
{
el contador i se iguala a NUM_OF_ITERATIONS_IN_SEND_EVENT_FROM_ISR para se que finalicen
las iteraciones;
}
se incrementa el contador i en una unidad;
}
}
}
38
Comunicación entre Agentes
Existen dos clases de comunicación entre agentes; la primera de estas es la transmisión que se
realiza entre entidades que se encuentran en el mismo contenedor. La segunda clase es la que
se presenta cuando los agentes que intervienen en la comunicación se encuentran en distintos
contenedores. Sin embargo, para el usuario, la función que debe escribir cuando desea enviar
un evento a un agente local o externo es la misma.
Comunicación entre Agentes del Mismo Contenedor
Cuando un comportamiento es activado por la recepción de un mensaje en la cola de un
comportamiento, éste puede desatar una serie de invocaciones a sus funciones asociadas.
Algunas de esas funciones podrán generar envíos a otros agentes. Si el agente al que se le
desea enviar pertenece al mismo contenedor (búsqueda en las páginas blancas), se realizará
simplemente un envío a la cola de recepción del canal de dicho agente. Cuando este
comportamiento no puede realizar un envió exitoso, esta función retorna un valor determinado
según la causa del fracaso. El remitente determinará entonces la acción más adecuada para esta
situación. Los posibles valores retornados por la función SendEvent en el caso de un envío local
son:
1
Send_ok
-7
Queue Full: Significa que no se ha podido depositar el evento en la cola de
recepción del canal del agente. Puede ser a causa de que se ha configurado mal
el tamaño de dicha cola para la velocidad y cantidad de eventos generados.
-8
Agent No Exist: El agente ha sido identificado como un agente local pero no se
ha encontrado su cola de recepción de eventos.
Puede deberse a una mala
configuración del tamaño del stack del canal o de los comportamientos (ver
Manual del programador en el anexo A).
-9 Container No Exist: El agente no pertenece a ningún contenedor.
Comunicación
entre Agentes de Distintos Contenedores
Inicialmente se identificaron los requerimientos básicos que se deben cumplir, según lo
determina la arquitectura BESA, en la comunicación entre agentes pertenecientes a distintos
contenedores. Dichas requerimientos se presentan a continuación:
o
Cualquiera de los contenedores podrá enviar mensajes en cualquier momento.
o
El número de contenedores del sistema debe poder crecer fácilmente. (criterio
de escalabilidad).
o
Todos los contenedores deben tener la misma prioridad para el envío y
recepción de mensajes.
39
Esta clase de comunicación se implementó de tal forma que para el usuario es transparente el
envío de un evento BESA a un agente local o a un agente externo.
La plataforma BESA-ME, al
determinar que el agente se encuentra en un contenedor externo, se encarga de hacer llegar los
datos al agente correspondiente e informarle al usuario si la comunicación fue exitosa o el tipo
de error que ha ocurrido en la comunicación.
Los posibles valores retornados por la función
SendEvent en el caso de un envío externo son examinados en la sección 3.4, donde se
encuentra una descripción detallada de los procedimientos
implicados en este tipo de
comunicación.
Además, fue necesario modificar el archivo tasks.c propio de freeRTOSTM, que contiene una tarea
que se ejecuta cuando el programa arranca (IdleTask), aquí se incluyó una configuración extra
para que la plataforma BESA-ME pudiera realizar la comunicación entre microcontroladores. Es
aquí donde se crea el modulo de configuración de la comunicación externa sólo cuando la
aplicación del usuario requiera de varios microcontroladores (ver anexos A y C).
3.4. Protocolo de Comunicación Externa
Teniendo presentes los 3 criterios planteados por el modelo BESA para la comunicación entre
contenedores, se estudiaron los protocolos de comunicación (Nivel Byte) disponibles en la familia
de microcontroladores seleccionada.
Luego se desarrolló un esquema de mensaje apropiado
para lograr una comunicación segura (Nivel Trama), que cuenta con una verificación de errores
y permite transparencia al remitente sobre si el envío que hace es local o externo, pero en el
caso de ser externo, le informa de los errores asociados a este tipo de comunicación.
3.4.1. Protocolo de Comunicación a Nivel Byte
En este nivel de la comunicación se controla el direccionamiento de los microcontroladores, el
flujo de datos byte por byte, y las señales necesarias para realizar el arbitramiento del bus de
comunicación, que será accedido por varios microcontroladores.
Selección del Protocolo de Comunicación a Nivel Byte
A nivel byte se presentan las siguientes necesidades, producto de los requerimientos del modelo
BESA:
o
Direccionamiento de los microcontroladores (Contenedores).
o
Arbitramento del bus de comunicación.
o
Comunicación bi-direccional.
o
Igual prioridad en el uso del bus de comunicación.
40
Los microcontroladores Microchip de la familia 18f ofrecen dos módulos de comunicación, estos
son la USART y el MSSP.
significativas
para
este
El módulo MSSP, frente a la USART presenta algunas ventajas
contexto;
el
primero
permite
mayor
control
por
Hardware,
proporcionando registros específicos y múltiples causas de interrupción diseñadas para este
propósito, que permiten realizar acciones como el direccionamiento de los dispositivos, el
arbitramento del bus, y el estado de la comunicación, haciendo más sencillo el software de
control a este nivel y en consecuencia permitiendo mayor velocidad en la comunicación.
El
módulo USART a diferencia del MSSP, no permite detectar por Hardware eventos ligados a la
transferencia de datos, como lo es determinar si el bus está ocupado o libre para transmitir, si el
byte recibido es un dato o una dirección, el inicio y el final de una trama de bytes, si la
transmisión está en proceso, etc.
Otra característica del módulo MSSP es que soporta la comunicación bi-direccional y sincrónica,
por lo cual solo necesita dos alambres de comunicación, uno para datos y otro para la señal de
reloj. Al ser sincrónica, no es crítica la configuración en la velocidad de transmisión desde los
diferentes dispositivos que se conecten al bus, presentando mayor robustez frente a la
comunicación asíncrona.
El módulo MSSP de los microcontroladores Microchip ofrece el modo SPI e I2C (Inter-Integrated
Circuit). SPI aunque de fácil implementación, no presenta homogeneidad en la asignación de
prioridades, ya que permite el manejo de un sólo maestro, dejando al resto de dispositivos como
esclavos. Además, para cumplir con el criterio de escalabilidad, se hace necesario el aumento
de pines de salida, mientras que I2C utiliza tan sólo dos señales para manejar hasta 128
dispositivos, los cuales pueden ser maestros o esclavos según la necesidad de envío
23
. De esta
forma también se cumple con el criterio de homogeneidad de prioridades de los contenedores,
cumpliendo así con los requerimientos de BESA, razones de peso para adoptar el protocolo I2C.
Introducción al Funcionamiento del Protocolo I2C
El protocolo utiliza dos señales para implementar la comunicación, estos son SDA (Datos) y SCL
(Reloj); cada una implica un alambre de comunicación diferente. I2C plantea dos estados para
poder llevar acabo toda comunicación, un dispositivo debe estar configurado como Master
(Transmisor) y el otro como Slave (Receptor).
En la transmisión, el protocolo requiere de una serie de secuencias para que la transferencia de
datos se pueda realizar correctamente. Antes de iniciar la transmisión, es necesario verificar el
estado del bus. Si el bus está libre, se inicia la comunicación con una señal START, colocando en
seguida en el bus la dirección del dispositivo al cual se le enviará el mensaje; el receptor
23
MICROCHIP, Inter-Integrated Circuit™ (I2C™). Microchip Technology Inc 2004.
41
correspondiente envía una señal de contestación indicando que está listo para recibir datos. El
transmisor coloca el dato (un byte) en el bus, seguido de la confirmación del receptor.
Esta
contestación es generada automáticamente por el modulo MSSP del microcontrolador, y puede
ser negativa por dos razones: si la dirección no existe en el sistema o si el bus I2C fue
desconectado durante la comunicación, razones por las cuales se debe finalizar la transferencia
de datos.
Si la contestación es afirmativa, se continúa con la comunicación hasta que el
transmisor genere una señal STOP.
Esta última le indica al receptor que ya no debe esperar
más datos, de tal forma que el bus es liberado para que otros microcontroladores puedan
comunicarse. Las señales START, STOP y Contestación negativa pueden observarse en la Figura
18.
I2C permite la transmisión y recepción de datos según lo requiera el dispositivo maestro. El tipo
de comunicación (lectura o escritura) que se llevará a cabo está dado por el último bit del byte
de dirección colocada en el bus inicialmente (1 = lectura; 0 = escritura). BESA-ME declara a
todos los contenedores del sistema inicialmente como esclavos. Cuando algún esclavo quiere
comunicarse con otro, el microcontrolador se establece como maestro para luego poner en el
bus la dirección del microcontrolador al cual desea enviar datos y espera la señal de
confirmación. Existirá entonces sólo un maestro en el sistema a la vez. El dispositivo que se
encuentre como maestro sólo puede escribir en los esclavos, lo que indica que en BESA-ME
nunca deberá ser declarada una dirección (CONTAINER_ID) en la cual el ultimó bit sea un 1,
debido a que se presentarían errores en la comunicación entre contenedores.
Las interrupciones generadas por las señales puestas en el bus, son escuchadas por todos los
dispositivos conectados a éste, pero únicamente el contenedor cuya dirección recibida coincide
con su CONTAINER_ID, es el que realiza el tratamiento adecuado para recibir los datos.
Al
producirse un evento que genere una interrupción (una señal de START, STOP, bit de
Confirmación
o
buffer
de
recepción
lleno),
la
bandera
de
interrupción
es
activada
(automáticamente por el modulo MSSP) de tal forma que en la rutina de interrupción propia de
BESA-ME se ejecuta el procedimiento adecuado, y se continúa con la espera de otro suceso
relevante.
En la comunicación por I2C, cada uno de los bytes enviados es puesto en el bus tras una rutina
de interrupción.
Luego de que un byte es puesto en el bus, se abandona la interrupción,
liberando el control del procesador durante el tiempo de envío de cada uno de estos datos, ya
que la velocidad de transmisión es aproximadamente 100 Khz, pequeña en comparación con la
velocidad de oscilación del reloj del microcontrolador; permitiendo de esta forma que otros
procesos puedan ser ejecutados durante esos periodos.
42
Implementación del Protocolo de Comunicación a Nivel Byte
Para maximizar el uso de la CPU del microcontrolador durante la transmisión de datos a otro
microcontrolador se implementó el uso y control del protocolo I2C usando las herramientas de
interrupción que ofrece el módulo MSSP.
Para iniciar el envío de un byte a otro contenedor, es necesario realizar antes el arbitramento del
bus para verificar que esté libre y no haya error en la comunicación. Una vez haya sido tomado
el bus, se debe configurar el modulo como Master e inicializar ciertas variables utilizadas en la
transmisión. Todo lo esto se realiza la función SendEventI2C(), cuyo pseudo código se muestra
a continuación.
char SendEventI2C(unsigned char NumDataToSend)
{
Deshabilita Interrupciones Globales y del modulo I2C;
if( El bus está libre)
{
Cantidad de datos por enviar = NumDataToSend + 4;
Apuntador al buffer de Tx del Container = Primera posición del buffer de Tx del Container;
Se configura el modulo I2C como Transmisor (Master);
Se inicia la condición de start en el bus;
Habilita Interrupciones Globales y del modulo I2C;
Se retorna un cero;
}
else
{
Habilita Interrupciones Globales y del modulo I2C;
Retorna que no se pudo tomar el bus (BUS_COLLITION);
}
}
Cuando se transmite un byte, los posibles errores que pueden ser retornados al remitente del
evento BESA, son los siguientes:
o
BUS_COLLITION: El bus no está libre para iniciar la transmisión. Una vez el bus ha
sido ocupado, no puede ser tomado por otro micro-controlador hasta que se genere
una señal de STOP por el dispositivo que estaba realizando la transmisión.
o
NO_ACK_HARDWARE: Al finalizar la transmisión de un byte, este no ha sido recibido
por el microcontrolador destinatario.
Las posibles causas de este error son: El
microcontrolador receptor no tiene capacidad física de recibir (desconectado del bus
o apagado) o ningún microcontrolador responde a la dirección transmitida, que en el
contexto de BESA-ME es el CONTAINER_ID. Cuando esto sucede, el Administrador
local del microcontrolador remitente genera una señal de STOP en la transmisión,
43
con lo cual libera el bus para que pueda ser usado por otro microcontrolador. En el
microcontrolador destinatario se reiniciará la recepción y se pondrán los datos en las
posiciones de memoria adecuadas cuando se reciba una señal de START.
Una vez el bus de comunicación haya sido tomado, desde el microcontrolador remitente se
genera una señal START que es detectada por el módulo MSSP de los microcontroladores
conectados al bus. Inmediatamente después de la señal START, el remitente envía la dirección
del microcontrolador destinatario (7 bits). Si están configurados adecuadamente, los módulos
MSSP que detectaron la señal START compararán la dirección recibida con la dirección interna
(CONTAINER_ID) que esta cargada en un registro para tal propósito. La comparación se hace
automáticamente por hardware y no necesita control adicional por software. Cuando en alguno
de los microcontroladores la comparación ha coincidido entonces su módulo MSSP genera una
señal eléctrica que aquí llamamos Acknowledge Hardware. Una vez esta señal de Acknowledge
Hardware es detectada por el transmisor, se inicia el envío de los bytes de información que
conforman la trama de datos.
El pseudo código que se muestra a continuación corresponde a la rutina de interrupción
implementada para integrar la comunicación a nivel byte y la comunicación a nivel trama.
void i2cISR(void)
{
Se limpia la bandera de interrupción del módulo I2C;
If ( El modulo esta en modo TRANSMISOR (Master) )
{
********
ESTA EN MODO TRANSMISOR ***********
if ( La interrupción fue a causa de un STOP )
{
Pasa a modo Receptor (Slave);
Libera el semáforo de protección del buffer (SemBuffer);
}
else
{
if (Hubo Acknowledge de Hardware para el último byte transmitido)
{
if (Cantidad de datos por enviar>0 )
{
Buffer Módulo I2C = Lo apuntado por el apuntador al buffer
de
Transmisión
del Container;
Se disminuye en uno la Cantidad de datos por enviar;
Se incrementa el Apuntador al Buffer de Transmisión del Container en
uno;
}
else
{
Cantidad de datos por enviar = 0;
Se genera una señal de STOP en la transmisión;
Se espera a que se termine de transmitir el STOP;
44
Limpia la bandera de interrupción del módulo I2C;
Pasa al modo Receptor (Slave);
Se libera el semáforo de protección del buffer (SemBuffer);
}
}
else
{
Cantidad de datos por enviar = 0;
Limpia la bandera de No Ack_Hardware para el último byte transmitido;
Se genera un STOP en la transmisión;
Se espera a que se termine de transmitir el STOP;
Limpia bandera de interrupción del módulo I2C;
If( Se estaba transmitiendo una trama EventBESA y no una AckBESA )
{
Informa a la tarea que transmitió que no hubo Acknowledge;
}
Pasa a modo Receptor (Slave);
Libera el semáforo de protección del buffer (SemBuffer);
}
}
}
else
// ****
ESTA EN MODO RECEPTOR ***********
{
Activa el modo Clock Stretching;
(asegura no recibir más datos hasta que no se lea el buffer del modulo
I2C donde se guarda el dato recibido)
if (La interrupción fue a causa de un STOP )
{
Limpia la bandera de over flow;
Envía a la tarea vSend_ack una copia del buffer de Recepción del container;
}
else
{
if( La interrupción fue a causa de que el buffer de Rx del modulo I2C está lleno)
{
if( El último dato recibido fue una dirección )
{
Apuntador al buffer de Rx del Container = Primera posición del buffer de Rx del
Container;
Posición apuntada por Apuntador al buffer de Rx del Container = buffer de Rx
del módulo I2C;
Se incrementa en uno el Apuntador al Buffer de Recepción;
}
else
{
Posición apuntada por Apuntador al buffer de Rx del Container = buffer de Rx
del módulo I2C;
Se incrementa en uno el Apuntador al Buffer de Recepción;
}
}
else
{
Limpia la bandera de over flow;
45
}
}
Libera el bus para recibir más bytes (Deshabilita Clock Stretching);
}
Habilita las interrupciones del módulo I2C;
}
Cada una de las acciones propias de I2C se implementó usando funciones, de tal forma que la
adopción de otro tipo de protocolo implicará sólo cambios internos en dichas funciones, sin
entrar a reparar el esquema de tratamiento a nivel trama.
3.4.2. Protocolo de Comunicación a Nivel Trama
Se diseñaron dos tramas de comunicación, una para el envío de eventos BESA y otra para el
envío de mensajes de confirmación BESA (Acknowledge BESA).
Al transmitir las dos tramas,
sólo se envía los bytes que contienen información útil para el sistema. El tamaño máximo de
trama de eventos BESA corresponde al tamaño de la estructura stBufferBESA (ver Figura 11).
Sin embargo, este tamaño varía según la configuración de BESA-ME, en función del número de
bytes de los eventos BESA creados por el usuario (ver Manual del Usuario, Anexo A).
En la
Figura 16 se observan una representación gráfica de los dos tipos de tramas BESA utilizadas en
la comunicación entre contenedores.
Figura 16.
Formato de tramas utilizadas para la comunicación entre Contenedores.
Trama Evento BESA
En la Tabla 2 se encuentra la descripción de cada byte de la trama EventBESA.
Las celdas
sombreadas corresponden a los bytes que conforman el Evento BESA, tal como se usa en los
envíos locales (ver Figura 13). El campo Cantidad de Datos (Data Size) de la trama, contiene el
número
de
bytes
N
que
comprenden
el
Evento
BESA,
es
correspondientes al campo Event Type, Data Size y Data BESA.
decir,
incluye
los
bytes
Para los diferentes tipos de
eventos, el tamaño de los datos puede diferir del máximo MAZ_DATA_SIZE definido para el
sistema (ver figura 12), por lo que únicamente se envían los bytes que son utilizados por el tipo
46
de evento en particular, haciendo variable la longitud de la trama EventBESA y más eficiente el
uso del bus de comunicaciones.
Posición del byte
Nombre del byte
Descripción
1
Container ID Rx
Es el byte que será comparado con el registro
SSPADD del receptor que se encuentra en modo
esclavo. Byte de Dirección para el protocolo I2C.
2
Alias
Usado por el administrador local para hacer llegar el
evento BESA al agente.
3
Container ID Tx
Se almacena para enviar el Ack BESA al contenedor
adecuado, una vez el evento BESA haya sido enviado
al agente destinatario.
4
Event Type
5
Data Size
Número de bytes ( N ) que componen el Evento BESA.
6
Data BESA…
Los Bytes en los que se encuentra la información del
usuario.
…
N+4
Tipo de Evento transmitido
….
Check sum
Byte calculado realizando la operación XOR entre
todos los bytes de la trama anteriores al Check sum.
Usado para control de errores en la transmisión.
Tabla 2. Descripción de los bytes de la trama Event BESA para un Data Size de tamaño N.
Trama Acknowledge BESA
El tamaño de la trama AckBESA es constante para todos los casos. En la Tabla 3 se encuentra la
descripción de cada byte de la trama AckBESA. Como se observa en esta tabla, el byte Ack (que
luego será retornado por la función SendEvent al remitente), puede tener los mismos valores
que retorna la función SendEvent en el caso de un envío local, y adicionalmente, el valor
correspondiente a un error de check sum. Esto se debe a que se recibe una trama de AckBESA
sólo cuando el contenedor destinatario recibió la Trama EventBESA y su administrador local
intentó realizar el envío en su contenedor. Cuando la trama EventBESA no puede ser enviada al
destinatario, la función SendEvent retornará al remitente un Ack local, con otros valores
correspondientes a otros tipos de error, los cuales se explican en la Secuencia de Comunicación.
47
Posición del byte
Nombre del byte
1
Container ID Rx
Es el byte que será comparado con el registro
SSPADD del receptor que se encuentra en modo
esclavo. Byte de Addres para el protocolo IIC.
0x00H
Este campo corresponde al alias del Buffer de
recepción del contenedor.
El valor 0x00H esta
reservado para identificar cuando la trama
corresponde a un Ack BESA.
2
Descripción
3
Ack
Resultado de la transmisión.
siguientes valores:
1 Send_ok
-5 Chk sum bad
-7 Queue Full
-8 Agent No Exist
-9 Container No Exist
4
Check sum
Check sum para verificación
transferencia de los datos.
Puede
de
tener
la
los
correcta
Tabla 3. Descripción de los bytes de la trama Ack BESA. Constante para cualquier tamaño de datos.
Secuencia de Comunicación del Protocolo a Nivel Trama
Transmisión de las Tramas
El primer byte que se transmite corresponde al ID del container con el cual se desea establecer
comunicación. Cuando una confirmación ack hardware indica que la dirección existe y que dicho
contenedor está listo para recibir, se continúa entonces con el envío de los datos como lo
muestra la trama del mensaje de datos (Ver figura 16).
El contenedor transmisor envía
entonces el Alias del agente al que está dirigido el mensaje, seguido de la identificación del
contenedor transmisor, al cual se le deberá responder cuando el mensaje haya llegado al
agente destinatario. Cabe anotar que cuando el bit Ack no es recibido en cualquier momento de
la comunicación, la trama no se termina de enviar, y se genera la instrucción STOP, propia de
I2C.
A continuación se tiene el tipo de evento (xEventType) de los datos que se envían,
seguidos del número de datos N que se deben esperar. En esta cantidad se incluye el byte de
tipo de evento y el byte usado por la cantidad de datos, pero no está incluido el de seguridad de
información (check sum). Este último se calcula con la función lógica XOR de los primero N+3
bytes de la trama. Si suponemos que se desea enviar un sólo byte como dato, tendríamos
entonces en cantidad de datos N=3, correspondientes a tipo de evento, cantidad de datos y un
byte del dato; completando un tamaño total de trama de 6 bytes (N+3) de información del
sistema más 1 byte de check sum.
Recordemos que cada uno de los bytes está seguido
automáticamente del bit de ack hardware generado por el contendor esclavo.
48
Envío en Condiciones Normales de una Trama EventBESA
Figura 17.
Tipos de respuesta acknowledge en BESA-ME. Ejemplo del envío de un agente X a un agente Z
ubicados en distintos contenedores.
En la figura 17 se representa de manera general la secuencia normal de comunicación entre
agentes de distintos contenedores.
El envío exitoso de un evento BESA a un agente que se
encuentra en un contenedor externo comprende los siguientes pasos:
1.
Ejecución de la función SendEvent
2.
Se revisa el directorio de páginas blancas.
3.
Se determina si el agente habita en el contenedor.
4.
Si no, se revisa que exista en algún contenedor.
A partir de aquí inicia el envío externo…
5.
Se obtiene el Container ID del contenedor receptor en el cual existe el agente, y se toma
el semáforo de protección de envío de eventos (SemSend).
6.
Si se pudo tomar el semáforo SemSend, entonces se toma el semáforo de protección del
Buffer de transmisión (SemBuffer).
7.
Una vez tomado SemBuffer, se llena el Buffer de transmisión con la información
correspondiente a la Trama Event BESA que se desea transmitir.
8.
Se realiza el arbitramento del bus I2C para determinar si se puede tomar el bus.
9. Una vez se toma el bus, se pone el módulo de comunicación en modo Master y se
genera la secuencia de Start que da inicio a la comunicación.
10. Cuando se termina de transmitir el último byte de la Trama EventBESA, se genera una
señal de STOP en I2C y se libera el semáforo de protección del SemBuffer.
49
11. El comportamiento que generó el envío permanece bloqueado hasta que se reciba un ack
en la cola de recepción de ack.
12. Llega una trama nueva de datos por el bus I2C al contenedor transmisor.
13. Se revisa que sea de tipo AckBESA verificando el byte 2 que ha llegado en la trama.
14. Se revisa que se esté esperando un AckBESA, verificando que el semáforo SemSend no
ha sido liberado.
15. Si se está esperando el AckBESA, el byte de Ack recibido dentro de la trama es enviado
a la cola de recepción de ack, que permite desbloquear el comportamiento remitente de
la trama EventBESA.
16. El comportamiento remitente libera el semáforo SemSend.
17. Se retorna al remitente (quien hizo un llamado a la función SendEvent) el valor del Ack
recibido.
El comportamiento que envió inicialmente el mensaje se encuentra bloqueado hasta que la
confirmación BESA sea recibida.
El campo Ack en 0x01 (hexagesimal) indica que el evento
enviado fue recibido exitosamente por el agente destino. De no ser así, el campo Ack variará
con valores negativos según la causa del error permitiendo que el remitente decida cual es el
procedimiento a seguir.
Gestión de Errores en el Envío de una Trama EventBESA
Dentro de los pasos anteriores, ejecutados para realizar el envío externo de un evento BESA, se
pueden presentar errores por diversas causas. A continuación se muestra cual tipo de error se
retorna y en qué pasos del protocolo pueden ocurrir.
1.
Ejecución de la función SendEvent
2.
Se revisa el directorio de páginas blancas.
3.
Se determina si el agente habita en el contenedor.
4.
Si no, se revisa que exista en algún contenedor.
A partir de aquí inicia el envío externo…
5.
Se obtiene el Container ID del contenedor receptor en el cual existe el agente, y se toma
el semáforo de protección de envío de eventos (SemSend).
Error:
Si no se puede tomar el Semáforo inmediatamente, el comportamiento que
invocó la función SendEvent se bloquea durante el tiempo máximo que puede transcurrir
entre el instante en que un comportamiento tome este semáforo y el instante en que lo
libera al recibir una trama AckBESA.
50
Si transcurrido este tiempo, el comportamiento que había tomado el semáforo no lo ha
liberado, entonces se libera de manera obligada y se retorna al remitente el error
TIME_OUT_SEND (-2).
Se sugiere que este tiempo de espera sea medido bajo condiciones controladas de
comunicación entre dos contenedores, tal como se muestra en la Figura 19,
multiplicando por un factor de error de 1.5, con el cual se contempla el tiempo
transcurrido entre el momento en que se toma el SemSend y el momento de la
transmisión del primer byte de la trama, así como el tiempo transcurrido entre la llegada
del último byte de la Trama AckBESA y el instante en que se libera el SemSend, los
cuales no pueden ser medidos con las señales del bus I2C.
6.
Si se pudo tomar el semáforo SemSend, entonces se toma el semáforo de protección del
Buffer de transmisión (SemBuffer).
Error:
Si
no
se
puede
tomar
el
Semáforo
SemBuffer
inmediatamente,
el
comportamiento que invocó la función SendEvent se bloquea durante el tiempo máximo
que puede transcurrir entre el instante en que un comportamiento toma este semáforo y
el instante en que lo libera, lo cual sucede al transmitir el último byte de una trama de
datos y generar una secuencia de Stop de I2C. En la figura 19 se puede ver a manera
de ejemplo como calcularlo fácilmente.
Si transcurrido este tiempo el comportamiento o servicio que lo había tomado no ha
liberado el semáforo, entonces se libera de manera obligada y se retorna al remitente el
error TIME_OUT_BUFFER (-3).
7.
Una vez tomado SemBuffer, se llena el Buffer de transmisión con la información
correspondiente a la Trama Event BESA que se desea transmitir.
8.
Se realiza el arbitramento del bus I2C para determinar si se puede tomar el bus.
Error: Cuando hay colisión en la toma el bus de comunicación debido a que otro
contenedor no ha finalizado el envío de una trama de datos entonces se retorna al
remitente el error BUS_COLLITION (-6). El usuario puede establecer en un archivo de
configuración (ver anexo A) el número de veces que debe intentar el sistema el envío del
evento cuando se obtiene este error.
9.
Una vez se pudo tomar el bus, se pone el módulo de comunicación en modo Master y se
genera la secuencia de StART de I2C que da inicio a la comunicación.
51
Error: Si en cualquier momento de la comunicación el microcontrolador receptor no
puede recibir algún byte retornará una señal de no Ack de hardware.
Esto puede
deberse por ejemplo, a desconexión física, desconfiguración, o a que se encuentra en
una región crítica en la que no pudo vaciar los registros de recepción del modulo MSSP.
Cuando ningún dispositivo está identificado con el CONTAINER_ID correspondiente al
primer byte transmitido entonces también se recibe este tipo de error. La comunicación
es interrumpida automáticamente por el microcontrolador Maestro generando una
secuencia de Stop de I2C, tal como se muestra en la Figura 18. Se retorna al remitente
el error NO_ACK_HARDWARE (-4).
Al igual que en el caso anterior, el usuario determina la cantidad de veces que se intenta
enviar el evento al producirse este error.
El número de intentos es igual para ambos
casos.
10. Cuando se termina de transmitir el último byte de la Trama EventBESA, se genera una
señal de STOP en I2C y se libera el semáforo de protección del SemBuffer.
11. El comportamiento que generó el envío permanece bloqueado hasta que se reciba un ack
en la cola de recepción de ack.
Error:
Si transcurrido el tiempo máximo de espera de un AckBESA este no llega,
entonces se detiene la espera, se desbloquea el comportamiento remitente y se libera el
semáforo SemSend. Se retorna al remitente el error TIME_OUT_ACK (-1).
Las variables intervinientes en el cálculo de este tiempo son la velocidad de CPU de cada
microcontrolador, el tamaño de la trama de datos y la velocidad del reloj de transmisión.
Se sugiere que sea medido bajo condiciones controladas de comunicación entre dos
contenedores, tal como se muestra en la Figura 19, multiplicando por un factor de error
de 1.2, con el cual se contempla el tiempo transcurrido entre el momento en que se
envía la Trama EventBESA y el instante en que se recibe el byte ack en el
comportamiento que se encuentra bloqueado, después de recibida la trama AckBESA.
12. Llega una trama nueva de datos por el bus I2C al contenedor transmisor.
13. Se revisa que sea de tipo AckBESA verificando el byte 2 que ha llegado en la trama.
52
14. Se revisa que se esté esperando un AckBESA, verificando que el semáforo SemSend no
ha sido liberado.
Error: Si el semáforo esta libre, quiere decir que ningún comportamiento está bloqueado
esperando un AckBESA, por lo cual se descarta este mensaje. En este caso puede ser
que el destinatario se haya demorado un tiempo mayor al TIME_OUT_ACK, por lo cual
este último debe ser revisado.
15. Si se está esperando el AckBESA, el byte de Ack recibido dentro de la trama es enviado
a la cola de recepción de ack, que permite desbloquear el comportamiento remitente de
la trama EventBESA.
16. El comportamiento remitente libera el semáforo SemSend.
17. Se retorna al remitente (quien hizo un llamado a la función SendEvent) el valor del Ack
recibido.
Error: Si el ack recibido es igual a CHK_SUM_BAD, antes de retornar el valor recibido al
comportamiento remitente, se reintenta el envío el mismo número de veces que para los
errores de bus_collition y no_ack_hardware de los Pasos 8 y 9.
Este tipo de error se
puede producir si los datos originales sufren alguna alteración durante la secuencia de
transmisión o recepción.
La comunicación fue implementada intentando reducir al máximo los errores asociados al
hardware.
Por esto, para este tipo de errores el usuario tiene la oportunidad de decidir el
número de veces que la plataforma debe reintentar un envío al producirse el error, como se
explicó en los pasos 8, 9 y 17. Para los errores producidos a nivel de sistema BESA, el usuario
tiene también la posibilidad de decidir la acción a seguir una vez se ha recibido el ack
informando el resultado de la comunicación.
Cuando se presenta un error en la dirección del dispositivo esclavo, o un error de conexión física
entre los dispositivos conectados al bus I2C, se obtiene la señal de la Figura 18. En esta figura
la señal de arriba corresponde a la dirección del esclavo incluyendo el noveno bit en alto que
significa “No Acknowledge Hardware”.
La señal de abajo es el reloj de sincronización @ 100
Khz. Ambas señales son generadas por el dispositivo configurado como maestro en el momento
de la transmisión.
53
Dirección generada
por el transmisor
Bit de No Acknowledge Hardware
generado por el receptor
t4
t1
START
STOP
t2
t3
Señal de reloj generada por el
receptor. Trama AckBESA
Figura 18.
Señales START, no Acknowledge Hardware y STOP.
En la figura 18 se pueden observar claramente los eventos START y STOP generadas por el
modulo I2C. El microcontrolador reconoce que ocurrió un START cuando la señal SDA baja a
cero antes de que lo haga la señal SCL. Un STOP se reconoce cuando la señal SCL sube a uno y
en seguida lo hace también la señal SDA.
Como se dijo antes, el dispositivo identifica
automáticamente estos eventos por Hardware.
En la figura 19, se puede observar en la parte superior izquierda la trama EventBESA y a la
derecha la respuesta en la trama AckBESA.
Bajo las condiciones específicas de la prueba, el
valor mínimo que deberían tener los tiempos de espera antes de generarse los errores de
TIME_OUT_SEND y TIME_OUT_ACK, (sin multiplicar por el factor a tener en cuenta en cada uno)
es de aproximadamente 7.2 ms.
La señal superior corresponde a los datos y la inferior a la
señal de reloj. Reloj de transmisión @ 100 KHz. Reloj CPU Microcontrolador transmisor @ 20
MHz. Reloj CPU Microcontrolador receptor @ 25 MHz.
A partir de la figura 19, se puede entender con mayor claridad el comportamiento de las señales
en el bus de comunicación.
El contenedor que transmite en un momento dado (configurado
como Master), es el que genera también la señal de sincronismo SCL. Los tiempos indicados en
la figura, muestran a manera de ejemplo algunos de los tiempo y eventos que se producen
durante en la comunicación por I2C:
54
o
t1 -> Antes de iniciar la transmisión, se toma SemSend.
o
t2 y t4 -> Un instante antes de enviar el primer byte se toma SemBuffer.
o
t3 y t5 -> Un instante después de terminar el envío de la trama se libera SemBuffer.
o
Tiempo de respuesta de Ack = T2.
t3
t1
t4
t2
T1
T2
t5
Señal de datos (SDA)
Señal generada por el transmisor.
Trama EventBESA
Señal generada por
el receptor. Trama
AckBESA
Señal de Reloj (SCL)
Figura 19.
Señales presentes durante la comunicación exitosa desde un contenedor hacia otro contenedor.
Tamaño máximo de Datos igual a 6. DataSize igual a 8.
Entre los tiempos t2 - t3 y t4 - t5 se toma y se libera el semáforo SemBuffer. El mayor tiempo
se obtiene entre t2 y t3, que es el tiempo que debe esperarse para producir el error de
TIME_OUT_BUFFER. El tiempo debe medirse al transmitir el tamaño máximo de datos posible
para tener en cuenta el peor caso.
Par establecer el tiempo TIME_OUT_SEND en que debe liberarse el semáforo SemSend, es
necesario obtener el tiempo T1 que se muestra en la figura 19. Este tiempo se mide a partir de
que comienza la transmisión del primer byte por el bus, hasta que se transmite el último byte de
la trama AckBESA por parte del receptor; se debe multiplicar por 1,5 para tener en cuenta el
tiempo de procesamiento que se realiza antes y después de la transmisión y recepción.
o
Tiempo de bloqueo de SemSend = T1 x 1,5.
Para establecer el tiempo TIME_OUT_ACK en que debe liberarse el semáforo SemSend al no
recibirse una confirmación (Acknowledge), se debe tomar el mismo tiempo T1; debe
multiplicarse por 1,2 para tener en cuenta también el tiempo de procesamiento asociado a la
55
comunicación. Sin embargo, el factor de escalamiento es menor que en el caso anterior, ya que
el comportamiento remitente se bloquea después de transmitir la señal de START de I2C.
o
Tiempo máximo de espera de AckBESA = T1 x 1,2.
La velocidad escogida para la transmisión por el bus I2C fue de 100 Khz como se observa en las
figuras 18 y 19. Aunque es posible según los estándares del protocolo transmitir a frecuencias
mayores (400 Khz y 1Mhz), los errores de los diferentes tipos mencionados anteriormente, y en
especial de “NO_ACK_HARDWARE” y “BUS_COLLITION” presentados en estas velocidades
durante las pruebas de comunicación, fueron bastante superiores a cuando se transmitió con
velocidad de reloj igual a 100 Khz.
Recepción de las Tramas de Datos
La tarea vSendAck, que hace parte del Administrador Local, es la encargada de leer y filtrar la
información del buffer de recepción del contenedor cada vez que llega una trama de datos. La
información del buffer de recepción es enviada desde la rutina de interrupción de recepción
cuando se termina de recibir una trama, y es recibida por la tarea vSendAck (Figura 20), por
copia, en la cola creada para tal propósito.
Figura 20.
Envío y recepción de eventos al bus I2C por medio de interrupciones.
56
Una vez se ha recibido se filtra su información para, si se recibió un AckBESA, realizar los pasos
14 y 15 descritos anteriormente, pero si se recibió una trama EventBESA realizar los pasos
siguientes:
1. Se calcula el check sum sobre la trama recibida y se realiza la comparación con
el valor de check sum recibido.
2.
Si la comparación muestra error en los datos, se salta al paso 6. Si el chk_sum
es correcto se procede a hacer un envío local al agente indicado por el byte alias.
Al agente alias se le envía la sección EventBESA de la trama recibida.
3.
Se ejecuta la función SendEvent que originará un envío local.
4.
Se guarda el ack retornado por la función SendEvent
5.
Se toma el semáforo SemBuffer
6.
Se llena el buffer de transmisión del contenedor con la trama de AckBESA
obtenida a partir del ack resultante del envío local del paso 3 o con el ack
CHK_SUM_BAD, obtenido en el caso de error en el paso 2.
7.
Se toma el bus I2C.
8.
Se inicia la comunicación generando la rutina de Start en el bus I2C.
9.
Cuando la rutina de interrupción termina la transmisión, libera el semáforo
SemBuffer.
A continuación se presenta el pseudo código de la tarea vSendAck:
void vSend_Ack(void * pvParameters)
{
Creacion de la estructura tipo stBufferBESA y su respectivo apuntador;
Creación de las variables necesarias;
for(;;)
{
while(no llegue un evento a la cola xQueueRxFromISR, se espera el máximo tiempo posible
(portMAX_DELAY)){}
if( la trama recibida es una trama ackBESA )
{
if( se estaba esperando una trama ackBESA )
{
se envía la trama a la cola xQueueRxAck para desbloquear al comportamiento que estaba
esperando el ackBESA;
}
else
{
se libera el semáforo xSemaphoreSendProtection;
}
}
else
{
Se inicializa la variable check_sum en cero;
Se apunta pBuffer_rx a la primera posición de la estructura que acaba de llegar
Se calcula el check_sum;
if( el check_sum calculado no es igual al recibido )
{
en el campo de ack de la trama AckBESA se coloca la causa de recepción corrupta de
datos;
57
}
else
{
se realiza un envío de los datos recibidos al agente interno correspondiente, y si el
envió es exitoso en el campo correspondiente de la trama AckBESA se coloca recepción
exitosa;
}
Luego de tener lista la trama AckBESA para enviar, se intenta tomar el semáforo
xSemaphoreBufferProtection solamente 3 veces, cada una de estas durante un tiempo de espera igual a
X_BLOCK_TIME_SEMAPHORE_BUFFER
if( se pudo tomar el semáforo xSemaphoreBufferProtection? )
{
Se arma toda la trama AckBESA para ser enviada al agente que realizó el envió;
if( el bus está ocupado)
{
El sistema espera la liberación del bus I2C un tiempo igual a
X_BLOCK_TIME_WAITING_FOR_BUS_I2C;
if( el bus ya fue liberado?)
{
Se realiza el envío;
}
else
{
No se realiza el envió y se libera el semáforo
xSemaphoreBufferProtection.
Es decisión del programador lo que se realiza en este caso;
}
}
}
}
}
Diagrama de Flujo de la Comunicación entre Agentes en BESA-ME
El diagrama de flujo que se muestra en la figura 21 representa los dos esquemas que se llevan
acabo para el envió y la recepción de eventos en determinado contenedor. La sección sombreada
(derecha) muestra el proceso de recepción externa, mientras que los bloques no sombreados y
de colores (izquierda) muestran los pasos que se llevan a cabo en el envió de eventos, tanto
internos como externos.
Cuando el agente X (amarillo) realiza una transferencia de datos al agente Y (amarillo), la
comunicación se ejecuta internamente como los muestra la figura 21 en la parte superior
izquierda. La búsqueda de la ubicación del agente destino la realiza el administrador local como
se explicó anteriormente. Si el agente X desea enviar un evento a un agente que se encuentra
fuera del contenedor (agente Z), la secuencia de sucesos que realiza la plataforma BESA-ME es
ahora mas compleja y se hace necesario utilizar los servicios de sincronización (bloques
naranjas).
Luego de enviar los datos al agente externo, el comportamiento del agente X espera la
contestación AckBESA de Z. Cuando dicho suceso ocurre, las interrupciones necesarias se llevan
a cabo (bloque azul de la parte inferior derecha) para recibir toda la trama. Una vez completa la
recepción, se confirma que la trama sea de tipo AckBESA, de ser así, el comportamiento del
agente X, quien generó el evento, finaliza la espera y se desbloquea (si la contestación indica
que Z recibió exitosamente).
58
Los pasos realizados por el agente Z, durante la recepción, son los indicados por los bloques
sombreados, pero en el microcontrolador donde se encuentra contenido Z. Cuando la trama
recibida está completa, se observa que el tipo de mensaje no es AckBESA sino un evento
externo, de modo que se realiza lo correspondiente para que dicho evento llegue al agente Z.
Una vez recibido, este agente genera la trama AckBESA que se enviará a X. Este envío debe
utilizar también los servicios de sincronismo para lograr colocar su trama en el bus I2C, de modo
que toma los mismos semáforos propios de los envíos de eventos externos. Para el envío de
contestación no se espera respuesta (ovalo verde).
59
Behavior x
cQueueReceive
cQueueReceive
SendEvent
El Agente
detino es
local ?
Agente W
Agente Y
Agente X
SI
NO
Se retorna un valor
según el motivo
Se
recibío el
mensaje
?
SI
Se finaliza
la comunicación
El
mensaje
se recibió
?
Se realiza un
envío local
( cQueueSend )
NO
La acción que se
realiza depende
del usuario
Se busca la dirección del
contenedor en el que se encuentra
el Agente destino
Se construye el mensaje
de contestación positivo
SI
Se realiza un
envío local
( cQueueSend )
NO
NO
N intentos
?
NO
SI
Se toma el semáforo
de protección de
envio externo
Fue la
confirmación
positiva ?
Se construye el mensaje
de contestación negativo
según el motivo
SI
Se toma el semáforo
de proteccion del Buffer
para envio externo
Desbloquea el
comportamiento x
Se arma el mensaje
en el buffer de transmisión
Se construye el mensaje
de contestacion negativo
por mal check sum
Se desencapsula
en mensaje
Se analiza el contenido y
se libera el semaforo
de envio externo
NO
SI
N intentos
NO
Está
libre el bus
i2c ?
SI
Llegó la
confirmación
BESA ? NO
SI
N intentos
El mensaje
enviado era
de tipo Ack
BESA ?
Se generan las
interrupciones propias
de i2c para enviar el
mensaje externo en
paquetes de 1 byte
(SendEventRemoto)
NO
SI
NO
Check
sum
correcto ?
El tipo de
mensajes es un
ack
BESA?
No se espera
contestación y finaliza
la comunicación
SI
Se libera el semáforo de
escritura en el Buffer
NO
SI
N
intentos
Hubo ack
negativo de
Hardware
después del byte
anterior ?
Se genera interrupción por i2c
(entrada de mensaje)
BUS I2C
Figura 21.
Diagrama de flujo de la comunicación entre agentes en BESA-ME.
60
4. PRUEBAS Y ANÁLISIS DE RESULTADOS
El objetivo de las pruebas es comprobar el funcionamiento final de la plataforma BESA-ME y
establecer los límites y los rangos normales de operación.
Se pretende también que el
programador pueda contar con un soporte al cual referirse en el momento de crear una
aplicación.
Para lograr resultados satisfactorios que proporcionen información relevante respecto al
desempeño de la plataforma en general, se procedió a establecer un protocolo de pruebas para
luego continuar de manera ordenada con la evaluación del sistema y realizar un posterior
análisis de los resultados obtenidos.
4.1. Protocolo de Pruebas
El primer paso para lograr este objetivo es determinar las variables que intervienen en el
sistema, y con base en ellas se deben determinar las pruebas que se van a realizar.
4.1.1. Identificación de Variables
Para las pruebas se consideran tres tipos de variables: las variables independientes o de control,
las variables dependientes o de medición y las variables intervinientes.
Las primeras son
aquellas que se varían para crear diferentes situaciones de evaluación, las segundas son las que
se miden a la salida de la prueba y las terceras son aquellas variables que están presentes
inevitablemente y afectan el resultado de la prueba.
Estas últimas se controlan tratando de
dejarlas invariantes para que su influencia sea mínima o constante a lo largo de los
experimentos.
Variables Independientes
Tamaño del Stack
Cada tarea creada en el sistema tiene asignado un Stack o espacio de memoria donde se guarda
la información necesaria para que una vez reestablecida después de un cambio de contexto,
pueda seguir ejecutandose con los datos e información correcta. El tamaño del Stack puede ser
modificado para cada tarea, y su valor depende del espacio mínimo en memoria requerido para
su creación, del tamaño de las variables creadas y de las que accede durante su ejecución.
El tamaño del Stack es un parámetro crítico cuando se quiere crear una aplicación con un
consumo de memoria cercano al límite de la capacidad disponible. Entre mayor sea su valor,
61
menor cantidad de estructuras pueden ser creadas.
Es un parámetro importante para
comprobar la máxima capacidad del sistema, el cual debe ser llevado al mínimo valor posible
con el que la aplicación funcione correctamente.
Número de elementos en el sistema
Se entiende por elementos el número de Agentes, Comportamientos, Puertos, Guardas y Tipos
de Eventos existentes en el sistema.
Dependiendo del tipo de elemento creado, puede
aumentarse considerablemente el espacio reservado en memoria. En el caso de los Agentes, la
creación de una nueva entidad implica la creación de un Canal, un Comportamiento, un Puerto y
una Guarda como mínimo; en estos casos un nuevo elemento está ligado a otro, siendo mayor
el consumo de memoria requerido.
Al crear un nuevo Agente o un Comportamiento, se están creando tareas adicionales.
Cada
tarea adicional implica tiempo de procesador para su ejecución y una mayor carga de
procesamiento en el sistema, lo cual debe verse reflejado en un aumento en los tiempos de
respuesta a eventos.
En la creación de una nueva estructura como una Guarda o un Puerto, el aumento en los
tiempos de respuesta no debería ser significativo para incrementos pequeños en el número de
elementos.
Esto debido a que no hay implícito ningún cambio de contexto, sino un poco de
procesamiento
adicional.
Si
la
cantidad
de
elementos
se
incrementa
notablemente,
seguramente se producirá un cambio en el tiempo de procesamiento y de respuesta.
Periodo de envío de Eventos
Según la aplicación es posible que se requiera enviar periódicamente eventos a los agentes
presentes en el sistema.
La frecuencia con que son enviados los eventos puede ser variada
según se necesite.
Si el periodo de envío es muy pequeño, algunos de los eventos generados pueden no ser
entregados si la cola de recepción del destinatario se encuentra llena.
Es conveniente
determinar, bajo un entorno controlado, la frecuencia máxima de envío con la que se asegura
que los eventos lleguen a su destino.
Los tiempos de respuesta pueden también variar
dependiendo de los envíos realizados, pues el tiempo que mantienen ocupado el procesador
puede aumentar o disminuir según la frecuencia utilizada.
62
Variables Intervinientes
Funciones de Tratamiento
Las funciones de tratamiento a los eventos generados varían dependiendo de la aplicación a
implementar por el programador.
Una función donde se ejecuten gran cantidad de
instrucciones, puede aumentar significativamente los tiempos de respuesta del sistema.
La
función de tratamiento es una variable que incide en el desempeño de la plataforma y que no se
puede generalizar como constante para todos los casos.
No es posible ni conveniente definir entonces, rutinas de tratamiento estándar en función de las
cuales se realicen las pruebas.
Sin embargo para las pruebas realizadas y dependiendo del
caso, se debe implementar una función sencilla que se mantenga como una constante
interviniente controlada.
Tamaño de los datos de los eventos BESA
En el tamaño de los eventos se presenta el mismo caso anterior. Establecer un tamaño fijo de
datos es una limitante en el desempeño de la plataforma BESA-ME, pues depende totalmente de
la aplicación que el usuario final desarrolle. Tampoco es conveniente tratarla como una variable
independiente, ya que no es posible determinar valores estándar de tamaño de datos en función
de los cuales realizar las pruebas.
Por estas razones se considera el tamaño de los datos como una variable interviniente que
afecta el resultado de las pruebas, en especial en los casos en que haya comunicación entre
agentes de distintos contenedores, pero que puede mantenerse constante permitiendo observar
la influencia de otros parámetros más relevantes.
Velocidad de Procesamiento
La velocidad de procesamiento es una variable relacionada directamente con el tiempo de
respuesta a los eventos y con la cantidad de eventos que son enviados correctamente a su
destino.
Si el tiempo de respuesta aumenta, seguramente no todos los eventos generados
serán recibidos por la tarea correspondiente.
Está variable está ligada a la velocidad del oscilador seleccionado y a la cantidad de
instrucciones que tenga que ejecutar el procesador para lograr un resultado en la aplicación
creada. Interviene en los resultados de las pruebas, afectando directamente cualquier variable
dependiente del tiempo de procesamiento.
Para todas las pruebas se utilizará la misma
velocidad de reloj (oscilador microcontrolador @ 20 MHz, reloj de transmisión I2C @ 100 kHz),
logrando así que su efecto en los resultados sea constante.
Variables Dependientes
63
Se quiere observar el desempeño de la plataforma BESA-Micro Edition en cuanto al tiempo de
Respuesta a eventos, el funcionamiento y capacidad del sistema, y el número de errores y
envíos exitosos, es decir el número de envíos que se completan en la comunicación entre
agentes y en las interrupciones.
Es en estos parámetros en los que se espera se presenten
variaciones significativas en función de las variables independientes.
El tiempo de Respuesta a eventos, como se explicó anteriormente, está relacionado con el
porcentaje de uso de la capacidad máxima del sistema y con la frecuencia de envío de eventos.
Al igual que el número de errores y envíos exitosos, que dependen del tiempo de procesamiento
necesario para que un envío se pueda completar y del periodo con el que se envíen.
El funcionamiento y la capacidad del sistema están estrechamente relacionados.
El
funcionamiento del sistema depende de que no se excedan los límites bajo los cuales BESA-ME
opera correctamente, entre ellos, los límites de capacidad, dados por el número máximo de
elementos a partir del cual la operación de la plataforma se torna inestable.
4.1.2. Pruebas a Realizar
Para la realización de las pruebas se han definido tres grupos generales que comprenden las
variables identificadas anteriormente.
Pruebas de Capacidad
Las pruebas a realizar son simplemente una verificación de las capacidades del sistema. Esta
verificación se divide en dos partes, la primera a nivel de agente y la segunda a nivel de
sistema.
A nivel de agente, se busca el número máximo de comportamientos, guardas, puertos y eventos
que soporta el microcontrolador para un sólo agente. A nivel de sistema, se busca el número
máximo de agentes que soporta el sistema para cada microcontrolador.
Para cada caso se debe tratar de reducir al valor mínimo el tamaño del Stack asignado a cada
tarea, y así maximizar el espacio disponible para nuevas estructuras.
Además se hace
importante observar para cada prueba, cómo influye el aumento del número de elementos del
sistema, en los tiempos de respuesta a eventos del mismo.
Pruebas de Comunicación
Las pruebas de comunicación incluyen envíos entre agentes de distintos contenedores y del
mismo contenedor. El objetivo principal de las pruebas es, entre otros, observar los tiempos de
64
respuesta a eventos periódicos y los errores o envíos fallidos que se presentan en las
comunicaciones locales y externas.
Para estas pruebas no es relevante reducir el tamaño del Stack de las tareas al menor valor
posible, simplemente se debe asegurar un tamaño adecuado para su correcta operación.
El
número de elementos en el sistema debe ser el mínimo necesario para que el sistema funcione
en cada prueba y se logren los resultados esperados.
Pruebas de Interrupciones
Las pruebas de Interrupciones pretenden establecer los tiempos de respuesta a eventos
periódicos generados desde la rutina de interrupción, y observar para diferentes frecuencias, los
tipos de errores que se presentan y el número de envíos que no se pueden completar.
Al igual que en las pruebas de comunicación, el tamaño del Stack de las tareas y el número de
elementos en el sistema, no son parámetros relevantes para el caso, simplemente se deben
ajustar para asegurar el funcionamiento de la plataforma durante las pruebas.
4.2. Análisis de los Resultados Obtenidos
Es importante mencionar que para la mayoría de las pruebas, se creó una tarea adicional Prueba
que enviaba eventos constantemente a los agentes existentes en el Sistema. La creación de una
tarea auxiliar es una solución para cuando se requiere enviar eventos periódicamente. Además,
la función de tratamiento a los eventos fue una función sencilla creada igual para todos los
agentes.
El tamaño de los datos de los eventos BESA se dejó igual que el utilizado en las
pruebas realizadas durante la implementación de la comunicación entre contenedores (tamaño
máximo de datos igual a 6).
4.2.1. Pruebas de Capacidad
En las pruebas de capacidad se utilizó la tarea Prueba para enviar eventos a una frecuencia
constante.
Se realizó primero una pequeña prueba con diferentes tamaños datos y de Stack
para evaluar el funcionamiento de la plataforma.
Luego se procedió a hallar los valores
máximos de cada tipo de elemento o entidad que puede existir en el sistema, manteniendo las
demás en el mínimo valor posible.
Al obtener estos valores máximos especificados para la programación y diseño de futuras
aplicaciones, se procedió a analizar simultáneamente los cambios en los tiempos de repuesta
que ocurrían en el sistema respecto a la variación de entidades, es decir, al aumento de cada
una de las tareas y esquemas de la plataforma.
65
Tamaño del Stack
Para la siguiente prueba, se crearon las tres tareas que aparecen en la Tabla 4.
La tarea
Behavior y Channel pertenecientes al agente y la tarea adicional Prueba. Los valores mínimos
para los que funciona correctamente el sistema fueron hallados a través del método de prueba y
error, hasta acercarse a los valores óptimos.
Entre menor sea el Stack, menos recursos de
memoria consume y da cabida a más datos o tareas adicionales según se requiera.
Tamaño del Stack
Tarea Prueba
120
Tarea Behavior
120
Tarea Channel
120
MAX_DATA_SIZE
Funcionamiento
130
120
150
130
130
150
130
150
130
6
failed failed
ok
130
ok
10
15
16
ok
ok
ok
17
105
131
116
108
18
failed failed
17
ok
105
107
106
107
failed failed
ok
1
ok
ok
Tabla 4. Valores de los Stacks.
En la Tabla 4 se observan las pruebas realizadas para diferentes tamaños de datos, variando el
tamaño del Stack donde cada tarea almacena los datos a los que accede antes de un cambio de
contexto. Cuando el stack es muy pequeño el cambio de contexto no se produce correctamente,
ocasionando la perdida de los datos y el funcionamiento incorrecto del sistema.
Existe una relación entre el tamaño del Stack y el tamaño de los datos. Si el tamaño de los
datos aumenta, el Stack de las tareas que utilicen la variable debe aumentar al menos en la
misma proporción.
Esto se debe a que el número de datos que deben ser guardados en un
cambio de contexto aumenta al incrementarse el tamaño de los datos.
Sin embargo, se
aconseja según la documentación del RTOS 24 , definir el tamaño del Stack calculando el tamaño
de todas las variables que accede y crea la función y utilizar el doble al menos, para después
mediante pruebas acomodarlo a un valor más cercano al límite.
Cantidad de Agentes por Contenedor
En la Tabla 5 se observan diferentes tiempos de respuesta obtenidos a partir del momento en
que se le envía un evento al primer agente.
A su vez, se fue incrementando el número de
agentes en el Contenedor, dejando las otras variables constantes. Los tiempos fueron medidos
utilizando un osciloscopio, a partir del momento en que se enviaba el dato desde la tarea
Prueba, hasta cuando comenzaba a ejecutarse la función de tratamiento correspondiente en el
comportamiento de cada agente.
24
FreeRTOSPTM, www.freertos.org. Mayo 25 de 2005.
66
Variable
Tiempo de Respuesta (ms)
Cantidad
de agentes
Agente
Referido al
primer envío
1
a
0.512
a
0.512
b
3.22
b
1.26
2.02
c
3.22
1.96
2
3
4
5
Referido a su
propio envío
0.52
2.708
a
5.24
c
1.26
1.98
d
3.24
2
2.04
a
5.24
b
7.28
d
1.2
2
e
3.2
2.05
a
5.25
2
b
7.25
2.05
c
6
Diferencia de
Tiempo
0.52
Constantes
Comportamientos
1
Guardas
1
Guardas por puerto
1
Puertos
1
Funciones
1
5.24
5.24
Cantidad
Stacks
Prueba
70
Comportamiento
130
Canal
140
5.28
9.3
No funciona
No funciona
Tabla 5. Tiempos de Respuesta para distintas cantidades de Agentes en un Contenedor. Todos los tiempos en
milisegundos.
Referidos al Primer Envío
En el momento de hacer el primer envío de un evento desde la tarea Prueba al primer agente, se
cambiaba el estado de una bandera (se conmutaba el valor de un puerto de salida entre un cero
lógico y un uno lógico); en seguida se enviaban los demás eventos a los agentes restantes.
Cuando el comportamiento de cada agente iniciaba la ejecución de la función asociada, se
cambiaba el estado de una bandera diferente para cada agente.
A través del osciloscopio se
obtuvo el tiempo de respuesta al observar el tiempo transcurrido entre los cambios en los
puertos de salida para los casos descritos anteriormente.
Como se observa en la Tabla 5, aunque los tiempos no son constantes en todos los casos, si se
presenta una tendencia a repetirse cada tiempo según el orden en que han sido enviados. La
diferencia entre un valor mayor y el inmediatamente inferior tiende a 2 ms, por lo que hay cierta
constante entre los tiempos de respuesta. Sin embargo se puede apreciar que el orden en que
el planificador del RTOS otorga el procesador a cada tarea no depende del orden en que es
enviado el evento.
Referidos a su Propio Envío
En el momento en que se enviaba un evento desde la Tarea Prueba a cada agente, se cambiaba
el estado de una bandera diferente (un puerto de salida diferente) por cada envío.
Cuando
comenzaba a ejecutarse la función asociada desde el comportamiento de cada agente, se
67
cambiaba el estado de una bandera distinta para cada agente y utilizando un osciloscopio, se
medía el tiempo transcurrido entre el envío del evento al agente y la respuesta por parte del
mismo.
Se puede observar en la Tabla 5 que los tiempos obtenidos de esta forma, son los mismos según
el número de agentes en el sistema. El tiempo de respuesta obtenido entre el envío del evento
a un agente determinado y el comienzo de la ejecución de la función por parte del
comportamiento de dicho agente, es igual para cada uno, y aumenta de acuerdo al número de
agentes en el sistema, hasta hacerse casi estable a partir de tres agentes.
Cantidad de Comportamientos
Variables
Tiempo de Respuesta (ms)
Constantes
Comportamientos
1
Guardas por
Agente
1
2
2
3
3
4
4
5
5
6
6
Todos los comportamientos
asociado a un solo tipo de evento
0.512
- 0.888
1.4
- 0.12
1.52
- 0.20
7
7
8
8
9
9
10
10
11
11
2.04
12
12
No funciona
Cantidad
Agentes por contenedor
1
Guardas
1
Guardas por puerto
1
Puertos
1
Funciones
Tamaño de la Cola de
recepción
1
1
Stacks
1.72
- 0.296
1.816
- 0.224
Prueba
70
Comportamiento
105
Canal
105
Tabla 6. Tiempos de Respuesta para distintas cantidades de Comportamientos en un Contenedor.
Por cada comportamiento adicional es necesario crear una Guarda que relacione un tipo de
Evento y la función de tratamiento para el mismo con cada comportamiento. En la Tabla 6 se
puede observar como aumenta el tiempo de respuesta obtenido según aumenta el número de
comportamientos.
El tiempo es medido a partir del momento en que se envía el Evento al
agente desde la tarea Prueba, hasta el momento en que la función de tratamiento igual para
todos los comportamientos, es ejecutada por el primer comportamiento.
Los tiempos fueron tomados únicamente para números impares de comportamientos. Al restar
un valor con respecto al inmediatamente anterior, obtenemos una diferencia de 0.2 ms
aproximadamente, exceptuando la diferencia de tiempos de respuesta entre uno y tres
comportamientos, que es aproximadamente cuatro veces mayor.
Se podría afirmar según los resultados que después de tres comportamientos, por cada
comportamiento agregado, el tiempo de respuesta aumenta entre 0.1ms y 0.15ms.
68
Cantidad de Guardas
Variable
Funcionamiento
Constantes
Cantidad
# Guardas en un
solo puerto
Todos las Guardas
asociadas a un sólo
tipo de evento
Agentes por contenedor
1
Comportamientos
1
1
ok
5
ok
10
ok
15
ok
20
ok
21
No funciona
Puertos
1
Stacks
Prueba
70
Comportamiento
105
Canal
105
Tabla 7. Cantidad máxima de Guardas en un contenedor
En las pruebas realizadas para hallar el máximo número de Guardas con las que el sistema
funciona correctamente, no se hicieron pruebas de tiempo de respuesta.
Como las guardas
están asociadas a un mismo comportamiento, se repetiría la función de tratamiento al Evento
tantas veces como número de Guardas haya, por cada Evento que sea enviado al agente. Si se
quiere evitar que se pierdan los mensajes enviados al comportamiento, se debe crear su cola de
recepción, del mismo tamaño del número de Guardas.
Como se observa en la Tabla 7, las Guardas fueron creadas en un mismo Puerto, es decir, para
un sólo tipo de Evento. El sistema funcionó correctamente hasta 20 Guardas.
Cantidad de Puertos
Valores
Constantes
Tiempo de Respuesta (ms)
# Puertos =
Tipos de Eventos
Un evento activa todas las
Guardas
1
Valores Constantes
Agentes por contenedor
Cantidad
1
Guardas por puerto
1
0.52
Funciones
1
10
2.1
Variables por función
1
20
2.9
Comportamientos
30
3.48
40
4.16
Prueba
50
5.1
Comportamiento
105
Canal
105
51
1
Stacks
No funciona
70
Tabla 8. Tiempos de respuesta a eventos con distintas cantidades de Puertos
Cada puerto creado significa un tipo de evento diferente en el sistema. Como se observa en la
Tabla 8, el máximo número de puertos en el canal del agente con el que el sistema funcionó
correctamente fue 50. El tiempo de respuesta fue medido desde el momento en que se envía un
69
tipo de Evento hasta que es ejecutada la función asociada al mismo Evento.
A medida que
aumenta el número de Puertos el tiempo de respuesta, como se esperaba, se incrementa
también.
Este incremento se debe al tiempo adicional de procesamiento que conlleva la
existencia de un puerto más en el canal del agente.
El aumento más significativo de tiempo al incrementar el número de Puertos, se obtuvo al pasar
de un puerto a diez. Este resultado es coherente con los anteriores donde el mayor cambio en
los tiempos de respuesta se tiene en el incremento posterior a la prueba con el mínimo de
elementos en el sistema.
Síntesis de Resultados Obtenidos
Luego de hallar los valores máximos a condiciones optimas, es decir, manteniendo el resto de
variables en el menor valor posible, se tiene que:
A nivel Agente
Número máx. de comportamientos = 11;
Número máx. de Guardas en un sólo Puerto = 20;
Número máx. de Puertos = 50;
A nivel Sistema
Número máx. de Agentes por Contenedor = 5;
4.2.2. Pruebas de Comunicación
Las
pruebas
de
comunicación
realizadas,
contenedores y del mismo contenedor.
incluyen
envíos
entre
agentes
de
distintos
El objetivo principal de las pruebas es, entre otros,
observar los tiempos de respuesta a eventos periódicos y los errores o envíos fallidos que se
presentan en las comunicaciones locales y externas.
En su realización se utilizó la tarea Prueba, desde la que se envían eventos periódicamente a un
agente, utilizando la función del RTOS vTaskDelay ( t (ms) ). Esta función duerme la tarea por
el tiempo t dado en milisegundos.
El agente que recibe el evento lo envía de nuevo a otro
agente que dependiendo de la prueba realizada, puede estar en el mismo contenedor o no. Es
importante aclarar que el tiempo por el que la tarea se atrasa, el cual es introducido desde el
programa, varía respecto al tiempo real observado en un osciloscopio. La exactitud del tiempo
depende de elementos externos como lo es la velocidad del Oscilador y en general las
características del Hardware en el que se implementa.
70
Envíos de Eventos por el Canal de Comunicación
Para las siguientes pruebas se tuvo en cuenta:
-
Tiempo de bloqueo del canal. Dado en milisegundos. Suspende la ejecución de la tarea
para permitir un cambio de contexto y dar la posibilidad de que el comportamiento
pueda recibir el mensaje de la cola, y de esta forma, no se pierda el siguiente evento
que se envíe.
-
Tamaño de Cola.
Al aumentar la cola del canal o del comportamiento aumenta la
probabilidad de que los envíos sean exitosos y que el número de envíos que se pierden
sea menor.
Para estos datos constantes se probó con diferentes periodos de envío para observar como
afecta en el número de envíos exitosos de eventos.
Tiempo de
bloqueo del
canal (ms)
0
0
0
8
Tamaño de la
cola de
recepción del
canal
1
2
3
1
Tamaño de la
cola de recepción
del
comportamiento
Periodo entre
envío de
mensajes
usando
vTaskDelay (ms)
Eventos NO
enviados por I2C
(%)
Eventos
enviados por I2C
(%)
2
71
29
4
50
50
6
33
67
8
0
100
0
82
18
2
71
29
4
50
50
6
7
93
1
2
3
1
8
0
100
50
0
100
100
0
100
0
86
14
2
67
33
4
50
50
6
0
100
2
75
25
4
50
50
6
34
66
8
0
100
Tabla 9. Envíos de Eventos por el puerto I2C con diferentes tamaños de colas y periodos de envío.
71
Las variaciones en los tamaños de las colas se realizaron únicamente para el agente transmisor,
el cual recibía el evento proveniente de la tarea Prueba, para enviarlo luego desde el
comportamiento al agente destino ubicado en otro contenedor. Es importante resaltar que una
vez el evento es recibido por el comportamiento del agente transmisor, se asegura su envío por
el puerto de comunicaciones.
Los datos obtenidos se pueden observar en la Tabla 9. Para la prueba se consideró como un
envío bueno o completado, los envíos que se realizaron por el canal de comunicaciones I2C, sin
tener en cuenta si eran entregados con éxito al agente destino. Por el contrario, un envío que
no se pudo realizar por el puerto de comunicaciones, fue considerado como fallido.
Se puede ver que a medida que se aumenta el tamaño de la cola, el número de envíos no
recibidos por el comportamiento disminuye para los diferentes periodos.
Esto se hace más
notorio cuando el tamaño de la cola es tres; en este caso, para un periodo de envío igual a 6ms,
todos los envíos son recibidos por el comportamiento y por lo tanto transmitidos por I2C (ver
figura 24). Para los casos en los que el tamaño de la cola es uno y dos, sólo se completan todos
los envíos para un periodo de generación de eventos igual a 8 ms (ver figuras 22 y 23). Sin
embargo cuando el tamaño de la cola es dos, un porcentaje mayor de envíos se completa en
tiempos inferiores.
Por lo tanto una estrategia de asegurar que el comportamiento reciba la mayor cantidad de
envíos posible para que así puedan ser enviados, es aumentando el tamaño de las colas del
canal y/o de los comportamientos, con lo cual se pueden almacenar eventos mientras se está
atendiendo algún otro. Otra forma de garantizar que todos los envíos de eventos sean recibidos
por el agente, es aumentando el periodo en que le son generados los eventos, para que de esta
forma pueda ejecutar la transmisión por I2C y desocupar la cola de recepción a tiempo para el
siguiente envío que le llegue.
En el último caso, en el que el tiempo de bloqueo del canal se aumenta a 8ms, el significado de
los datos obtenidos cambia un poco.
Al bloquearse la tarea canal durante un tiempo, los
eventos que le sean enviados durante ese mismo tiempo no podrán ser almacenados en la cola
del canal, que en este caso es de tamaño uno. La cola únicamente podría recibir uno cada vez
que la tarea retome el control del procesador y vacíe su cola.
Para este caso los datos
mostrados como no enviados al comportamiento, son en realidad el número de eventos que no
fueron enviados al canal y por lo tanto nunca llegaron tampoco al comportamiento.
En la Figura 19 se pudo ver que el tiempo mínimo para un envío por I2C para el tamaño de
datos establecido es de 7.15 ms aproximadamente. El tiempo de bloqueo de la tarea canal es
entonces 8ms para darle tiempo al comportamiento de hacer la transmisión y estar listo para
72
recibir un nuevo envío.
Esta es otra estrategia para evitar que los envíos se pierdan, sin
embargo, no es la más adecuada, pues bloquear el canal, retardaría el envío de eventos a otros
comportamientos que podrían ejecutarse en paralelo.
Porcentaje de Enviados Vs Periodo de Envío
%
Tam año de Cola = 1
120
100
80
60
40
20
0
Enviados
No Enviados
2
4
6
8
ms - Generados con vTaskDelay
Figura 22.
Envíos exitoso para diferentes frecuencias de envío y tamaño de cola igual a uno.
Porcentaje de Enviados Vs Periodo de Envío
%
Tam año de Cola = 2
120
100
80
60
40
20
0
Enviados
No Enviados
0
2
4
6
8
50 100
ms - G ener ad o s co n vT askD el ay
Figura 23.
Envíos exitoso para diferentes frecuencias de envío y tamaño de cola igual a dos.
73
%
Porcentaje de Enviados Vs Periodo de Envío
Tamaño de Cola = 3
120
100
80
60
40
20
0
Enviados
No enviados
0
2
4
6
m s - Generados con vTaskDelay
Figura 24.
Envíos exitoso para diferentes frecuencias de envío y tamaño de cola igual a tres.
Tiempos de Respuesta a Eventos
Periodo entre
envío de
mensajes
(ms)
Tiempo de
respuesta
(ms)
200
9.2
100
9.2
30
9.2
25
9.2
22
9.2
21
9.2
20
9.2
19
9.2
15
9.2
Tabla 10. Tiempos de respuesta a un envío remoto por I2C.
Los tiempos de respuesta de la Tabla 10 fueron medidos a partir del momento en que en el
comportamiento de un agente origen comienza a hacer el envío externo por I2C a un agente
destino, hasta que finaliza la trama de datos de un evento enviado por el agente destino al
agente origen, como respuesta al evento que recibió. A partir de los resultados se deduce que
sin importar la frecuencia de envío de eventos, el tiempo que transcurre entre el envío de un
evento a un agente remoto y el final de la respuesta por parte de este, es constante.
74
Periodo de eventos (ms
usando vTaskDelay)
Periodo de la atención
al evento (ms)
0-9
10.4
10
11.2
12
12.8
15
16
20
21
25
26
30
31.2
35
36.8
40
41
Tabla 11. Tiempos de atención a los envíos externos de eventos generados periódicamente.
El tiempo de atención al evento obtenido en la Tabla 11, indica la periodicidad con la que se
ejecuta la función de tratamiento desde el comportamiento, es decir, el tiempo que transcurre
desde que se ejecuta la función hasta que vuelve a ejecutarse de nuevo, para diferentes
periodos de generación de eventos.
Debido a que la función de tratamiento corresponde a envíos externos por I2C, el menor tiempo
obtenido sigue siendo mayor al mínimo requerido para un envío remoto, el cual es 7.2 ms
aproximadamente incluyendo la confirmación (trama AckBESA), como se observa en la figura
19.
Entonces, para tiempos menores a 9 ms en la generación de eventos, el periodo en que se
atienden en los comportamientos se hace constante.
Se puede concluir que en las pruebas
realizadas el tiempo mínimo que requiere un comportamiento para ejecutar un envío externo
periódicamente es de 10.4ms aproximadamente.
En la Figura 25 se observan con mayor
claridad los resultados.
Periodo de atención al Evento Vs. Periodo de envío
50
ms
40
30
20
10
0
0
9
10
12
15
20
25
30
35
40
ms
Figura 25.
Tiempos de atención a eventos periódicos de envíos externos, desde los comportamientos.
75
Periodo de eventos (ms
usando vTaskDelay)
Periodo de la
atención al evento
(ms)
1
2
2
3
3
4
4
5
5
6
6
7.8
7
8
8
9
9
10
10
11.5
12
12
15
16
20
21
25
26
30
31
35
36.8
40
41
Tabla 12. Tiempos de atención a los envíos locales de eventos generados periódicamente.
Los tiempos obtenidos en la Tabla 12 a diferencia de los anteriores, corresponden a funciones de
tratamiento de envíos locales.
Por esta razón el periodo de atención es mucho menor; los
comportamientos se demoran menos en ejecutar un envío local que uno remoto.
Los datos
indican una variación de aproximadamente 1ms entre la periodicidad con la que se generan y se
atienden. Es importante recordar que para generar los eventos se esta utilizando una función
proporcionada por el RTOS, donde el tiempo que se introduce en el programa, varía ligeramente
con el tiempo real obtenido. En la Figura 26 se observan los datos obtenidos.
Periodo de atención al Evento Vs. Periodo de envío
50
ms
40
30
20
10
0
1
2
3
4
5
6
7
8
9 10 12 15 20 25 30 35 40
ms
Figura 26.
Tiempos de atención a eventos periódicos de envíos locales, desde los comportamientos.
76
Tipos de Errores en la Comunicación Externa
Un agente transmisor y un agente receptor ubicados en distintos contenedores
Las colas de recepción de los comportamientos y de los canales, de los dos agentes
intervinientes, son de tamaño 2. La tarea Prueba se encarga de generar eventos con un
determinado periodo. Sin embargo, no todos estos envíos son recibidos con éxito por el agente
transmisor, el cual envía eventos externos, según su capacidad de recepción y envío lo
permitan.
Los resultados plasmados en la figura 27 corresponden a 500 intentos de envío realizados por el
agente 'a' hacia el agente 'c' a través del bus i2c, para cada periodo de envío de eventos.
Figura 27.
Envíos exitosos vs periodo de envío, para dos agentes ubicados en distintos contenedores. Cada
punto representa un grupo de 100 envíos
Cuando el periodo de generación de los eventos es inferior a 10.4ms aproximadamente, el
agente 'a' no es capaz de transferirlos todos al bus I2C, por esta razón, muchos de esos eventos
no pueden ser atendidos por el agente 'c'. El número de envíos exitosos para periodos menores
a 10.4 ms aproximadamente es entonces aleatorio, según el estado de procesamiento del
microcontrolador, es decir, depende de qué tarea se esta ejecutando actualmente, y de cuáles
otras están pendientes por ser atendidas. Igual ocurre entonces con la frecuencia con la que el
comportamiento del agente 'c' puede ejecutar su acción.
La razón más frecuente por la cual los envíos no logran alcanzar con éxito su destino es debido a
que se cumple el tiempo límite de espera del mensaje de confirmación (TIME_OUT_ACK) del
agente receptor, en este caso el agente 'c'.
La segunda razón más frecuente por la cual los
envíos no se completan satisfactoriamente la transmisión,
es la finalización del tiempo de
espera para poder realizar envíos externos (TIME_OUT_SEND), debido a que otro agente ha
tomado anteriormente este semáforo. Los resultados que sustentan las anteriores afirmaciones
77
se pueden observar en las figuras 28, 29, 30 y 31. En estas figuras se ven los diferentes tipos
de errores que se encontraron para varias pruebas realizadas para diferentes periodos de
generación de eventos.
Porcentaje de tipos de
error
TIPOS DE ERRORES
3.5
3
2.5
2
TIME OUT ACK
TIME_OUT_SEND
1.5
1
0.5
0
-0.5 0
TIME_OUT_BUFFER
CHK_SUM_BAD
BUS_COLLITION
2
4
6
8
Número de la prueba
Figura 28.
Porcentaje de causas de error para un xDelayTime de 2ms.
Porcentaje de tipos de
error
TIPOS DE ERRORES
60
50
TIME OUT ACK
40
TIME_OUT_SEND
30
TIME_OUT_BUFFER
20
CHK_SUM_BAD
10
BUS_COLLITION
0
0
2
4
6
Número de la prueba
Figura 29.
Porcentaje de causas de error para un xDelayTime de 11ms.
Porcentaje de tipos de
error
TIPOS DE ERRORES
70
60
50
40
30
20
10
0
-10 0
TIME OUT ACK
TIME_OUT_SEND
TIME_OUT_BUFFER
CHK_SUM_BAD
BUS_COLLITION
2
4
6
Número de la prueba
Figura 30.
Porcentaje de causas de error para un xDelayTime de 14ms.
78
Porcentaje de tipos de
error
TIPOS DE ERRORES
70
60
50
40
30
20
10
0
TIME OUT ACK
TIME_OUT_SEND
TIME_OUT_BUFFER
CHK_SUM_BAD
BUS_COLLITION
0
2
4
6
Número de la prueba
Figura 31.
Porcentaje de causas de error para un xDelayTime de 20ms.
Cabe anotar que los tiempos de espera de los envíos, como el de la confirmación de
acknowledge BESA (TIME_OUT_ACK), el de espera a la liberación del semáforo de envío
(TIME_OUT_SEND) y el del buffer de transmisión (TIME_OUT_BUFFER), son valores que el
usuario, según su necesidad en la aplicación y la longitud de las tramas externas definidas,
puede llegar a modificar fácilmente.
Por la seguridad del funcionamiento de la plataforma se
recomienda hacer los cambios de acuerdo a las consideraciones hechas anteriormente y a las
instrucciones dadas en el archivo configuration.h.
Dos Agentes Transmisores en un Contendor y un Agente Receptor Ubicado en otro
Contenedor.
En este caso, son dos agentes, 'a' y 'b', los que envían eventos a un sólo agente 'c', ubicado en
otro contenedor. Como es de esperarse, cuando la frecuencia de generación de envíos es muy
alta (periodo pequeño), los eventos que logran llegar con éxito al agente externo son muy
pocos. A medida que el periodo de envío aumenta, es mayor el lapso de tiempo dado al agente
'c' para que atienda todos los mensajes recibidos y poder ejecutar las funciones asociadas.
El periodo de generación de eventos para el cual se alcanza un 100% de envíos exitosos, es
mayor que cuando sólo se tenía un agente transmisor (ver figura 32). Esto se debe a que ya
son dos los agentes que compiten por el uso del bus de comunicaciones, aumentando la carga
de procesamiento e incrementado como consecuencia el número de posibles errores en los
envíos. Como lo muestra la figura 32, solamente cuando el retardo en la tarea Prueba alcanza
un valor de 26ms, el 100% de las transferencias se culminan exitosamente.
79
Envios Exitosos por I2C
120.00
100.00
%
80.00
60.00
40.00
20.00
0.00
0
5
10
15
20
25
30
Periodo de Generación de Eventos (ms)
Figura 32.
Envíos exitosos vs periodo de envío, para 2 agentes productores y un consumidor.
El valor del periodo de envío correspondiente a 26ms es aproximadamente el doble del valor en
el cual se estabilizaba el sistema cuando existía un sólo productor y un sólo consumidor. Este
era un valor esperado, ya que se están generando el doble de envíos por parte de los agentes 'a'
y 'b', por lo cual se aumenta también la carga de recepción para el agente 'c'.
Tipos de Errores
(Periodo de Envio = 3 ms)
%
40.00
30.00
TIME OUT ACK
20.00
TIME OUT SEND
10.00
TIME OUT BUFFER
CHK SUM_BAD
0.00
0
2
4
6
BUS COLLITION
Tipo de Muestras
Figura 33.
Porcentaje de Causas de error para un xDelayTime de 3 ms.
80
Tipos de Errores
(Periodo de Envio = 10 ms)
30.00
TIME OUT ACK
%
20.00
TIME OUT SEND
10.00
TIME OUT BUFFER
0.00
-10.00 0
2
4
6
CHK SUM_BAD
BUS COLLITION
Tipo de Muestras
Figura 34.
Porcentaje de Causas de error para un xDelayTime de 10 ms.
Tipos de Errores
(Periodo de Envio = 14 ms)
60.00
TIME OUT ACK
%
40.00
TIME OUT SEND
TIME OUT BUFFER
20.00
CHK SUM_BAD
0.00
-20.00
0
2
4
6
BUS COLLITION
Tipo de Muestras
Figura 35.
Porcentaje de Causas de error para un xDelayTime de 14 ms.
Las causas por las cuales se presentan errores en la comunicación son variadas. Sin embargo se
observa que de nuevo la causa que presenta mayor porcentaje en la aparición de errores de la
comunicación es el agotamiento del tiempo de espera del mensaje de confirmación BESA
(TIME_OUT_ACK). Cuando son dos los productores que ubican eventos en el bus i2c, aumentan
las colisiones, y por consiguiente es más frecuente la recepción de tramas con alteración en los
bits, es decir, un checksum erróneo. También es considerable el número de casos en los que se
agota el tiempo de espera para la liberación del buffer de envío. Las figuras 33, 34 y 35
muestran la distribución de las causas de los errores, para los tiempos en los que más se
presentaron.
4.2.3. Pruebas de Interrupciones
Para las pruebas realizadas con Interrupciones se programó un modulo del microcontrolador
(Timer4) utilizado para que genere las interrupciones periódicas.
Desde la rutina de
Interrupción se hace el envío de un evento a un agente local, cambiando el estado de una señal
en el momento de enviarlo. Cuando el evento es recibido por el agente y este ejecuta la función
asociada al comportamiento respectivo, se cambia de nuevo una bandera indicando su correcta
81
recepción. Los tiempos de respuesta fueron calculados promediando entre el mayor y el menor
tiempo obtenido en el osciloscopio.
Se realizaron cinco series de cien envíos periódicos para cada tiempo seleccionado, calculando el
promedio de los envíos correctos, los fallidos y el número de veces que se generó la
interrupción, después de las cinco repeticiones. Cada repetición termina en el momento en que
la tarea vAdaptor, encargada de recibir los eventos provenientes de interrupciones y enviarlos al
agente destino, intenta 100 envíos al agente, sin importar si fueron exitoso o no.
Tiempo de
Interrupción
(ms)
Promedio
Envíos
Correctos
Promedio
Envíos
Fallidos
Promedio
Interrupciones
Tiempo
Promedio
de Respuesta
(ms)
10,48
100
0
100
3,7
9,83
100
0
100
3,7
9,17
100
0
100
3,7
8,51
100
0
100
3,7
7,86
100
0
100
3,7
7,2
100
0
100
3,7
6,55
100
0
100
3,7
5,89
100
0
100
3,7
5,24
100
0
100
3,7
4,58
100
0
100
3,7
3,93
100
0
100
3,6
3,27
100
0
100
3,6
2,62
86
14
100
3,6
1,96
68
32
113
3,6
1,31
62
38
140
3,6
0,65
41
59
231
3,6
0,32
27
73
325
3,6
Tabla 13. Promedio de Envíos exitosos y fallidos generados desde una rutina de interrupción a un agente local.
Los resultados obtenidos en la Tabla 13, indican que para tiempos de interrupción menores de
3,27ms aproximadamente, los envíos realizados al agente desde una interrupción no son
atendidos en su totalidad. Para tiempos inferiores, no todos los envíos generados por la rutina
de interrupción llegan a la cola de recepción de la tarea vAdaptor (cuando el tamaño de la cola
de recepción es uno), y no todos los que son recibidos pueden ser enviados al agente destino.
Es posible observar que desde envíos periódicos cada 1,96ms aproximadamente, se necesitan
mayor número de envíos desde la rutina de interrupción para generar 100 envíos desde la tarea
vAdaptor, bajando notablemente el nivel de efectividad a medida que el tiempo se hace más
pequeño.
82
Envíos desde Interrupciones
350
300
Promedio Envíos
Correctos
250
200
Promedio Envíos
Fallidos
150
100
Promedio
Interrupciones
50
0.32
0.65
1.31
1.96
2.62
3.27
3.93
4.58
5.24
5.89
6.55
7.2
7.86
8.51
9.17
9.83
10.5
0
(m s)
Figura 36.
Envíos generados desde interrupciones periódicas.
A su vez, se concluye que una vez la tarea recibe los eventos provenientes de Interrupción, para
tiempos inferiores a 3,27ms aproximadamente, los envíos realizados al agente no son 100%
exitosos. El número de veces que encuentra la cola de recepción del canal del agente ocupada
(cola de recepción de tamaño uno), aumenta cuando el tiempo se hace inferior. Esto se debe a
que el tiempo de procesamiento necesario para que el canal atienda el evento no es suficiente
cuando el periodo de las interrupciones es muy pequeño; además las interrupciones propias del
funcionamiento del RTOS, sobrecargan también el sistema.
En la Figura 36 se observa claramente la tendencia de aumento para pequeñas reducciones en el
tiempo, de los envíos fallidos desde la tarea hacia el agente y del número de interrupciones
necesarias para generar cien envíos exitosos a la tarea vAdaptor.
Para tiempos inferiores al mínimo utilizado en las pruebas, el sistema se torno inestable y no
funcionó correctamente.
Por lo anterior es recomendable utilizar las interrupciones para la
generación de eventos aleatorios.
Si se quieren generar envíos periódicos a un agente, se
recomienda crear una tarea adicional (la tarea Prueba por ejemplo), de mayor prioridad si es el
caso, de donde se realicen los envíos cada determinado tiempo utilizando la función
vTaskDelay ( t (ms) ).
83
4.3. Aplicación de Demostración
Para demostrar el funcionamiento de la plataforma desarrollada, se establecieron aspectos que
debían tenerse en cuenta para demostrar cada una de las características y cualidades de la
plataforma.
Además, esta aplicación puede servir como punto de partida para el diseño de
nuevas aplicaciones, ya que le da al programador una idea de cómo puede abordar los
problemas que desee solucionar con enfoque multi-agente en un sistema distribuido.
Las siguientes son las características presentes en la aplicación:
•
Sistema distribuido.
•
Evento sincrónico.
•
Evento asincrónico.
•
Recursos compartidos.
•
Varios agentes.
Situación Hardware
Se desea medir y mostrar la amplitud y el promedio de una señal que se encuentra alejada
físicamente de la interfaz con el usuario. El promedio y la amplitud desean ser mostrados en dos
pantallas de LED que son controladas por microcontroladores diferentes. Como la señal que se
está observando presenta varios rangos de frecuencia, se debe poder cambiar la frecuencia de
muestreo para obtener un cálculo más preciso.
Inicialmente se determinan las capacidades ofrecidas por el hardware con el que se cuenta. El
microcontrolador que contiene el ADC debe ubicarse cerca de la señal que se desea medir,
igualmente sucede con la pantalla de LED. La otra pantalla esta ubicada en otro lugar para
mostrar el periodo de la señal, junto con un interruptor que cambiará el periodo de muestreo de
la señal observada.
Diagrama de Agentes
Debido a que la lectura del ADC se realiza de forma sincrónica, se implementará entonces como
una tarea periódica, y no dentro de una rutina de interrupciones. El valor instantáneo de la
lectura será mostrado en la pantalla de LED. También se calcula el promedio de dicha señal para
ser enviado al microcontrolador que contiene la otra pantalla. Una posible solución a este
problema, con enfoque multiagente, en este caso para la plataforma BESA-SE ME encuentra en
la figura 37.
84
Figura 37.
Distribución de los agentes y sus respectivos comportamientos para la aplicación de demostración.
Cuando la información mostrada por la pantalla promedio no es estable debido a la frecuencia de
muestreo, el usuario puede oprimir la tecla de cambio de frecuencia, de esta forma se modifica
el estado de este agente, y determinado comportamiento realiza un envío al agente del ADC,
para que incremente la frecuencia de muestreo, logrando así una comunicación permanente
entre los agentes y todos sus recursos, para lograr un resultado optimo. La distribución de los
agentes se muestra en la figura 38.
Finalmente, para probar la comunicación entre más de dos contenedores, se conectó un tercer
microcontrolador al bus de comunicaciones, el cual genera envíos de evento tipo 1, el cual es el
correspondiente a la lectura del adc. Estos envíos se los hace a uno de los agentes interfaz, que
también recibe información del agente calculador.
El código fuente de esta aplicación se encuentra en el anexo B, en la carpeta demo_besa, dentro
de la cual se encuentra como proyecto base para iniciar cualquier desarrollo.
85
Figura 38.
Distribución de los agentes según los recursos físicos disponibles.
86
5. CONCLUSIONES
A partir de las experiencias recogidas durante el desarrollo e implementación de la plataforma
BESA-ME y de los resultados obtenidos en las pruebas realizadas, se ha podido llegar a dos
grupos generales de conclusiones, referentes al producto desarrollado y a los sistemas MultiAgente en general.
BESA-Micro Edition se ofrece como un enfoque que facilita la solución de problemas complejos.
La manera en que permite esquematizar y dividir los grandes objetivos en pequeños oficios,
para luego distribuirlos en agentes dedicados y, lo más importante, implementarlos rápidamente
sobre plataformas hardware, permite brindar ahora una forma de afrontar problemas de control.
Los diseñadores de hardware dedicado pueden contar con un nuevo modelo de programación,
que muy seguramente con el paso del tiempo, desplazará los antiguos métodos de diseño
electrónico digital.
La implementación del modelo BESA-Micro Edition para dispositivos
microcontroladores permite la creación de aplicaciones orientadas a sistemas Multi-Agente de
una manera sencilla y eficiente. El tiempo invertido en el desarrollo del código de aplicación se
disminuye una vez se conozca la plataforma, se entienda el concepto Multi-Agente y cómo
enfocarlo en una aplicación determinada.
En BESA-ME se redujo al máximo el uso de variables globales en el sistema sin sacrificar
robustez y seguridad. Con lo cual se maximizó la memoria de datos libre que puede ser usada
por las tareas y en consecuencia se aumentó el número de comportamientos y agentes que
pueden ser creados por el programador.
La creación de tareas adicionales como los son el adaptador de interrupciones a eventos BESA y
el administrador de mensajes externos, no hacen parte del modelo abstracto BESA, sin
embargo, brindan mayor robustez al sistema y gran utilidad al programador cuando la aplicación
lo requiera, evitando trabajo adicional por parte de él.
El tiempo que tarda la plataforma en iniciar determinada función de tratamiento, luego de la
aparición de un evento (tiempo de respuesta), es una variable importante en cualquier sistema
en que se requiera control de un ambiente. Sin embargo en BESA-ME la prioridad está en que
todos los eventos lleguen a su destino para luego ser atendidos. Para lograrlo BESA-ME permite
el uso de prioridades y ejecuta concurrentemente las tareas asignadas gracias al RTOS que la
soporta. De esta forma se asegura que todos los eventos se reciben y son procesados dando
apariencia de paralelismo, respondiendo con mayor eficiencia a los sucesos ocurridos interna y
externamente al sistema.
87
La plataforma fue desarrollada procurando siempre una alta robustez, con lo cual se sacrificó en
aspectos como velocidad de respuesta y memoria libre, para facilitarle así al usuario, la toma
de decisiones en el momento en que el sistema detecte las fallas. Los errores que se presenten
en el sistema, BESA-ME tiene la capacidad, no sólo de detectarlos, sino de darle la oportunidad
al programador de tomar la decisión más prudente según su aplicación. Los posibles errores que
se puedan presentar en el sistema son errores de comunicación, falla en la detección de agentes
o en el envío y recepción de eventos.
Las restricciones presentadas por los microcontroladores en cuanto a recursos físicos, en
especial la limitación de memoria disponible, fue de los factores más importantes a tenerse en
cuenta en el momento de realizar cambios respecto al modelo original para adaptarlo al
hardware seleccionado. Las modificaciones realizadas estuvieron orientadas a la adaptación de
BESA a las estructuras y servicios prestados por el RTOS, y al ahorro de recursos limitados.
Estos cambios no representaron una variación en cuanto al concepto planteado por el modelo
abstracto BESA.
Estas mismas restricciones existentes, hacen que BESA-Micro Edition cuente con un número
limitado de agentes y comportamientos en un sólo contenedor, tal como se observa en el
protocolo de pruebas.
Sin embargo esta necesidad es resuelta al implementarlo como un
sistema distribuido, incluyendo nuevos contenedores (microcontroladores) en el sistema. Esta
expansión del sistema sólo requiere modificaciones en la configuración del sistema, facilitando
así al usuario la creación de aplicaciones complejas para ambientes distribuidos.
En BESA-Micro Edition sólo se implementó la creación estática de agentes, a diferencia del
modelo abstracto donde se plantea la gestión del ciclo de vida de los agentes. Esta restricción
depende directamente del modelo de manejo de memoria utilizado por el RTOS seleccionado,
que no permite liberar memoria una vez ha sido reservada, imposibilitando la creación,
destrucción y movilidad de los agentes entre diferentes contenedores, de forma dinámica.
La portabilidad de la plataforma BESA-ME a otra familia de microcontroladores, esta
directamente relacionada con el RTOS seleccionado.
Debe verificarse que el RTOS se pueda
implementar en el dispositivo escogido, de no ser así, deben realizarse los cambios necesarios
para lograr su adaptación y garantizar su funcionamiento. Además, el procesador debe tener la
capacidad suficiente de memoria para soportar la plataforma y un puerto de comunicaciones
para permitir que el sistema sea distribuido.
La implementación del protocolo de comunicación escogido se realizó de tal forma que la
adopción de uno nuevo no implique grandes cambios en la plataforma.
88
Sin embargo es
indispensable respetar la estructura y el procedimiento establecido a nivel de trama de datos,
asegurando así la correcta operación del nivel superior. Los cambios a realizar serán entonces
mínimos, dependiendo de las limitaciones y ventajas ofrecidas por cada protocolo de
comunicación en particular.
Proyecciones Futuras
Dentro del desarrollo futuro de la plataforma BESA-ME planteamos los siguientes proyectos:
•
Diseño e implementación de mecanismos que permitan la creación dinámica de agentes.
Esta característica será de gran utilidad para aplicaciones de inteligencia artificial.
•
Desarrollo de un directorio de páginas amarillas que acerque más el modelo BESA-ME al
BESA.
•
Inclusión de mecanismos para la gestión del ciclo de vida de los agentes.
•
Adaptación de otros protocolos de comunicación, como blue tooth, wi-fi, para proveer la
comunicación entre contenedores.
•
Diseño e implementación de un módulo de comunicación para conectar una plataforma
diseñada sobre BESA-ME a una construida sobre BESA en versión Java permitiendo
salida a una red de computadores.
89
90
6. BIBLIOGRAFIA
CASTO GUTIÉRREZ, Alberto, “Migración de un Sistema Operativo De Tiempo Real, MaRTE OS, a
un microcontrolador”, http://marte.unican.es/alberto_slides.ppt, Septiembre 5 de 2004.
Foundation For Intelligent Physical Agents, http://www.fipa.org, Noviembre 5 del 2004.
FreeRTOSTM, www.freertos.org. Mayo 25 de 2005.
GONZALEZ, Enrique, AVILA, Jamir, BUSTACARA, César. “BESA” Bogotá, Colombia. 2003.
LIU, Jiming. “Multi – Agent Robotic Systems”. CRC Press, Boca Ratón, Fl. 2001.
MICROCHIP, PIC18FXX2 Data Sheet, Microchip Technology Inc 2002.
MICROCHIP, PIC18F6520/8520/6620/8620/6720/8720 Data Sheet, Microchip Technology Inc
2002.
MICROCHIP, Inter-Integrated Circuit™ (I2C™). Microchip Technology Inc 2004.
MICROCHIP, I2C™ Master Mode, Overview and Use of the PICmicro® MSSP I2C Interface with a
24xx01x EEPROM. Abril 15 de 2005.
MILENKOVICH, Milan.
“Sistemas Operativos: Conceptos y Diseño”. Mc. Graw Hill, Madrid,
España. 1998.
Robocup Federation, “RoboCup Home Page”. http://www. robocup.org.
SALVOTM, http://www.pumpkinc.com, Febrero 15 de 2004.
SIRP, Sistemas Inteligentes, Robótica y Percepción. Grupo de Investigación de la Faculta de
Ingeniería Electrónica, Pontifica Universidad Javeriana.
STALLINGS, William. “Sistemas Operativos”. Prentice Hall. Madrid, España. 2001.
WEISS, Gerhard. “Multiagent systems: A modern approach to Distributed Artificial Intelligence”.
Masachussets, U.S.A 1999.
91
92
7. ANEXOS
ANEXO A. MANUAL DEL USUARIO.
93
ANEXO B. CODIGO DE PROGRAMACION.
El código completo que se desarrolló se encuentra en el CD que se adjunta con este
documento. Los archivos propios de BESA-ME SE encuentran a continuación.
94
ANEXO C. CAMBIOS REALIZADOS EN EL RTOS (freeRTOSTM).
CAMBIO EN EL ARCHIVO LINKER
Código Original (Para PIC18F452)
// $Id: 18f8620.lkr,v 1.1 2003/12/16 14:53:08 GrosbaJ Exp $
// File: 18f8620.lkr
// Sample linker script for the PIC18F8620 processor
LIBPATH .
FILES c018i.o
FILES clib.lib
FILES p18f8620.lib
CODEPAGE
NAME=vectors
START=0x0
END=0x29
CODEPAGE
NAME=page
START=0x2A
END=0xFFFF
CODEPAGE
NAME=idlocs
START=0x200000
END=0x200007
PROTECTED
CODEPAGE
NAME=config
START=0x300000
END=0x30000D
PROTECTED
CODEPAGE
NAME=devid
START=0x3FFFFE
END=0x3FFFFF
PROTECTED
CODEPAGE
NAME=eedata
START=0xF00000
END=0xF003FF
PROTECTED
ACCESSBANK NAME=accessram
START=0x0
END=0x5F
DATABANK
NAME=gpr0
START=0x60
END=0xFF
DATABANK
NAME=gpr1
START=0x100
END=0x1FF
DATABANK
NAME=gpr2
START=0x200
END=0x2FF
DATABANK
NAME=gpr3
START=0x300
END=0x3FF
DATABANK
NAME=gpr4
START=0x400
END=0x4FF
DATABANK
NAME=gpr5
START=0x500
END=0x5FF
DATABANK
NAME=gpr6
START=0x600
END=0x6FF
DATABANK
NAME=gpr7
START=0x700
END=0x7FF
DATABANK
NAME=gpr8
START=0x800
END=0x8FF
DATABANK
NAME=gpr9
START=0x900
END=0x9FF
DATABANK
NAME=gpr10
START=0xA00
END=0xAFF
DATABANK
NAME=gpr11
START=0xB00
END=0xBFF
DATABANK
NAME=gpr12
START=0xC00
END=0xCFF
DATABANK
NAME=gpr13
START=0xD00
END=0xDFF
DATABANK
NAME=gpr14
START=0xE00
END=0xEFF
ACCESSBANK NAME=accesssfr
START=0xF60
END=0xFFF
SECTION
ROM=config
NAME=CONFIG
PROTECTED
PROTECTED
STACK SIZE=0x100 RAM=gpr14
Código Modificado ( Para PIC18f8720)
// $Id: 18f8620.lkr,v 1.1 2003/12/16 14:53:08 GrosbaJ Exp $
// File: 18f8620.lkr
// Sample linker script for the PIC18F8620 processor
LIBPATH .
FILES c018i.o
FILES clib.lib
FILES p18f8620.lib
CODEPAGE
NAME=vectors
START=0x0
95
END=0x29
PROTECTED
CODEPAGE
NAME=page
START=0x2A
END=0xFFFF
CODEPAGE
NAME=idlocs
START=0x200000
END=0x200007
PROTECTED
CODEPAGE
NAME=config
START=0x300000
END=0x30000D
PROTECTED
CODEPAGE
NAME=devid
START=0x3FFFFE
END=0x3FFFFF
PROTECTED
CODEPAGE
NAME=eedata
START=0xF00000
END=0xF003FF
PROTECTED
START=0x0
END=0x5F
ACCESSBANK NAME=accessram
DATABANK
NAME=BIG_BLOCK
START=0X60 END=0XDFF
ACCESSBANK NAME=accesssfr
START=0xF60
SECTION
ROM=config
NAME=CONFIG
STACK SIZE=0x60
END=0xFFF
PROTECTED
RAM=BIG_BLOCK
CAMBIO EN EL CÓDIGO DE LA TAREA IdleTask
Este archivo no se modificó en su totalidad. El cambio mostrado a continuación representa solo a
la IdleTask, que hace parte del archivo tasks.c propio de freeRTOSTM.
Código Original (Para cualquier aplicación)
/*----------------------------------------------------------* The Idle task.
*----------------------------------------------------------*/
static void prvIdleTask( void *pvParameters )
{
/* Stop warnings. */
( void ) pvParameters;
for( ;; )
{
/* See if any tasks have been deleted. */
prvCheckTasksWaitingTermination();
if( sUsingPreemption == pdFALSE )
{
/* If we are not using preemption we keep forcing a task switch to
see if any other task has become available.
If we are using
preemption we don't need to do this as any task becoming available
will automatically get the processor anyway. */
taskYIELD();
}
}
} /*lint !e715 pvParameters is not accessed but all task functions require the same prototype. */
96
Código Modificado (Para BESA-ME)
/*----------------------------------------------------------* The Idle task.
*----------------------------------------------------------*/
static void prvIdleTask( void *pvParameters )
{
/* Stop warnings. */
( void ) pvParameters;
if(NUM_OF_CONTAINERS>1)
{
Config_Extern_Communication();
}
if(CONTAINER_ID==0X60)
{
OpenTimer_4();
}
for( ;; )
{
/* See if any tasks have been deleted. */
prvCheckTasksWaitingTermination();
if( sUsingPreemption == pdFALSE )
{
/* If we are not using preemption we keep forcing a task switch to
see if any other task has become available.
If we are using
preemption we don't need to do this as any task becoming available
will automatically get the processor anyway. */
taskYIELD();
}
}
} /*lint !e715 pvParameters is not accessed but all task functions require the same prototype. */
Proyecto Final de BESA-ME en MPLAB
La inclusión en el proyecto de MPLAB de archivos propios de BESA-ME implica la inclusión de los
archivos .h. El anexo A (manual de usuario) muestra cuales son los archivos que debe contener
el proyecto que el programador debe incluir para su aplicación.
main_besa que se muestra a continuación.
/**************************************************************
BESA-ME v. 1.0 - Junio 2005
PONTIFICIA UNIVERSIDAD JAVERIANA-INGENIERÍA ELECTRÓNICA
David Magín FLÒREZ RUBIO
Juan Manuel ORTIZ GÓMEZ
Guillermo Andrés RODRÍGUEZ CANTOR
97
Uno de estos archivos es el
BESA-ME v. 1.0 Fue desarrollada sobre freeRTOS (marca registrada)
**************************************************************/
/* Scheduler include files. */
#include "projdefs.h"
#include "portable.h"
#include "task.h"
#include "semphr.h"
/* Demo app include files. */
#include "partest.h"
/* BESA-ME include files. */
#include "public_besa.h"
#include "user_besa.h"
/* Creates the tasks, then starts the scheduler. */
void main( void )
{
/* Initialise the required hardware. */
vParTestInitialise();
vPortInitialiseBlocks();
/* Initialise BESA (agents, beahviors, events, etc). */
SetupContainer();
Inicio();
/* Start the scheduler.
Will never return here. */
vTaskStartScheduler( portUSE_PREEMPTION );
}
/*-----------------------------------------------------------*/
CAMBIO EN EL CÓDIGO DE PORTMACRO.h
Las siguientes líneas corresponden a una de las secciones de configuración de freeRTOS en el
archivo portmacro.h, adecuadas para el contexto de este proyecto.
/* These are the only definitions that can be modified!. */
#define portUSE_PREEMPTION
1
#define portTICK_RATE_HZ
( ( portTickType ) 1000 )
#define portCPU_CLOCK_HZ
( ( unsigned portLONG ) 20000000 )
#define portMAX_PRIORITIES
(1)
#define portMINIMAL_STACK_SIZE
( 110 )
#define portGLOBAL_INT_ENABLE_BIT
0x80
#define portTOTAL_HEAP_SIZE
( 3100)
98
Descargar