sábado, agosto 08, 2020

Guía rápida para usar Tortoise HG (Mercurial)

Si quieres tener un control de versiones de un proyecto puedes usar muchas herramientas. Existe el súper popular git o también Mercurial a través de TortoiseHg.

En esta guía rápida veremos cómo usar Tortoise HG para:
- Respaldar un proyecto
- Agregarle cambios
- Ignorar archivos
- Revertir cambios
- Hacer un branch al proyecto

Instala Tortoise HG

Para instalarlo debes descargarlo de su página:

https://tortoisehg.bitbucket.io

Respalda un proyecto

Mi recomendación es que tu proyecto y todos sus archivos existan en un subfólder:

└───ejemplo        ---> Fólder superior
    └───ejemplo    ---> Subfólder
            code.c

Esto es porque Mercurial genera un fólder oculto llamado .hg que se encarga de tener el historial de todos los archivos y sus cambios. No querrás que este fólder aparezca en tu IDE (Eclipse o Netbeans, como ejemplo) porque tiene muchísimos archivos que te darán lata. Mantenlo aparte.

Una vez que definiste el fólder superior con el fólder dentro de tu proyecto puedes abrir TortoiseHgG. Debes dar de alta un usuario y un email, aún cuando no vayas a hacer commits (subir código) a otros servidores. Entra a Settings y dalo de alta. Un ejemplo: John Doe <johndoe@fake.com>.

Selecciona New Repository...

Elige el fólder superior:

Dale Create sin cambiar las demás opciones.

Te mostrará una ventana con los contenidos aún no guardados de tu proyecto.

El branch default aún no existe pero podemos inicializarlo si se selecciona. Nos dirá qué archivos nuevos entrarán al control de versiones. En este momento muestra la versión +/1 porque no se ha hecho nada aún.

Mi proyecto sólo tiene un archivo.c dentro del fólder ejemplo. También se creó en automático un archivo llamado .hgignore. Ese archivo te será de utilidad para cuando quieras ignorar archivos en tu control de versiones. Por ejemplo podrías ignorar todos los .o que se generan cuando compilas tus C.

Hagamos nuestro primer commit. Selecciona ambos archivos poniéndoles la palomita. En el cuadro de la derecha pon un comentario para tu commit. A mí me gusta ponerle una versión, pero puede ir cualquier texto. Finalmente presiona Commit.

Te pedirá que pongas tu nombre, dile que sí. Te preguntará si quieres agregar los archivos seleccionados, dile que también.

Y listo, tendrás un respaldo local de tu primer versión del proyecto. Este existirá sobre el branch default.

Agrega cambios a tu proyecto

Tu proyecto siempre está mejorando... digamos que haces un cambio en un archivo... Tortoise se dará cuenta cuando presionas el botón de Refresh mientras estás sobre el *Working directory*. En mi ejemplo actualicé el texto del printf. Te lo reportará al dar click sobre ese archivo. Si tuvieras instalado un visor de diferencias puedes usarlo dando click derecho sobre el archivo.

Como ese cambio queremos respaldarlo podemos entonces hacer un nuevo commit. Dale a la palomita, introduce un texto para el commit y dale Commit.

Ignorar cambios

Ignorar archivos o fólders es muy fácil. Al darle refresh Tortoise no te mostrará esos archivos. En mi ejemplo agregué un code.o que simula la salida de la compilación del C y una imagen. Sólo me interesa respaldar la imagen así que le daré click derecho al .o y le diré a Tortoise que lo ignore. Y seleccionaré la imagen para que me la guarde en un nuevo commit.

Verás que el archivo .hgignore se actualizó también. Asegúrate de que también tiene palomita para que en los siguientes commits Tortoise siga ignorando ese code.o. Puedes usar comodines e ignorar todos los .o e incluso puedes ignorar fólders completos. Es cuestión de que experimentes para que veas cómo lograrlo.

Revertir cambios

Digamos que cometiste un error o que simplemente quieres ir a una versión anterior de tu código. En mi ejemplo cambié el texto de code.c.

Simplemente doy click derecho al archivo que quiero restaurar y le digo Revert.

Revert with backup - creará una copia temporal del archivo actual por si te arrepientes y restablece el archivo.
Discard changes - sólo restablece el archivo.

Regresar a un commit anterior

Es posible regresar a un snapshot de tu proyecto. Debes ser cuidadoso porque si hay archivos que quieras mantener debes guardarlos en un commit antes de moverte a uno anterior. En mi ejemplo me iré a la versión 0.1. Sólo hay que dar click derecho sobre el commit deseado y darle Update...

