Saturday 17 December 2016

Viznut Binary Options

PETSCII Bienvenido a la página de PETSCII, donde puedes encontrar todo lo que has querido saber sobre el editor PETSCII ingeniosamente llamado PETSCII. La herramienta le permite crear pantallas y animaciones basadas en caracteres para las computadoras Commodore 64, VIC-20, PET y Plus / 4. Enjoy News 30.10.2016: Niza obras lanzadas este fin de semana en X82172016. Orgulloso de notar que todos ellos utilizando mi herramienta, también 13.8.2016: Alguna rotación en la galería. Añadido Zelda PETSCII por Awsm. 23.7.2016: Añadido algunas demostraciones y juegos a la galería. 22.7.2016: Tenga en cuenta que las últimas versiones y cambios de registro están disponibles aquí solo. CSDb alberga alguna versión antigua que simplemente no funciona. 20.7.2016: Echa un vistazo a Fort Django. Los fondos se hacen con PETSCII 18.7.2016: Algunas nuevas fotos de Vammala Party añadido a la galería. 3.7.2016: Una demostración masiva de PETSCII por el Proyecto Genesis. Bien hecho 2.6.2016: Un nuevo binario con los dos arreglos mencionados a continuación. 27.5.2016: Sólo fuente: no se bloquea más si pulsa los dos botones del ratón mientras selecciona. Gracias de nuevo a Basscadet por el informe. 21.5.2016: Source-only: una corrección para un error de conversión de imagen bastante raro en el PET (80). 21.5.2016: El error de cambio fijado en la liberación binaria ahora. 21.5.2016: Oops8230 un error de falla con el cambio de caracteres de palo después de cargar una imagen. Se ha corregido en la (s) versión (es) fuente y probablemente pronto en el binario también. Gracias a Basscadet por el descubrimiento. 17.5.2016: Recientemente no he estado actualizando I8217ve en Pixel Polizei durante un tiempo. 16.5.2016: El material de última generación con potencialmente buggy ya está disponible a partir de ahora en svn: //kameli. net/marq/petscii 7.5.2016: Hacer las cosas bien. A partir de ahora Command en lugar de Ctrl en Macs, porque Ctrl-LMB es RMB, que comenzó a ser tedioso. Además, coincide con las convenciones de la plataforma. Uso Debe ser sencillo descargar y descomprimir el paquete, después de lo cual se puede ejecutar la versión que corresponde a su sistema operativo de elección: Linux, Mac o Windows. Debe tener Java Runtime Environment 1.7 (JSE 7) o superior instalado antes de eso. Las versiones autónomas no requieren procesamiento, pero si eres una persona aventurera y quieres ajustar la configuración, obtén el paquete beta o consulta el directorio src. Ya sabes lo que estás haciendo. Usa los botones GUI para guardar tu trabajo. El formato de archivo nativo es una matriz C, por lo que la extensión de archivo debe ser 8220.c8221. Además, la copia de seguridad automática creará un archivo llamado backup. c en el directorio del programa cada dos minutos aproximadamente. El botón Ref cargará una imagen de referencia (png / jpg / gif) que se puede superponer con los caracteres. Para mostrar la pieza en una máquina real necesita exportar la imagen a un archivo. prg. En este momento las animaciones pueden ser exportadas como ejecutables independientes. Vea los atajos de teclado a continuación y, en el caso de las exportaciones de código fuente, verifique el archivo generado para obtener más instrucciones. No todas las opciones de exportación están disponibles para todas las plataformas de destino. La forma más fácil en la mayoría de los casos: Guarde su imagen y presione e (exportación PRG) Ejecute el. prg resultante Opcionalmente, cree una imagen d64 (c1541 es parte de VICE): c1541 - format mypic, 0 d64 mypic. d64 - attach mypic. D64 - write image. prg image Botones del ratón botón izquierdo del ratón dibujar, seleccionar el color de la pluma, seleccionar char desde el selector botón central del ratón selector de caracteres, seleccionar el color de la frontera del selector de borrador del botón derecho del ratón, seleccionar bg color del selector, bloquear / desbloquear Marco en la línea de tiempo, alternar minúsculas en el selector de caracteres Comandos de edición C convertir los colores a Plus / 4 después de cargar una imagen C64 (Plus / 4 sólo) entrar en el modo de mecanografía, shift-enter para caracteres invertidos Alt (shift) En una máquina real Selección de color y reverso, de la misma manera Ins / Del / Backspace / PageUp / Dn / Inicio / Fin de trabajo Los administradores de ventanas, etc, pueden utilizar algunas combinaciones de teclas para sus propios propósitos, así que guárdate esc salir de escribir modepageid2717 f floodfill Pulsar y hacer clic), shift-f llena el color sólo h flip horizontal inteligente, shift-h en el cursor r rotación inteligente en el sentido de las agujas del reloj, shift-r en el cursor espacio activar / desactivar la selección T convertir la imagen de referencia a PETSCII Tabulación a través de conjuntos predefinidos de caracteres relacionados u deshacer U rehacer (al menos algún tipo de deshacer-deshacer) v flip vertical inteligente, shift-v en el cursor x invertir, shift-x inverte en el cursor / Paso arriba / abajo / derecha / izquierda, /. Ciclo a través de bg y colores de frontera pick charactercolor (igual que mmb), shift - (o) para seleccionar sólo color GUI alterna c alternar reticulación g alternar rejilla i alternar información mostrar t ciclo a través de diferentes niveles de referencia imagen de la transparencia Animación relacionada 1..0 Saltar al fotograma 1..10 d duplicar el fotograma al extremo derecho saltar al último fotograma saltar al inicio del primer fotograma l bloquear / desbloquear el marco de edición izquierda / derecha saltar un fotograma Teclas modificadoras alt 1/4 char pixel modo de dibujo ) Ctrl (comando en Macs) modo de selección: arrastre con lmb presionado para seleccionar una región, rmb para seleccionar áreas de forma libre, ctrl-a selecciona todo el modo de cambio de imagen (izquierda), sólo el color se cambia ) Desplazamiento (derecha) modo de sólo carácter Operaciones de archivo un archivo de exportación como datos asm Un archivo de exportación como visualizador asm autónomo (formato ACME) b exportar como visualizador de BASIC autónomo e exportar un PRG autónomo que se puede ejecutar directamente P exportar como imagen PNG, shift-p incluye bordes q exportar como SEQ (sólo C-64) s guardar (datos C simples, el formato de imagen predeterminado) S exportar como visualizador C autónomo (formato cc65) Cheat Sheet Olvidó algunas teclas Por supuesto que no me acordé de todos ellos. Imprima esta práctica hoja de trucos para apoyar su memoria fallida: En Mac, use la tecla Comando en lugar de Ctrl. Configuración Puede controlar algunos ajustes generales con un archivo llamado prefs. txt que debe estar en el mismo directorio que el programa real. Hasta ahora se reconocen las siguientes configuraciones: Tamaño de píxel del editor ZOOM. 2 de forma predeterminada. 1 es el mínimo y cualquier cosa más allá de 3 puede ser bastante inutilizable. ASPECTO en las máquinas donde cuenta. Uno de PAL / NTSC / SQUARE. Si no se establece, el valor predeterminado es PAL. FRAMERATE tasa de actualización. 60 fps de forma predeterminada. Decremento para menos uso de la CPU, incremento para una mejor capacidad de respuesta. MÁQUINA uno de C64, VIC20, PET, PETHI, PLUS4. Dejar vacío para obtener el selector normal al inicio. PATH ruta predeterminada para sus imágenes. Dé una ruta completa como / home / marq / Pictures. Sin comillas. CONVERTER para ejecutar al exportar múltiples marcos (principalmente para gifs animados). Con ImageMagick utilice algo como esto: convert - delay 20 - loop 0 - scale 200 XSIZE y YSIZE establecen un tamaño de lienzo no estándar. Asigne un nuevo valor como este: ZOOM2. El archivo de preferencias de ejemplo proporcionado en el paquete viene con líneas de nuevo de Unix. Trate de tarifa. Protips La selección se puede utilizar de varias maneras: se puede girar, voltear o incluso utilizar para colorear regiones (intente presionar shift). La rotación, voltear, invertir etc. afectan el carácter bajo el cursor cuando se presiona el cambio. La conversión de imagen - gt PETSCII depende del color de fondo seleccionado, así que experimente con varias opciones. Tres niveles de escala de grises en la imagen de origen con color bg definido como gris medio parece funcionar bastante bien para las fotos. Puede reconvertir las imágenes existentes en PETSCII siempre y cuando la paleta esté lo suficientemente cerca y las dimensiones coincidan (320215200 y sin bordes para C64). PETSCII utiliza estos valores de color C64 por Pepto, así que haga lo mismo cuando trabaje con programas externos para asegurar una conversión fiel. Consulte mc64.pde, mvic20.pde y mplus4.pde para los valores RGB. Shift-mmb seleccionará sólo el color en lugar de charactercolor Seleccione un color de pluma y pulse ctrl y haga clic en otro color en el selector para reasignar todos los caracteres del mismo color. Si hay una selección, sólo se verá afectada. Los colores de fondo y borde pueden ser diferentes para cada marco. Incluso si usted no está haciendo una animación, un segundo marco puede ser útil como almacenamiento temporal. Puede eliminar los caracteres de una selección haciendo clic en el selector de caracteres. It8217ll te dejará los agujeros que don8217t afectan el dibujo útil por ejemplo para cortar 8220sprites8221. Uso de una computadora lenta Desactive la cruz si se encuentra en (c) y la pantalla de información (i), además de establecer ZOOM a 1 y FRAMERAR a 30 utilizando prefs. txt. Los debilitros inferiores son posibles, por supuesto, pero no tan buenos para dibujar. Desea crear gifs animados Instalar las herramientas de línea de comandos de ImageMagick, exportar como png (pulsar p o P) y luego simplemente: convertir - resize 200 - loop 0 - delay 10 frames. png animation. gif Solucionar problemas Tratar de crear una aplicación crossplatform confiable en Java Es un negocio difícil en estos días. Si todo falla, recomiendo descargar la versión de sólo fuente y ejecutarla directamente desde el procesamiento (2.x). 8220Blah blah está dañado y can8217t puede ser abierto8221. Esto se debe a Apple8217s llamada seguridad que won8217t le permiten ejecutar otras aplicaciones que los descargados de su tienda. Para hacer una larga historia corta: vaya a Privacidad de privacidad de Preferencias de Sistema y admita las aplicaciones descargadas desde cualquier lugar para ejecutar. Usuarios de OS X: Java 7 u 8 es necesario en estos días, pero desafortunadamente son mucho más lentos que la versión 6 de Apple optimizada. Si los trucos normales de aceleración don8217t lo hacen por usted, incluso podría considerar la instalación de Apple8217s Java 6 paquete y ejecutar PETSCII utilizando una antigua versión de procesamiento (2.0). Vea aqui para mas informacion. El botón central del ratón puede no funcionar en todas las Macs. Utilice la tecla en su lugar para elegir un carácter del lienzo, si su teclado tiene uno. El color del borde se puede seleccionar presionando la tecla de punto. Con todos estos problemas de OS X (y probablemente haya más por venir), incluso consideras la posibilidad de ejecutar el editor dentro de una máquina virtual Linux / Windows. En Linux, el tiempo de doble clic para los selectores de archivos puede ser frustrantemente corto. Vea aquí una solución: blog. trifork / 2008/10/13 / descrease-la-doble-clic-velocidad-para-java-aplicaciones-en-ubuntu-linux / Descargar La fuente estable binarios compilados están disponibles aquí: kameli. net / marq / kode / petscii. zip. Tenga en cuenta que necesita tener Java Runtime Environment instalado en su sistema. WIP solo para el aventurero: kameli. net/ marq / kode / petscii-beta. zip o svn: //kameli. net/marq/petscii. El código se puede utilizar de acuerdo con los términos de la licencia liberal WTFPL. Los informes de errores se pueden enviar a marq en iki dot fi. Galería Algunos esfuerzos artísticos para darle un vistazo de lo que es posible. Por favor, hágamelo saber si usted ha hecho algo con el editor, para que pueda actualizar la galería y mantener mi motivación Además de imágenes fijas hay demos y juegos en los que el editor ha sido puesto en buen uso. Here8217s algunos: Adiciones y correcciones más bienvenidos, como de costumbre. Agradecimientos Gracias a Dr. TerrorZ por sus obras de arte, numerosos comentarios y remapear tablas, Viznut para ayudar con el VIC-20, seis para el ejemplo de conversión de SEQ, BassCadet para informes de errores y Rexbeng, Man, Shine, Electric, Archmage, Hammerfist y Awsm Para las imágenes de la galería. Dónde comprar, descargar el software y encontrar las especificaciones - Actualización 7: Los proyectos de RC Arduino serán compilados y probados en una gama más amplia de tablas incluyendo Mega (ahora que tengo uno), Teensy y Due cuando recibo eso. Espera ver un nuevo Tested On Header apareciendo en los posts en breve y una lista de proyectos probados aquí. Actualización 6: Si todavía no lo has visto, aquí está la foto de la Due, tal como se publicó en la página de inicio de arduino. cc. Ese chip tiene un tamaño impresionante. También hay una sección dedicada Due del foro de Arduino con las últimas actualizaciones sobre hardware, software, compatibilidad de escudos y bibliotecas. Actualización 5: Si su interesado en lo que su Due o Teensy está haciendo bajo el capó Puedo confirmar que el enfoque para ver el código de ensamblaje resumido aquí funciona para ambos de los nuevos consejos, voy a actualizar las capturas de pantalla en algún momento, El proceso sigue siendo el mismo - rcarduino. blogspot / 2012/09 / how-to-view-arduino-assembly. html Y aquí está mi Teensy3.0 con los encabezados adjuntos - Pastillas de pin adicionales desde el inverso trajo a las cabezas femeninas pegadas a la principal Encabezados Utilicé el pegamento del gorila para atar el sistema exterior de cabeceras, hice esto antes de ponerlos en cualquier lugar cerca del Teensy. El pegamento tiene algunos disolventes muy agresivos que no quería arriesgar el daño de la junta con. Vista inferior que muestra las almohadillas y un solo hilo de gancho hasta el alambre utilizado para conectarlos a las cabeceras. Actualización 4: Estoy contento de ser uno de los afortunados de haber ordenado un Due, la Tienda Arduino ahora está mostrando la deuda como fuera de stock sin embargo, un número de minoristas en línea ahora están mostrando que tienen o están esperando acciones por lo que hay Aún unidades por ahí si estás buscando. Actualización 3: Información oficial del hardware, y mucho más aquí - La biblioteca de audio en particular debe ser interesante como referencia para el uso de DMA (Direct Memory Access) para acceso de alta velocidad al almacenamiento externo. Actualización1: Arduino Due está disponible y disponible para su compra. Descargo de responsabilidad: Los siguientes enlaces anuncian el Arduino Due para la venta que se proporcionan para propósitos de la información solamente, esto no es un endoso de cualquier producto o enchufe ni está en de todos modos una garantía que estas tiendas tienen dispositivos disponibles para el envío. Parece que la información detallada sobre el Arduino Due se está retrasando hasta que los tableros estén disponibles para la venta al por menor el 22 de octubre. Continúo supervisando a minoristas en línea para los pedidos previos pero no he visto ninguno todavía. Los siguientes enlaces contienen una selección de la información publicada hasta el momento - Comparación rápida con los actuales Arduinos y Teensy 3.0 Teensy 3.0 soporta overclocking a 94Mhz Teensy 3.0 se basa en la arquitectura ARM M4 que se basa en la misma arquitectura M3 que el Due, pero con añadido Instrucciones de procesamiento de señales digitales. Ninguno de los proyectos en el blog de RCArduino usan toda la potencia de una UNO de Arduino, de hecho el proyecto de temporizador de vuelta es el más grande y todavía sólo usa 10K de los 32K disponibles en una UNO. Si eres un principiante, consigue una UNO. Todos los ejemplos en línea funcionarán con una UNO, también pueden conectarse directamente a una amplia gama de dispositivos externos sin circuitos adicionales. Esto no se aplica al Due. El Due es un dispositivo de 3,3 voltios donde, como los Arduinos actuales son 5 voltios, esto no es mucho de un problema, pero un problema más grande es que el Due es muy limitado en la cantidad de corriente que puede aceptar (sink) fuente). Un gran número de proyectos que se pueden encontrar en línea hoy en día se necesitan circuitos adicionales para ser ejecutado en un Arduino Due. Si usted es un principiante no se da el dolor de cabeza adicional de tener que convertir los ejemplos en línea para funcionar en el debido, pero no tome mi palabra para él, aquí es una cita de uno de los originadores del proyecto de Arduino - también se ha confirmado Por Massimo que el Arduino Due no será compatible con el gran número de escudos de extensión que se han desarrollado para los viejos 5V Arduino Mega - esta podría ser una gran oportunidad para recoger viejos escudos de acciones a un precio más bajo, siempre se pueden convertir Para ejecutarse en Due una vez que esté familiarizado con la plataforma. Nada de esto es negativo, el Due es un procesador de alto rendimiento muy avanzado que se ha añadido a la línea de Arduino. Sin embargo, como cualquier cosa de alto rendimiento que necesita ser tratado un poco más cuidadosamente. El Due abrirá una enorme gama de nuevas aplicaciones que simplemente no son posibles con la generación actual Arduinos y una de sus mayores fortalezas será que usted puede aprender los conceptos básicos de un poco duro Arduino UNO y luego transferir exactamente el mismo conjunto de habilidades a la Super rendimiento Arduino Due. Mientras que los detalles del Arduino Due se están reteniendo hasta el lanzamiento, la hoja de datos para el microcontrolador Atmel SAM3X8E en el corazón de la nueva Due está ampliamente disponible. Una de las mejores referencias que he encontrado está disponible en el enlace de abajo sin embargo tenga en cuenta que un objetivo importante o el proyecto Arduino es para protegerlo de este nivel de complejidad por lo que para la gran mayoría de los usuarios de Arduino el siguiente documento es irrelevante. Tenga la seguridad de que todos seguiremos utilizando pinMode, digitalRead, digitalWrite y todas las bibliotecas principales de la nueva plataforma Arduino Due, sin embargo, para cualquiera que desee escribir bibliotecas orientadas al rendimiento para el nuevo Arduino Debido, será útil leer, para todos De lo contrario, salte este enlace. Un poco más de información accesible aquí, también tengo un Teensy 3.0 en su camino a Dubai que obtiene una mención en este post - Massimo Banzi del equipo Arduino ha estado respondiendo a algunas preguntas relacionadas con el tema de Due en este Arduino foro - Actualización: con sólo Cuatro días hasta que se lance el Arduino Due, mi Teensy 3.0 ha llegado a Dubai. Al igual que el Due, el Teensy se basa en un núcleo de procesador ARM el Teensy realmente utiliza un núcleo Cortex M4 que tiene ventajas para aplicaciones de procesamiento de señal digital sobre el núcleo Cortex M3 ofrecido por el Arduino Due. Teensy 3.0 ARM Cortex M4 basado Arduino compatible. Teensy - Es realmente muy pequeño, aquí se esconde en la parte superior derecha de un Arduino UNO, es aproximadamente del mismo tamaño que el chip ATMega328 desnudo en un Arduino UNO. Una cosa acerca de estos nuevos tableros que tendrán impacto inmediato es la entrada muy baja y las corrientes de salida en comparación con la actual generación de tableros. No hay muchos proyectos en los que pueda pensar que un Teensy será una ranura en reemplazo de un Uno o un Mega sin algunos circuitos adicionales para cambiar la corriente de 20 mA típicamente de un pin de Arduino. En los próximos días voy a tratar de convertir algunos de los proyectos existentes de RC Arduino para utilizar el Teensy, será interesante ver con qué facilidad el software y, especialmente, la conversión de hardware. Este es un pequeño proyecto interesante que se puede construir en minutos. Reproduce 13 melodías diferentes que se generan a partir de una sola línea de código C, las melodías se seleccionan a través de cuatro botones que tienen 16 combinaciones posibles, incluyendo el silencio y dos ranuras libres para su propia música. El proyecto también incluye un visualizador de 8 LED que es impulsado por la misma línea de código que la música. Acerca de la música algorítmica Las melodías originales fueron producidas por Viznut y por otros en respuesta a su blog original aquí - El puerto Arduino original fue completado por Arduino Forum usuario Stimmer y se puede encontrar en este post - Arduino Forum usuario Zeni también tiene una interesante variación Que permite al usuario introducir nuevos algoritmos en tiempo de ejecución, esto se puede ver en acción en el tema del foro anterior. La versión RCArduino añade la capacidad de seleccionar el algoritmo actual y el visualizador 8 LED. El código de RCArduino versión y el esquema se puede encontrar a continuación, si su interesado en la teoría detrás de la música o demoscene en general (en. wikipedia. org/wiki/Demoscene) puede recoger el rastro de Viznuts vídeo original vinculado al inicio de esta publicación. Una aplicación en la síntesis de granos Un área que sería interesante aplicar estas técnicas es la síntesis de grano. La síntesis de grano se basa en la repetición de un simple grano de sonido, mientras que la adición de granos adicionales, sobres, osciladores o filtros para hacer el sonido más interesante. Estas operaciones pueden ser computacionalmente caras y no siempre producen sonido interesante. Las técnicas utilizadas para generar la música algorítmica a partir de un simple contador demostrado por Viznut también podría aplicarse a la generación de granos de síntesis más interesantes. El ejemplo más conocido de un sintetizador Arduino Grain es el Auduino, es increíble ver que todo el sonido generado por un auduino es el resultado de superponer sólo dos formas de onda triángulo. En uno de los videos enlazados a continuación podrás ver las formas de onda del triángulo interactuando junto con el sonido rico que resulta. Un interesante desarrollo de la síntesis de granos sería combinarlo con el trabajo de carga de código en tiempo real de Zeni, debería ser posible crear granos que se modulan y se transforman para crear una paleta de sonido más interesante. RCArduino Version - Basado en el trabajo original de Viznut y el puerto original de Arduino de stimmer // una música algorítmica de una línea // ver blog de viznuts countercomplex. blogspot / 2011/10 / algorithmic-symphonies-from-one-line-of. html // Y youtube / watchvGtQdIYUtAHgampfeaturerelated // portado a arduino por stimmer // Salida de audio en pin 10 // Más portado a Generación de música basada en interrupción con selección de 4 botones de hasta 16 algoritmos (o 15 silencio sin pulsar botones) // by Duane B aka RCArduino // // Los botones son digitales 8,9,10,11, la salida de música está en digital 6 // // También se agrega un visualizador de cuatro LEDs en pins digitales 2,3,4,5 // // Actualización - Visor LED Es ahora 8 bits utilizando pines digitales 2,3,4,5 y pines analógicos 0,1,2,3 define SAMPLEMAX (65535.0) define SAMPLEFREQUENCY (8000.0) define TIMER1FREQUENCY 2000000 define UPDATERATE 8000 // manteniendo t global que podemos usar para conducir el visualizador, así larga t // iterar los granos y LFO SEÑAL OCR1A (TIMER1COMPAvect) (TIMER1FREQUENCY / UpdateRate) interruptor (PINBamp15) por defecto: caso 0: 0 OCR0A caso de ruptura 1: OCR0A ((-tamp4095) (255ampt (tamptgtgt13 )) gtgt12) (127ampt (234amptgtgt8amptgtgt3) gtgt (3amptgtgt14)) // por tejeez caso estadía de 2: OCR0A t (tgtgt11amptgtgt8amp123amptgtgt3) // por tejeez caso descanso de 3: OCR0A t ((tgtgt9tgtgt13) amp25amptgtgt6) // por caso ruptura visy 4 : OCR0A (t (tgtgt5tgtgt8)) gtgt (tgtgt16) // por tejeez caso de ruptura 5: OCR0A ((t (tgtgt8tgtgt9) amp46amptgtgt8)) (tamptgtgt13tgtgt6) // por caso ruptura xpansive 6: OCR0A ((tamp4096) ((t ( tt255) (tgtgt4)) gtgt1) :( tgtgt3) ((tamp8192) tltlt2: t)) // por Skurk (raers versión) caso de ruptura 7: OCR0A (tgtgt7ttgtgt6) 104 (tamptgtgt13tgtgt6) // por viznut, xpansive, rotura varjohukka caso 8: OCR0A t5amp (tgtgt7) t3amp (t4gtgt10) // por caso ruptura Miiro 9: OCR0A (t (tgtgt9tgtgt7)) apisonar (tgtgt11tgtgt9) // por la caja roja del descanso de 10: larga v OCR0A v (vgtgt1) (vgtgt4) t (((tgtgt16) (tgtgt6)) amplificador (69amp (tgtgt9))) // por caso ruptura pyryp 11: OCR0A (tgtgt6ttgtgt (tgtgt16)) 10 ((tgtgt11) amp7) // por caso ruptura viznut 12: OCR0A (t (47amptgtgt13) gtgt ((tgtgt9) amp3) amp127) // por estuche de estimulación break 13: // libre de usar break case 14: // libre de usar break case 15: // libre de usar break // any more y we necesitará otro bit del PORTB void setup () // TCCR1A0x0 establecer el temporizador para pre-escalador 8 16/8 2 MHz TCCR1B0x02 // establecer el temporizador para pre-escalador 8 16/8 2 MHz TIMSK1 (1ltltOCIE1A) // salida de habilitación de interrupción comparar partido en OCR1A // TCCR0A0B10110011 // - 8 bits de audio PWM TCCR0A0B10000011 // - PWM de 8 bits de audio // // TCCR0A0x83 definir el tiempo de modo de generación de forma de onda de PWM rápida, clara OC0A sobre el partido, fijado en la parte inferior - pin digital OC0A 6. TCCR0B0x01 // establece según el reloj Frecuencia, sin prescaler OCR0A127 / / set en el medio - ¿necesitamos esto. probablemente no. DDRD1ltlt6 // Establece el pin digital 6 en los canales de salida 2 y 3 15) // establece los pines digitales 8,9,10,11 como entradas DDRD (1ltlt2) (1ltlt3) (1ltlt4) (1ltlt5) 2,3,4,5 como salidas para el visualizador DDRC amp (15) void loop () salida de char sin signo OCR0A // borrar bits de visualizador en portD PORTD amplificador 0B000011 // establecer la parte portd del visualizador usando los 4bits superiores de salida PORTD ((outputgtgt4) ltlt2) // establece la parte portc del visualizador utilizando los 4 bits inferiores de la salida PORTC amp 0B110000 PORTC (amplificador de salida B1111) Para un circuito amplificador simple para usar con proyectos Arduino ver aquí - Estoy trabajando actualmente Un sintetizador modular basado en Arduino con un sonido muy diferente, permanezca sintonizado Este post continúa la serie RCArduino Lap Timer Build Along. Los pasos anteriores se pueden encontrar aquí - Aquí hay dos demostraciones rápidas del sistema en acción en el Pro RC Track en Dubai, la primera muestra la tabla de pan construir a lo largo del temporizador de vuelta y una versión de rodillo cerrado. El segundo vídeo muestra el audio externo habilitado para las cuentas regresivas de tiempo por vuelta y los tonos de indicador de vuelta más rápidos de la vuelta / no más rápidos. Transpondedor Descripción general El transpondedor funciona generando una simple señal infrarroja muy similar a la que genera su televisor. Esta es una técnica establecida que es ampliamente utilizada en RC Tracks, pistas de kart e incluso pistas de carreras de automóviles. Si su pista tiene un Transpondedor de IR existente puede utilizar la señal existente y no necesita construir su propio transpondedor. La Parte 4 le mostrará cómo hacerlo. Si planea construir su propio transpondedor siga leyendo. El transpondedor puede ser alimentado de dos maneras: 1) Uso de energía dedicada - Si utiliza el transpondedor en un automóvil o kart, puede utilizar una batería de 9 voltios o 4 pilas AA para alimentar el circuito directamente. 2) Uso de la energía almacenada en búfer / compartida - El temporizador 555 es un componente notoriamente ruidoso, si usted intenta compartir energía con cualquier equipo sensible tal como un receptor de RC, usted necesitará amortiguar la energía compartida del contador de tiempo 555. Una solución barata y efectiva es usar un regulador de voltaje 7805, las etapas finales de este post muestran cómo agregar este componente. Energía del coche de RC El diseño del transpondor se ha probado extensivamente en muchos coches en la pista de ProRC en Dubai. El transpondedor se puede conectar fácilmente al enchufe de equilibrio de una batería LIPO usando una sección de 3 pines del encabezado de PCB o un enchufe de balance macho si tiene uno. Al compartir energía de esta manera, es importante utilizar el circuito regulador 7805 para evitar interferencias con los modelos RC Systems. Uno de los coches de prueba - El actual titular de registro de vueltas de m-chasis en el Pro RC Track - un montón de carbono, aluminio anodizado y aceite de rosca choques todo alrededor. Si no está usando energía compartida, no necesitará completar los últimos pasos de la compilación (pare en el paso 10), sin embargo, si espera compartir energía con algún equipo sensible en algún momento en el futuro, vale la pena incluir estos pasos. ¿Cómo funciona el transpondedor? El transpondedor utiliza la misma técnica y los mismos componentes que su televisor - un diodo emisor de luz infrarrojo se enciende y apaga 38.000 veces por segundo, esta es nuestra frecuencia portadora. El portador es generado por uno de los 555 temporizadores sin embargo para transmitir una señal o datos necesitamos alterar el portador de alguna manera. El transpondedor utiliza una señal muy simple - un pulso de 500 microsegundos, que se genera por el segundo temporizador que simplemente se enciende y apaga el primer temporizador. En la parte final de la serie construiremos el IR Detector en nuestro circuito Arduino, el IR Detector estará sintonizado con la señal de 38Khz del transpondedor. Recuerde que estamos usando dos temporizadores. Uno para generar la señal de 38Khz y otro para pulsarlo a 1Khz. Esto proporciona una codificación muy simple que nos permite buscar pulsos de 500us de largo y sabemos que estamos recibiendo señales de transpondedor en lugar de luz solar reflejada, señales de TV remoto o señales de otros transpondedores de vía. Algunos transpondedores alternativos El trabajo del transpondedor es 1) Conectar y desconectar el diodo a una frecuencia de 38.000 veces por segundo. 2) Para activar y desactivar 1) A una frecuencia de 1.000 veces por segundo. Para hacer esto usamos dos temporizadores 555 conectados, el primero genera la señal 38Khz y el segundo habilita y desactiva esta señal a la frecuencia mucho más baja de 1Khz. El circuito del transpondedor puede ser reemplazado por cualquier circuito simple capaz de generar dos ondas cuadradas de frecuencia fija. Las opciones incluyen microcontroladores, osciladores NAND, osciladores op-amp - cualquier cosa que puede generar una onda cuadrada. Construir el transpondedor del contador de tiempo 555 - antes y después El transpondedor se puede construir en un pedazo de tablero de la tira 16 agujeros de par en par 14 profundamente. Para asegurarse de que este es el tamaño final de la tabla, recuerda que las filas y las columnas que cortas serán inutilizables, necesitas 1614 dentro del área de corte. Las tiras de cobre deben estar funcionando de izquierda a derecha a través de su tablero - ésta es la orientación usada a través de la estructura. El circuito es razonablemente simple con sólo 11 componentes necesarios para el uso de la pared del pozo y un adicional de cuatro si planea utilizar el circuito en un vehículo RC. Debido al ángulo en algunas de las imágenes, es útil comprobar la colocación de sus componentes en función del esquema, también puede ver las imágenes de las etapas posteriores para una referencia cruzada. 1) Colocación de los temporizadores 555 Coloque los dos temporizadores con la muesca hacia la parte superior de su circuito. Deje cuatro filas de espacio por encima del temporizador superior, una fila entre la parte superior e inferior y debe quedar con una fila vacía por debajo del segundo temporizador. Los temporizadores deben colocarse con seis columnas libres a cada lado. Vea la imagen para referencia. Importante: las pistas de cobre en su tablero de tira deben estar corriendo de izquierda a derecha confirmar esto antes de soldar. 2) Agregue condensadores de desacoplamiento Añada un condensador cerámico de 0.1uf como condensador de desacoplamiento a través de los pines 1 y 8 (arriba a la izquierda y arriba a la derecha) de cada temporizador 555. He soldado el mío directamente a los pines 1 y 8 para ahorrar espacio. 3) Añada Potencia Positiva Añada las conexiones a potencia positiva. Cuando añadimos el regulador 7805 en un paso posterior, la tercera fila (contando desde la parte superior) será nuestro carril de alimentación de 5 voltios. Conéctelo a PIN 8 (arriba a la derecha) de ambos 555 temporizadores. En este caso estoy usando el cable anaranjado para las conexiones al carril de la energía de 5 voltios. En este punto también podemos conectar el PIN 4 (abajo a la derecha) del temporizador 555 superior a 5 voltios. Este es el pin de reinicio, está activo bajo, por lo que conectándolo a 5 voltios nos aseguramos de que el temporizador nunca se restablezca. 4.1) Agregue conexiones de tierra 4.2) Agregue resistencias de sincronización Dos pasos en uno aquí - 1) Agregue conexiones a tierra. El pin 1 (superior izquierdo) de cada temporizador 555 debe conectarse al raíl de alimentación de tierra. Cuando añadimos el regulador 7805, la segunda fila (contando desde la parte superior) será molida, conecte esta fila a Pin 1 de cada temporizador, he usado alambre marrón para esta conexión en la imagen. 2) Resistencias de temporización - Ahora añadimos el primero de nuestros componentes de temporización. En orden de arriba a abajo añadimos una resistencia de 1K (marrón, negro, rojo) desde el riel de potencia de 5 voltios (tercera fila hacia abajo) hasta el pin 7 del temporizador 555 superior. Luego añadimos una resistencia de 10K (marrón, negro, naranja) del mismo pin 7 a la fila que dejamos libre entre los dos 555 temporizadores. La resistencia final es una resistencia de 1K (marrón, negro, rojo) conectada desde el pasador 7 del temporizador inferior 555 a la fila muy inferior de nuestro tablero. 5) Agregue Resistencias de Tiempo Continuación A continuación tenemos que añadir dos resistores más al segundo temporizador. Conecte una resistencia 220 (roja, roja, marrón) del pin 8 al pin 7 del temporizador 555 inferior. Conecte una resistencia 680 (azul, verde, marrón) desde el pin 7 al pin 7. Sí, eso es desde el pin 7 a 7, es la resistencia azul en la imagen y para que tenga algún efecto necesitamos cortar la pista de cobre por debajo La resistencia. También es una buena oportunidad para mencionar que necesitamos cortar las pistas que de otro modo conectarían los 555 timer pins de izquierda a derecha. Refiérase a la imagen más adelante en el post. 6.1) Adición de condensadores de temporización 6.2) Añadir conexiones de sincronización Añada el condensador electrolítico 1uf (lata negra grande) entre los pines 2 y 1 del temporizador 555 superior. Tenga en cuenta que estos condensadores son direccionales, hay una tira con un signo negativo impreso en ella que indica qué lado debe conectar a tierra (pin 1) en la imagen que la tira está mirando hacia fuera de la cámara. El otro lado está conectado a la clavija 2. A continuación, conectamos el condensador cerámico 0,01uf entre los pines 1 y 2 del temporizador inferior. This capacitor is not directional. Finally we need to add connections between pin 2 and 6 (trigger and threshold) of the timers. In the picture I have used yellow wire for this, it would have been possible to route the wire directly across the chips from pin 2 to 6 however in this case I have chosen to route two wires, one down from pin 6 to the empty row immediately below the chip and one back up from from the empty row to pin 2. Repeat this for each of the two timers. Electrolytic Capacitor Orientation Larger value capacitors tend to be available as electrolytic capacitors, these have an appearance something like a can. Electrolytic capacitors are directional, to ensure that they are correctly placed, the cans have a band marked with a minus sign to indicate the side/pin which should be connected to ground. 7) Connect The Timers Together This one is easy. We want to connect the output of the first timer (top) to the enable of the second timer (bottom). This allows the top timer which is running at 1000hz to switch the bottom timer on and off to generate our coded 38Khz signal. This connection is shown by the white wire connecting pin 3 (output) of the top timer to pin 4 (reset) of the bottom timer. 8) LED Current Limiting Resistor As with any LED we need to limit the current passing through our infra red LED. As we are pulsing the LED it is only on for very short durations and so we have the option of passing more current through it. In this case I am using a 100 Ohm resistor (brown, black, brown) to limit the current to 50 milli amps, you could use a lower resistor for more power which would give a greater lap detection distance however on a narrow RC Track which loops back on itself a 100 Ohm resistor is perfect. The 100 Ohm resistor is connected from pin 3 (output) of the lower 555 timer to pin 1 (ground). In the next step we will add the LED and cut the track between pin 3 and the resistor. 9) Double Check Its a good time to double check progress. Here is the circuit constructed so far shown from the left side, double check yours against this and the previous images. 10) Add The IR LED Not a great picture, but its an easy step. Like all LEDs, the infra red ones are directional. This means the LED will only light if connected the correct way. As we cannot see infra red, its worth a little extra explanation to make sure we get this part right. Most LEDs have on leg which is longer than the other, the long one should be connected to the positive (closest to the chip) and the short to negative (the path to ground is provided by the 100 Ohm resistor). However I have recently bought a batch of LEDs where the legs were cut incorrectly. To double check you LED placement, look at the inside of the LED you should see to metal plates which are roughly triangular. The smaller of the two plates is the positive side of the LED and should be connected nearest to pin 3 of the bottom timer. The other leg should be connect next to the 100 Ohm resistor where it joins the same row as pin 3. You will need to leave at least one spare hole in the board between the LED legs, you will need to bend one of the legs into an S/Z shape to do this. As both ends of the LED are connected through the strip of copper running from the resistor to pin 3, we need to cut the copper strip to force the electricity to pass through the LED. Cut the track in the spare hole you left between the two LED Legs - refer to the underside picture for reference. Almost Finished The original transponder design is finished here and if you intend to use the transponder for motor racing or kart racing, just add a positive power connection to row 3 (third row down counting from the top and linked to the orange positive power wires) and a ground connection to row 2 (second row down connected to the brown ground wires). Add a 9 volt battery or even better 4 AA Batteries and go racing If you intend to use the transponder in an RC Vehicle and want to share the RC Power you will need to buffer your RC Receiver from the switching noise generated by the 555 timer. The most effective way I have found to do this is by using a 7805 regulator. 11) Adding The Regulator The 7805 regulator prevents the switching noise in the transponder circuit from being transmitted through the power circuit and into your RC Receiver. For the regulator to function it also needs two capacitors as supporting components which we will add in a later step. For now place the 7805 regulator in the 10th hole counting from left to right. The regulator should be orientated so that the heat sink is on the right side of the circuit and the legs point down towards the 555 timers. You might want to cut the heat sink off the 555 timer, this makes it easier to mount in your cars window, do this before soldering so that you do not damage the circuit while cutting. 13.1) Add The Capacitors 13.2) A Diode 13.3) Power Connection Lets do this in the order in which power enters our circuit. 1) Solder your positive power wire ( the red wire) to the very top row of the circuit, is the top left most hole. 2) Solder your ground (black wire) connection to the second row, if we have followed the steps correctly this should also be the same row as the middle pin of the 7805 regulator. 3) Connect a 0.1uf decoupling capacitor between the positive and negative power rails, in the picture you can see that I added mine to the left of the wires, you can add yours to the right as long as its immediately next to the incoming power connections. 4) Add a diode. Diodes are directional components, they only conduct electricity in the one direction, the direction is indicated by a band printed on the diode. In the picture the silver band indicates the direction in which electricity is allowed to flow. The band is facing the 7805 regulator meaning that electricity can flow into our circuit but if electricity is connected in the reverse direction the diode will prevent it from flowing and damaging our circuit. The diode is connected to the positive power track at the top left of our circuit, once we cut the copper track underneath the diode the electricity will have to travel through the diode to reach our circuit. If we accidentally connect power in the wrong way, the diode will prevent damage to the rest of the circuit from the reverse power. 5) Add the 7805 Supporting capacitors. In order to regulate the power to our circuit, the 7805 requires some additional external components, in this case we are using two 100uf electrolytic capacitors. Like all electrolytic capacitors these are directional components, a band on the capacitor indicates the side which should be connected to ground. The middle pin of the 7805 is the ground, it should be soldered in the second track down on our board which will be the ground rail. The outer pins are the input power supply and the 5volt regulated output, each of these should be connected to the center ground pin through one of the 100uf Capacitors - make sure that the band indicating the negative side of each capacitor is connected to the center ground pin of the 7805. Final Steps Our final step is to cut the copper tracks under the 555 timers so that the left and right pins are not shorted together, a 3mm drill bit will do this nicely. Final checks and trouble shooting - 1) The copper tracks on the underside of the circuit should be cut in the following locations - In the picture the copper tracks are running from left to right across the underneath of the board. The red marks indicate where a track should be cut, in order from top to bottom these points are - Diode - We need to cut the track directly underneath the diode in the top left of the circuit, this will force the electricity through the diode ensuring that if we connect power the wrong way around, no electricity will flow and no damage will occur. 555 Timers - We need to cut the tracks between the left and right pins or the two timers, this means 4 cuts on the first time and four on the bottom so that the pins are not shorted by the copper tracks. 680 Ohm Resistor - This resistor is connected to pin 7 of the second (lower) 555 timer and runs horizontally along the board. As this is the same direction as the copper tracks under the board, we need to cut the track under the resistor otherwise the electricity will by pass it through the copper track. IR LED - This component is also connected horizontally across the board. In order for the electricity to pass through the LED we need to cut the track between its two legs, in the picture the cut is marked one hole to the left of where the positive leg of the LED is soldered next to pin 3 (output) of the lower 555 timer. 2) Confirm that all of the components are correctly orientated. 3) Test the circuit - in order to test the circuit we need an IR Detector, a simple test circuit is provided in the following link, if you can light the red LED with the signal from your transponder, well done you have a working transponder. Next time - Adding the IR Detector to our lap timer circuit. As an optional step you might want to consider adding the amplifier circuit shown here - The external audio mode can be switched on and off through the lap timer menu for extra volume when you need it. The new lap time countdown mode that you can hear in the video can also be switched on and off through the system menu. External Audio and best lap time countdown demo - It is sometimes useful to be able to view the code that your Arduino has to execute, for example the two lines of C code A and B could result in code that is upto 6 times longer when A is a global integer and B is a local byte. This approach has been confirmed to work with Arduino Due code also - some of the file and directory names will be different, see the screen shot at the end of the post - follow these steps to easily get the assembly output. Step By Step Guide To Viewing Arduino Assembler Here is a simple set of steps you can use to view your source code and the corresponding assembly generated by the compiler - 1) Turn on verbose output Start the Arduino editor and from the File menu select Preferences to display the screen shown below. Find and select the option to Show verbose output during and tick the compilation check box. With this option selected, the Editor will show a trace of each step of the compilation process, it does not change anything within the process, it just displays the commands that the IDE issues to compile and upload your sketch. This can be useful to know especially if you would like to try alternative editors or you are having problems uploading to a new target. 2) Compile your sketch As the sketch compiles, you should see the output window at the bottom of the editor filling up with a series of commands being issued by the editor. Once the process has completed and the status bar shows Done Uploading your sketch has been successfully compiled. 3) Find the ELF file One of the last commands displayed in the output window will be avr-objcopy targetting a. elf file for your sketch. Find this command in your output window, select and copy the whole command. The quickest way to do this is to use the mouse to highlight the line and then use the keyboard short cut for copy CTRL C on windows machines. If you are using an ARM Based Arduino (Arduino Due), the structure will be the same with some difference in the command lines - the procedure is the same so read on. 4) Open a command prompt. Open a command prompt. In windows you can simply type cmd into start/run. With the command prompt open, paste the command we copied in 3 into the command prompt - we will edit this command in the next step so do not run it yet. If you are struggling to paste the command line, you can try the keyboard short cut CTRL V or right click and access the Paste option from the context menu or you can also access Paste from the Edit section of window menu accessed through the icon in the top left of the window. 5) Replace avr-objcopy with avr-objdump The command is formed in three parts, the command itself, one or more options and then finally the target file. The target file is correct, but we need to change the command and replace the options. To change the command, move the cursor back to the command avr-objcopy and change it to read avr-objdump, this is the program that is able to generate a file containing our original source code combined with the corresponding assembly code generated by the compiler. 6) Replace the options Because we have changed the program we are running against our target file, we must also change the options. To do this remove everything between the end of the obj-dump command and the start of the path to our target file and replace this with - S. In the case of my example sketch - Change this: C:arduino-1.0-windowsarduino-1.0hardwaretoolsavrbinavr-objcopy - O ihex - R. eeprom C:DOCUME To this: (changes in bold ) C:arduino-1.0-windowsarduino-1.0hardwaretoolsavrbin avr-objdump - S C:DOCUMEdnload. py is a script for generating minimal ELF binaries from C code. It serves no practical real-world use case, but can be utilized to aid in the creation of size-limited demoscene productions. The bridging header file can be created on any nix or Windows platform with an up-to-date Python installation and a suitable compiler. Generating a final binary is supported on nix platforms only. Due to practical purposes (i. e. the OS of choice of the author), the primary target operating system is FreeBSD. Existence of binutils toolchain ( as. ld. etc.) on the system is assumed. The script is self-contained, and should require no external python packages to be installed. Both Python versions 2.7.x and 3.x should work. For compiling without size optimizations, GLEW and SDL development files are needed. This is subject to change if/when other backends are added. Note: Cross-compilation is not (yet) supported. Building of binaries must be done on the actual target system. If you want to develop 32-bit software on a 64-bit system, you will need to set up a chroot/jail environment or a virtual machine. The script is used for two purposes: Building size-limited binaries directly from C/C source on systems, where compilation is supported. Generating a header file to hide the complexities of size-limited linking. This can be also be on systems where compilation is not supported. The main use of this feature is to allow demo developers to work on other platforms except the main targets. The generated header tries to preserve portability. When invoked, the script will: Probe for suitable compiler, usually gcc or clang, cl. exe on Windows. Search for header file it was supposed to generate. By default this is called dnload. h. Examine the location the header file was found in. If a source file was given on command line, only operate on it. Otherwise take all source files from this location. Preprocess the source files with the compiler found earlier. Examine preprocessor output and locate all function calls made with a specific prefix. By default this prefix is dnload . Generate a loader code block that locates pointers to given functions. Write the header file. If the script was invoked to additionally generate the binary: Search for usual binary utilities in addition to the compiler. Compile given source file with flags aiming for small code footprint. Perform a series on operations on the compiler output known to further reduce code footprint. Link an output binary. Possibly strip the generated binary. Compress the produced binary and concatenate it with a shell script that will decompress and execute it. To understand how to use the script, a simple example will clarify the operation with more ease than any lengthy explanation would. This tutorial will cover a traditional hello world program. Use this command to clone the repository: The checked out repository will have the dnload. py script in the root folder. The minimal example is included in the src/ folder and called helloworld. cpp. The example looks like this (removing non-essential comments): When beginning to work with a project, the first thing needed is to ensure that our header is up to date. To do this, run: This should produce output somewhat akin to this: You should now have an up-to date header file, which can be used to build the program. You may take a look at the contents of the header, but it will be explained in detail ThequestforminimalELFbinaries later on. Even when developing an intro, the programmer is hardly interested in building a size-optimized binary every time. For this purpose, everything in the generated header file is wrapped to compile-time guards that allow us to compile the program as normal from Makefiles, Autotools scripts, CMake or even Visual Studio projects. To do this, we need to set the USELD flag, for example by (replace with your favorite compiler): Note: The include directory and invoking sdl-config are currently necessary since SDL backend is what will be included by the generated headers. When USELD is turned on, all tricks will essentially evaluate to NOP, and all calls made with the reserved dnload prefix will simply call the functions as normal. To invoke the script and perform full compilation, use: You might notice the flags are similar to the conventions used in other binary utilities. This is intentional. The command should produce output somewhat similar to this: The actual program output should be: First of all, all programs wanting to use the loader will have to include the generated header file: This will internally include the relevant loader and some other header(s) present in the src/ subdirectory into the project. The user may of course include any other source files necessary, but all function calls should be done through the interface wrapped herein. To understand what the script does, we will look at the main function: If the macro USELD would be defined, all this would simply evaluate to a self-explanatory hello world program: If USELD is not defined, the program instead uses an entry point named start. This is because even if using main() normally, it is not the real entry point into the program. In practice, the linker will generate code that will perform initialization of global variables, environment, etc. and only afterwards pass the control to the main function created by the programmer. The actual entry point generated by the compiler/linker system is traditionally called start. Since were aiming for a small binary, we will not be using any automatically generated entry point code, and declare it ourselves. The two first lines of main function comprise the actual program: This will perform of dynamic loading of all required symbols (here: only puts ) and call the appropriate function pointer. After saying our hellos, the only thing left to do is to exit the program: Since we already abandoned the default main procedure, no-one is going to terminate our program. We could make it return but that would normally only pass control to the shell provided by the system, we now have nowhere to return to. Thus, we must make a system call Ref11 to terminate the program ourselves. The code that will do this is written into the dnload header directly as inline assembler. On i386 architecture, it will evaluate into the following single instruction: Note that this is not the traditional exit system call. Instead, its a trap ref30 that will break into debugger or exit the program if a debugger is not available. It has the advantage of taking less space than moving 1 into eax and executing a normal int 128 system call. The return value for the program is irrelevant, as the decompressor shell script the program is eventually wrapped in would eventually mask it anyway. The src/ folder contains two other examples: quad. cpp and intro. cpp. The quad example will simply open a coder-colored window, whereas the intro example performs (extremely primitive) raycasting and outputs 8-bit music (from very short programs) for a couple of seconds. The intro example can also be compiled with CMake for a interactive program with a debug mode. To compile this, run (you will need Boost, GLEW, libPNG, OpenGL and SDL): This should open a window allowing mouse pan and WASD movement. You can size-optimize the program with: This section of the documentation explores both the current and historical methods of reducing executable file size on nix systems. If you are only interested in the current best practice operation of the script, you can skip to Current compression procedure . We can alter the compiler output to produce smaller binaries both by making it actually optimize for size and by altering the output to be more compressable. The command line options would fall into three categories: Options that decrease size of generated code or constants. Options that (either randomly or unintentionally) produce a smaller or better compressable binary. Options that disable language features, making output smaller. Despite Clang being all the rage nowadays, gcc seems to still produce binaries that size-optimize better. In particular, the script will attempt to use whichever g is currently the latest available on FreeBSD ( g49 at the time of writing). Note: Any compiler may be specified with the - C or --compiler command line option, but compilation is currently only supported with gcc or clang. cl. exe may be used to generate the header in Windows. Using g, the flags of the first type (just smaller) would be: - Os - ffast-math - fomit-frame-pointer - fsingle-precision-constant - fwhole-program These are all self-explanatory. In general, mere - Os - ffast-math - fomit-frame-pointer seems to do an excellent job. The following options are of the second type, seeming to consistently produce code that compresses better: - marchltarchgt. Some subsets of the instruction set seem to yield better results. As an example, on i386 architecture, after permutating through all available instruction sets with several different intros, Pentium 4 was usually the best choice. - mpreferred-stack-boundaryltaligngt. Forces the compiler to attempt keeping the stack aligned at 2ltaligngt bytes. It seems its advantageous to keep this at the smallest possible value for any given architecture. Some flags of the third type, which disable fancy language features, are: - fno-threadsafe-statics. By default some code is generated to ensure thread-safe initialization of local static variables. This code seems to get generated even if no statics actually exist. - fno-asynchronous-unwind-tables. Disables generation of stack unwind information that could be used to debug stack contents at locations other than at the function call boundary. - fno-exceptions. Self-evident. - fno-rtti. Self-evident. Note: One could ask why C to begin with if were not using any of its features The answer is, that it should never be detrimental. After manually disabling all the features that would increase code footprint, we can basically write C using a C compiler. In some cases the C syntax will be beneficial. Scouring old releases, the first instance of a nix 4k using a self-dumping shell script seems to be helsinki-spiegelberg by tsyg ref12. However, instead of dumping an executable binary, this entry actually unpacks to a source and compiles before execution. There are some other variants afterwards, but the first use of the modern one-line filedump is found in Yellow Rose of Texas by Fit amp Bandwagon ref13. Consequently, this is also the first big Linux 4k intro. The concept of self-dumping shell script is to have the first n bytes of a file be plain text that will be executed by normal sh - compatible shells. The shell code will: Extract the rest of the file using common nix tools (the compressed data starts immediately after the script). Write the extracted data as a file into system temporary folder. Make the file executable. Run it. Remove the file after program exits, since thats the proper thing to do. The header in Yellow Rose looks like this: There are multiple programs that crunch classic gzip files to as small sizes as possible, but modern nix systems come with better compressors and better tricks. For example, using a trick from ts/TDA ref27. redefining HOME allows using the tilde character for clever reduction: This unpack header has gone to 57 bytes (newline for tail is needed at the end) from the 66 needed by Marq, but its still unnecessarily large as its trying to be nice. If we omit removing the extracted file and allow the compressed garble to flood the screen, we can do the same in 44 bytes: One could assume that xz format would be more advantageous than the earlier lzma, but this seems not to be the case as lzma compression headers are smaller ref28 ref29 . We use the xz toolkit, however, as it allows free customization of the compression parameters. For actual compression parameters, which yields decent results, we use: At least on our bruteforced tests, this seems to consistently yield the best results for binaries aiming to the 4k threshold. For academic interest, the script can create its output using nothing besides the unpack header trick. To do this, use the command line flag - m vanilla (as in --method ). This yields us the baseline whencefrom we begin our quest for smaller binaries: Note: Unless otherwise mentioned, all sizes, code excerpts and implementation details in this chapter refer to FreeBSD-ia32. which was the original supported platform. The stripped binaries listed above are generated by just removing all non-needed sections from output binaries. These include ment. ehframe. ehframehdr. fini. gnu. hash. gnu. version. jcr. Nota. note. ABI-tag and. note. tag. Using the compiler/linker - s flag seems to leave some of these in, so strip is called manually afterwards. Besides the modern unpack header, Yellow Rose also introduced the concept of using POSIX dlopen ref14 and dlsym ref15 to load the OpenGL functions it required. This is relevant, because the symbol tables consume quite a lot of space. Taking a look into the FreeBSD system headers ref17 we can examine the symbol structs (going into. dynsym ): This is 16 bytes per symbol. In addition the linker will generate linkage tables (going into. plt ), which seem to be at least 2 instructions per symbol (look at Prodedure Linkage Table in the ELF specification part 2 ref16 ). Global Offset Table adds 4 bytes each. In any case, were talking roughly 30 bytes per symbol. Not counting the space consumed by the function names themselves. Luckily, using the forementioned two symbols, we can perform dynamic loading ourselves. Yellow Rose loaded only the GL functions this way, but using a clever arrangement of text, we can embed the library information in a text block at practically no cost: First string is a library name, terminated by zero. Successive strings are function names. Two successive zeroes revert to initial state, next string will again be a library name. Third successive zero stops loading. This produces the following loader (using intro. cpp example): The code snippet reveals a fake symbol table with the name gsymboltable. It is simply a list of function pointers constructed from the prefixed function names found when preprocessing the source file earlier. Depending on the build mode, we will either select the regular function call or redirect to our table. For the hello world example, the code would look like this: To gain access to these functions, we need to link against the standard C library with - lc flag. On Linux, use - ldl instead. Additionally on FreeBSD, when using SDL, user must manually link against libthr. Since SDL is not explicitly linked against, it is not pulling the thread library as consequence. It seems threading is not properly initialized unless the dynamic linker gets to load libthr . Recompiling with - m dlfcn. we get new sizes: Interestingly, this method does not really seem to be that advantageous at all on modern FreeBSD. Small binaries actually get larger due to additional program logic in the function loading system. On any nontrivial program there is a slight tradeoff in favor of just using plain ld though. Even if the cost of function name only is rather little, it still adds up for a large block of data, especially as using dlopen and dlsym requires us to have symbol definitions and all the PLT/GOT information required for them in the binary. Fortunately, there is a better way. In 2008, Pouet users parcelshit ref3 and las/Mercury ref4 published code to search for symbols in ELF32 shared objects by their hashed names. Some of the code linked in the discussion ref19 seems to be unaccessible by now, but at least the original import-by-hash implementation ref18 (used as proof-of-concept for our implementation) seems to still be available. The technique essentially takes advantage of the DTDEBUG element in the. dynamic section (when present) that will contain information about linked shared libraries. We simply need to gain access to it. Programs using ELF will have access to their own headers directly at the program load address ( 0x8048000 by default). The ELF32 header is 52 bytes long, and is immediately followed by an array of program headers. Each program header looks like this (from FreeBSD system headers): For examining the dynamically loaded elements, we need to look for a program header of type PTDYNAMIC. Upon finding the header, the pvaddr virtual address pointer will point directly to the dynamic section. The dynamic section, then further consists of an array of structures of type Elf32Dyn. they look like this: When the dynamic linker passes control to your program, the Elf32Dyn structure with the tag DTDEBUG will have been filled with a pointer to the debug structure associated with the program. The debug structure looks like this: In here, the element rmap will contain a pointer to a linked list of structures representing shared objects, that is, libraries. They look like this: The field lld in this structure is a pointer to the particular. dynamic section of this shared object. Reading the ELF specification References 16, we also know that: All symbols of the shared object are located in the section pointed by tag DTSYMTAB . All symbol names are located in the section pointed by tag DTSTRTAB . Symbols names point to offsets from the start of DTSTRTAB section. The total number of symbols in a shared object is the number of chains in the hash table of the shared object. Using this information, we can simply go through the shared objects, one by one, then go through the symbols in these shared objects, one by one, only stopping when we find a name with a hash matching the hash we want. We can also use the symbol table format defined in the earlier section by storing these hashes at the same location the function pointer is going to get stored at. The only thing that remains to be done is to find a convenient hashing algorithm. Fortunately, this has been done for us already ref20. There are many good candidates where collisions are improbable enough to be nonexistent. We simply pick the one that produces smallest code. Parcelshits original code used the DJB hash, which is already good, but in my testing, using SDBM hash produced a smaller binary. Combining all this, gives us the following proof-of-concept implementation: Compiling with - m hash and linking against normal libraries (as opposed to what was needed with the dlfcn method) gives us new sizes: The command line option - m hash additionally does some low-hanging optimizations such as removing all known unneeded symbols ( end. edata and bssstart ) and combining. rodata and. text into one section to free 40 bytes that would be consumed by a section header. This kind of hacking is, however, ultimately uninteresting as the only real way to further reduce the size is to construct all the ELF headers manually. There are earlier examples, on manually writing Linux ELF32 headers byte ref21 by byte ref22. These are easily executable even on FreeBSD 32-bit Linux emulation. The also come complete with source code, so one would assume switching between operating systems would be as easy as changing 8th byte of the ELF header into ELFOSABIFREEBSD (i. e. 9) and recompiling with nasm. Unfortunately, things are not quite so easy, and binaries constructed thus will just crash. However, even if the examples themselves are not usable, they prove that manual hacks are least possible. What we need to do is, have some kind of access into the process of dynamic loading itself, and see what we can do to decrease space. This is all done for us already, quoting manpages of ld-elf. so : The ld-elf. so.1 utility is a self-contained shared object providing run - time support for loading and link-editing shared objects into a process address space. It is also commonly known as the dynamic linker. Full operating system sources have already been provided in /usr/src. Recompiling the dynamic linker is as easy as going there and building (but not installing) world by issuing: This constructs our dynamic linker in /usr/obj/usr/src/libexec/rtld-elf/ld-elf. so.1. and gives us access to the source in /usr/src/libexec/rtld-elf/ . The authors have been kind enough to literally point out where the hacking should begin. rtld. c line 334: What can I say Thank you We obviously do not want to replace our own rtld with a crappy, hacked version so its better to use the custom version directly. Reading A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux ref2 and Executable and Linkable Format (ELF) ref16. we can construct the minimal program to do this and start the investigation: You can copypaste the earlier into, say, header. S and run: This should produce: Disappointing. But add something, anything, into your custom rtld sources, recompile rtld, and try again. At the time of writing this document, mine says: So thats why it crashes. From this on, its all just manual work, instrumenting the dynamic linker and seeing what can be done to minimize size. As this is an ongoing process, we will simply itemize the current findings. The maximum compression mode uses certain techniques to decrease binary size, described below. These seem to be not needed. En absoluto. ELF uses the section information for introspection. Names of sections are contained in a specific section, readelf will expect fixed section names to decrypt symbol tables, etc. However, when push comes to shove, the program will still be executed solely based on instructions in program headers and the. dynamic information. Section headers are 40 bytes a piece. We will have none of that. Traditionally programs put uninitialized but statically reserved memory in a section named. bss or Block Started by Symbol that will be handled by the linker. We naturally do not have anything of the like. However, the program header PTLOAD provides a possibility to set the size on disk ( pfilesz ) as different from size in memory ( pmemsz ). Setting these into different sizes will simply cause more memory to be allocated. We parse the variable definitions directly from assembler code and construct virtual locations and pointers after the end-of-file in the following manner (taken from quad. cpp example): The file size will use end while the memory size will use bssend . Note: This will fail with a bus error if the size of fake. bss segment nears 128 megabytes. If this happens, the solution is to do the exact same thing ld would do - construct another PTLOAD segment at the next memory page without the execute flag set and assign all uninitialized memory there instead. As described in Example program earlier, we take care from entry and exit from the start procedure ourselves. The compiler will happily push registers at the beginning and subtract the stack at the end of the function. On i386, this looks like the following (from helloworld. cpp example): None of the push operations at the beginning or any operations after the system call are necessary. They may be discarded. Compilers seem to generate alignment directives rather arbitrarily. This is necessary on some architectures, but unnecessarily high alignments are irrelevant. All alignment takes space on disk. To prevent this, all alignment directives greater than the register width (32 or 64-bit) in the generated assembler source are converted to explicit. balign directives for 4 or 8 bytes. Note: It turns out that on alignment can sometimes be completely removed by effectively aligning one byte. This is not possible on any architectures where instruction pointer is assumed to be aligned to instruction size, but works at least on amd64 and on ia32 . As Brian Raiter already noted in A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux ref2. it does not really seem to matter if the ELF headers overlap. The structures will be assigned addresses exactly based on the offsets given, and they can freely overlap with other structs in memory. The process of interleaving the structs is automated. This produces, for example, the following: In this particular case, the merging takes advantage of:.interp section is aligned at one-byte boundary. This alignment is the last value of PTINTERP phdr. Hash table containing only the symbols required by libc starts with number 1 (one chain)..dynamic section can start with many numbers. We put the PTNEEDED library requirements at the top so it can correctly interleave with the last value of the hash table..dynamic section ends with the PTNULL terminator. Symbol table starts with the null symbol. Size of null terminator is 8 bytes plus varying amount (depends on byte order) of remaining null bytes from the earlier DTDEBUG dynamic structure. These can be partially interleaved..interp section ends with terminating zero for the interpreter string, and. strtab always starts with a zero as per specification. Note: Interleaving with DTDEBUG is dangerous, as the structure will be filled on runtime as seen in Import by hash - scouring ELF headers. In practice, it seems to not cause problems currently. Default ELF entry point is fixed to address 0x8048000. This can be changed to a better compressable address. The only issue here is that specifying --entry to ld does not actually change the entry point (it probably would if ld would also construct the headers). We need to modify linker scripts. This is done the same way as in Import by hash - scouring ELF headers - make the linker export the full linker script and change the SEGMENTSTART directives into a better constant ( 0x2000000 at the time of writing). If symbols are present in the object, a hash table must be present to allow the dynamic linker to look for symbols. Either a GNU hash table or the traditional SYSV ELF hash table could be used. GNU hash table however uses 16 bytes for the mere headers, and does not look all that promising. SYSV hash tables seem to be relatively small. They look like this (all values are unsigned 32-bit integers): Number of buckets. Number of chains. List of indices, size equal to number of buckets. List of indices, size equal to number of chains. In here, the number of buckets serves as the basis of the hashing. Symbol equates into a hash value, that is modulated by number of buckets. Value from given bucket points to an index to start iterating the chain array from. The FreeBSD rtld. c implementation looks like this: The obvious solution is to only have one bucket and point it at the end of the chain array, then have the chain array count down from this index, going through the symbols one by one. It is definitely ineffective, but that hardly matters. This results as a generation algorithm as follows: Write one integer, number of buckets (1). Write one integer, number of symbols plus one. Write one integer, pointing at the last symbol index, adding one for the obligatory empty symbol ( STNUNDEF is 0). Write a zero, for padding. Write an increasing list of integers, starting from 0, ending at index of last symbol minus one (last symbol index was already at the only bucket we had). The total cost of adding symbols would thus be 8 (for dynamic structure referencing DTHASH ) (4 numsymbols) 4 (for hash itself) (1 numsymbols) 16 (for symbol structs plus one empty symbol struct) strlen(symnames) bytes. Nota . In FreeBSD, where libc requires symbols environ and progname this would be 99 bytes exactly. When not constructing headers manually, the rdebug debugger structure containing the link map to iterate over linked shared libraries must be found by examining the program headers, starting right from the entry point. In his similar project ref32. minas/Calodox uses the manually constructed headers to directly know the location into which the dynamic linker will write this address. After adding a label into the header assembler code, accessing the link map is thus reduced from: Logically, before iterating through the symbols in a library, their total amount would be interpreted from that librarys hash table. This only takes a bit of space on FreeBSD where (easily interpretable) SYSV hash tables seem to be present in every library. On Linux, some libraries only contain GNU hash tables the parsing of which significantly increases code footprint ref25 . Luckily, minas/calodox noticed that DTSTRTAB and DTSYMTAB seem to have two interesting relations: Linkers seem to always put DTSTRTAB directly before DTSYMTAB in the dynamic section. Conversely, symbol table seems to always immediately precede string table in program memory. The only program that does not obey these rules is our own binary, which is the first entry in the ELF debug listing. Using this information, the symbol scourer part of the loader can be reduced into something like this: To see the difference compared to actually interpreting the hash, compile using --safe-symtab command line option. Linux libc does not require the user program to define environ and progname. I was initially just leaving the hash and symtab segments blank. A blank symtab consists of just one empty ( NULL ) symbol, which already saves quite a lot of space. However, as Amand Tihon ref23 points in his own similar project ref24. on Linux the whole of symbol table can be omitted. This is done by having the DTSYMTAB dynamic structure entry point to address value 0 and by omitting DTHASH completely. All in all, this means that size-optimized binaries on Linux are 99 bytes (Minimal DTHASH ) smaller than on FreeBSD. Interleaving of headers takes away some of this advantage, in practice it seems to be about 30 compressed bytes. Compiling with all the tricks listed above (using - m maximum or just omitting the option) gives us: Note: Sizes subject to change. This script would not have been possible without the prior work done by various other parties. Especially the following entities deserve kudos for their efforts: Marq/Fit ref1 for the original unpack header and dlopen/dlsym implementation. Brian Raiter for A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux ref2 and the insight of interleaving headers. parcelshit ref3 and las/Mercury ref4 for the original ELF32 import-by hash algorithm. Hymy ref5 and Ye Olde Laptops Posse ref6 for earlier forays into manual ELF32 header construction. Amand Tihon ref23 for BOLD - The Byte Optimized Linker ref24 and noticing that DTSYMTAB can be empty. ts/TDA ref26 for INT 3 exit, HOME - shell script trick, and probably something else. minas/calodox ref31 for elfling ref32 and various symbol scouring tricks. viznut/PWP ref7 for the series Experimental music from very short C programs ref8. a snipped of which is used in one of the examples. The list might be missing some parties. Please notify me of any errors or omissions, so that people will get the credit they deserve. All contained code is licensed under the new BSD license ref9 . Note that this license only pertains to the code of the script(s) themselves. There are no restrictions imposed on the end products of the script(s) just like there are no restrictions imposed on a binary built with a compiler. To be honest, even that doesnt really mean anything. Just do whatever you want, but if you improve on the mechanisms, I would prefer to incorporate the improvements. Even on a 64-bit system, you should be able to execute the result file if the compatibility layer is set up correctly. The easiest way to do it is to just install a 32-bit jail ref10 and point LD32LIBRARYPATH environment variable to the /usr/local/lib of that jail. This has the added benefit of enabling full 32-bit compatibility and easy cross-compiling. There are probably easy ways to do the same on Linux, but they are out of the scope of this document. It turns out the techniques described in this document are suitable for 64-bit ELF with minor or no changes. No specific new tricks are required. The script supports ELF64 just the same way it supports ELF32, the description is kept in 32-bit particulars for simplicity of explanation. The name USELD is legacy, which has preserved unchanged from earlier Faemiyah prods. You may change the definition with the - d or --definition command line argument when invoking the script. When manually creating the program headers, the symbol would not necessarily need to be named start - it could be anything, and the name will be stripped out anyway. However, this is a known convention. You you looked into the generated header, you might have seen something like this: These symbols might seem nonsensical, as they are not used anywhere in the program or the generated code. Taking a look into the standard C library (i. e. /lib/libc. so.7 ) will clarify their purpose: We do not need these symbols, but libc expects them to be present in the binary. In practice, the dynamic linking procedure will fail if the program symbol table does not contain them. Note: These symbols seem to be not needed on Linux. The suffix attribute((externallyvisible)) is present in some symbols defined, most notable in start. This is due to Gnu C Compiler semantics. When compiling for binary size, it is necessary to use the - fwhole-program flag to make g discard all irrelevant code. Unfortunately, unless the compiler finds something it needs, this will actually cause it to discard everything within the source file as there is no main() present to start building a dependency graph from. This attribute explicitly marks functions as symbols to be externally visible, so the dependency graph build shall include them. Note: Clang does not seem to either require or support this attribute. Should probably create the header file in a smart(er) manner if it is not found. Add cross-compilation support, at the very least between nix systems at the maximum operation mode. Only SDL/OpenGL supported right now. Should probably also support GLFW. Perhaps there are more efficient ways to interleave the header structs Perhaps this can be permutated


No comments:

Post a Comment