domingo, 20 de julio de 2014

msp430 toolchain en Ubuntu 14.04 - parte I: mspgcc

Preliminar

Primero: es doloroso instalar el toolchain desde los fuentes. La primera pregunta debe ser ¿por qué molestarse en instalar desde los fuentes en vez de usar los paquetes de los repositorios de Ubuntu?.
La versión estable anterior no soporta direccionamiento/registros de 20 bits, esto significa que si tenemos un micro con 128 KB de memoria flash solo vamos a poder usar 64 KB porque el compilador no permite manejar direcciones más allá.
http://forum.43oh.com/topic/5444-msp430-gcc-does-it-support-20-bit-addressing/

Pero al final termina siendo más una cuestión de aprendizaje (y orgullo) que de utilidad. Porque estoy seguro de que al ser una rama de desarrollo van a surgir multitud de problemas al compilar programas, librerías, etc.
¿Cual es el futuro?, empezar a usar la versión de mspgcc ofrecida por TI, porque mspgcc no seguirá siendo desarrollado por pabigot y le da la posta:
http://www.ti.com/tool/MSP430-GCC-OPENSOURCE
Traté de instalarlo pero no salió a la primera (al ejecutar el .run no pasa nada), así que supongo será una futura (o inexistente) entrada del blog.

Podría haber escrito un script de instalación que automatice todo, pero los scripts no funcionan a menos que tengo la misma distribución de linux, la misma versión de todos los paquetes, etc. Lo más probable es que al ejecutar el script haya errores y no se termine de ejecutar, y queden librerías a medio compilar desparramadas en el home y en /usr

Hechas las consideraciones metafísicas pasemos al proceso de instalación. Voy a tratar de cubrir instalación del toolchain, mspdebug, eclipse-cdt luna y su configuración para trabajar con mspgcc.
En otros palabras, llegar a tener un proyecto de led parpadeando y poder depurarlo desde eclipse.

Actualización: hice un resumen para ejecutar todo desde la consola utilizando comandos, si quieren ahorrarse el palabrerío: mspgcc

Instalación del toolchain

Dependencias y descargas


sudo apt-get install patch ncurses-dev build-essential bison flex libgmp3-dev libmpfr-dev libmpc-dev zlib1g-dev

Siguiendo [3], desinstalar texinfo si ya está de antemano, e instalar los siguientes paquetes (dependencias):
sed (>=4.2.1-9), bison (>=1:2.4.1), automake (>=1.11.1), gawk (>=3.1.8),mawk (>=3.1.8), libusb-1.0.0, libusb-1.0.0-dev, libreadline6-dev, dos2unix, srecord
Descargar e instalar:
https://packages.debian.org/wheezy/amd64/texinfo/download
En lo personal solo tuve problemas con texinfo al construir gdb, no con binutils ni gcc

Descarga fuentes:
En mi caso lo instalo en Install/mspgcc
http://sourceforge.net/projects/mspgcc/files/mspgcc/DEVEL-4.7.x/mspgcc-20120911.tar.bz2/download
ftp://ftp.gnu.org/pub/gnu/binutils/binutils-2.22.tar.bz2
ftp://ftp.gnu.org/pub/gnu/gcc/gcc-4.7.0/gcc-4.7.0.tar.bz2
ftp://ftp.gnu.org/pub/gnu/gdb/gdb-7.2a.tar.bz2

Notas: las versiones de gcc/gdb/binutils son las indicadas en los archivos .patch que contienen no solo eso sino también instrucciones de compilación e instalación. No dejar de leerlos, como también el README de mspgcc.

Parches adicionales por bugs (guía contiki):
http://sourceforge.net/p/mspgcc/bugs/_discuss/thread/fd929b9e/db43/attachment/0001-SF-357-Shift-operations-may-produce-incorrect-result.patch
http://sourceforge.net/p/mspgcc/bugs/352/attachment/0001-SF-352-Bad-code-generated-pushing-a20-from-stack.patch

Descomprimir binutils, gcc, gdb y crear una nueva carpeta build -> Install/mspgcc/build.

Binutils

Abrir el terminal e ir a la carpeta binutils:
cd ~/Install/mspgcc/binutils-2.22
patch -p1 < ../msp430-binutils-2.22-20120911.patch