Usa las opciones que muestro a continuación... recuerda: borrará todo cambio actual para irse al pasado.

La grafiquita ya muestra cómo estamos sobre un commit anterior y nos dice que no es el head.

Creando un nuevo branch

Digamos que ésta versión era estable y que quieres continuar trabajando sobre ella, pero quieres que tenga otro branch para que sepas sobre qué proyecto estás. Creemos el branch y llamémosle stable. Da click en Branch: default y dile que quieres uno nuevo.

Ingresa un texto para el commit. En Mercurial los branches crean commits. En git no.

Ya estando en tu nuevo branch puedes hacer nuevos commits o regresarte al branch default. Recuerda guardar tus cambios con commits antes de moverte en el tiempo.

Y esta es la guía rápida. Dominar Tortoise no toma tiempo. Sólo ten cuidado cuando te muevas entre branches y aprovecha la herramienta al máximo.

lunes, agosto 03, 2020

Revista Club Nintendo Año 6 Número 4 1997

Cuando uno quiere hacer espacio en su casa empieza a abrir cajas y cajas y empiezan a salir objetos de los que uno ni se acordaba. En esta ocasión aparecieron mis revistas de Club Nintendo y me dio mucho gusto verlas en buenas condiciones.

Me daré a la tarea de leerlas de vez en cuando y si hay algo que me parezca interesante o curioso pues lo compartiré en este blog.

En esta ocasión la primera revista a la mano fue la Club Nintendo Año 6 Número 4 de Abril de 1997... hace 23 años.


Me impresionó mucho ver que el Nintendo 64 era lo popular del momento en cuanto a Nintendo y que el Super Nintendo aún estaba en casa de muchos de nosotros también. Como artículos fuertes de la revista se mencionaba a Mario Kart 64... un tutorial de MK64... ¡hoy en día saber jugar Mario Kart es sentido común! Igualmente trae tutoriales para otros juegos que ya son leyenda. Hay un artículo de BlastCorps que personalmente a mí me encantó jugar en N64.

Es curioso ver que se usaba la Página 64 como una sección especial de la revista... así como el SUMARIO que también trae jiribilla en el nombre.

Siempre me causó mucha emoción el Taller de Luigi. Un lugar oficial donde reparaban tus consolas de Nintendo y sabían lo que hacían... o al menos eso nos hacían creer.

Asistí dos veces. La primera ocasión fue para que repararan mi Super Nintendo. Tenía fallas después de jugarlo un rato... se corrompía el video. Ese Super Nintendo nunca falló desde que lo repararon en el taller. La segunda fue para que me arreglaran la salida de audífonos de mi GameBoy Pocket amarillo. El ingeniero me dijo que era mejor que siempre lo usara con audífonos porque así se gastaban menos baterías. Hoy en día que también soy ingeniero entiendo el por qué.


Les gustaba trabajar en zonas costosas de la Ciudad de México. Los teléfonos de la Cd. de México aún eran de 7 dígitos.

Y bueno... Clubnin era en discreción una revista con propaganda de Nintendo pero con todo el contenido que tenía y la camaradería con la que los editores la redactaban uno ni se daba cuenta. Uno la disfrutaba.

Como propaganda siempre advertían del peligro que era comprar en negocios no establecidos y los riesgos de comprar piratería. Es entendible que lo hicieran, era la revista oficial de Nintendo en México, igualmente patrocinada por Gamela en esos entonces.

Si tan oficiales eran... ¿cómo es que se les fue un error de ortografía en el logotipo de Nintendo? Jeje ¿Seal of Quallity?


Así como había Nintensivos de Mario Kart 64 también había de Super Mario 64. Estoy sorprendido con la calidad de las imágenes que en esos ayeres publicaban. ¿Usaban tarjetas de captura? ¿Las conseguían de la revista hermana Nintendo Power?

Los tutoriales... ¿eran copia de Nintendo Power o se hacían 100% en México?


El GameBoy original seguía vendiéndose y vendiéndose... creo que fue la consola más longeva de Nintendo.


Gus Rodríguez siempre apareciendo en la revista. Buenos recuerdos. Ya en los últimos momentos del SNES había que vender hasta el último que quedara.


En 1997 la internet apenas se daba a conocer en México. Club Nintendo ya estaba al día en esos asuntos. ¿Recuerdan el tutorial de HTML? Muchos de nosotros lo seguimos al pie de la letra y aprendimos a codificar páginas web súper básicas (y ridículas como la mía).


Hoy en día mi página sólo es visible a través de archive.org...

