Software de Vuelo para Nano-Satélite Cubesat
Software de Vuelo para Nano-Satélite Cubesat
net/publication/323919133
CITATION READS
1 10,285
1 author:
Carlos Gonzalez
German Aerospace Center (DLR)
12 PUBLICATIONS 29 CITATIONS
SEE PROFILE
All content following this page was uploaded by Carlos Gonzalez on 21 March 2018.
PROFESOR GUÍA:
MARCOS DÍAZ QUEZADA
MIEMBROS DE LA COMISIÓN:
CLAUDIO ESTÉVEZ MONTERO
ALEX BECERRA SAAVEDRA
SANTIAGO DE CHILE
AÑO 2013
RESUMEN DE LA MEMORIA PARA OPTAR
AL TÍTULO DE INGENIERO CIVIL ELÉCTRICO
POR: CARLOS EDUARDO GONZÁLEZ CORTÉS
FECHA: AÑO 2013
PROF. GUÍA: SR. MARCOS DÍAZ QUEZADA
El diseño del software consiste en una estructura de tres capas, que consigue dividir el
problema convenientemente. La de más bajo nivel considera los controladores de hardware,
la capa intermedia alberga al sistema operativo, y la de nivel superior, contiene los detalles
de la aplicación requerida específicamente para este sistema. Para la arquitectura de la capa
de aplicación, se estudia y aplica el concepto de patrón de diseño, en específico, se realiza
una adaptación de command pattern. De esta manera, el satélite se concibe como un ejecutor
de comandos genéricos y se obtiene una solución mantenible, modificable y extensible en
el tiempo, mediante la programación de los comandos concretos que sean requeridos. La
implementación se realiza sobre un PIC24F y considera controladores para los periféricos
I2C, RS232 y SPI, así como para los subsistemas de radiocomunicaciones y energía. Se decide
utilizar el sistema operativo FreeRTOS, como capa intermedia, lo que permite contar con el
procesamiento concurrente de tareas, herramientas de temporización y sincronización. Se ha
puesto especial énfasis en la implementación de la arquitectura planteada para la capa de
aplicación, consiguiendo un software capaz de ejecutar una serie de comandos, programados
para cumplir los requerimientos operacionales del proyecto, lo cual representa el método
principal para extender sus funcionalidades y adecuarse a futuras misiones.
i
A mis padres Carlos González Espeleta y Paula Cortés González por que les debo todo lo
que soy, porque gracias a su gran esfuerzo y apoyo incondicional he podido llegar a estas
instancias en la vida, los amo. A mis hermanas, siempre estaré con ustedes.
ii
Agradecimientos
A todos los miembros del proyecto SUCHAI, porque este trabajo integra, de manera
directa o indirecta, el esfuerzo de todo el equipo, se agradece y reconoce la labor de cada
uno. En especial a Tomás Opazo, cuya contribución al proyecto ha sido fundamental, por ser
un gran compañero y amigo. A Francisco Reyes, quien desarrolló el software del sistema de
energía y la consola serial. Al equipo de comunicaciones: Felipe Troncoso, Sebastián Derteano
y Camilo Rojas, grandes amigos. Al equipo de energía: Juan Carlos Piña, Pablo Bilbao y
Francisco Reyes, grandes amigos y compañeros. Participar en este proyecto ha sido la mejor
experiencia en mi formación universitaria, tanto por los desafíos que presentó, como por el
excelente grupo humano que se formó entorno al laboratorio.
A todos los miembros del laboratorio ALGES, por su compresión y apoyo durante en el
desarrollo de la memoria. A Miguel Patiño, por su gran disposición y ayuda, siempre con una
solución a la mano.
iii
Tabla de contenido
1. Introducción 1
1.1. Objetivos generales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2. Objetivos específicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3. Estructura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2. Marco teórico 4
2.1. Sistemas embebidos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.1.1. Microcontroladores PIC . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2. Sistemas operativos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2.1. Sistemas operativos de tiempo real . . . . . . . . . . . . . . . . . . . 10
2.3. Ingeniería de software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.3.1. Calidad de software . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.3.2. Patrones de diseño . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.3.3. Arquitecturas de software basadas en patrones . . . . . . . . . . . . . 18
2.4. Pequeños satélites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.4.1. Satélites tipo Cubesat . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.5. Proyecto SUCHAI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
4. Implementación 49
4.1. Ambiente de desarrollo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
4.1.1. Computadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
4.1.2. Control de versiones . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
iv
4.1.3. IDE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
4.1.4. Compilador y programador . . . . . . . . . . . . . . . . . . . . . . . . 51
4.1.5. Tarjeta de desarrollo . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
4.2. Organización del proyecto . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
4.2.1. Directorios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
4.2.2. Configuración del IDE . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.2.3. Sistema de documentación . . . . . . . . . . . . . . . . . . . . . . . . 54
4.3. Controladores de hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
4.4. Sistema operativo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
4.5. Aplicación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.5.1. Implementación del patrón de diseño . . . . . . . . . . . . . . . . . . 60
4.5.2. Comandos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
4.5.3. Repositorio de comandos . . . . . . . . . . . . . . . . . . . . . . . . . 65
4.5.4. Repositorios de estados . . . . . . . . . . . . . . . . . . . . . . . . . . 66
4.5.5. Implementación del dispatcher . . . . . . . . . . . . . . . . . . . . . . 70
4.5.6. Implementación del executer . . . . . . . . . . . . . . . . . . . . . . . 74
4.5.7. Implementación de listeners . . . . . . . . . . . . . . . . . . . . . . . 76
4.5.8. Funcionamiento de la aplicación . . . . . . . . . . . . . . . . . . . . . 77
4.6. Específico al proyecto SUCHAI . . . . . . . . . . . . . . . . . . . . . . . . . 81
4.6.1. Consola serial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
4.6.2. Plan de vuelo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
4.6.3. Comunicaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
4.6.4. Inicialización del sistema . . . . . . . . . . . . . . . . . . . . . . . . . 83
5. Pruebas y resultados 86
5.1. Pruebas de rendimiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
5.1.1. Estadísticas del programa . . . . . . . . . . . . . . . . . . . . . . . . 86
5.1.2. Estadísticas de uso de memoria . . . . . . . . . . . . . . . . . . . . . 86
5.1.3. Estadísticas de uso del procesador . . . . . . . . . . . . . . . . . . . . 87
5.2. Pruebas de integración . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
5.2.1. Configuración . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
5.2.2. Resultados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
6. Conclusiones 109
6.1. Conclusiones generales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
6.2. Limitaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
6.3. Trabajos futuros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Glosario 113
Bibliografía 114
v
Índice de tablas
vi
Índice de ilustraciones
vii
4.12. Diagrama de flujo para taskCommunications . . . . . . . . . . . . . . . . . . 84
4.13. Diagrama de flujo para taskDeployment . . . . . . . . . . . . . . . . . . . . . 85
viii
Capítulo 1
Introducción
El computador a bordo del satélite debe ejecutar un programa que permita desarrollar
todas las acciones que requiere la misión. Esta aplicación se denomina sotfware de vuelo y su
objetivo es controlar el satélite, ejecutar operaciones específicas durante el vuelo y permitir
la comunicación con la estación terrena para la descarga de datos y subida de telecomandos,
entre otras tareas fundamentales. Su desarrollo se realiza siguiendo una metodología ordenada
que consta de tres etapas: diseño, implementación y pruebas.
La etapa de diseño consiste en explicitar los requerimientos del sistema y generar una
arquitectura de software que representa de manera conceptual la solución a implementar, en
esta etapa se hace un uso extensivo del concepto de patrones de diseño para conseguir la
solución al problema planteado. Durante la implementación se toma la solución conceptual y
se programa el software utilizando las herramientas adecuadas a la plataforma consiguiendo
una plataforma base que consta de controladores de hardware, sistema operativo y la apli-
1
cación específica a la misión. Las pruebas se desarrollan sobre el sistema integrado en sus
tres subsistemas básicos mediante la puesta en funcionamiento del satélite por un tiempo
prolongado usando la técnica denominada hardware on the loop simulation adecuada para
probar sistemas embebidos complejos.
El resultado de este trabajo es la base para obtener un vehículo espacial con las funciones
fundamentales para su operación y así dejar establecido el flujo a seguir para agregar más
subsistemas.
Los objetivos específicos del proyecto definen las tareas que permiten cumplir el objetivo
general del proyecto y se enumeran a continuación:
• Diseñar la arquitectura de software de vuelo del satélite, que permita cumplir los re-
querimientos operacionales de la misión.
• Implementar controladores de hardware para el microcontrolador PIC24F y sus periféri-
cos de comunicaciones Inter Integrated Circuit (I2C), Universal Asynchronous Receiver-
Transmitter (UART) y Serial Peripheral Interface (SPI), para poder integrar el resto
de los subsistemas del satélite.
2
• Integrar un sistema operativo de tiempo real y multitarea en el sistema embebido.
• Implementar la arquitectura diseñada para la aplicación que controla la operación del
satélite.
• Integrar el sistema de comunicaciones y energía al software de vuelo, para contar con
el sistema base de la misión satelital.
• Pruebas del sistema integrado, para verificar el cumplimiento de los requerimientos
funcionales.
1.3. Estructura
3
Capítulo 2
Marco teórico
Los sistemas embebidos, a diferencia de un computador personal que es usado con fines
generales para una amplia variedad de tareas, son sistemas computacionales normalmente
utilizados para atender una cantidad limitada de procesos; realizar tareas específicas o dotar
de determinada inteligencia a un sistema más complejo. Está compuesto por uno o más micro-
controladores pequeños , los que cuentan con periféricos para manejar diferentes protocolos
de comunicación, conversores análogo-digital, timers, puertos de entrada y salida digitales,
todos integrados en un mismo chip para ahorrar espacio y energía. Parte fundamental de
un sistema embebido es el software que provee la funcionalidad final. Usualmente se usa el
término firmware para referirse a este código con que se programa el microcontrolador, el que
por lo general es específico para la plataforma de hardware y se relacionan a muy bajo nivel.
A diferencia de un computador de propósito general, donde el usuario puede cargar una serie
de programas para un amplio rango de usos, acá no se tiene la capacidad de re-programarlo
fuera de las posibilidades que el desarrollador ha brindado al sistema [4].
Para el diseño de sistemas embebidos se deben considerar ciertos aspectos que los diferen-
cian de otros tipos de sistemas de computacionales, tales como [5]:
4
• El diseño de software para sistemas embebidos requiere una interacción de bajo nivel.
Existe una amplia gama de plataformas de hardware para desarrollar sistemas em-
bebidos y se requiere interactuar también con una variedad de dispositivos externos.
Por esto, se requiere desarrollar capas de controladores de periféricos que oculten las
diferencias de hardware a la aplicación final del sistema.
• Es importante considerar aspectos de seguridad y confiabilidad del sistema durante
todo su desarrollo debido a que la mayoría de los sistemas embebidos son usados para
controlar otros sistemas críticos en diversos procesos.
Memoria Memoria
Familia Instrucciones Datos Velocidad Periféricos Usos
Programa RAM
Espacio reducido, bajo costo. Lógica digital,
PIC10 12 bit 8 bit 512 Words 64 Bytes 16MHz IO, ADC
control IO
Bajo costo. Logica digital, control IO,
PIC12 12 bit 8 bit 4 Kwords 256 Bytes 32MHz IO, ADC, TIMER, USART
sensores
Control, sensores, recolección de datos,
PIC16 14 bit 8 bit 16 Kwords 2 Kbytes 48MHz IO, ADC, TIMER, USART, PWM
display, interfaz serial.
IO, ADC, TIMER, USART, PWM, Control, sensores, datos, interfaz serial,
PIC18 16 bit 8 bit 64 Kwords 4 Kbytes 64MHz
USB, CAN, ETHERNET, LCD ethernet, display.
5
Arquitectura.
Poseen un juego de instrucciones Reduced Instruction Set Computing (RISC) (80 instruc-
ciones) de ancho fijo en 24 bits que en su mayoría se ejecutan en un solo ciclo, excepto:
divisiones, cambios de contexto y acceso por tabla a memoria de programa [6]. Se basa en
una arquitectura Harvard modificada de 16 bits de datos [7], lo que significa que el dispositivo
posee una memoria de datos tipo Random Access Memory (RAM), separada de la memoria
de datos, pudiendo acceder de manera independiente e incluso simultánea a las instrucciones
del programa y a los datos de este alojados en RAM. La arquitectura de la CPU la completa
una Arithmetic Logic Unit (ALU), con hardware dedicado para realizar multiplicaciones y
divisiones. El detalle de la arquitectura del microcontrolador PIC24 se muestra en la figura
2.1. También posee un vector de hasta 128 interrupciones, con capacidad para atender hasta
8 de ellas de manera simultánea, lo que permite liberar al procesador de la espera de sucesos
asíncronos, ya que son notificados y atendidos de manera específica en una rutina de atención
de la interrupción.
Figura 2.1: Arquitectura de la CPU del PIC24F. Fuente: PIC24F Family Reference Manual
[7].
6
Periféricos.
Figura 2.2: Perifericos del PIC24F. Además de la CPU, el PIC24F consta de una serie de pe-
riféricos. Fuente: Microchip, http: // www. microchip. com/ pagehandler/ en-us/ family/
16bit/ architecture/ pic24f. html .
Desarrollo.
1. Compilador
2. Entorno de desarrollo
3. Programador
7
Por lo general, es el fabricante del dispositivo el que provee la mayoría de ellas. En este
caso el compilador y entorno de desarrollo se pueden obtener a través de su página web:
[Link] Se dispone de diferentes compiladores
para dispositivos de 8, 16 y 32 bits, correspondiendo para la familia PIC24 el compilador
xc16 para lenguaje C que es gratuito en su versión lite. El entorno de desarrollo integrado
que se denomina MPLABX, un programa multiplataforma basado en NetBeans, que integra
las funcionalidades del compilador y programador sumado a un editor de texto avanzado
para proveer un entorno de desarrollo completo.
Para grabar el software desarrollado para estos dispositivos se debe utilizar una herra-
mienta externa denominada programador. Existe un serie de programadores disponibles los
cuales deben ser adquiridos por separado. Entre los más populares se encuentran:
8
Usuario
Aplicación
Sistema Operativo
Hardware
Figura 2.3: Sistema operativo como capa de abstracción de hardware. Accede directamente
al hardware y provee servicios a la capa de aplicación.
9
• Gestión de dispositivos de entrada y salida: los dispositivos de entrada y salida
son compartidos por todas las tareas que se ejecutan, por lo tanto, el sistema operativo
provee el servicio de gestionar el acceso a estos dispositivos de manera uniforme y
organizada.
Un sistema operativo de tiempo real, posee un scheduler diseñado para proveer un flujo
de ejecución determinista, pues solo sabiendo con exactitud la tarea que el sistema ejecutará,
en un determinado momento, se pueden cumplir los requerimientos estrictos de timing [8].
Esto es un aspecto de especial interés en sistemas embebidos que, normalmente, requieren
respuesta en tiempo real ante eventos no predecibles como las interrupciones.
La figura 2.4 muestra la forma de conseguir un sistema de tiempo real, mediante el uso
de prioridades para las diferentes tareas. En este ejemplo, la mayor parte del tiempo el
sistema está en estado idle, sin código que ejecutar. Sin embargo, ante la presencia de ciertos
eventos, el sistema debe responder de manera instantánea cambiando de contexto a la tarea
correspondiente. Ciertas tareas pueden requerir un estricto timing ejecutándose de manera
periódica. En tal caso se le asigna una alta prioridad para asegurar que el sistema operativo
siempre ejecute esta tarea cuando corresponda.
Tarea de control
Tarea Principal
Tarea Idle
t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11
Tiempo
Figura 2.4: Real time scheduling. En un sistema operativo de tiempo real las interrupciones
deben ser atendidas sin retrasos y las operaciones de cambio de contexto se realizan en un
tiempo constante e independiente de la cantidad de tareas presentes.
FreeRTOS
FreeRTOS es un tipo de Real Time Operating System (RTOS), que está diseñado para ser
lo suficientemente pequeño, en términos de consumo de memoria como, para ser utilizado en
un microcontrolador [8]. Como estos sistemas son realmente limitados, normalmente no exis-
te la posibilidad de ejecutar un sistema operativo completo como GNU-Linux, sin embargo
FreeRTOS provee un kernel capaz de manejar múltiples tareas con prioridades, comunicación
10
entre tareas, timing y primitivas de sincronización. Por su reducido tamaño no entrega fun-
cionalidades de alto nivel como una consola de comandos, así como tampoco funcionalidades
de bajo nivel, como controladores para el hardware o periféricos.
El scheduler es la parte fundamental del kernel, que controla la ejecución de las diferentes
tareas disponibles. Su objetivo es generar la sensación de estar en un ambiente multi-proceso,
cuando en realidad solo una función puede ejecutarse a la vez, ya que se cuenta solo con un
procesador. Como se detalla en la figura 2.6, la función del scheduler es entregar una porción
de tiempo de ejecución fijo a una tarea, y una vez que se agota se debe guardar su estado y se
procede a ejecutar otra. Así cada una de las tareas se procesa durante un breve momento, de
manera cíclica, hasta que completa su trabajo; si el tiempo de proceso asignado a cada una
es lo suficientemente pequeño, pareciera que muchas cosas ocurrieron simultáneamente. Una
11
sola operación tomaría, en términos absolutos, un lapso menor en completarse si no fuera
interrumpida, pero se gana un sistema más fluido cuando se deben ejecutar, en conjunto,
tareas que toman mucho tiempo de proceso y otras relativamente cortas.
No ejecutándose
Suspendida
vTaskResume()
vTaskSuspend()
vTaskSuspend()
Lista Ejecutándose
Cambio de
vTaskSuspend() contexto
API de
Event
bloqueo
Bloqueada
Tarea 1
Tarea 2
Tarea 3
t1 t2 tn
Tiempo
Tarea 1
Tarea 2
Tarea 3
t1 t2 tn
Tiempo
12
Las que están en estado “suspendido” y “bloqueado” nunca son seleccionadas por el schedu-
ler y por lo tanto no consumen recursos. Haciendo un correcto uso de las prioridades y los
diferentes estados se consigue un sistema que se ejecuta de manera fluida, haciendo un uso
óptimo del procesador.
13
• Compatibilidad: Grado en que el producto puede compartir información con otros
productos o sistemas, y realizar sus funciones mientras se comparte el mismo entorno
de hardware o software.
– Coexistencia: Cómo un producto puede llevar a cabo sus funciones mientras
comparte un entorno y recursos comunes con otros, sin afectarlos.
– Interoperación: Cómo un producto puede compartir y usar información con otro.
• Usabilidad: Cómo el producto puede ser usado para sus fines determinados de manera
efectiva, eficiente y satisfactoria.
– Reconocible como apropiado: Grado en que los usuarios pueden reconocer que
el producto es apropiado para sus necesidades.
– Aprendizaje. Grado en que el producto se puede aprender a usar de manera
efectiva, sin riesgos y satisfactoria.
– Operatividad. Grado en que el producto tiene atributos que lo hacen fácil de
operar
– Protección de cometer errores: Grado en que el sistema previene al usuario
de cometer errores.
– Estética de la interfaz de usuario: Grado en que la interfaz de usuario permite
una interacción placentera y satisfactoria.
– Accesibilidad: Cómo el producto puede ser usado por personas con variedad de
características y capacidades.
• Fiabilidad: Grado en que el producto o sus componentes cumplen las funciones espe-
cificadas por un determinado periodo de tiempo.
– Madurez: Grado en que el sistema cumple las necesidades de fiabilidad bajo una
operación normal.
– Disponibilidad: Grado en que el sistema es operacional y accesible cuando se
requiere su uso.
– Tolerancia a fallas: Grado en que el sistema o sus componentes operan como es
debido a pesar de la ocurrencia de fallos de software o hardware.
– Capacidad de recuperación: La capacidad del sistema de recuperar los datos
afectados y restablecer el estado deseado ante una interrupción o falla.
• Seguridad. Cómo un sistema protege la información y los datos, de modo que las
personas o productos tengan el grado de acceso adecuado a sus tipos y niveles de
autorización.
– Confidencialidad: Grado en que el sistema asegura que los datos sólo son acce-
sibles por las personas autorizadas.
– Integridad: Grado en que el sistema previene el acceso y modificación de los
datos o programas.
– No rechazo: Grado en que es posible demostrar que las acciones han tenido lugar,
para no poder ser negadas más tarde.
– Responsabilidad: Grado en que las acciones de una entidad pueden ser asociadas
de manera inequívoca a ella.
14
– Autenticidad: Grado en que la identidad de un sujeto o recurso puede ser com-
probada.
• Mantenimiento: Grado de la eficiencia y eficacia con la que un producto o sistema
puede ser modificado por los mantenedores.
– Modularidad: Grado en que un sistema o software está compuesto por elementos
discretos, de modo que el cambio en un componente tiene el mínimo impacto en
el resto del sistema.
– Reusabilidad: Grado en que un activo puede ser usado en más de un sistema o
en la construcción de otro.
– Analizable: Grado de eficiencia y eficacia con que es posible identificar el impacto
de un cambio en una parte del sistema, o diagnosticar deficiencias o fallas en alguna
de sus partes, o identificar aquellas que deben ser modificadas.
– Modificable: Grado en el sistema que puede ser modificado de manera efectiva
y eficiente, sin introducir defectos o degradar la calidad existente.
– Testeable: Grado en que es posible establecer un criterio para probar el sistema
y las pruebas que pueden ser desarrolladas, para determinar que el criterio se ha
cumplido.
• Portabilidad. Grado de la eficiencia y eficacia con la que un producto o sistema puede
ser transferido de un hardware, software o ambiente de uso a otro diferente.
– Adaptabilidad: Grado en que el producto puede ser adaptado a un hardware o
software diferente de manera eficiente y efectiva.
– Instalación: Grado de efectividad y eficiencia con que el sistema puede ser ins-
talado o desinstalado.
– Reemplazo: Grado en que el producto puede reemplazar a otro para el mismo
propósito en el mismo ambiente.
Estos parámetros de calidad se definen también como requerimientos del proyecto, defi-
niendo la importancia de cada apartado en el contexto de la aplicación final.
Calidad de software
Idoneidad Eficiencia de
Fiabilidad Usabilidad Seguridad Compatibilidad Mantenimiento Portabilidad
funcional funcionamiento
15
2.3.2. Patrones de diseño
Modelo-Vista-Controlador.
Este patrón de diseño divide una aplicación interactiva en tres componentes: el modelo, que
contiene la funcionalidad base y los datos; la vista, que despliega la información al usuario;
y el controlador, que maneja la entrada del usuario para cambiar el estado de la aplicación.
Así, la interfaz gráfica se refleja en el controlador y la vista, de modo que cada acción se
propaga a través del controlador hacia el modelo, actualizando a la vez la vista [10][11].
16
El usuario sólo interactúa con el controlador, y los cambios realizados en el modelo
deben ser propagados hacia la vista. Como cada vista comparte el modelo, los cambios
se verán actualizados en cada una de ellas.
• Estructura: los componentes que completan la estructura del patrón Modelo-Vista-
Controlador (MVC) se detallan a continuación:
– Modelo: encapsula la información y todas las funcionalidades de la aplicación,
de manera independiente de su representación gráfica. Provee los métodos para
realizar los procesos específicos de la aplicación así como para acceder a los datos
de esta. A la vez implementa el mecanismo de propagación de los cambios hacia
las diferentes vistas suscritas a este modelo.
– Vista: despliega la información al usuario a partir de los datos del modelo y puede
permitir múltiples formas de visualizarlo. Provee un método de actualización que
es activado por el mecanismo de propagación de cambios del modelo suscrito.
– Controlador: cada vista tiene asociada un controlador, que recibe la entrada del
usuario, como presionar un botón o seleccionar una entrada de menú. El contro-
lador solicita el servicio correspondiente al modelo, causando a la vez una actua-
lización de la vista si es necesario.
Para clarificar las relaciones entre los componentes del patrón se cuenta con el diagrama
de la figura 2.8. La esencia dinámica del esquema en ejecución se observa a través del
diagrama de colaboración detallado en la figura 2.9.
• Consecuencias: alguno de los beneficios que provee son: múltiples vistas para el mis-
mo modelo, las cuales pueden estar sincronizadas dado que los cambios en el modelo se
propagan a aquellas que lo comparten; vista y controlador intercambiable de manera
independiente, permitiendo portar la aplicación a diferentes plataformas sin cambiar la
funcionalidad. Por otro lado, los inconvenientes que genera son: aumento de compleji-
dad, al necesitar adaptar cada módulo al controlador y sus funcionalidades; excesivo
número de actualizaciones al propagar cambios del modelo a todas las vistas; alto aco-
plamiento entre la vista y el controlador -aún como elementos separados su diseño está
muy relacionado-; acoplamiento entre el modelo y el conjunto vista-controlador, ya que
cualquier cambio en la interfaz que se provee, tiene un efecto directo en el funciona-
miento de este conjunto, que accede directamente a sus servicios.
A partir del ejemplo, se observa que el proceso de creación de una aplicación parte por la
búsqueda de patrones de diseño bien documentados y que solucionen un tipo de problema
similar al que se tiene por objetivo. Comparar patrones de diseño cuando se tienen varios
candidatos a solucionar el problema, también se hace sencillo dado que la forma de presentar
cada patrón permite obtener sus principales características y posible implementación. Además
una aplicación puede hacer uso de varios patrones de diseño, en diferentes niveles de su
arquitectura para cumplir la totalidad de las especificaciones.
17
específicas del nuevo desarrollo.
Command pattern
Figura 2.8: Diagrama de clases del patrón de diseño MVC. Fuente: A System of Patterns.
Pattern-Oriented Software Architecture [11].
18
Figura 2.9: Esquema de colaboración del patrón de diseño MVC. Fuente: A System of
Patterns. Pattern-Oriented Software Architecture [11].
19
cios:
– Los comandos pueden ser requeridos de manera flexible, es decir, desde diferen-
tes fuentes según se implemente el controlador correspondiente. De hecho, podría,
existir más de un controlador o cliente generando el mismo comando desde dife-
rentes lugares.
– La aplicación es fácil de modificar y extender a través de la implementación de
nuevos comandos, dado que el procesador de comandos sólo trabaja con la interfaz
genérica de ellos. Es posible agregar algunos más complejos combinando los ya
existentes en una macro.
– El procesador de comandos, al centralizar la gestión de éstos, es el lugar adecuado
para implementar servicios como: registro de comandos ejecutados, filtrar, pospo-
ner, repetir o deshacer la ejecución, o incluso gestionar un sistema de prioridades
entre comandos.
Entre las desventajas y limitaciones de este diseño se debe mencionar:
– La cantidad de comandos puede crecer considerablemente en cuanto aumenta la
complejidad de la aplicación.
– El cliente que genera un comando tiene poca o nula información sobre el momento
en que, efectivamente, este se ejecuta o sobre el resultado de su ejecución.
– Se dificulta la creación de aplicaciones fuertemente basadas en eventos, ya que
cuando el comando obtiene los parámetros para su ejecución, puede ser diferente
del momento en que se crea.
Figura 2.10: Diagrama de clases del patrón de diseño procesador de comandos. Fuente: A
System of Patterns. Pattern-Oriented Software Architecture [11].
20
Figura 2.11: Esquema de colaboración del patrón de diseño procesador de comandos. Fuente:
A System of Patterns. Pattern-Oriented Software Architecture [11].
A partir del año 1999, se comienza a desarrollar el proyecto Cubesat como una iniciativa
entre California Polytechnic State University, San Luis Obispo y Stanford University. Con el
objetivo de facilitar el acceso al espacio a pequeños payloads, en un corto periodo de desarrollo
y a bajo costo. Para esto se crea un nuevo estándar de vehículo espacial, que considera satélites
de pequeñas dimensiones, acotados a un cubo de 10 [cm] de arista y un peso máximo de 1.3
kg. como el mostrado en la figura 2.12 (a). Cuando se combinan se pueden conseguir Cubesat
de 2 unidades (2U) o tres unidades (3U); un satélite compuesto por un solo cubo se denomina
una unidad (1U). El proyecto contempla tanto las especificaciones generales del satélite, así
como una plataforma estándar para ser desplegados desde el vehículo de lanzamiento. Este
dispositivo se denominada P-POD y consiste en un compartimiento capaz de albergar hasta
tres Cubesat de 1U y desplegarlos mediante un sistema de resortes cuando se requiera. La
figura 2.12 (b) ilustra la estructura de un P-POD.
Estándar. Las restricciones que fija el estándar Cubesat se detallan formalmente en las
especificaciones de diseño, desarrolladas por California Polytechnic State University [2]. A
continuación se resumen las principales consideraciones:
• Requerimientos generales
– Todos los componentes deben estar fijos al satélite durante el lanzamiento, des-
pliegue y operación. No se permite liberar elementos extras al espacio.
– No se permite ningún tipo de elemento explosivo o pirotécnico.
– La energía química almacenada no debe superar los 100 Wh.
21
(a) Cubesat (b) P-POD
Figura 2.12: Satélite tipo Cubesat. A la izquierda el satélite japonés OSCAR-66, lanzado el
año 2008. A la derecha un P-POD, dispositivo desde el cual se despliega un Cubesat. Fuente:
http: // cubesat. aero. cst. nihon-u. ac. jp/ english/ index. html
• Requerimientos Mecánicos
– La configuración y dimensiones del satélite deben estar de acuerdo a la figura 2.13
– El cubo debe tener dimensiones de 100x100x113 mm. en los ejes x, y, z respecti-
vamente según la figura 2.13.
– Los componentes no deben sobresalir más de 6.5 mm. en dirección normal a cada
cara.
– Sólo los rieles exteriores de la estructura pueden tener contacto con el P-POD.
– El satélite no debe superar los 1.33 Kg. de masa.
– La estructura externa debe estar construida en aluminio 7075 o 6061, anodizado
en los rieles.
• Requerimientos Eléctricos
– Ningún componente electrónico debe estar activo durante el lanzamiento, esto
incluye desactivar completamente o descargar las baterías.
– El Cubesat debe poseer un interruptor en la base de uno de sus rieles que permita
apagar completamente el satélite cuando está presionado.
– Adicionalmente debe contar con un conector tipo Remove Before Flight que debe
cortar toda la energía del satélite y será removido una vez se integre en el P-POD.
• Requerimientos de operación
– Cubesat con baterías deben ser capaces de recibir un comando para apagar trans-
misiones según las regulaciones de la FCC.
– Todos los mecanismos de despliegue del satélite no se deben activar antes de 30
minutos luego del lanzamiento desde el P-POD.
– Transmisores de radio de potencia mayor a 1 mW. no deben funcionar antes de
cumplirse 30 minutos luego del despliegue desde el P-POD.
– Se debe contar con la licencia de uso de frecuencia de radio. Para frecuencias
amateur la coordinación se realiza a través de la International Amateur Radio
Union (IARU)
22
El estándar mencionado corresponde a un Cubesat de una unidad (1U). Opcionalmente,
se pueden combinar hasta tres unidades para obtener satélites de 2U o 3U. Esto permite
contar con mayor volumen, para posicionar los componentes físicos del satélite y una mayor
superficie para situar paneles solares y así brindar mayor autonomía energética.
Figura 2.13: Especificaciones de diseño del estándar Cubesat de una unidad. Fuente: http:
// www. cubesat. org/ index. php/ documents/ developers .
23
y proyectos de exploración minera, son algunas de las posibles aplicaciones capaces de ser
desarrolladas como un proyecto aeroespacial tipo Cubesat.
Se trata de un satélite tipo Cubesat de una unidad, con fines educacionales y científicos. El
objetivo del proyecto es poner en órbita un satélite, desarrollado por estudiantes de la carrera
de ingeniería, que sea capaz de enviar un beacon para ser escuchado y decodificado por la
estación terrena, también ejecutar experimentos asociados a payloads y enviar como teleme-
tría la información de funcionamiento del satélite y los datos recolectados. Por otro lado, su
ejecución permitirá adquirir el conocimiento necesario para desarrollar proyectos satelitales
de manera local, que será la base para futuras misiones relacionadas. Además posibilitará la
integración de alumnos de pregrado en equipos multidisciplinarios, que requieren proponer
soluciones no triviales a un problema abierto.
24
Figura 2.15: Satélite SUCHAI junto a una langmuir probe. Imagen tomada durante etapas
tempranas de integración.
25
Capítulo 3
En este capítulo se describe el proceso de diseño del software de vuelo para el satélite.
El proceso considera, en primera instancia, los requerimientos operacionales de la misión;
requerimientos no operacionales, relacionados con la calidad del software; y la plataforma de
hardware objetivo, para tener claro las limitaciones y alcances de la solución. El diseño de la
aplicación se detalla en diferentes niveles, incluyendo una visión global sobre los componentes
principales de esta y se centra, en específico, en la propuesta de una arquitectura de alto nivel
basada en un patrón de diseño. Finalmente, se realiza un análisis de la solución, esto con
la finalidad de plantear una arquitectura final que permita implementar las funcionalidades
detalladas en los requerimientos operacionales.
3.1. Requerimientos
Se refieren a las funcionalidades que se espera que el computador a bordo del satélite
SUCHAI deba realizar. Son los requisitos básicos que el sistema debe cumplir para considerar
que se cuenta con un satélite capaz de llevar a cabo la misión. La lista de requerimientos
proviene de una serie de reuniones sostenidas con los integrantes de los diferentes grupos de
trabajo, todo de acuerdo con los lineamientos del jefe de proyecto.
Área de comunicaciones
Configuración inicial del transcevier : el satélite debe ser capaz de fijar, si lo permite, las
configuraciones iniciales del sistema de comunicaciones, por ejemplo: encender el transcevier,
silenciar las comunicaciones durante determinado tiempo luego del lanzamiento, configurar
la frecuencia de transmisión a la asignada por la IARU y la potencia si el equipo lo permite,
configurar y encender la baliza o beacon, entre otros.
26
Se debe almacenar de manera permanente estas configuraciones iniciales, para así poder
reconfigurar el transcevier en caso de reinicio o falla, también para permitir un ajuste de
parámetros durante el desarrollo de la misión.
Protocolo de enlace: el satélite debe ser capaz de recibir y enviar datos a la estación
terrena. Para esto se requiere, en primer lugar, que se pueda rastrear mediante la transmisión
de una señal de baliza o beacon. Segundo, el satélite debe establecer comunicación con la
estación terrena para determinar si se recibirán ordenes o si se descargará información. Y
tercero, proceder con las operaciones de descarga y subida de datos.
Envío de telemetría: el satélite recolectará los datos requeridos por la misión, los que
incluyen información general sobre el estado de funcionamiento de todos los subsistemas, así
como los datos generados por los payloads abordo. El envío de telemetría puede ser automático
cada vez que el satélite se enlace con la estación terrena, o bien bajo demanda a través de
telecomandos que indiquen el tipo de información que es requerida.
Control central
Plan de vuelo: se debe ser capaz de recibir y ejecutar un plan de vuelo, consistente en una
serie de acciones a realizar en momentos determinados de tiempo. El plan de vuelo puede
ser precargado en el satélite antes de ser lanzado, así como también debe ser actualizado
mediante telecomandos. Esto provee flexibilidad en las tareas que se ejecutarán durante la
misión, permitiendo controlar el uso de los diferentes recursos del satélite.
27
Obtener el estado del sistema: de manera autónoma, el software de control debe reco-
lectar información básica sobre el estado del satélite en general. Esta información será usada
para determinar la salud del sistema y tomar las acciones necesarias en órbita, o bien será
descargada como telemetría para ser posteriormente analizada. Ejemplos de variables asocia-
das al estado del sistema son: el nivel de carga de las baterías, la hora del reloj interno, el
estado del dispositivo de comunicaciones, el estado del computador abordo, entre otras.
Inicialización del sistema: el software control debe poseer un algoritmo de inicio del
sistema en general, que considera la configuración del software con los parámetros adecuados,
la inicialización de otros módulos o subsistemas, así como las obligaciones de silencio radial
durante el lanzamiento, y el despliegue de antenas. Debe tener la capacidad de reiniciarse de
manera segura manteniendo variables fundamentales y la consistencia con el estado anterior
al reinicio
Área de energía
Órbita
Payloads
28
o eliminar módulos que se relacionen con el control de payloads sin afectar al resto de los
sistemas.
Tolerancia a fallos
El sistema debe tener cierto grado de tolerancia a fallos de hardware y software que
permitan mantener la misión operativa. Debido a las adversas condiciones del medio espacial
y la incapacidad de acceder directamente al dispositivo, este debe ser capaz de:
El eje principal para el diseño del software de control del satélite, responde a contar
con una aplicación que sea altamente mantenible debido a dos factores básicos: primero, el
desarrollo será incremental, estará a cargo de más de una persona, por lo tanto, debe ser
flexible en la adición de funcionalidades, desacoplando módulos para que las intervenciones
en el código sean lo más acotadas posible; segundo, el sistema debe ser la base para futuras
misiones aeroespaciales, por lo tanto, debe ser fácilmente adaptable a nuevos requerimientos
funcionales que incluyen la adición de nuevos payloads y sus módulos de control. En el futuro,
la arquitectura diseñada debe proveer la capacidad de análisis para los nuevos desarrolladores,
con el objetivo de determinar claramente qué módulos se deben intervenir, para agregar
nuevas funcionalidades o corregir posibles errores. Especial mención requiere la necesidad de
expandir la aplicación, pues se considera como filosofía de trabajo, el contar siempre con un
sistema funcional ante la eventual posibilidad de lanzar el satélite. Así, se partirá con una
implementación que realice las operaciones básicas o requerimientos mínimos, para así agregar
complejidad y funciones al software de manera incremental. Lo anterior, conduce a poner
especial énfasis en el diseño de una arquitectura que genere un software modular, reusable,
analizable y modificable, elementos agrupados en la característica denominada “mantenible”
en la norma ISO/IEC 25010 [9].
29
La fiabilidad del sistema es un elemento importante en cualquier misión espacial, debido
al ambiente extremo en el cual se desarrolla la misión, lo que incluye grandes cambios de
temperatura y efectos de la radiación solar sobre los componentes electrónicos. Esto significa
que la aplicación debe tener un nivel adecuado de tolerancia a fallos, y ser capaz de recu-
perarse ante una interrupción o reinicio. En lo que a software respecta, la característica de
tolerancia a fallos será considera en su nivel básico, debido a que, por lo general, esto significa
diseñar sistemas altamente redundantes que elevan la complejidad del diseño y el costo de
implementación. Lo anterior se contradice con otros requerimientos no operacionales y con
la filosofía propia de los satélites tipo Cubesat que, por lo general, utilizan componentes de
tipo comercial no diseñados, necesariamente, para su uso en el espacio.
Existen algunas características de calidad que no serán relevantes en este diseño, ya que al
ser la primera aproximación en la materia para el equipo de desarrollo, se requiere mantener
cierto nivel de simplicidad en la solución, luego probarla y así ganar la experiencia necesaria
en proyectos aeroespaciales. Por ejemplo, el desempeño, referido a términos computacionales,
no es una restricción importante por la siguientes razones: se cuenta con una plataforma de
baja capacidad de cómputo y limitados recursos energéticos; el sistema requiere realizar una
cantidad baja de tareas y aquellas de alta demanda computacional pueden ser ejecutadas en
tierra; y no se consideran acciones que requieran una gran precisión de tiempo. La seguridad
tampoco es una componente fundamental, si bien, se podría tratar de evitar un uso mal
intencionado de la plataforma por parte de otros operadores satelitales, salvo por errores,
esto es poco probable; por el contrario se busca obtener la mayor cooperación posible de otros
operadores como la comunidad de radio-aficionados. Por último en el caso de la portabilidad,
lo único importante es determinar claramente los diferentes niveles de abstracción de la
arquitectura y su intercomunicación, debido a que las plataformas objetivo cuentan con muy
bajo nivel de estandarización en los niveles más cercanos al hardware.
En definitiva, la tabla 3.1 resume los requerimientos no funcionales del proyecto, asignán-
dole una determinada prioridad o importancia a considerar en el diseño.
30
sistema la simplicidad necesaria asegurando funcionalidad. La totalidad de los requerimientos
operacionales se obtendrá a través de mejoras incrementales sobre los requerimientos mínimos
ya mencionados.
Características Importancia
Observaciones
Categoría Subcategoría Poca Media Alta
Completitud funcional X
Idoneidad Correctitud funcional X El software debe entregar solución a
Funcional todos los requerimientos operacionales
Adecuación Funcional X
Tiempo X Pocas restricciones de tiempo
Eficiencia del
Utilización de recursos X Debe caber en el sistema embebido
desempeño
Capacidad X No se pretende sobrecargar el sistema
Co-existencia X El software controla todo el sistema
Compatibilidad
Interoperabilidad X Comunicación con subsistemas
Reconocible como apropiado X
Aprendizaje X
Operabilidad X El sistema funciona principalmente de
Usabilidad manera utónoma.
Protección de cometer errores X
Su operación se lleva a cabo por expertos
Estética de la interfaz de usuario X
Accesibilidad X
Madurez X Se busca llegar a un nivel aceptable de
Disponibilidad X fiabilidad.
Fiabilidad
Tolerancia a fallas X Alta incertidumbre debido a la inexistencia
Capacidad de recuperación X de experiencia previa
Confidencialidad X
Integridad X No se consideran estos aspectos en este
Seguridad No rechazo X primer diseño.
Responsabilidad X Se prefiere simplicidad.
Autenticidad X
Modularidad X Sistema altamente modular
Reusabilidad X Base para futuras misiones
Mantenimiento Analizable X Arquitecutura clara
Modificable X Flexibilidad en agregar funcionalidades
Testeable X Pruebas de funcionalidad
Adaptabilidad X Capacidad de agregar nuevos modulos
Portabilidad Instalación X Instalación experta
Reemplazo X No aplica
Área Requerimiento
Proveer energía
Energía
Monitorizar el estado de carga de las baterías
Recoger telemetría periódicamente
Control central
Ejecutar comandos
Despliegue de antenas
Emitir beacon
Comunicaciones
Enviar telemetría
Recibir telecomandos
31
3.2. Plataforma
Adicionalmente, se cuenta con los siguientes dispositivos para EPS y comunicaciones res-
pectivamente, que completan la base del vehículo satelital:
Por lo tanto, se cuenta con todo el hardware básico para el funcionamiento del satélite y
se considera fijo para el proceso de diseño del software de vuelo.
Figura 3.1: CubesatKit de Pumpkin Inc. A la izquierda, los componentes del kit, que incluye
una placa de desarrollo, procesador, programador y la estructura del satélite. En la derecha la
estructura metálica de un Cubesat de una unidad. Fuente: http: // www. cubesatkit. com/ .
El computador a bordo del satélite, está compuesto por una placa madre que contiene una
interfaz PC104, a través de la cual se conectan el resto de los subsistemas, y por el módulo
para el procesador que se integra directamente a la placa madre, como se muestra en la figura
3.2.
32
(a) Placa madre (b) Módulo del procesador
Figura 3.2: Dos módulos que componen el computador a bordo del satélite. A la izquier-
da, la placa madre que incluye un conector PC104. En la derecha un microcontrolador
PIC24FJ256GA110. Fuente: http: // www. cubesatkit. com/ .
La placa, cuenta además con un reloj de tiempo real que se comunica por un bus I2C,
el cual puede ser usado como reloj, alarma y/o watchdog externo. Cuenta con un slot de
memoria SD, para albergar un medio de almacenamiento masivo de hasta 2 GB.; una interfaz
USB 2.0 para comunicaciones previas al lanzamiento; así como la electrónica para proveer
alimentación al bus PC104 y al módulo del procesador [13].
• Arquitectura de 16 bit.
• Memoria de programa flash de 256 kB.
• 16 kB de memoria RAM.
• Hasta 16MIPS @ 32 MHz.
• 4 UARTs, 3 SPIs, 3 I2Cs.
• ADC de 10 bit, 16 canales, 500 ksps.
• 5 timers de 16 bit.
• Real Time Clock and Calendar (RTCC), Watchdog timer (WDT)
• Selector de pines de periféricos.
• Se deberá utilizar las herramientas de desarrollo que provee el fabricante del microcon-
trolador, es decir, lenguaje C para el compilador XC16 de Microchip.
• Se debe efectuar un trabajo de bajo nivel, implementando drivers para los periféricos
del microcontrolador y para cada dispositivo que se agregue al sistema.
33
• Solo existen algunos sistemas operativos básicos para este tipo de dispositivos, y en
general solo permiten organizar el software en módulos, procesos o tareas que se ejecuten
de manera concurrente.
• Existe una cantidad muy limitada de código previo que se pueda reutilizar para im-
plementar el diseño de la aplicación, descartando de plano la posibilidad de utilizar
librerías para bases de datos, protocolos TCP, UDP o POSIX, como en otros proyectos
de similares características [15].
Con todo el diseño de la aplicación final será a medida y no deriva de un trabajo previo,
con el objetivo de ajustarse a los requerimientos y restricciones de la mejor manera posible.
La arquitectura del software de vuelo consiste en diseño conceptual, con un alto grado
de abstracción, de los principales módulos que conformarán la aplicación y la manera de
relacionarse entre sí.
Se analizará esta arquitectura a diferentes niveles, partiendo por una visión general de la
aplicación, donde se identifican las principales áreas en que se divide. Cada una de estas áreas
o capas de abstracción presenta sus propias particularidades, por lo que se requiere ahondar
en el diseño de la arquitectura de cada uno de ellos.
A nivel global, el software de vuelo, se concibe como una serie de capas que agrupan
funcionalidades similares, e interactúan según una dinámica en que la capa inferior es una
prestadora de servicios para la superior [5]. Este diseño se denomina arquitectura de capas y
es una buena forma de generar sistemas portables entre diferentes plataformas de hardware.
Esto porque, siempre que se mantengan las interfaces entre capas, cualquiera de ellas puede
ser reemplazada por una implementación diferente.
La figura 3.3 detalla una arquitectura de tres capas apropiada, en general,s para el diseño
de software en sistemas embebidos donde se pueden distinguir al menos los siguientes niveles:
capa de bajo nivel relacionada con los controladores de hardware, también llamada capa de
abstracción de hardware o Hardware Abstraction Layer (HAL); la intermedia que corresponde
al nivel del sistema operativo o gestor de tareas; y una superior que corresponde a la aplicación
final del proyecto en cuestión.
La capa de más bajo nivel corresponde a los controladores de hardware, que pueden ser
varios módulos específicos para cada componente físico o subsistema presente, y permite a
las capas superiores acceder a ellos sin conocer en detalle sus particularidades. Por ejemplo,
provee los servicios para acceder al periférico de comunicaciones o subsistemas externos, como
pueden ser los diferentes payloads. Por lo general, existen varias alternativas de hardware
disponibles para un mismo objetivo, o bien se requiere que el sistema se adapte a la presencia
34
Aplicación
Sistema Operativo
Controladores
de diferentes payloads, por lo que la integración de varios controladores en este nivel permite
mantener el resto del sistema intacto, siempre y cuando se respeten las interfaces entre capas.
La capa intermedia corresponde al sistema operativo, que provee soporte para la gestión
de tareas en el sistema embebido, permitiendo la ejecución concurrente de procesos. A este
nivel en el diseño, la decisión de qué sistema operativo utilizar no es relevante, pues toda la
lógica de gestión de tareas está concentrada en esta capa que utilizará las funcionalidades
dadas por los niveles inferiores y que provee la base para implementar la aplicación.
Una de las principales desventajas de esta arquitectura, sobre todo en sistemas embebidos,
es que puede existir la necesidad de una comunicación entre capas no adyacentes, rompiendo
la arquitectura [5] propuesta. Esto se debe tratar de evitar, o al menos realizar de manera
controlada.
En todo sistema computacional se requiere de una capa de bajo nivel que realice la interfaz
entre el hardware y el software, para entregar las funcionalidades de configurar, controlar y
deshabilitar adecuadamente las diferentes dispositivos. Se llaman controladores o drivers a
aquellas librerías que permiten inicializar y manejar el acceso a este hardware a las capas de
sistema operativo y de aplicación [16].
35
o funcionalidades bajo una interfaz común, que permita abstraer las particularidades de la
implementación de cada uno. Hacia las capas superiores se maneja el concepto de “qué hace”
el dispositivo, entregando funciones básicas que persisten entre diferentes arquitecturas de
hardware, tales como: la inicialización, encendido o habilitación del dispositivo; su configura-
ción; la lectura y escritura de datos; así como deshabilitar o apagarlo. A esto se suman todas
aquellas funcionalidades específicas del componente.
Se considera el uso de una arquitectura de controladores síncronos, cuando las tareas que lo
invocan necesariamente deben esperar la respuesta del controlador. Si se provee la adecuada
sincronización, entonces el resto del sistema puede seguir funcionando mientras la tarea en
cuestión se encuentra esperando. Cuando termina el proceso de entrada o salida de datos, la
tarea retoma su funcionamiento.
Llamada
de la tarea Resultado Sinc.
Controlador ISR
Operaciones E/S
Datos
Dispositivo de
hardware IRQ
36
• Obtener el estado o la información desde el dispositivo.
• Retornar la información requerida.
Cuando se utiliza una rutina de atención de interrupciones, ésta se encarga de las siguientes
operaciones:
En ocasiones, la tarea que solicita las acciones al controlador, puede continuar su ejecución
sin esperar el resultado. En este caso, se habla de un controlador asíncrono. Este tipo de driver
no es común de encontrar, y por lo general se pueden evitar, cuando no tiene sentido avanzar
en la ejecución sin que se terminen las operaciones de entrada y salida. Un caso especial es
cuando se realizan operaciones en varias etapas, aquí, la tarea puede procesar los datos de la
primera etapa, mientras el controlador obtiene los datos de la siguiente.
Este tipo de arquitectura se detalla en la figura 3.5. Se observa que el driver lo componen
el módulo o función que ejecuta la operaciones, la rutina de atención de interrupciones, así
como una cola de mensajes que almacena los resultados parciales de la operación de entrada
o salida. La sincronización, a través de esta cola, permite a la tarea procesar en paralelo la
información que se le entrega.
Llamada
de la tarea Resultado
Cola de mensajes
Controlador ISR
Datos
Dispositivo de
hardware IRQ
37
• Obtener la información desde (o enviar hacia) el dispositivo de hardware.
• Empaquetar la información en un mensaje.
• Agregar el mensaje a la cola.
Un caso particular de driver asíncrono, que se observa de manera común en sistemas em-
bebidos, corresponde a la entrada de datos seriales asíncronos. En este tipo de controladores
se cuenta con la llegada de una gran cantidad de datos de manera serial, y el término de la
operación está dado por la cantidad máxima a recibir o por algún indicador, en los mismos
datos, del término de la secuencia.
La arquitectura que responde a esta situación se detalla en la figura 3.6. En este caso, en
adición a los módulos mencionados anteriormente, se agrega un buffer de memoria que es
creado al inicio de las operaciones de entrada de datos, y es accedido por referencias para
evitar el uso adicional de memoria.
Llamada
de la tarea
Buffer de datos
Llamada
de la tarea Resultado Crear Datos
Cola de mensajes
Controlador ISR
Datos
Dispositivo de
hardware IRQ
38
3.3.3. Sistema operativo
• Gestión de tareas.
• Sincronización entre tareas.
• Temporización.
• Gestion de memoria.
• Gestion de dispositivos de entrada y salida.
El diseño de un sistema operativo está fuera del alcance del proyecto, en cuanto existen
una serie de alternativas ya disponibles para su uso. A continuación se analiza la arquitectura
y servicios que proveen algunos de los sistemas operativos para sistemas embebidos recomen-
dados por el fabricante del microcontrolador utilizado. En particular, nos interesan dos de
ellos: Salvo RTOS, por ser parte del kit adquirido y es el recomendado por el fabricante del
computador a bordo; y FreeRTOS por ser una solución ampliamente utilizada comercialmente
en sistemas embebidos y además posee una licencia libre y es gratuito.
39
3.3.4. Aplicación
Como las restricciones que se han impuesto al diseño de la aplicación indican que no
se utilizará un lenguaje de programación orientado a objetos, sino que uno procedural, se
realizará una adaptación de la idea de este patrón, utilizando los recursos y servicios que
proveen las capas inferiores de la arquitectura. En el esquema de la figura 2.10, se observan
dos tipos de módulos: activos y no activos.
Los módulos no activos son aquellos que sólo prestan servicios a las tareas que estan
funcionando dentro del sistema operativo, como librerías, estructuras de datos, controladores
y repositorios de datos. Entre ellos se encuentran: la estructura de comandos genérica o
abstract command, los comandos, el proveedor de servicios o suplier, además de otras librerías
y repositorios presentes. No se justifica considerar estos elementos de software como tareas
debido a que pasarían la mayor parte del tiempo sin realizar acciones, salvo cuando son
requeridos por módulos activos. Si estuvieran al mismo nivel que estos, se debería agregar
una completa batería de sincronización, que permita activarlos y desactivarlos, lo cual a la
larga se hace complejo de mantener. La forma correcta de visualizarlos es como estructuras
de datos, repositorios y librerías, implementados según las posibilidades de la capa de sistema
operativo, drivers o características propias del lenguaje de programación.
Listeners.
40
Son los únicos encargados de generar los comandos en la aplicación. Pueden existir varios
listeners, dado que implementan la inteligencia del sistema para generar la acciones deseadas
ante diferentes circunstancias. Su denominación proviene de la siguiente filosofía adoptada en
el diseño: la única justificación para que un listener exista es que se mantenga “escuchando”
alguna variable del sistema o el estado de un subsistema, para tomar decisiones sobre los
comandos que se deben ejecutar en cada momento. Se pueden ver como las “aplicaciones” o
“procesos” de otras arquitecturas de software para pequeños satélites [17][15], en cuanto acá se
realizan procesos de manera periódica y se mantienen activos durante todo el funcionamiento
del sistema. Estos módulos permiten extender las funcionalidades del satélite, en cuanto se
requiera una aplicación que, dado ciertos parámetros, tome decisiones en tiempo real y ejecute
las acciones necesarias, por ejemplo, conceptualmente se pueden considerar como un listener
los siguientes procesos:
• Dado un temporizador, realizar de manera periódica una revisión del estado del sistema.
• Dada la posición actual en la órbita, ejecutar un plan de vuelo.
• Dado que llegan telecomandos desde la estación terrena, procesarlos y ejecutar las
solicitudes.
• Dado que se reciben datos por el puerto serial, procesar y ejecutar las acciones solici-
tadas.
Los listeners no realizarán acciones que involucren directamente el acceso a bajo nivel
hacia otros subsistemas, evitando así el uso simultáneo de recursos de hardware compartido
-como módulos de comunicaciones- que puedan causar un estado de data race. El patrón de
diseño indica que en este nivel tampoco se llevan a cabo, directamente, las acciones de los
comandos, sino que son generados y encolados para su posterior ejecución. Esto plantea la
limitante de que quien envía el comando, no puede saber si efectivamente fue ejecutado o cuál
fue el resultado. No obstante se puede lograr cerrar el lazo de control a través de la lectura del
repositorio de estados y mediante la modificación de una variable en este repositorio por parte
del comando generado. Por lo tanto se permite el acceso de solo lectura a los repositorios de
estados, datos y de comandos para obtener la realimentación necesaria de las acciones que
han sido requeridas.
Dispatcher.
41
es aceptado el, dispatcher encargará su ejecución al siguiente nivel de la arquitectura. Entre
las responsabilidades que pueden ser asignadas se encuentran:
• Recibir todos los comandos generados y decidir si serán enviados para su ejecución.
• Ordenar la ejecución de comandos según prioridades.
• Filtrar comandos según el estado de salud del sistema. Por ejemplo, evitar la ejecución
de aquellos que usan mucha energía cuando el nivel de carga de las baterías sea crítico.
• Filtrar los comandos provenientes o hacia un determinado sub-sistema que pueda estar
causando fallas.
• Llevar un registro de los comandos que se han generado.
• Llevar un registro del resultado de la ejecución de comandos.
Sólo una instancia de este módulo existe en el sistema, permitiendo centrar las estrategias
de control de las operaciones que se realizan, sin afectar el funcionamiento de otras áreas.
La información que dispone el dispatcher para establecer el control son dos: el estado del
sistema obtenido desde el repositorio correspondiente y la meta información disponible en los
comandos que son encolados.
Entre las ventajas que presenta este esquema, se encuentra la capacidad de encapsular el
proceso de auditoría de las operaciones que realiza el software, así como la forma de ejecutar
los comandos de cara a los clientes o listeners que solicitan estas acciones. Este es el punto
adecuado para implementar las funcionalidades de deshacer acciones, llevar un registro de
sucesos, postergar la ejecución de comandos, entre otras.
La principal desventaja es que por ser el único módulo que recoge las acciones solicitadas
por todos los listeners, representa el principal cuello de botella, retrasando la ejecución de
comandos a un punto en que no se logra cumplir con los requisitos de tiempo del resto de
las tareas del software de vuelo. Por ello, se debe mantener acotada la cantidad de acciones
que se realizan en el dispatcher y establecer un tamaño adecuado a la cola de llegada para
no bloquear el resto de las tareas.
Executer.
Corresponde al módulo final en el flujo de comandos del sistema, donde estos son ejecu-
tados. Equivale al objeto receiver dentro del patrón de diseño original, en cuanto es quien
finalmente realiza las acciones solicitadas. El executer recibe un comando desde el dispatcher
y obtiene la función que se debe ejecutar desde el repositorio de comandos. Luego se ejecuta
la función, que realiza todas las acciones implementadas en dicho comando, tales como: leer
datos, acceder a dispositivos, cálculos y almacenamiento resultados. Al término, su código de
retorno es notificado al dispatcher, indicando la disponibilidad del executer para una nueva
operación.
42
• Executer único: tener un sólo executer que funciona con máxima prioridad respecto
al resto de las tareas. Esto permite brindar acceso exclusivo del sistema al comando en
ejecución. Así se ahorran los problemas que surgen de sincronizar el uso compartido de
recursos o subsistemas. Sin embargo, se debe cuidar que el comando en ejecución no
cause una falla que deje al sistema congelado.
• Múltiples executers: se puede implementar un patrón thread pool para permitir la
ejecución de varios comandos de manera concurrente. Esto implica tener varios executers
esperando a recibir ordenes desde una cola. Cuando uno de ellos esté disponible, toma un
comando y lo ejecuta, encolando también su resultado. Se puede obtener un sistema que
funcione de manera más fluida cuando se cuenta con una alta demanda de comandos,
sin embargo, se requiere una cuidada sincronización de todos los recursos compartidos
del sistema para evitar situaciones de data race.
Repositorios.
Los módulos en ejecución requieren acceder a los datos básicos del sistema, que indican
el estado de funcionamiento y permiten tomar decisiones según determinadas variables de
control. Del mismo modo los comandos ejecutados requieren informar de cambios en el es-
tado de funcionamiento, reconfiguración de parámetros y el almacenamiento de información
proveniente de experimentos. Esta funcionalidad se abstrae en el concepto de repositorios de
datos, que son módulos encargados de organizar toda la memoria disponible en el sistema y
proveer métodos de acceso que transparenten la lectura y escritura. Los repositorios, por lo
general, no son módulos activos en su ejecución, es decir, se tratan como librerías que proveen
funciones para manejar el acceso a los datos, organizar el lugar físico en que se conservará la
información y supervisar su integridad, sobre todo ante casos de falla o reinicio del sistema.
Arquitectura de la aplicación
43
Esuchan eventos del sistema y generan
los comandos correspondientes
Command pattern - Clients
Nuevos comandos
Command pattern - Invoker
Dispatcher
Lectura
Repositorio
Lectura
Encola los comandos y decide el siguiente
a ejecutar. Supervisa su ejecución.
Código de retorno
Escritura
Siguiente comando Lectura Almacena, da acceso y organiza
diferentes datos del sistema
Executer
Llama
Se puede usar el
patrón thread pool
Command pattern - Reciver
Figura 3.7: Arquitectura del software de vuelo en la capa de aplicación.. Corresponde a una
adaptación de command pattern.
44
Tabla 3.5: Análisis de la arquitectura, según requerimientos operacionales, para el área de
control central
Área de control central
Función Módulo Implementación
Organizar Repositorio de Se cuenta con un repositorio de datos que brinda acceso de forma
Telemetría datos ordenada a los diferentes tipos de datos. Existen comandos especí-
ficos que recogen la información y usan el repositorio de datos para
guardarla.
Plan de vuelo Listener El plan de vuelo consta de un itinerario con los comandos a ejecu-
(FlightPlan) tar según la ubicación del satélite. Se puede configurar a través de
comandos que modifiquen entradas específicas del itinerario.
Recoger Listener De forma periódica se ejecutan comandos que revisan parámetros
información del (HouseKeeping) del sistema y actualizan variables en el repositorio de estados.
estado del
sistema
Tolerancia a Dispatcher Se lleva un registro de los comandos ejecutados y sus códigos de
fallos de retorno. Se puede evitar le ejecución de comandos (o grupos de co-
software mandos) que esten generando problemas en el sistema (lista negra).
Se puede filtrar comandos desde ciertos listeners.
Capacidad de Listener Se cuenta con una consola serial capaz de interpretar órdenes como
debug (DebugConsole) comandos internos del sistema. Los comandos se pueden ejecutar en
modo debug para tener una salida con información relevante sobre
la ejecución.
Inicialización Listener Inicialmente sólo existe un listener, que genera los comandos pa-
del sistema (Deployment) ra toda la secuencia de inicio, que implica configurar parámetros,
repositorios, subsistemas, silencio radial, despligue de antenas y la
activación del resto de los listener s.
45
Tabla 3.7: Análisis de la arquitectura, según requerimientos operacionales, para el área de
energía, órbita y payloads
Área de energía, órbita y payloads
Función Módulo Implementación
Estimación de Listener De forma periódica se ejecuta comando que lee datos desde EPS y
la carga de la (HouseKeeping) actualiza variables en el repositorio de estado del sistema.
batería
PowerBudget Dispatcher Antes de ejecutar un comando se chequea el estado de energía del
sistema. Los comandos tienen niveles de energía aceptables y sólo
se ejecuta si su nivel requerido es menor o igual al estado de carga
actual.
Actualizar NA (1) La orbita se calcula en tierra y se actualiza el itinerario según
parámetros de las predicciones de órbita. (2) Se cuenta con un GPS y se ejecuta el
orbita itinerario según localización.
Ejecución de Listener Comandos se generan según el itinerario del plan de vuelo
comandos de (FlightPlan)
payloads
El resultado de este ejercicio revela los módulos que son necesarios en el diseño de la
arquitectura de software a nivel de aplicación, específicamente los listeners que se deben
implementar son:
El módulo dispatcher contará con las siguientes características, que permiten cumplir con
los requerimientos de tolerancia a fallos y control del estado del sistema:
• Recibir todos los comandos generados y decidir si serán enviados para su ejecución.
• Filtrar comandos que requieren mayor energía que la disponible en determinado mo-
mento.
• Llevar un registro de los comandos que se han generado.
• Llevar un registro del resultado de la ejecución de comandos.
46
Respecto al módulo executer, en el diseño actual se considera la utilización de sólo un exe-
cuter, dado que el sistema no será utilizado bajo una alta demanda de ejecución de comandos,
según lo expresado en los requerimientos no operacionales.
La arquitectura se completa con los repositorios de datos, que según lo analizado deben
ser tres:
• Repositorio de estados: provee acceso a todas las variables de estado del sistema,
por ejemplo, información sobre el funcionamiento, estado de salud y parámetros de
configuración actuales. La información en este repositorio suele estar presente en forma
de flags, contadores o registros de configuración. Dependiendo de la aplicación, algunos
de estos datos pueden requerir almacenamiento persistente, con el fin de mantener el
estado de funcionamiento entre reinicios.
• Repositorio de datos: provee funcionalidades para almacenar y recuperar datos gene-
rales como resultados de experimentos, registro de sucesos o telemetría. Por lo general,
se requerirá de almacenamiento persistente y de gran capacidad.
• Repositorio de comandos: este repositorio provee el acceso a todos los comandos
disponibles en el sistema. Es usado tanto para construir el comando que se desea generar
por parte de los listeners, así como para determinar la función asociada al código que
es recibido por el executer.
47
Esuchan eventos del sistema y generan
los comandos correspondientes
Command pattern - Clients
InitSystem
Escucha: reinicio del sist.
DebugConsole Communications FlightPlan Housekeeping
Escucha: puerto serial Escucha: TRx Escucha: posición orbital Escucha: tick del sistema
Nuevos comandos
Command pattern - Invoker
Dispatcher
Repositorio de estados
Lectura
Encola los comandos y decide el siguiente Lectura
a ejecutar. Supervisa su ejecución.
Código de retorno
Escritura
Siguiente comando Almacena, da acceso y organiza
Lectura
todas las variables de estado
Executer
Llama Repositorio de datos
Escritura
Función del comando Lectura
Lectura
Lee los comandos y ejecuta la
función que corresponde. Reporta Retorna
los resultados al dispathcer.
Almacena, da acceso y organiza
datos generados por los comandos
Repositorio de comandos
Lectura Lectura
48
Capítulo 4
Implementación
El proceso consta de tres etapas principales, que se alinean con la visión global del soft-
ware como una arquitectura de tres capas. Primero se detallan los drivers que se requieren
implementar para esta plataforma, definiendo el tipo de arquitectura utilizada para guiar
la implementación. En segundo lugar se detalla la forma de integrar el sistema operativo
FreeRTOS. Y tercero, se procede montar la aplicación final la que se implementará módulo
a módulo hasta lograr un sistema funcional.
49
4.1.1. Computadores
En principio no existen restricciones sobre el sistema operativo a utilizar, dado que las
principales herramientas como el IDE y el compilador son multiplataforma. Sin embargo, el
presente trabajo se ha desarrollado sobre plataformas GNU/Linux por su flexibilidad, libertad
de distribución, disponibilidad de herramientas y estabilidad. Las principales distribuciones
de Linux utilizadas fueron Kubuntu 12.04 LTS amd64 y LinuxMint 14 amd64.
4.1.3. IDE
50
de documentación, entre otros. En este proyecto se utiliza el IDE de Microchip denominado
MPLABX, que se caracteriza por ser un entorno multiplataforma, basado en el proyecto de
código libre NetBeans. Integra un avanzado editor de texto, con funcionalidades de control
de cambios, múltiples configuraciones para un mismo proyecto, integración con múltiples
compiladores, acceso directo a la programación y depuración del dispositivo, todo desde la
misma aplicación, centralizando el proceso de desarrollo en un ambiente adecuado, como se
muestra en la figura 4.1.
Permite realizar las pruebas sobre el sistema embebido funcionando y es fundamental para
el desarrollo de la aplicación, debido a que el producto final no se puede ejecutar en el mismo
computador, sino que en el hardware objetivo que corresponda. En este caso se utiliza la
plataforma de desarrollo que provee el Cubesat Kit de Pumpkin [18]. Esta tarjeta permite
51
montar un módulo de procesador con un PIC24F256GA110 en un bus PC104, al cual se
conectan todos los componentes del satélite. Cuenta además con un slot de memoria SD, un
reloj de tiempo real y un conversor RS232 a USB para fines de debug (ver figura 4.2). Es
eléctricamente idéntica a la placa madre que se utilizará en el satélite, por lo tanto es la he-
rramienta adecuada para realizar todo el trabajo de programación y pruebas del software. Se
debe hacer hincapié en lo fundamental de esta herramienta en el proceso de desarrollo de un
sistema embebido, debido a que la aplicación compilada es específica para el dispositivo obje-
tivo, las herramientas de simulación de microcontroladores no son suficientes para probar las
reales condiciones de ejecución del software, y porque el ciclo de desarrollo se completa con la
solución y ajuste de problemas observados durante la ejecución de la aplicación en su sistema
objetivo, de manera dinámica, como resultado de respuestas a entradas no deterministas.
Figura 4.2: Tarjeta de desarrollo para Cubesat Kit de Pumpkins. Es eléctricamente igual a
la placa madre del computador abordo del satélite. Permite conecta un módulo de procesador
al bus PC104, cuenta con un conector de memoria SD, conversor RS232 a USB, alimentación
y protección de sobre corriente.
4.2.1. Directorios
Con el objetivo de mantener un orden a lo largo del desarrollo del software, se debe dar
una estructura lógica a los diferentes archivos fuentes que lo componen. Así, se organiza un
árbol de directorios que permita encontrar, de manera sencilla, cada archivo fuente según su
función en el sistema. La organización de los directorios sigue la arquitectura de capas de la
aplicación, quedando de la siguiente manera:
main/
Drivers/
include/
FreeRTOS/
Payloads/
Cmd/
include/
52
Drivers/
include/
SUCHAI.X/
System/
include/
main.c
Los desarrolladores deben seguir esta estructura al momento de agregar un archivo con
código fuente al proyecto. En la tabla 4.2 se detalla la funcionalidad de cada directorio.
Directorio Descripción
main Directorio principal, contiene el archivo main.c y archivos de confi-
guración globales.
include Dentro de cada directorio de fuentes, se agrega un directorio include
que contiene las cabeceras de cada archivo fuente en el nivel superior.
Drivers Contiene las fuentes para los drivers del sistema, como el computador
a bordo, el sistema de comunicaciones y el sistema de energía.
FreeRTOS Carpeta con el nombre del sistema operativo. Contiene los archivos
fuentes, cabeceras y librerías del sistema operativo según su organi-
zación particular.
Payloads Comandos y drivers relacionados con payloads. Se encuentra en un
directorio aparte pues acá se concentrarán la mayoría del software
específico de la misión.
Payloads/Cmd Implementación de comandos del sistema relacionados con payloads.
Payloads/Drivers Implementación de drivers relacionados con payloads.
SUCHAI.X Directorio con la configuración del proyecto generado por el IDE
MPLABX.
System Archivos con las fuentes del sistema base, incluye implementación de
comandos, repositorios y tareas.
53
Tabla 4.3: Configuración del compilador XC16
XC16
xc16-gcc
Categoría: Memory Model
Opción Valor Observaciones
Code model Large El tamaño de la aplicación supera el espacio de
memoria cercano.
Data model Large El tamaño de la aplicación supera el espacio de
memoria cercano.
Scalar model Large El tamaño de la aplicación supera el espacio de
memoria cercano.
Location of Code space
constant model
Categoría: Optimizations
Opción Valor Observaciones
Optimization level 0 Las optimizaciones pueden introducir cambios
en la forma de ejecución del código, por ejem-
plo, evitar ciclos for o while que realizan busy
waitings.
Categoria: Preprocessing and messages
Opción Valor Observaciones
C include dirs ..; ../Drivers/include; Configura los directorios donde el IDE busca las
../System/include; cabeceras para poder incluirlas solo por su nom-
../<RTOS>/<include>; bre y activar el auto completado.
../Payloads/Cmd/include;
../Payloads/Drivers/include
Additional Seleccionada Permite un nivel mayor de advertencias en tiem-
warnings po de compilación
Parte fundamental para cumplir con los requerimientos no operacionales, es la correcta do-
cumentación del código desarrollado. Esto tiene dos propósitos principales: por un lado, guiar
la implementación de la arquitectura para futuras modificaciones, y por otro documentar el
objetivo, parámetros y uso de cada comando.
Con el objetivo de extraer esta información desde el código, a un formato más adecuado
para su presentación y para establecer una convención en la forma de documentar, se utiliza el
software Doxygen. Al seguir un determinado formato en los comentarios agregados al código,
Doxygen es capaz de extraerlos y generar documentos bien acabados en diferentes formatos
como HTML, LATEX, RTF, entre otros.
54
ejemplo, para documentar una función en C con dos parámetros, se utiliza la sintaxis del
código 4.1. Al ejecutar Doxygen, para generar la salida como página web, se obtendría el
resultado de la figura 4.3
Código 4.1: Prueba de Doxygen
1 /* *
2 * Suma dos valores ingresados como parametros
3 * @note Solo acepta valores enteros sin signo
4 * @param a Primer elemento a sumar
5 * @param b Segundo elemento a sumar
6 * @return Suma de los parametros
7 */
8 int suma ( unsigned int a , unsigned int b )
9 {
10 return a + b ;
11 }
55
rar sus registros, manejar periféricos o ejecutar un programa general. Requiere de un
compilador de assembler para generar el binario.
2. Utilizar un compilador en C: el compilador provee un nivel mayor de abstracción al
permitir programar en un lenguaje de alto nivel y portable como C. Además, posee
librerías básicas para las funciones de cada dispositivo.
3. Utilizar una librería externa: un controlador de hardware puede requerir los servicios de
otro controlador para su funcionamiento. Es el caso típico de dispositivos que utilizan
algún protocolo de comunicación (RS232, SPI, I2C), pues su controlador consiste en
implementar una API de llamadas sobre este protocolo.
En este caso se hará un uso extensivo de las librerías escritas en C, que provee el compilador
XC16, para construir drivers más complejos a través de sus funciones base. Lo principal es
implementar los drivers de cada periférico disponible en el microcontrolador, pues serán los
recursos que utilizarán los dispositivos externos que completan el sistema del satélite.
Periférico Arquitectura
Timers Síncrono
I2C Síncrono
SPI Síncrono
UART Escritura Síncrono
UART Lectura Cola de entrada de datos seriales
En la capa de sistema operativo se ha optado por utilizar FreeRTOS. Está diseñado es-
pecíficamente para sistema embebidos y provee la capacidad de implementar tareas, que son
módulos de software que funcionan de manera concurrente y pueden compartir información a
través de diferentes estructuras de sincronización. Soporta una gran variedad de microcontro-
ladores a través de ports y aplicaciones demo, que se obtienen al descargarlo desde la página
web del proyecto ([Link]). La estructura de software de este sistema operativo
consta de cinco archivos fuentes en lenguaje C (sólo tres son necesarios para la utilidad bási-
ca), once archivos de cabecera y una capa portable dependiente del dispositivo sobre el cual
se trabaja. Fuera de los demos y diferentes ports incluidos con la descarga, el siguiente árbol
de directorio se agrega a la carpeta del proyecto y en la configuración de MPLABX:
FreeRTOS/Source/tasks.c
FreeRTOS/Source/queue.c
FreeRTOS/Source/list.c
56
FreeRTOS/Source/portable/[compiler]/[architecture]/port.c
FreeRTOS/Source/portable/[compiler]/[architecture]/portasm_[architecture].S
FreeRTOS/Source/portable/MemMang/heap_2.c
FreeRTOS/Source/include
FreeRTOS/Source/portable/[compiler]/[architecture]
El primer paso para integrar el sistema operativo, es crear el archivo de cabecera con su
configuración, llamado FreeRTOSConfig.h. El archivo se compone de una serie de defines,
que cambian el comportamiento de FreeRTOS y lo ajustan a las necesidades de la aplicación.
Una plantilla con los posibles valores a configurar se encuentra en su página web: http:
//[Link]/[Link]. Un ejemplo de este archivo se detalla en el código 4.2
En segundo lugar, se deben crear las tareas que ejecutará el sistema. En FreeRTOS, una
tarea es una función con una firma específica y que por lo general, entrará en un ciclo
infinito para mantener su ejecución en el tiempo. Deben poseer la siguiente firma: void
taskName(void *), donde el nombre de la función varia de tarea en tarea, pero siempre
debe retornar void y recibir un puntero void como parámetro. Un simple prototipo se detalla
en el código 4.3. La tarea se denomina taskTest y recibe a través de su parámetro una
cadena de texto, luego entra en un ciclo e imprime de manera periódica el string entregado.
Aunque está en un ciclo infinito, no se encuentra en una situación de busy waiting, ya que
utiliza la función vtaskDelay, que detiene su ejecución de durante un periodo de tiempo,
liberando los recursos del procesador.
Una vez programada la tarea se puede indicar al sistema operativo que la ejecute. Esto se
realiza en el archivo main.c, donde se realizan las configuraciones del hardware, se crean las
tareas y se inicia el sistema operativo. Para crear tareas se utiliza la función xTaskCreate,
indicando la función a ejecutar, un nombre, prioridad, memoria asignada y parámetros; para
detalles referirse a la documentación [19]. El sistema operativo se inicia con la llamada a
vTaskStartScheduler() y una vez alcanzado este punto, el control de los procesos queda
en manos de FreeRTOS, quien según su algoritmo de scheduling, seleccionará la tarea que
debe ejecutarse en cada instante. El llamado a la función vTaskStartScheduler no retorna
57
Código 4.2: FreeRTOSConfig.h
1 # include taskTest . h
2
3 void taskTest ( void * param )
4 {
5 const unsigned long Delayms = 500 / portTICK_RATE_MS ;
6 char * msg = ( char *) param ;
7
8 while (1)
9 {
10 vTaskDelay ( Delayms ) ;
11 printf ( " [ taskTest ] %s \ n " , msg ) ;
12 }
13 }
58
a menos que se produzca un error en la ejecución. El código 4.4 ilustra la forma de iniciar
FreeRTOS con dos tareas ejecutándose de manera simultanea. Para mantener la generalidad
no se incluyen configuraciones de hardware específicas.
1 /* RTOS Includes */
2 # include " FreeRTOSConfig . h "
3 # include " FreeRTOS . h "
4 # include " task . h "
5
6 /* Task includes */
7 # include " taskTest . h "
8
9 int main ( void )
10 {
11 /* Creating all task */
12 xTaskCreate ( taskTest , ( signed char *) " taskTest " ,
configMINIMAL_STACK_SIZE , ( void *) " T1 Running ... " , 1 , NULL ) ;
13 xTaskCreate ( taskTest , ( signed char *) " taskTest " ,
configMINIMAL_STACK_SIZE , ( void *) " T2 Running ... " , 2 , NULL ) ;
14
15 /* Start the scheduler . Should never return */
16 printf ( " >> Starting FreeRTOS \ n " ) ;
17 v Ta s k St a rt S c he d ul e r () ;
18
19 /* Never get here */
20 return 0;
21 }
Con esto concluye la integración del sistema operativo en el software de vuelo y se de-
muestra el correcto funcionamiento de FreeRTOS. Ahora, se cuenta con un nivel mayor de
59
abstracción, donde el sistema operativo tiene el control sobre los procesos que se ejecutan en
el microcontrolador y la aplicación final se implementa en las diferentes tareas que se crean.
4.5. Aplicación
60
C que represente al objeto comando, encapsulando la función a ejecutar y los meta
datos asociados.
• Repositorios: Los repositorios o proveedores de servicios, se implementan en librerías.
Se genera una API que da acceso a funciones de las capas inferiores del sistema, como
drivers para dispositivos de entrada y salida, manejo de memoria y almacenamiento
persistente.
4.5.2. Comandos
Los comandos se han implementado como funciones que poseen una firma específica y
que se convierte en un nuevo tipo de dato. En este caso, la función debe retornar un entero
y recibir sólo un parámetro, como se detalla en el código 4.6, lo que define dos aspectos
fundamentales del software:
• Todo comando debe retornar un valor que puede tomar un significado dentro de la
aplicación, en este caso, se define que el comando ha terminado su ejecución de manera
insatisfactoria si retorna un valor cero, al contrario, un valor no cero para indica el éxito
de la operación. Con esa convención se hace natural utilizar el llamado a las funciones
dentro de una sentencia condicional, que utilice directamente el valor retornado como
condición.
• Los comandos reciben un sólo parámetro, en principio de cualquier tipo, a través de
un puntero void. Esto tiene una serie de consecuencias. Por un lado se hace flexible
la llamada a la función ya que los comandos podrían recibir diferentes tipos de datos,
siempre que se desreferencien adecuadamente. También hace eficiente la llamada a
la función, pues los parámetros no son copiados. La desventaja es natural al uso de
punteros, pues este debe seguir siendo válido en el momento la ejecución del comando
para evitar desreferenciar un puntero nulo o corromper algún sector de memoria.
1 /* *
2 * Defines the prototype that every command must conform
3 */
4 typedef int (* cmdFunction ) ( void * ) ;
Para encapsular la información asociada a los comandos que llegan hasta el módulo exe-
cuter, se crea una nueva estructura de datos definida como se muestra en el código 4.7. La
estructura contiene dos campos: el puntero a la función que implementa el comando según la
definición del código 4.6 y su parámetro. Si solo se utilizara esta estructura para representar
los comandos dentro del sfotware, cada vez que se desee ejecutar uno, se debería agregar
a mano el puntero a la función objetivo. Esto supone un inconveniente para los listeners,
quienes deberían conocer todas las funciones disponibles y agregar sus definiciones mediante
la inclusión de todos los archivos de cabecera que fueran necesario. Como consecuencia, se
obtendría un método poco práctico, que no posibilita la generación de comandos en serie ni
de manera automatizada en la estación terrena.
61
Código 4.7: Estructura de comandos para executer
1 /* *
2 * Structure that represents a command passed to executer . Contains a
3 * pointer of type cmdFunction with the function to execute and one
4 * parameter for that function
5 */
6 typedef struct exec_command {
7 int param ; // / < Command parameter
8 cmdFunction fnct ; // / < Command function
9 } ExeCmd ;
Para evitar estos inconvenientes, los comandos serán representados a través de un có-
digo numérico único, delegando al repositorio de comandos la responsabilidad de asociar
los códigos a la función correspondiente. Se requiere entonces una estructura de datos, que
representa a los comandos enviados desde los listeners hacia el dispatcher y que contenga,
además, ciertos meta datos que le permiten tomar decisiones sobre su ejecución. La definición
de esta estructura se muestra en el código 4.8. Dos campos de información son especialmente
relevantes:
• Origen del comando: este campo contiene un código numérico que identifica al mó-
dulo que ha generado el comando. Esto permite implementar el filtrado de comandos
desde cierta unidad cuando, por ejemplo, no esté funcionando correctamente.
• Requerimiento de energía: este campo indica el nivel de energía que requiere el
comando para ejecutarse, así se pueden filtrar aquellos que requieran más energía que
la disponible.
1 /* *
2 * Structure that represent a command passed to dispatcher . Contains
3 * only a code that represent the function to call , a paremeter and
4 * other command ’s metadata
5 */
6 typedef struct ctrl_command {
7 int cmdId ; // / < Command id , represent the desired command
8 int param ; // / < Command parameter
9 int idOrig ; // / < Metadata : Id of sender subsystem
10 int sysReq ; // / < Metadata : Level of energy the command requires
11 } DispCmd ;
62
utilizado en el proyecto. Este ejemplo es tiene una gran funcionalidad dentro del software de
vuelo, pues permite obtener información sobre el uso de memoria del sistema operativo. El
objetivo es utilizar la función xPortGetFreeHeapSize de FreeRTOS, que entrega la cantidad
de memoria en bytes disponible en el heap [19] para desplegarla en consola. La convención
utilizada indica que retornar un valor cero desde el comando significa error, lo cual demuestra
su conveniencia en este caso, pues el comando puede retornar directamente la cantidad de
memoria disponible.
1 /* *
2 * Performs debug taks over current RTOS . Get rtos memory usage in bytes
3 *
4 * @param param Not used
5 * @return Availible heap memory in bytes
6 */
7 int o b c _g e t_ r to s _ me m or y ( void * param )
8 {
9 size_t mem_heap = x P o r t G e t F r e e H e a p Si z e () ;
10 printf ( " Free RTOS memory : %d " , mem_heap ) ;
11
12 return mem_heap ;
13 }
63
3. Descentralizar cada arreglo de comandos en en archivo diferente: cada archivo que im-
plementa un grupo de comandos cuenta con un arreglo con las funciones. El repositorio
utiliza este arreglo como una variable externa.
• V: Mejor agrupación de comandos. Bajo impacto en el código al agregar uno nue-
vo, pues sólo se modifica el archivo donde se encuentra sin intervenir el repositorio.
• D: Se dificulta el seguimiento de cambios en los códigos que identifican cada
comando. Agregar un nuevo grupo de comandos, en un nuevo archivo, requiere
modificaciones en el repositorio.
4. Descentralizar comandos y utilizar enums para asignar códigos identificadores: similar
a la alternativa anterior, pero el identificador de cada comando y la forma de llenar los
arreglos se basa en una estructura de enumeración de C, que abstrae el uso de códigos
numéricos por sentencias textuales.
• V: Agregar un comando sólo requiere cambios locales en el archivo que agru-
pa un determinado tipo. Se facilita el seguimiento de cambios en los comandos
disponibles, pues la definición textual de la enumeración es fija.
• D: Aún se requiere modificar el repositorio de comandos cuando se agrega un
archivo con un nuevo grupo de funciones. Al completar los arreglos de funciones
a través de las enumeraciones, no se puede crear un arreglo de manera manual en
memoria de programa y se utiliza más memoria RAM. Se requiere una función
que configure los arreglos cada vez que se inicia el sistema.
Cada archivo con un grupo de comandos, debe tener una estructura de enumeración (enum
en C) que representan los códigos de cada comando. El primer valor de la enumeración debe
ser diferente para cada grupo para evitar ambigüedades y para agruparlos también por su
identificador. El último valor de la enumeración es un elemento dummy, que sólo es utilizado
para controlar el tamaño del arreglo. Luego, por cada función que implemente un comando,
se agrega un valor en la enumeración, como en el código 4.10.
1 /* *
2 * List of availible commands
3 */
4 typedef enum {
5 obc_id_reset = 0 x1000 , // / < @cmd_first
6 obc_id_get_rtos_memory , // / < @cmd
7
8 ppc_id_last_one // Dummy element
9 } OBC_CmdIndx ;
64
En este caso se registran dos comandos, obc_reset y obc_get_rtos_memory. La conven-
ción de sintaxis utilizada indica que se debe utilizar el prefijo del grupo, obc_, y un prefijo que
indique que se trata de un código identificador, id_. El código 4.10 también muestra como se
utiliza Doxygen para mantener en la documentación del proyecto una lista actualizada con el
valor de cada enumeración que permita de manera directa asociar el código de un comando
cuando estos se generen de manera remota.
También en el archivo cmdOBC.c se debe crear el arreglo que contiene la lista de funcio-
nes, en este caso denominado obc_Function cuyo tamaño se determina a través del último
elemento de la enumeración. Esta lista debe ser inicializada a través de una función que se
ejecutará al inicio del sistema, en este caso se denomina obc_onResetCmdOBC. El código 4.11
detalla este proceso.
Este repositorio corresponde a una librería con funciones que brindan acceso a los coman-
dos registrados en el sistema. Sus dos responsabilidades principales son:
• Inicializar el repositorio de comandos creando los arreglos con las funciones disponibles.
• Asociar cada código de comando con su función correspondiente.
Los códigos de los comandos se representan como un entero sin signo de 16 bit, en formato
hexadecimal. Los 8 bits más significativos identifican el grupo, dejando los 8 bit restantes
65
para la posición dentro de su arreglo. Esto limita la cantidad de comandos por grupo a un
total de 256 como se detalla en la tabla 4.6
Tabla 4.6: Estándar para identificar comandos
Por diseño, una vez inicializado, el repositorio tiene acceso de sólo lectura, de modo que no
se hace necesaria la implementación de sincronización para su uso. La única acción que puede
generar una condición de data race es la lectura de un elemento del arreglo de comandos, sin
embargo, estos son almacenados en memoria interna, por lo que es una operación atómica y
no genera problemas de acceso concurrente.
Este repositorio almacena aquellas variables que contienen información sobre el estado de
operación del sistema satelital. Las variables de estado son consultadas por los listeners para
tomar decisiones sobre los comandos que se generarán. También cumple la función de cerrar
el lazo de control en el sistema, puesto que los listeners sólo generan el comando sin tener
información sobre la ejecución o su resultado. El dispatcher utiliza esta información para
comparar los requerimientos de cada comando con los recursos disponibles en el sistema y
decidir su ejecución. Los comandos tienen acceso de escritura y lectura sobre el repositorio
de estados, pues se espera que ajusten variables de funcionamiento o cambien el modo de
operación del satélite.
Las operaciones básicas que provee el repositorio son: leer una variable de estado, lo cual
se realiza en la función dat_getCubesatVar; escribir el valor de una variable de estado, lo
cual se realiza en la función dat_setCubesatVar; e inicializar el repositorio ante un reinicio
del sistema a través de la función dat_onResetCubesatVar. Estas funciones se encuentra
implementadas en el código 4.13.
Este repositorio es leído y escrito de manera concurrente por una serie de tareas, por lo que
se puede generar una condición de data race. Esto se hace más evidente cuando se implementa
en una memoria externa, lo que puede resultar operaciones de lectura y escritura no atómicas,
donde además se requiere utilizar recursos compartidos como periféricos de comunicaciones.
Por esta razón, se debe implementar una estructura de sincronización que provea la exclusión
mutua entre las diferentes tareas que acceden a este repositorio. Esta situación se observa en
el código 4.13 cuando se usan las funciones xSemaphoreTake y xSemaphoreGive de FreeRTOS
[19].
66
Código 4.12: cmdRepository.c
67
Código 4.13: dataRepository.c
68
de tolerancia a fallos. Entre los métodos explorados se encuentra:
En general, cualquier tipo de memoria no volátil se puede usar para estos fines, aunque
si se utilizan lo métodos 2 o 3, es conveniente contar con una memoria de acceso aleatorio,
en lugar de dispositivos que leen o escriben por bloques, ya que el uso de este repositorio es
bastante intenso dentro del funcionamiento del sistema.
69
el código 4.13 se implementa este diseño en el repositorio de estados. Sin embargo, no contar
con un almacenamiento persistente de los datos es una limitación crítica, ya que el objetivo
de este módulo es que el sistema de vuelo sea tolerante a reinicios inesperados, volviendo a
funcionar según sus últimos estados almacenados. Este método es factible de utilizar para
pruebas o bien como un sistema de respaldo en caso de que una falla fuerce al sistema a
trabajar con funcionalidades mínimas.
Una parte fundamental de este módulo es la cola de comandos, donde llegan los requeri-
mientos realizados por los listeners en espra a ser procesados. Al ser un recurso compartido,
presenta el esquema típico del productor-consumidor, con múltiples productores y un único
consumidor, por lo que el acceso concurrente debe estar sincronizado (ver figura 4.4). La solu-
ción a este tipo de esquemas es bien conocido y se logra mediante la utilización de semáforos
o mutexes.
Productor Consum.
1 1
Cola sincronizada
Produce y encola Consume y procesa
Dato Dato Dato Dato Dato Dato
elementos elementos
Productor Consum.
n n
Sin embargo, FreeRTOS provee una estructura de datos adecuada para esta tarea, deno-
minada queue, que poseen las siguientes características [19][8]:
70
• Escribir y leer un elemento en la cola implica una copia byte a byte de los datos.
• Permiten operaciones de lectura y escritura en múltiples tareas.
• La lectura de una cola es bloqueante si la cola está vacía. La tarea que espera por un
elemento, despierta de manera automática cuando hay datos disponibles.
• La escritura en una cola es bloqueante si la cola está llena. La tarea que espera por
escribir en la cola, despierta de manera automática cuando hay espacios disponibles.
Figura 4.5: FreeRTOS Queue. Permiten el acceso sincronizado a datos en una cola, para la
comunicación entre tareas. Se crean con un taño fijo y los elementos son almacenados por
copia. Fuente: http: // www. freertos. org/ Embedded-RTOS-Queues. html
71
La implementación de este módulo corresponde al diagrama de flujo de la figura 4.6.
Las tres funcionalidades básicas del procesador de comandos son: recibir un comando y
obtener sus meta datos; determinar si su ejecución es posible; y construir la estructura que se
entregará al ejecutor. El código 4.14 implementa este diagrama de flujo, agregando una tarea
de FreeRTOS basada en eventos, pues despierta solamente cuándo existe algún comando
disponible en la cola. La función check_if_executable contiene la lógica que decide si
puede ejecutarse o no, en base a sus meta datos y el estado actual del sistema. Finalmente, se
consulta al repositorio por la función asociada al código entregado y se construye la estructura
de datos que representa un comando para el executer, que contiene el puntero a la función
y su parámetro. Como sólo existe un proceso que ejecuta los comandos, el dispatcher debe
esperar a que termine su ejecución antes recuperar uno nuevo. Esta comunicación también
se logra a través de una cola, de un sólo elemento, donde el executer envía el resultado que
retornó el comando que acaba de ejecutar.
72
Código 4.14: taskDispatcher.c
73
4.5.6. Implementación del executer
El flujo de operación del executer se detalla en la figura 4.7, y es bastante simple, en cuánto
cumple sus tres obligaciones de manera secuencial. Esta simplicidad, sin embargo, no revela
la verdadera utilidad de este módulo: proveer un ambiente de ejecución exclusivo al comando.
Por diseño, sólo un módulo ejecutor existe en el sistema, por lo que una vez alcanzado este
punto, el comando toma el control exclusivo del procesador, de todos los recursos de hardware
y software, para realizar su tarea. Además aprovecha la generalidad definida por la interfaz
de los comandos para permitir la ejecución de cualquier función que implemente la firma
requerida.
El código 4.15 detalla la implementación de este módulo. Al momento de crear esta tarea
se deben tener en cuenta las siguientes consideraciones:
• Entregar la mayor cantidad de memoria de stack posible. Esta tarea realiza todas las
funciones importantes para el sistema y cada función que se ejecuta utiliza la memoria
de stack que se le asigna. A diferencia del resto de las tareas, donde su uso de memoria
es parejo en el tiempo, el executer llama a diferentes funciones y algunas de ellas pueden
74
requerir más memoria que otras. Como el objetivo es proveer el entorno de ejecución
para un comando, se debe contar con la memoria suficiente de modo que ningún co-
mando cause un stack overflow, lo cual se debe determinar de manera experimental,
utilizando las herramientas de depuración disponibles en el entorno de desarollo.
• Asignar la prioridad más alta posible. De esta manera se consigue que el comando en
ejecución no sea interrumpido por ningún otro proceso con lo cual se aseguran dos
puntos: primero, el comando se ejecuta en el menor tiempo posible; segundo, se elimina
la necesidad de brindar una sincronización excesiva de los recursos compartidos de
hardware, asegurando el acceso exclusivo.
75
4.5.7. Implementación de listeners
Los listeners, como se describe en el capítulo 3, son los módulos encargados de implementar
la lógica de generación de comandos dentro la aplicación. Existen una serie de listeners bajo la
premisa de que, a cada uno, le corresponde controlar un determinado subsistema del satélite.
Estos módulos se implementan como tareas de FreeRTOS, que se activan de manera periódica,
ejecutando operaciones de control que tienen como resultado una serie de comandos, que son
agregados a la cola del dispatcher. La lógica de operación se detalla en el diagrama de la
figura 4.8. FreeRTOS ofrece dos funciones para obtener periodicidad en la ejecución de las
tareas, mediante la técnica de suspender su ejecución por una cantidad determinada de ticks,
estas son, vTaskDelay y vTaskDelayUntil. Cada una de estas funciones cambia el estado
de la tarea a suspendida, donde no utiliza ningún recurso del procesador, para que luego
del tiempo especificado retome su ejecución. La diferencia entre ambos métodos, es que el
primero siempre suspende la tarea durante un tiempo fijo, mientras que el segundo mantiene
fijo el tiempo que transcurre entre ambas llamadas de delay [19]. vTaskDelayUntil es más
adecuada para tareas de tipo hard real-time, por lo que es la utilizada en los listeners para
proveer una resolución de tiempo más precisa.
Una de las funcionalidades principales que se puede esperar del sistema es la ejecución
de acciones de manera periódica, las que incluyen tareas de control interno del propias del
susbsistema del computador a bordo. Este listener es denominado housekeeping y su lógica
de operación consiste en ejecutar comandos de control interno a periodos fijos de tiempo.
Según las necesidades del sistema, se puede implementar varios periodos de tiempo, en este
76
caso ejecutarán comandos cada 10 segundos, 1 minuto, y 1 hora. Para guiar la programación
de este módulo, su lógica se detalla en la figura 4.9.
Con la implementación del primer listener y la correcta inicialización del sistema operativo,
las tareas y los repositorios, se tiene la primera versión funcional del software de vuelo. Si
bien no se realiza ninguna tarea fundamental para la misión satelital, la generalidad de la
implementación responde, principalmente, a los requerimientos no operacionales del proyecto
y se convierte en la base para trabajos futuros. Para unir el desarrollo anterior, se debe
programar el punto de entrada de la aplicación: la función main. Esto se muestra en el
código 4.17, dónde se han omitido las configuraciones de hardware específicas. Este punto del
desarrollo está marcado como la versión v0.1-base dentro del sistema control de versiones
y se puede encontrar en los anexos.
77
Código 4.16: taskHouskeeping.c
78
Código 4.17: main.c
79
El resultado de la programación y ejecución del software en el microcontrolador, se muestra
en el registro 4.18.
Código 4.18: Registro de ejecución del software de vuelo
80
4.6. Específico al proyecto SUCHAI
En las secciones anteriores se implementa la base del sistema de vuelo, con mínimas
funcionalidades, básicamente completando la arquitectura de software propuesta. Sobre esta
base, se agrega el resto de los requerimientos operacionales del satélite, lo que implica extender
el software mediante dos métodos: agregar listeners que controlan subsistemas específicos del
satélite y programar comandos para cada función que sea necesaria.
La salida de datos hacia el puerto serial es bastante directa, pues uso del controlador
implementado para los módulos UART, además de la adaptación de funciones comunes como
printf. Como los mensajes de debug están bastante extendidos a lo largo del programa,
las tareas que se ejecutan de manera concurrente, pueden requerir el acceso simultaneo a
este recurso compartido. Por esto, una adaptación importante consiste en convertir a printf
en una función thread safe, mediante la utilización de herramientas de sincronización que
provean la exclusión mutua sobre este recurso.
La solución consiste en implementar un listener que monitorice la hora y fecha del sistema,
para obtener desde el plan de vuelo el comando correspondiente a cada instante. El plan de
vuelo consiste en una lista ordenada temporalmente, con los códigos de los comandos y sus
81
Figura 4.10: Diagrama de flujo para taskConsole.
4.6.3. Comunicaciones
Uno de los módulos fundamentales del sistema satelital corresponde a las comunicaciones.
El sistema debe ser capaz de recibir y procesar telecomandos enviados desde la estación
terrena, enviar la telemetría generada hacia la estación terrena, activar la transmisión de
82
Figura 4.11: Diagrama de flujo para taskFlightPlan.
Por diseño, se tienen dos formas de completar estos requerimientos: agregar comandos y
programar un listener. Las funciones que se deben implementar a través de nuevos comandos
incluyen:
El software de vuelo debe ser capaz de recuperarse adecuadamente ante un renicio ines-
perado. Esta situación se puede provocar por diferentes motivos como: falla en la ejecución
de una instrucción en el microcontrolador, un reinicio provocado por el watchdog si es que la
83
Figura 4.12: Diagrama de flujo para taskCommunications.
84
aplicación se congela, la falta de energía en los buses de alimentación por la descarga de las
baterías, sobrecorrientes o por algún factor externo como la radiación.
Para realizar estas funciones, se implementa una tarea cuya función sea ejecutar las ac-
ciones de inicialización del sistema. Esta es la primera en entrar en funcionamiento y tiene
prioridad por sobre el resto, ya que sus operaciones son fundamentales para el correcto fun-
cionamiento de todo el satélite. Esta tarea no es periódica, por el contrario, sólo se ejecuta
una vez, para luego ser eliminada. Antes de terminar su ejecución, se ocupa de iniciar el
resto de los listeners, quienes toman el control del sistema. La implementación se basa en el
diagrama de flujo de la figura 4.13
85
Capítulo 5
Pruebas y resultados
Mediante las herramientas que provee el IDE MPLABX, se obtienen diferentes estadísticas
sobre el código que se ha programado, para generar una medida básica de la envergadura del
proyecto. Lo anterior se muestra en la tabla 5.1.
86
la tabla 5.2.
Tabla 5.2: Uso de memoria de la aplicación
Memoria [bytes]
Tarea Prioridad
Asignada Usada Porcentaje de uso
idle 0 115 79 69 %
flightplan 2 230 145 63 %
communications 2 230 125 54 %
console 2 230 91 39 %
housekeeping 2 230 97 42 %
dispatcher 3 230 109 47 %
executer 4 575 85 14 %
87
Central Processing Unit (CPU) se ve sobre cargada con la ejecución del software o bien, si
quedan recursos disponibles para agregar más funcionalidades.
Figura 5.1: Registro de uso del procesador. El registro cambia de 0 a 1 cada vez que se
entra en estado idle. Si no hay tareas que ejecutar esto ocurre cada 100 ms, de otro modo se
observan periodos más largos.
Figura 5.2: Porcentaje de uso del procesador. La solución no sobrecarga la CPU, dejando
un 91.8 % de capacidad de cómputo para nuevas funcionalidades
88
5.2. Pruebas de integración
5.2.1. Configuración
• Entorno de prueba:
– Caja limpia para albergar el satélite.
– Computador para registro de datos.
– Programador Microchip ICD3.
– Cable USB para comunicación serial.
– Equipo de radio portátil UHF.
– Cámara de video para registro de la prueba.
– Multímetro.
• Estación terrena:
– Antena monopolo, 50Ω, de baja ganancia.
– Equipo de radio ICOM 910H.
– Computador para capturar y procesar audio.
• Satélite:
– Computador a bordo con placa madre CubesatKit rev. D y módulo de procesador
CubesatKit D1 con PIC24F256GA110.
– EPS CS-1UEPS2-NB ClydeSpace
– Transceptor AllSpace ASCOM-01 rev. 3
– Paneles solares.
89
satélite, a través del software de vuelo, funciona de manera autónoma y la interfaz de debug
sólo se utilizará para registrar información útil para la prueba.
Figura 5.3: El satélite se encuentra en una caja limpia, conectado a un computador que
registra la prueba (a). La estación terrena se controla remotamente, a través del software
GPredict y el proveído por el fabricante del transcevier(b)
90
5.2.2. Resultados
Los resultados obtenidos son utilizados para verificar los requerimientos operacionales de
la misión, en específico, aquellos que dependen directamente del software de vuelo.
Área de comunicaciones
* Setting TRX
Setting beacon : SUCHAIATINGDOTUCHILEDOTCL -
>> TRX Setting BEACON :
Setting Offset ...
Setting Content ...
Setting Beacon Length ... 26
La correcta ejecución de estos comandos, como se muestra en el registro 5.1, implica una
comunicación activa con el dispositivo, así como una confirmación de la correcta configuración
de las variables escritas. Con esto se comprueba que el dispositivo, en lo referido a su interfaz
con el software, se encuentra operativo.
El silencio radial se lleva a cabo configurando el transcevier en modo silencioso al inicio del
sistema. Como medida adicional, se evita la generación de cualquier transmisión, inhibiendo
la ejecución de comandos durante el periodo de inactividad. Durante la prueba, se mantiene
cerca la radio portátil para detectar cualquier transmisión, así como para generar intentos
de comunicación con el satélite que no deben tener respuesta. El resultado se detalla en el
registro 5.2 que revela que, en efecto, ningún comando de transmisión de datos se efectúa
durante el periodo de inactividad radial. También se comprueba el tiempo de inactividad
toma 33 minutos, de acuerdo a lo requerido.
Registro 5.2: Registro del periodo de inactividad
91
Despliegue de antenas: este proceso está a cargo de la secuencia de inicio del software
de vuelo, que activa y controla el sistema de despliegue. El proceso se muestra en la consola,
como se observa en el registro 5.3. En este caso luego del séptimo intento de despliegue se
detecta que el switch indicador del despliegue se ha liberado continuando con el inicio del
sistema.
Registro 5.3: Registro del despliegue de antenas
En la figura 5.4 se observan las antenas antes y después del proceso de despliegue.
92
falla, a lo largo del proceso de desarrollo, ha hecho imposible la comunicación confiable entre
la estación terrena y el satélite. Los detalles de su detección y posibles soluciones escapan al
desarrollo de este trabajo.
A los cuatro minutos de funcionamiento se genera el primer beacon, cuyo contenido es:
SUCHAIATINGDOTUCHILEDOTCL-0. Esto es el identificador seguido de un guión y un número
que indica que este mensaje no tiene más información. El siguiente beacon corresponde al tex-
to: SUCHAIATINGDOTUCHILEDOTCL-11000017H30761940780001 e incluye variables de estado
en su contenido, según lo especificado en la tabla 5.4.
En la estación terrena se reciben estas señales y son procesadas por el software que permite
decodificar el código Morse. Un ejemplo de la señal recibida en la estación terrena se muestra
en la figura 5.5. Los textos obtenidos para una secuencia de tres beacons transmitidos fueron:
O0000V0000000XHX02000000000000000GBW00000000DK000024,
O0000V0000000XHX02000000000000000GBW00000000DK000025,
O0000V0000000XHX02000000000026.
93
Tabla 5.4: Beacons generados por el software de vuelo
Figura 5.5: Beacon recibido en la estación terrena. Se utiliza el software MixW para deco-
dificar una transmisión de radio demodulada por la estación terrena.
Lo anterior claramente significa una falla, debido a que no se recibe el texto esperado, y
se debe a un error del equipo de comunicaciones al configurar el nuevo texto del beacon. Se
descartan errores en la estación terrena debido a que la secuencia decodificada tiene sentido:
al final de cada linea recibida se observa un contador, que es agregado automáticamente por
el transcevier, y que aumenta de manera secuencial en cada transmisión. El cero al inicio
94
de la secuencia, también es parte del formato agregado por el dispositivo transmisor, lo cual
permite concluir que es este quien no configura de manera correcta el mensaje.
El protocolo de enlace, una vez identificado el satélite, requiere enviarle una señal iniciar la
descarga de datos o ejecutar telecomandos. Debido a las fallas del equipo de comunicaciones,
que no permiten la recepción de telecomandos, el satélite funciona un modo de respaldo. En
este modo, ante la presencia de un nivel fuerte de señal en la banda asignada, durante al
menos 10 segundos, se inicia automáticamente la descarga de los datos recolectados.
95
En este modo, para ordenar una transmisión de telemetría, basta con enviar la señal de
la portadora durante una cantidad de tiempo determinada, por ejemplo, 10 segundos.
No se puede seleccionar el tipo de telemetría a descargar, sino que se envían todos los
datos recolectados hasta el momento.
Durante la prueba sólo estuvo disponible el modo de respaldo, por lo que se transmite la
portadora durante el tiempo especificado en la configuración de la aplicación, en este caso,
10 segundos. El satélite detecta la señal y el software determina si estuvo presente el tiempo
necesario, como se detalla en el registro 5.6.
96
Registro 5.6: Descarga de telemetría en modo de respaldo
Control central
Plan de vuelo: la ejecución del plan de vuelo está a cargo del listener denominado
taskFlightPlan el cual, de manera periódica, consulta la lista de comandos manejada por
el repositorio de datos y determina el siguiente que se debe ejecutar.
Para la verificación de este requerimiento, se revisan los registros de la consola, que cuentan
con una estampa de tiempo, para determinar la frecuencia y momento de ejecución de los
97
Tabla 5.5: Plan de vuelo
98
Figura 5.7: Gráfico de funcionamiento del plan de vuelo. Se observan los dos comandos
programados ejecutándose cada 10 minutos. Cerca de las 19:39 hrs. se produce un reinicio
del sistema y como respuesta a la falla, el plan de vuelo ejecuta el comando pendiente.
operadores del satélite, debido a que contiene todos los datos relevantes sobre el estado de
funcionamiento del sistema. Un ejemplo de esta información se muestra en el registro 5.8.
Para comprobar la correcta actualización de las variables de estado durante el funcionamiento
del satélite, se ha tomado un set de ellas y se ha graficado su valor en el tiempo, lo cual se
muestra en la figura 5.8.
El set de variables consideradas en el gráfico 5.8, tiene por objetivo mostrar el funciona-
miento del repositorio de estados, más que un análisis exhaustivo de sus valores instantáneos.
Los resultados muestran cómo este repositorio permite mantener actualizado el estado de
funcionamiento del satélite, retroalimentando al resto de los módulos de software con esta
información. Acá se almacenan variables con información instantánea, como el caso de los
voltajes y corrientes en el sistema de energía, o el nivel RSSI presente el sistema de comu-
nicaciones. Otras son modificadas de manera periódica como la hora actual del sistema o
el tiempo total de operación. Algunas variables representan configuraciones del satélite y
no varían, a menos que se instruya una modificación manual de ellas, como el caso de las
potencias de transmisión de telemetría y beacon.
Es muy importante que ciertas variables mantengan su valor entre cada reinicio del siste-
ma, para que el software de vuelo retome su estado de operación anterior a una falla o reset.
Esto se verifica en las pruebas de reinicio, revisando el valor de las siguientes variables:
ppc_lastResetSource, ppc_hoursAlive, ppc_hoursWithoutReset, ppc_resetCounter y
dep_ant_deployed. La información se resume en el gráfico de la figura 5.9. Se observa que
ciertas variables se van actualizando con el tiempo, como el caso de las horas de funciona-
miento y las horas sin reinicio. Las pruebas de reset comienzan a las 19:44 hrs. lo cual se
refleja en el valor de las variables ppc_hoursWithoutReset y ppc_resetCounter, que indi-
can la cantidad de horas que el sistema ha funcionado sin reiniciarse y el contador de estos
eventos, respectivamente. La prueba incluye reinicios generados por diferentes fuentes, como
software, hardware y el watchdog, las cuales se observan en la variable ppc_lastResetSource.
99
Registro 5.8: Comandos generados por el plan de vuelo
===================================
Contenido de CubestatVar :
===================================
ppc_opMode = 1 // Modo de operación
p pc _ l as t Re s et S o ur c e = 4 // Oringen de último reinicio
ppc_hoursAlive = 0 // Total de horas de funcionamiento
ppc_hoursWithoutReset = 0 // Horas sin reinicio
ppc_resetCounter = 1 // Contador de reinicios
ppc_enwdt = 1 // Estado del watchdog
ppc_osc = 3 // Estado del oscilador
p p c _ M B _ n O E _ U S B _ n I N T _ s t a t = 0 // Estado del selector del USB
p pc _ M B_ n OE _ MH X _ st a t = 1 // Estado del selector del TRX
p pc _ M B_ n ON _ MH X _ st a t = 0 // Estado del selector de voltaje del TRX
pp c_ MB _nO N_ SD _st at = 0 // Estado del selector de la tarjeta SD
-----------------------------------
dep_ant_deployed = 1 // Estado de despliegue de las antenas
dep_ant_tries = 3 // Intetos de despliegue de las antenas
-----------------------------------
rtc_year = 13 // Fecha del sistema , año
rtc_month = 8 // Fecha del sistema , mes
rtc_week_day = 6 // Fecha del sistema , dia
rtc_day_number = 23 // Fecha del sistema , dia de la semana
rtc_hours = 20 // Hora del sistema , horas
rtc_minutes = 35 // Hora del sistema , minutos
rtc_seconds = 19 // Hora del sistema , segundos
-----------------------------------
eps_bat0_voltage = 172 // Voltaje de la batería ( ADC )
eps_bat0_current = 902 // Corriente de la batería ( ADC )
eps_ bus5V_cur rent = 1023 // Corriente en bus 5 V ( ADC )
eps_ bus3V_cur rent = 1023 // Corriente en bus 3 V ( ADC )
eps_bat0_temp = 559 // Temperatura de la batería ( ADC )
eps_panel_pwr = 0 // Potencia del panel solar ( ADC )
eps_status = -16384 // Estado de la EPS ( ADC )
eps_soc = 8 // Nivel de carga de la batería
eps_socss = 8 // Estimador de la carga de la batería
eps_state_flag = 2 // Estado del estimador de carga
eps_charging = 1 // Estado de carga de la batería
-----------------------------------
trx_frec_tx = -14510 // Frecuencia de TX ( ADC )
trx_frec_rx = -16448 // Frecuencia de RX ( ADC )
trx_opmode = 16 // Modo de operación del TRX ( ADC )
trx_temp_hpa = 2164 // Temperatura del HPA ( ADC )
trx_temp_mcu = 1150 // Temperatura MCU del TRX ( ADC )
trx_rssi = -53 dBm // Nivel de señal ( dBm )
trx_beacon_pwr = 1 // Potencia del bacon ( ADC )
trx_ telemetry _pwr = 1 // Potencia de la telemetría ( ADC )
trx_status_tc = 0 // Estado de recepción de comandos
trx_count_tm = 0 // Contador de telemetría
trx_count_tc = 0 // Contador de telecomandos
trx_lastcmd_day = -1 // Días desde el último telecomando
-----------------------------------
100
Figura 5.8: Gráfico con el valor de las variables de estado en el tiempo. Arriba, variables
relacionadas con el computador a bordo. Abajo, el valor del Received Signal Strength Indicator
(RSSI) del transcevier, los máximos coinciden con las transmisiones de beacon.
La prueba del buen funcionamiento del sistema, ante estos eventos, es que los valores de las
variables de estado siguen siendo coherentes cada vez que el sistema se vuelve a iniciar, como
se ve en el caso del indicador de antenas desplegadas (dep_ant_deployed), el contador de
reinicios y la cantidad total de horas de funcionamiento.
Inicio del sistema: el inicio del sistema cuenta de dos etapas. En la primera, se inician
funciones de bajo nivel como configuraciones de periféricos del procesador, puertos de entrada-
salida, instanciar variables del sistema operativo e iniciarlo. Cuanto esta etapa se ejecuta
correctamente, se han configurado los puertos seriales y por lo tanto está disponible la salida
de depuración a través de la consola. En el registro 5.9 se muestra este proceso, que concluye
con el inicio de FreeRTOS y la tarea de deployment encargada de ejecutar la segunda etapa.
101
Figura 5.9: Variables de estado ante un reinicio. El repositorio de estados mantiene consis-
tente el valor de las variables ante fallas o reinicios.
// Configuraciones de perifericos
Initializing sattelite bus
* Microcontroller IO pins
* CubesatKit MB
* PC104 Bus
102
de la capa de aplicación, incluyendo: periféricos externos, repositorios, estructuras de datos y
el resto de los listeners. En este momento se ejecuta, si corresponde, el periodo de inactividad,
así como el despliegue de antenas.
La salida por consola, que se muestra en el registro 5.10, es incremental a cada función
ejecutada y demuestra la correcta operación de cada etapa de la secuencia de inicio. También
se demuestra la capacidad del software para recordar el estado anterior a su reinicio, siendo
capaz de determinar si es la primera vez que se inicia y en tal caso, ejecutar el periodo de
inactividad junto al despliegue de antenas.
Registro 5.10: Secuencia de inicio de alto nivel
103
Setting Beacon Length ... 26
Al final de esta secuencia, se inician el resto de los listeners que comienzan su ejecución en
segundo plano. El éxito de la operación se logra al visualizar el prompt de la consola serial,
indicando que el satélite está preparado recibir comandos y registrar los sucesos del software
de vuelo, lo cual se muestra en el registro 5.11
Registro 5.11: Pantalla de bienvenida de la consola serial del satélite
>>
Área de energía
A partir de los datos del gráfico 5.10, se verifica el correcto funcionamiento del sistema
de energía. Los valores de corriente leídos en la EPS son normales: al rededor de 30 mA
104
Figura 5.10: Gráfico con variables de EPS y estimación de SOC. El sistema de energía se
comporta según lo esperado, según lo indicado por las variables de corriente y voltaje. Se
observa una correspondencia entre la variable eps_charging y el voltaje de las baterías. El
nivel de SOC estimado por el software de vuelo corresponde a los calculados a posteriori.
para el bus de 3.3 V, al que se conecta la placa de payloads, y 50 mA para el bus de 5.0 V,
donde se encuentra el computador a bordo. Las baterías se cargan en cuanto se conecta el
puerto USB, lo que es indicado por la variable eps_charging y se refleja en el voltaje leído.
También se verifica el requerimiento de estimar la carga presente en las baterías, a través
de la variable eps_soc y contrastando estos datos con valores calculados a posteriori, según
los datos de voltaje y corriente. Cabe destacar que la diferencia en la estimación del SOC,
observada en los registros de las 20:01 hrs. es normal, producto de una corrección según los
datos de temperatura, realizada por el software de vuelo.
Presupuesto de energía: el nivel de SOC, como variable de estado, indicará la energía que
se dispone para ejecutar comandos en el sistema. El encargado de velar por el cumplimiento
del presupuesto energético es el módulo Dispatcher, quien realiza una comparación entre la
energía requerida por un comando y la disponible en ese momento.
105
Para verificar el requerimiento de contar con un presupuesto de energía, que guía las
operaciones del satélite, se lleva a cabo el test de SOC. Para esto, de manera simulada, se
cambian los requerimientos energéticos de una serie de comandos, a niveles mayores que
la energía disponible, para luego intentar su ejecución. El comando correspondiente es el
0x8006 o tcm_set_sysreq, que cambia los requerimientos energéticos de todas las funciones
del grupo TCM, encargadas de generar telemetría y beacons. En el registro 5.12 se observa la
ejecución de este comando, cambiando los requerimientos a nivel 10, cuando se dispone de un
SOC de 4. Así cuando se intenta ejecutar un comando del grupo 0x8000 estos son rechazados
por el Dispatcher evitando su ejecución.
Registro 5.12: Registro de la prueba de nivel SOC bajo
Esta situación no solo ocurre bajo condiciones de prueba, puede ocurrir que tras algu-
nas operaciones que demandan grandes cantidades de energía, el nivel de SOC disminuya,
quedando bajo el umbral que requieren los comandos. Este es el caso de las transmisiones
de telemetría y beacons, como se observa en el registro 5.13, donde luego de dos envíos de
telemetría el nivel de SOC baja a 3, causando que una posterior solicitud de descarga de
datos sea rechazada.
Registro 5.13: Comando rechazado debido a un nivel de SOC bajo
106
[20: 09:02.414 715] [ Dispatcher ] Orig : 0 x1104 | Cmd : 0 x5000 | Param : 0
[20: 09:02.429 875] d r p _ u p d a t e A l l _ d a t _ C u b e s a t V a r () ..
[20: 09:02.710 113] SOC = 3
La tabla 5.6 resume los resultados de la prueba de SOC. Se observa que el control realizado
por el módulo Dispatcher aplica efectivamente las indicaciones del presupuesto de energía
planificado, el cual se expresa en el parámetro SOC y la cantidad de energía que requiere
cada comando. Durante la prueba todos los comandos que requieren al menos el nivel de
energía disponible fueron ejecutados mientras que aquellos con requerimientos superiores
fueron rechazados, validando el requerimiento.
El power budget se aplica a diferentes niveles dentro del sistema que representa el satélite.
La parte que corresponde al software de vuelo, tiene relación con la estimación de la cantidad
de energía disponible en base a los parámetros que entrega la EPS, y con evitar la ejecución
de comandos que requieren más recursos energéticos que los disponibles. El resto de la pla-
nificación energética queda por parte del equipo de operación del sistema, en lo que refiere a
determinar la cantidad de energía correcta para cada comando, la frecuencia de ejecución de
aquellos de alto consumo, como el envío de beacon, o la correcta programación del plan de
vuelo.
107
Órbita
Payloads
108
Capítulo 6
Conclusiones
En lo que se refiere a la capa de aplicación del software de vuelo, el gran valor del proyecto
es haber analizado y adaptado el patrón de diseño command pattern. Según lo analizado en
el proceso de diseño, este patrón permite implementar todos los requerimientos operaciona-
les, lo cual se ha demostrado en las pruebas realizadas. Tal como se plantea en la literatura
sobre el uso de patrones de diseño [10] [11], se concluye que esta metodología de trabajo
ha disminuido considerablemente los riesgos asociados al desarrollo de la aplicación, por los
siguientes motivos: los patrones de diseño son esquemas bien probados para resolver cierta
clase de problemas; están claramente documentados; proveen un lenguaje común para enten-
der la forma de funcionamiento del software, facilitando los procesos de pruebas, verificación
y modificación; y permiten de forma directa cumplir con los requerimientos no operacionales
109
más importantes. Esta capa ha demostrado ser lo suficientemente general y flexible, para que
a partir de lo expuesto en la sección de implementación del sistema base, se programen la
totalidad de las funcionalidades requeridas, a través de dos métodos propuestos:
La arquitectura base del sistema ha sido licenciada según los términos de la GPL y su
código puesto a disposición en repositorios públicos. De esta manera el trabajo desarrollado
se transforma en un aporte a la comunidad de software libre esperando ser un aporte para
futuros proyectos aeroespaciales o sistemas embebidos en general. El uso de una licencia
GPL, a diferencia de otras licencias más permisivas, asegura que el código desarrollado se
mantenga abierto en miras de la posibilidad de colaboración en la mejora y extensión de este
trabajo.
110
cación, como una adaptación al patrón de diseño command pattern, lo que ha sido la
base para extender al sistema con funcionalidades específicas de la misión.
5. Se integran los subsistemas de comunicaciones y energía a través de la programación de
listeners y comandos para su operación. Se comprueba su funcionamiento a través de las
pruebas de integración, concluyendo que el sistema de energía funciona correctamente,
mientras que el transceiver presentó fallas que hicieron imposible la transmisión y
recepción de datos.
6. Con el sistema integrado se realizan pruebas de funcionamiento para verificar los reque-
rimientos operacionales, con resultados satisfactorios, salvo por los relacionados con el
subsistema de comunicaciones, que ha presentado fallas a lo largo de todo el desarrollo
del proyecto.
6.2. Limitaciones
111
6.3. Trabajos futuros
112
Glosario
113
Bibliografía
[2] C. P. SLO, “Cubesat design specification,” Tech. Rep. 12, California Polytechnic State
University, 2009.
[4] S. Heath, Embedded System Design. England, Newnes, 2nd ed. ed., 2003.
[6] Microchip Technology Inc., 16 bit MCU and DSC Programmer’s Reference Manual, 2011.
[8] R. Barry, Using the FreeRTOS Real Time Kernel. A Practical Guide, PIC32 Edition.
USA: Real Time Engineers, 1st ed. ed., 2009.
[9] ISO, “Iso/iec 25010:2011 systems and software engineering – systems and software quality
requirements and evaluation (square) – system and software quality models,” tech. rep.,
ISO, 2011.
[10] E. Gamma, R. Helm, R. Johnson, and J. Vlissides, Design Patterns. Elements of Reusa-
ble Object-Oriented Software. Addison-Wesley, 1st ed. ed., 1995.
[12] A. Becerra, M. Diaz, and J. Zagal, “Feasibility study of using a small satellite conste-
llation to forecast, monitor and mitigate natural and man-made disasters in chile and
similar developing countries.,” in 26th Annual AIAA/USU Conference on Small Satelli-
tes, USA, 2012.
[13] Pumpkins Inc, CubeSat Kit Motherboard (MB), rev. d ed., 2009.
[14] Pumpkins Inc, CubeSat Kit Pluggable Processor Module (PPM) D1, rev. a ed., 2010.
114
[15] G. Manyak, “Fault tolerant and flexible cubesat software architecture,” Master’s thesis,
California Polytechnic State University, 2011.
[16] T. Noergaard, Embedded System Architecture. Elseiver, 9th ed. ed., 2005.
[17] M. Dabrowski, “The design a software system for small space satellite,” Master’s thesis,
University of Illinois at Urbana-Champaign, 2005.
[18] Pumpkins Inc, CubeSat Kit Development Board (DB) D, rev. d ed., 2010.
[19] R. Barry, The FreeRTOS Reference Manual. USA: Real Time Engineers, 1st ed. ed.,
2011.
115
Anexos
116
View publication stats