cd ../build
mkdir binutils
cd binutils
../../binutils-2.22/configure --target=msp430 --prefix=/usr/local/msp430 2>&1 | tee co
make 2>&1 | tee mo
sudo make install 2>&1 | tee moi


Todo se instalará en /usr/local/msp430. Quizás hubiera sido mejor en /usr/local/msp430x para tenerlo instalado a la par de la versión estable.
No soy un gran conocedor de linux, se que el comando configure prepara el archivo makefile, que el comando make hace la compilación, y que make install hace la instalación. El archivo makefile contiene las instrucciones para compilar (fuentes, archivos objeto a generar, dependencias, comandos de compilación e instalación...)
Pero no sabía que significa 2>&1 ni que significa esto de |tee co/mo/moi.
http://stackoverflow.com/questions/818255/in-the-shell-what-is-21
2 se refiere a salida stderr, 1 es salida stdout (como archivos).
> es comando de redirección, por ejemplo, si queremos guardar el árbol de una carpeta a un archivo de nombre haríamos:
ls -R >tree
Estamos redirigiendo lo que normalmente saldría por stdout (la consola) al archivo tree.
Entonces 2>&1 esta redirigiendo stderr a stdout (el & creo que es para referirse a stdout luego de >, de lo contrario crea un archivo llamado 1 en vez de enviar los datos a stdout).
El operador | (pipe) sirve para conectar la salida de un comando con la entrada de otro (en este caso la salida de make con la entrada de tee).
Tee es un programa que copia la entrada a (la salida de make) a un archivo (en nuestro co/mo/moi) y a stdout.

Eso es util trabajar de esa forma, nos queda el resultado de configure en co, el de make, en mo, y el de make install en moi; y a la vez vemos el resultado por pantalla.
Quizás sería mejor solo ver los errores por pantalla, y que guarde stdout y stderr en el archivo.

Binutils fue el menos problemático para mí (no para otras personas), gcc fue un dolor de cabeza. Revisar los archivos co, mo, moi para ver si hubo algún error; si los hubo lo siento no los puedo ayudar porque no me paso a mí.
Mis archivos co, mo, moi de binutils.

GCC


Hay algunos lugares donde usan la versión 4.7.2 o 4.7.4 de gcc. Cuando hice los parches con esas versiones tenía errores del tipo
patching file gcc/convert.c
Hunk #1 FAILED at 774.
Hunk #2 FAILED at 811.
2 out of 2 hunks FAILED -- saving rejects to file gcc/convert.c.rej


Y también aún en parches exitosos, el resultado es del tipo:
patching file gcc/emit-rtl.c
patching file gcc/emit-rtl.h
patching file gcc/except.c
patching file gcc/explow.c
patching file gcc/expmed.c
Hunk #1 succeeded at 1474 (offset 20 lines).
Hunk #2 succeeded at 1708 (offset 20 lines).
Hunk #3 succeeded at 2213 (offset 20 lines).

Me preocupa el offset, supongo que quiere decir que el código parcheado estaba desplazado 20 líneas del lugar esperado.

Por eso decidí utilizar la versión 4.7.0 que es la indicada en el parche del mspgcc msp430-gcc-4.7.0-20120911.patch.
Los archivos .patch contiene instrucciones para buscar cierta porción de código y agregar/eliminar/modificar las instrucciones de c, en 1 o más archivos.
La idea es bajar el código versión X, usar los parches para esa versión (que pueden corregir bugs o agregar funcionalidad), y luego compilar e instalar la versión parcheada.


Continuando desde la carpeta /build/binutils:
cd ../../gcc-4.7.0
#Ahora estamos en ~/Install/mspgcc/gcc-4.7.0, aplicamos parches
patch -p1 < ../msp430-gcc-4.7.0-20120911.patch
patch -p1< ../0001-SF-352-Bad-code-generated-pushing-a20-from-stack.patch
patch -p1< ../0001-SF-357-Shift-operations-may-produce-incorrect-result.patch


La diferencia es que al aplicar los patch ahora no hay mensajes de offset, ni fail, ni nada. La salida es como:

patching file gcc/tree-ssa-ccp.c
patching file gcc/tree-ssa-forwprop.c
patching file gcc/tree-ssa-loop-ivopts.c
patching file gcc/tree.c
patching file gcc/var-tracking.c
patching file gcc/varasm.c
patching file gcc/varpool.c
patching file libgcc/config.host
patching file libgcc/config/msp430/crt0.S


Debemos bajar los pre-requisitos del gcc:mpfr, gmp, mpc. Algunos bajan estas librerías a mano y las construyen por comandos como hicimos con binutils, pero el problema es que hay que bajar la versión correcta, por eso usamos el script que ya nos provee gcc:
./contrib/download_prerequisites

Ahora vamos al configure, desde la carpeta build:


cd ../build
mkdir gcc-4.7.0-msp430
cd gcc-4.7.0-msp430
../../gcc-4.7.0/configure --target=msp430 --enable-languages=c,c++ --prefix=/usr/local/msp430 2>&1 | tee co

Sin problemas, y acá empieza la odisea, va a estar compilando un rato largo y va a tirar error:
make 2>&1 | tee mo

Error:
/home/daniel/Install/mspgcc/build/gcc/./gcc/xgcc -B/home/daniel/Install/mspgcc/build/gcc/./gcc/ -B/usr/local/msp430/msp430/bin/ -B/usr/local/msp430/msp430/lib/ -isystem /usr/local/msp430/msp430/include -isystem /usr/local/msp430/msp430/sys-include    -g -O2 -mcpu=430x -O2  -g -O2 -DIN_GCC -DCROSS_DIRECTORY_STRUCTURE  -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition  -isystem ./include   -g -DIN_LIBGCC2 -fbuilding-libgcc -fno-stack-protector -Dinhibit_libc  -I. -I. -I../../.././gcc -I../../../../../gcc-4.7.0/libgcc -I../../../../../gcc-4.7.0/libgcc/. -I../../../../../gcc-4.7.0/libgcc/../gcc -I../../../../../gcc-4.7.0/libgcc/../include  -DHAVE_CC_TLS -DUSE_EMUTLS -o _negdi2.o -MT _negdi2.o -MD -MP -MF _negdi2.dep -DL_negdi2 -c ../../../../../gcc-4.7.0/libgcc/libgcc2.c
../../../../../gcc-4.7.0/libgcc/libgcc2.c: In function ‘__negdi2’:
../../../../../gcc-4.7.0/libgcc/libgcc2.c:73:1: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
make[4]: *** [_negdi2.o] Error 1
make[4]: Leaving directory `/home/daniel/Install/mspgcc/build/gcc/msp430/mcpu-430x/libgcc'
make[3]: *** [multi-do] Error 1
make[3]: Leaving directory `/home/daniel/Install/mspgcc/build/gcc/msp430/libgcc'
make[2]: *** [all-multi] Error 2
make[2]: Leaving directory `/home/daniel/Install/mspgcc/build/gcc/msp430/libgcc'
make[1]: *** [all-target-libgcc] Error 2
make[1]: Leaving directory `/home/daniel/Install/mspgcc/build/gcc'
make: *** [all] Error 2



Se ve que hay un error con la función __negdi2 en el archivo libgcc2.c

Encontrar a que se debía este error llevó muchísimo tiempo, porque no estaba seguro de que era lo que fallaba: faltaba algún pre-requisito?, había parcheado mal?, hacía falta algún argumento de make?.
Después de mucho buscar llego a que el error surge al compilar gcc-4.7 con gcc-4.8 (versión que usa Ubuntu 14.04), y hay que modificar el archivo ira-int.h:
http://permalink.gmane.org/gmane.comp.hardware.texas-instruments.msp430.gcc.user/11667
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56927
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56308
https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=191605


Información de la revisión:

Bajar el nuevo ira-int.h de:
https://gcc.gnu.org/viewcvs/gcc/branches/gcc-4_7-branch/gcc/ira-int.h?view=markup&pathrev=191605

Y reemplazar:
/Install/mspgcc/gcc-4.7.0/gcc/ira-int.h

Ahora al volver a construir ya no hay errores y podemos continuar, esto tarda un rato:
make 2>&1 | tee mo
sudo make install 2>&1 | tee moi