https://web.archive.org/web/20091027035122/http://geocities.com/migsantiagov/

También había dinámicas muy padres en donde los lectores enviaban sus récords en videojuegos o donde proponían retos a vencer. Este de Link's Awakening suena como que es resolvible con un glitch del juego, pero como nunca lo acabé... no sé cómo se resuelva.


Y bueno, eso es lo que me llamó la atención de este número. Espero poder encontrar los números en donde mis preguntas salieron publicadas. También estoy interesado en leer el especial de Pokemon de Generación 1... lo traía por todos lados. Espero que ése no sea donde infamemente Clubnin dijo que cuando uno presionaba el botón B justo cuando la pokebola explotaba ayudaba a subir la posibilidad de atrapar al Pokemon... rumores de hora del recreo publicados en una revista oficial 😉

Si quieres compartir comentarios te invito a hacerlo a través de Twitter:

https://twitter.com/migsantiagov

Hasta la próxima.


viernes, mayo 22, 2020

Calcular el stack en S32 Design Studio for ARM (S32K144)

El día de hoy me encontraba programando una FFT en un S32K144 en el IDE S32 Design Studio for ARM. El S32K144 tiene 64kB de RAM por lo que no me preocupé en declarar variables inmensas.

Las variables globales que declaré fueron:

#define FFT_SAMPLE_MAX                                  (2048U)
#define FFT_FREQUENCY_RESP_SIZE                         ((FFT_SAMPLE_MAX / 2) + 1)
#define FFT_FREQ_BANDS                                  (10U)

static uint16_t FFT_AudioSamples[FFT_SAMPLE_MAX];
static float FFT_HammingWindow[FFT_SAMPLE_MAX];
static float FFT_Frequency_Bands[FFT_FREQ_BANDS];

Alrededor de 13kB, entre otras variables estáticas locales que no contabilicé.

Posteriormente, dentro de una función declaré más variables pero esta vez como variables locales que se depositarán en el stack.

