Download 5. Implementación de la plataforma: AvrZigbit.java 5.1. Introducción
Document related concepts
no text concepts found
Transcript
5. Implementación de la plataforma: AvrZigbit.java 5.1. Introducción En el archivo AvrZigbit.java 1 se encuentra implementada, en software, la plataforma objeto del proyecto: AvrZigbit. Como se pudo ver en el capítulo 3, la plataforma se compone de dos elementos fundamentales: El microcontrolador ATMega1281 de Atmel [16]. Es el "cerebro" de la mota. Ejecuta las órdenes de las que se compone el programa que tiene almacenado en memoria. El chip radio, AT86RF230, también de Atmel [17]. Se encarga de las comunicaciones via radio de la mota. En las sucesivas secciones se va a detallar, de una manera funcional, el código incluido en dicho fichero. En primer lugar se presentará la nueva clase creada para encapsular la plataforma y se explicarán de manera general sus peculiaridades. Después se continuará describiendo cómo se añaden los dos dispositivos que la integran y cómo se interconectan entre ellos, que se hará de una forma idéntica a como se haría con el hardware real. Aunque se hace uso de una manera muy simple y puntual del modelo software del microcontrolador y de la radio en AvrZigbit.java, los detalles de la implementación propiamente del microcontrolador y la radio se presentarán y analizarán en capítulos posteriores. 5.2. Creación de la plataforma El conjunto de plataformas que se encuentran incluídas en Avrora se encuentran en la ruta: «avrora/sim/platform». Como se introdujo en el capítulo 4, todas ellas heredan de una clase abstracta padre llamada «Platform»2 . Esta clase define la base para la creación de nuevas plataformas. Contiene una serie de variables de instancia y métodos básicos que sirven para describir y manipular perfectamente los elementos que la componen. 1 2 Ubicado en: avrora/sim/platform Ubicada en: avrora/sim/platform/Platform.java 65 Capítulo 5 Implementación de la plataforma: AvrZigbit.java Por lo tanto, para crear la plataforma AvrZigbit, en primer lugar, deberá heredar «Platform». A continuación, ya podrá añadir sus propias variables de instancia y definir cuantos nuevos métodos estime oportuno que le serán útiles para la simulación. 5.3. Implementación de la plataforma El primer paso es heredar la clase «Platform» y así disponer de sus variables de instancia y métodos ya definidos: public class AvrZigbit extends Platform Como en otras plataformas ya integradas, es útil definir una constante que indica la frecuencia a la que el micro va a trabajar (en Hz). En este caso, la declaración que se hace es: protected static final int MAIN_HZ = 8000000 Para poder crear una instancia de la plataforma que tenga asignada una identificación y poder especificar el programa que ejecutará en ella, todo ello necesario para que el simulador pueda cargar un nodo del tipo de plataforma dada, Avrora proporciona la interfaz «PlatformFactory»3 . Será obligatorio que AvrZigbit implemente dicha interfaz con objeto de que esté disponible para cualquier usuario que quiera realizar una simulación utilizando esta plataforma. La interfaz «PlatformFactory» define solo un método, «newPlatform(int id, Simulation sim, Program p)», donde: id : es el identificador de la plataforma que se creará. sim : es una referencia a la propia simulación de la que la plataforma formará parte. p : es el programa que será cargado en ella. Por tanto, solo es necesario implementar el método «newPlatform» definido en la interfaz. El código desarrollado se muestra a continuación: 3 Ubicada en: avrora/sim/platform/PlatformFactory.java 66 5.3 Implementación de la plataforma public Platform newPlatform(int id, Simulation sim, Program p) { ClockDomain cd = new ClockDomain(MAIN_HZ); cd.newClock("external", 32768); return new AvrZigbit(new ATMega1281(id, sim, cd, p)); } En primer lugar se crea un objeto de tipo «ClockDomain». Esta clase representa un conjunto de relojes que un dispositivo o una plataforma pueden utilizar. Incluye el reloj principal (que será identificado con el nombre "main") que es el que usará el microcontrolador para su funcionamiento normal. Solo es necesario indicarle la frecuencia del reloj a la que trabajará (es la constante definida anteriormente). Para proporcionar soporte para una posible fuente de reloj externa con la que el microcontrolador pueda obtener su señal de sincronismo, y como se especifica en la hoja de características del ATMega12814 , se añade otro nuevo reloj, de una frecuencia de 32768 Hz e identificado por "external" para indicar claramente que es una señal de reloj generada por un oscilador externo al propio microcontrolador. Con estas dos fuentes de reloj definidas, la plataforma (o más concretamente el micro) funciona dentro de unos rangos aceptables y normales tal y como se indica en la hoja de características del ATMega1281. Por último, el método termina con la creación y devolución de un objeto de tipo AvrZigbit que representa a la plataforma creada, la cual, a su vez, necesita que le sea indicado el microcontrolador que formará parte de ella, en este caso, el ATMega1281 (aceptará una instancia de la clase ATMega1281 que encapsula a dicho modelo de microcontrolador). Deteniendo la explicación en el constructor de la clase AvrZigbit, el código correspondiente al mismo se muestra en las siguientes líneas: private AvrZigbit(Microcontroller m) { super(m); sim = m.getSimulator(); addDevices(); } 4 Hoja de características del ATMega1281, pag. 45 67 Capítulo 5 Implementación de la plataforma: AvrZigbit.java Para construir la plataforma se necesitarán tres cosas fundamentales: El microcontrolador que la plataforma llevará integrado. Una instancia de tipo «Simulator» que sea capaz de emular este dispositivo hardware. Añadir los demás dispositivos de los que se compone la plataforma, por ejemplo LED’s, radio, etc. y llevar a cabo las conexiones apropiadas. El primer elemento se obtiene llamando al constructor de la clase Platform que, como se ha expuesto, es de quien hereda la nueva plataforma. Asimismo será necesario indicarle el microcontrolador que llevará integrado. Por otro lado, partiendo de éste se consigue una instancia de tipo «Simulator», que es capaz de emular este dispositivo hardware. Por último, se añadirán los componentes restantes de la plataforma. Para ello será necesario hacer una llamada al método «addDevices()», el cual se encargará de integrar en la plataforma el resto de elementos. 5.3.1. Añadiendo dispositivos a AvrZigbit Como se expuso en 1.1, la plataforma AvrZigbit solo está compuesta por el microcontrolador ATMega1281 y la radio AT86RF230. Por tanto una vez integrado el microcontrolador, solo hay que incorporar a dicha plataforma la radio. En el código ésto se realiza mediante las tres líneas de código siguientes: protected RF230Radio radio; RF230Radio radio = new RF230Radio(mcu, MAIN_HZ * 2); addDevice("radio", radio); Se crea un objeto del tipo «RF230Radio», clase que implementa al chip radio AT86RF230 en Avrora y que se detalla en un capítulo posterior (ver capítulo 7). Este objeto se le pasa como argumento al método «addDevice» (presentado en la sección 5.2), que ofrece la manera adecuada de agregar dicho elemento a la plataforma. 5.3.2. Interconexión entre el microcontrolador y la radio Una vez están integrados los dos componentes básicos de la plataforma, se procede a realizar el conexionado entre ambos elementos. Hay que tener especial precaución de hacer esto bien para que la comunicación entre ellos sea correcta y que la simulación se asemeje fielmente a la realidad. Para realizar la conexión se acudirá a la hoja de características del AT86RF2305 , donde viene esquematizado con qué pines del microcontrolador se deben unir los de la radio: 68 5.3 Implementación de la plataforma Figura 5.1.: Interfaz Microcontrolador - AT86RF230 El chip radio dispone de 8 pines de entrada o salida como se muestra en la figura 5.1: /SEL: Es la señal de selección del SPI, activa a nivel bajo. MOSI : Señal de datos del SPI (Master Output Slave Input). MISO: Señal de datos del SPI (Master Input Slave Output). SCLK : Señal de reloj del SPI. CLKM : Salida de reloj del AT86RF230, que se puede utilizar como fuente de señal de reloj para el microcontrolador o bien para tener una referencia de tiempo de alta precisión. IRQ: Interrupción generada por el AT86RF230. SLP_TR: Señal de control multifunción. Según el estado del transceptor, tiene una función u otra (Sleep/Wake up, comienzo de la transmisión o controlar la señal CLKM ). /RST : Señal de reset del AT86RF230, activa a nivel bajo. Según el esquema, /SEL, MOSI, SCLK, SLP_TR y /RST deben ser configurados como entradas en el transceptor. En cambio, MISO, CLKM y IRQ son de salida. Es obvio que los pines del AT86RF230 correspondientes al SPI, estarán conectados a sus homólogos en el microcontrolador. CLKM, o bien se puede conectar a una GPIO6 del micro o, si se dispone de él, a un pin específico que se use como entrada de una señal de reloj externa7 . El pin de interrupción se puede conectar a una GPIO o a un pin de interrupción de entre los 8 disponibles. SLP_TR y /RST se conectan a sendas GPIO’s. Hoja de características del AT86RF230, pag. 10 Entrada/salida de propósito general 7 En este caso, si se consulta la hoja de características del ATMega1281, es el pin XTAL1 5 6 69 Capítulo 5 Implementación de la plataforma: AvrZigbit.java Una vez claro como debe estar configurado cada pin del micro o del transceptor implicado en la interconexión de ambos, se procede a unirlos. Para realizar la conexión entre un pin del microcontrolador y un pin de la radio, se hace lo siguiente: En el fichero ATMega1281.java se encuentra la implementación de dicho microcontrolador dentro del simulador (se analizará posteriormente en el capítulo 6). Si se examina su contenido puede verse un listado con todos los pines de los que consta. Cada pin está representado por un nombre y un número que coincide con lo especificado en la hoja de características8 . Se dispone de la instancia mcu de la clase «Microcontroller» (como se vió en la sección 5.2) que será usada para obtener el pin identificado por un número en particular. Para ello se encuentra disponible dos métodos equivalentes: • El método «getPin(num)» de dicha clase, que devuelve un objeto de tipo «Pin» (clase que implementa, lógicamente, dicho concepto dentro del simulador) y que corresponde al número que se le pasa como parámetro (según la numeración dada en la hoja de características). • El método «getPin(name)» que funciona de la misma manera que el anterior solo que en vez de obtener el pin proporcionando el identificador numérico correspondiente, se obtiene mediante su nombre asignado. Una vez se tiene el pin, es el momento en el que se configura como entrada o como salida, según sea el caso. Por tanto, hay dos posibles opciones: • De entrada: Un pin se configura como entrada llamando al método «connectInput(Input i)» de la clase «Microcontroller», donde «i» indica cuál es el pin del otro dispositivo que será conectado a esta entrada del micro. • De salida: Un pin puede ser configurado como salida llamando al método «connectOutput(Output o)» de la clase «Microcontroller», donde «o» representa el pin del otro dispositivo a donde se conectará. Por tanto sabiendo cuáles de los pines del transceptor son de salida y cuáles de entrada y eligiendo previamente a qué entradas/salidas del micro se unirán, solo hace falta plasmarlo en el código: mcu.getPin(10).connectOutput(radio.SEL_pin); mcu.getPin(11).connectOutput(radio.SCLK_pin); mcu.getPin(12).connectOutput(radio.MOSI_pin); mcu.getPin(13).connectInput(radio.MISO_pin); mcu.getPin(24).connectInput(radio.CLKM_pin); mcu.getPin(7).connectInput(radio.IRQ_pin); mcu.getPin("PB4").connectOutput(radio.SLP_TR_pin); mcu.getPin("PA7").connectOutput(radio.RST_pin); 8 Hoja de características del ATMega1281, pag. 4 70 5.3 Implementación de la plataforma Para terminar con la creación de la plataforma AvrZigbit, solo resta conectar el interfaz SPI de la MCU y el de la radio de manera que se puedan comunicar ambos dispositivos dentro de la simulación. Avrora (al igual que hace con otros elementos básicos del microcontrolador como son Timer8Bit, Timer16Bit o USART) dispone de una clase que engloba e implementa el interfaz SPI que integran los micros de la familia Atmel que están soportados. Para conseguir unir las interfaces de ambos elementos es preciso, en primer lugar, obtener una instancia de dicha clase sobre la que poder trabajar. Como se vio en la sección 5.2, esto se consigue realizando una llamada al método «getDevice(“spi”)» del objeto de la clase «AtmelMicrocontroller» que no es más que una clase que incluye funcionalidad común que poseen los micros de la familia Atmel. Una vez se conseguido este objeto representando al interfaz SPI del micro, se procederá a unir con la interfaz SPI de la radio mediante el método «connect(radio.spiInterface)», donde «radio.spiInterface» representa al propio interfaz SPI del AT86RF230. Con ésto, ya estaría finalizado la implementación de la plataforma. SPI spi = (SPI)amcu.getDevice("spi"); spi.connect(radio.spiInterface); 71