Archivos co/mo/moi del gcc.

Exportamos
export PATH=/usr/local/msp430/bin/:$PATH
Pero esto solo sirve para la sesión de consola actual, para hacer los cambios permanentes se puede agregar al usuario actual editando /etc/profile, o a todos los usuarios editando /etc/environment.
Yo elegí editar /etc/environment, por si agrego usuarios a mi máquina y poder usar mspgcc desde cualquier cuenta.
sudo gedit /etc/environment

Agregar /usr/local/msp430/bin a la variable path, queda así:
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/local/msp430/bin"

Ahora hay que reiniciar para que tome los cambios en /etc/environment, lo que viene bien para la máquina después de hacerla trabajar tanto.

Si no agregamos esa ruta al path, el próximo paso nos dirá msp430-gcc no encontrado, o algo así.

GDB


Vamos a los fuentes:
cd ../../gdb-7.2
#Estamos en ~/Install/mspgcc/gdb-7.2
patch -p1 < ../msp430-gdb-7.2a-20111205.patch
cd ../build
mkdir gdb
cd gdb
../../gdb-7.2/configure --target=msp430 --prefix=/usr/local/msp430 2>&1 | tee co
make 2>&1 | tee mo

A esta altura si tenemos el texinfo 5.x nos tira el error:
../../../../gdb-7.2/bfd/doc/bfd.texinfo:326: unknown command `colophon'
../../../../gdb-7.2/bfd/doc/bfd.texinfo:337: unknown command `cygnus'


Lo que no quiere decir que haber instalado texinfo 4 nos solucione el problema, porque ahora make da el error:

../../../gdb-7.2/bfd/bfdio.c: In function ‘memory_bstat’:
../../../gdb-7.2/bfd/bfdio.c:580:30: error: argument to ‘sizeof’ in ‘memset’ call is the same expression as the destination; did you mean to dereference it? [-Werror=sizeof-pointer-memaccess]
   memset (statbuf, 0, sizeof (statbuf));
                              ^
cc1: all warnings being treated as errors
make[4]: *** [bfdio.lo] Error 1
make[4]: Leaving directory `/home/daniel/Install/mspgcc/build/gdb/bfd'
make[3]: *** [all-recursive] Error 1
make[3]: Leaving directory `/home/daniel/Install/mspgcc/build/gdb/bfd'
make[2]: *** [all] Error 2
make[2]: Leaving directory `/home/daniel/Install/mspgcc/build/gdb/bfd'
make[1]: *** [all-bfd] Error 2
make[1]: Leaving directory `/home/daniel/Install/mspgcc/build/gdb'
make: *** [all] Error 2


Aparentemente se trata de un error debido a que compilamos con gcc 4.8 (versión que viene con Ubuntu):
https://aur.archlinux.org/packages/msp430-gdb/
Se puede bajar un patch desde:
https://sourceware.org/git/?p=gdb.git;a=commitdiff;h=7f62f13c2b535c6a23035407f1c8a36ad7993dec





Click en patch, guardar en ~/Install/mspgcc
Y luego desde /Install/mspgcc/gdb-7.2
patch -p1 <../gdb.git-7f62f13c2b535c6a23035407f1c8a36ad7993dec.patch

O siendo un error tan simple, podemos editar directamente el archivo bfdio.c y buscar la línea 580, dentro de la función memory_bstat (bfd *abfd, struct stat *statbuf):
memset (statbuf, 0, sizeof (statbuf));
y reemplazarla por
memset (statbuf, 0, sizeof (*statbuf));

En este punto borré /build/gdb y empecé de vuelta omitiendo los parches que ya están hechos:

mkdir gdb
cd gdb
#Ahora estamos en ~/Install/mspgcc/build/gdb
../../gdb-7.2/configure --target=msp430 --prefix=/usr/local/msp430 2>&1 | tee co
make 2>&1 | tee mo
sudo make install 2>&1 | tee moi

Podemos verificar que se instaló con msp430-gdb --version:
daniel@daniel-desktop:~/Install/mspgcc/build/gdb$ msp430-gdb --version
GNU gdb (GDB) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-unknown-linux-gnu --target=msp430".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.