void FFT_GetFrequencyResponse(float* freqResponsePerBand)
{
    if (1 == FFT_bufferReady)
    {
        float audioReal[FFT_SAMPLE_MAX];
        float audioImag[FFT_SAMPLE_MAX];
        float freqResp[FFT_FREQUENCY_RESP_SIZE];

Alrededor de 20kB en esa función únicamente. Si sigo llamando funciones con nuevas variables en stack, éste seguirá creciendo.

Después de ver que mi código sospechosamente estaba corrompiendo las variables me di cuenta de que no había modificado el tamaño del stack y que por ello se estaban sobreeescribiendo.

Utilicé C/C++ Watchpoints para ver cuándo se escribía y leía la variable corrupta. Basta con abrir el Memory Browser (Menú Window, Show view) y poner el nombre de la variable. Se le da click derecho y se agrega el watchpoint (Range = 40 porque pesa 40 bytes mi arreglo). Esto también se conoce como Hardware Breakpoint.



Si uno abre el archivo .map de la aplicación encontrará el tamaño del stack configurado así como el del heap, que en mi caso no necesito:

                0x00000400                HEAP_SIZE = DEFINED (__heap_size__)?__heap_size__:0x400
                0x00000400                STACK_SIZE = DEFINED (__stack_size__)?__stack_size__:0x400

0x400 = 1kB

Ese kB es mucho menos que lo que necesito.

Claro, pude haber declarado las variables como globales para evitar el problema... pero no habría aprendido cómo cambiar el stack en este IDE.

El tamaño de heap y stack se configuran en el archivo *.ld (linker directive) del proyecto:

HEAP_SIZE  = DEFINED(__heap_size__)  ? __heap_size__  : 0x00000400;
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x00000400;

Cambiémoslos por algo más sensato:

HEAP_SIZE  = DEFINED(__heap_size__)  ? __heap_size__  : 0x00000000;
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x00005400;

También agregué el siguiente argumento para obtener el stack por función. GCC lo reporta en un archivo .su (stack usage) por cada .c:

-fstack-usage



fft_app.c:128:6:FFT_GetFrequencyResponse 20528 static

Compilé, pero empecé a invadir la sección .bss:

arm-none-eabi-gcc -o "s32k1_st7735.elf" "@s32k1_st7735.args" 
d:/s32k1/s32ds/s32ds/build_tools/gcc_v6.3/gcc-6.3-arm32-eabi/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/bin/real-ld.exe: region m_data_2 overflowed with stack and heap
d:/s32k1/s32ds/s32ds/build_tools/gcc_v6.3/gcc-6.3-arm32-eabi/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/bin/real-ld.exe: section .stack VMA [20001c00,20006fff] overlaps section .bss VMA [20000000,200030e7]

El stack crece hacia abajo.

Por lo que revisé cómo es que la RAM del S32K144 está distribuida:

0x14000000 - 0x14000FFF - FlexRAM (4kB)
0x1FFF8000 - 0x1FFFFFFF - SRAM L (32kB)
0x20000000 - 0x20006FFF - SRAM U (28kB)

La sección bss estaba ubicada en SRAM U:

/* Specify the memory areas */
MEMORY
{
  /* Flash */
  m_interrupts          (RX)  : ORIGIN = 0x00000000, LENGTH = 0x00000400
  m_flash_config        (RX)  : ORIGIN = 0x00000400, LENGTH = 0x00000010
  m_text                (RX)  : ORIGIN = 0x00000410, LENGTH = 0x0007FBF0

  /* SRAM_L */
  m_data                (RW)  : ORIGIN = 0x1FFF8000, LENGTH = 0x00008000

  /* SRAM_U */
  m_data_2              (RW)  : ORIGIN = 0x20000000, LENGTH = 0x00007000
}

  /* Uninitialized data section. */
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss section. */
    . = ALIGN(4);
    __BSS_START = .;
    __bss_start__ = .;
    *(.bss)
    *(.bss*)
    *(COMMON)
    . = ALIGN(4);
    __bss_end__ = .;
    __BSS_END = .;
  } > m_data_2

Que estaba siendo invadida por el stack. Por lo tanto reubiqué la sección bss en m_data, donde hay suficiente espacio:

  /* Uninitialized data section. */
  .bss :
  {
    /* This is used by the startup in order to initialize the .bss section. */
    . = ALIGN(4);
    __BSS_START = .;
    __bss_start__ = .;
    *(.bss)
    *(.bss*)
    *(COMMON)
    . = ALIGN(4);
    __bss_end__ = .;
    __BSS_END = .;
  } > m_data

Esta vez sí pasó el proceso de linking.

.bss
                0x1fff86a0                __bss_start__ = .
                0x1fffb788                __bss_end__ = .

Line 3144:                 0x20001c00                __stack_start__ = .
Line 3147:                 0x20007000                __stack_end__ = .

bss y stack ya están ubicadas donde se espera.



domingo, marzo 19, 2017

Remover OneDrive de Windows 10 Home Edition

OneDrive se usa para hacer backups de archivos en Windows 10 en la nube. Desafortunadamente en Windows 10 Home sale a cada rato y lo tuve que desactivar.

Primero desactívalo en la barra de íconos al lado del reloj, dando click derecho en la Nube gris de OneDrive y eligiendo Configuración (Settings).

En esa ventana desactiva la ejecución automática al iniciar Windows:



Luego, entra a esta ruta:

C:\Users\tu-nombre-de-usuario\AppData\Local\Microsoft\OneDrive\

Renombra el archivo OneDrive.exe a OneDrive.exe.backup para que ya no sea ejecutado.

Igualmente puedes renombrar los demás archivos:

OneDrivePersonal.cmd.backup
OneDriveStandaloneUpdater.exe.backup

De esta forma ya no estará dándote lata.


Si quiere regresar todo a la normalidad sólo renombra los archivos backup a su extensión original.

domingo, agosto 30, 2015

Recupera el Visor de Imágenes en Windows 10

Si estás usando Windows 10 verás que el Visor de Imágenes de Windows (Windows Photo Viewer) ya no está disponible cuando abres una imagen JPG o PNG desde el Explorador de Archivos. Personalmente no me gusta la nueva app de Fotos de Windows, la considero lenta. Si quieres tener disponible el Visor de Imágenes de nuevo, sigue estos pasos:

+ Descarga el siguiente modificador del registro de Windows:

http://www.4shared.com/zip/Gl4sgsllce/photoviewer_electrolinks.html

La contraseña de descompresión es: electrolinks

+ Descomprime el ZIP y da doble click en el archivo photoviewer.reg. Esto agregará una entrada en el registro de Windows para habilitar Photo Viewer como una opción más de visor de imágenes.

+ Da click derecho sobre una imagen JPG, JPEG o PNG en el Explorador de Archivos.

+ Selecciona Abrir con... (Open with...)


+ Da click en Elegir otra aplicación (Choose another app).

+ En el menú, da click en Más apps (More apps).

+ Elige Visor de Imágenes de Windows.



+ Repite lo mismo para todos los tipos de imagen que quieres que el visor abra.