Archivos co, mo, moi.

msp430mcu


cd ../msp430mcu-20130321/
#Estamos en  ~/Install/mspgcc/build/msp430mcu-20130321
sudo MSP430MCU_ROOT=`pwd` ./scripts/install.sh /usr/local/msp430 | tee so

El más fácil de todos!!!!
De hecho no se genera ninguna salida, el archivo so está vacío.

msp430-libc


Este no es tan fácil como el anterior :(
Bah, es fácil para alguien que entiende lo que está haciendo, no puedo decir que haya sido mi caso :P
La cuestión es que seguir fielmente las indicaciones dadas en
/msp430-libc-20120716/README
No resulta en nada. Estando en
~/Install/mspgcc/build/msp430-libc-20120716
Hacemos
./configure --prefix=/usr/local/msp430
cd src
make | tee mo

Tarda un buen rato, notar que se compila usando msp430-gcc que instalamos anteriormente, es necesario que ese paso haya salido sin fallas, y que /usr/local/msp430/bin esté agregado a la variable PATH del sistema.
sudo make prefix=/usr/local/msp430 install | tee moi

No da error, pero el resultado de esto debería ser que las librerías libc.a, libm.a, libfp.a estén copiadas en /usr/local/msp430/msp430/lib en una estructura como:






Nuevamente perdí muchas horas revisando el archivo makefile, buscando información, tiempo tirado a la basura.
Ya mientras estaba en la cama seguí buscando información y di con:
http://www.bradcampbell.com/installing-msp430-gcc-from-source/
http://energy.eecs.umich.edu/wiki/doku.php?id=msp430:mspgcc:start

Donde el comando de make install usado es:
sudo PATH=$PATH make PREFIX=/usr/local/msp430 install
desde ~/Install/mspgcc/build/msp430-libc-20120716/src

Y listo!!!!, con eso funciona. Faltaba poner PATH al principio, @!!#~@%!!!

Dejo un pseudo-moi (porque lo hice copiando y pegando desde el terminal y no con tee) para ver como debería ser la salida si las cosas salen bien:
https://drive.google.com/file/d/0B76ECNesbfvLNzY3X2ZldGJaWEU/edit?usp=sharing

Suficiente por ahora...
Vamos a dejar la instalación de mspdebug y eclipse para futuras entradas, y voy a tener que hacer una versión sin todo el blablaba para el que no quiera torturarse leyendo.
Primera entrada al fin!!!!.

Referencias

  1. Guía general para compilar el toolchain y aplicar parches
    https://github.com/contiki-os/contiki/wiki/MSP430X
  2.  Pautas para construir el toolchain e integrarlo en eclipse:
    http://richardnaud.wordpress.com/2013/10/02/installation-of-eclipse-cdt-msp430-gcc-4-7-0-mspdebug-0-21-and-more-on-ubuntu/
  3. Menciona el problema con texinfo, desinstalar versión 5.x e instalar el paquete sugerido:
    http://ubuntuandsecurity.blogspot.com.ar/2014/04/compiling-and-building-your-own-latest.html
  4. MSPGCC de texas v1.0.0:
    http://www.ti.com/tool/MSP430-GCC-OPENSOURCE
  5. http://m8051.blogspot.in/2014/03/beta-version-of-msp430gcc-supported.html 
  6. http://energy.eecs.umich.edu/wiki/doku.php?id=msp430:mspgcc:start
  7. http://www.bradcampbell.com/installing-msp430-gcc-from-source

3 comentarios:

  1. Muchas Gracias!
    thanks for the series of articles.
    The file from TI you need to do chmod +x *.run to be able to run it. I will try your process in opensuse 13.1 and let you know.

    ResponderEliminar
  2. De nada!!!, you are very welcome.
    Didn't expect any comments for a few months at least ;)

    Yup, I gave +x permissions to the .run file, and executed by double clicking, from the console, and using sudo but nothing happens.
    Didn't try too hard to make it work neither, maybe the download is corrupted.

    I'm doing a brief of the process in english, I will like to have a bilingual blog but maybe blogger is not the most friendly tool to do it.

    Good luck!!!

    ResponderEliminar