mirror of
git://projects.qi-hardware.com/nn-usb-fpga.git
synced 2025-01-10 07:40:15 +02:00
513 lines
32 KiB
TeX
513 lines
32 KiB
TeX
|
\chapter{Conceptos B<>sicos de los Sistemas Embebidos}
|
|||
|
|
|||
|
\section{Definici<EFBFBD>n}
|
|||
|
|
|||
|
Un Sistema Embebidos es un sistema de prop<6F>sito espec<65>fico en el cual, el computador es encapsulado completamente por el dispositivo que el controla. A diferencia de los computadores de prop<6F>sito general, un Sistema Embebido realiza tareas pre-definidas, lo cual permite su optimizaci<63>n, reduciendo el tama<6D>o y costo del producto \cite{Wik}
|
|||
|
|
|||
|
\section{Caracter<EFBFBD>sticas}
|
|||
|
|
|||
|
\begin{itemize}
|
|||
|
\item Los sistemas embebidos son dise<73>ados para una aplicaci<63>n
|
|||
|
espec\'{\i}fica, es decir, estos sistemas realizan un grupo de funciones
|
|||
|
previamente definidasm y una vez el sistema es dise<73>ado, no se puede cambiar
|
|||
|
su funcionalidad. Por ejemplo, el control de un asensor siempre realizar\'a
|
|||
|
las mismas acciones durante su vida \'util.
|
|||
|
\item Debido a su interacci<63>n con el entorno los ES deben cumplir
|
|||
|
esctr<74>ctamente restricciones temporales. El t\'ermino {\textit{Sistemas
|
|||
|
de Tiempo Real}} es utilizado para enfatizar este aspecto.
|
|||
|
\item Los Sistemas Embebidos son heterog\'eneos, es decir, est\'an
|
|||
|
compuestos por componentes Hardware y Software. Los componentes Hardware,
|
|||
|
como ASICs y Dispositivos L\'ogicos Programables (PLD) proporcionan la
|
|||
|
velocidad de ejecuci\'on y el cosumo de potencia necesarios en algunas
|
|||
|
aplicaciones.
|
|||
|
\item Los Sitemas Embebidos tienen grandes requerimientos en t\'erminos de
|
|||
|
confiabilidad. Errores en aplicaciones como la aviaci\'on y el
|
|||
|
automovilismo, pueden tener consecuencias desastrosas.
|
|||
|
\end{itemize}
|
|||
|
|
|||
|
\section{Arquitectura}
|
|||
|
|
|||
|
Una arquitectura t<>pica para un Sistema Embebido se muestra en la Figura \ref{es_arch}; La cual integra un componente hardware, implementado ya sea en un PLD (CPLD, FPGA) o en un ASIC, conocido con el nombre de perif<69>ricos y un componente software (procesador o DSP) cap<61>z de ejecutar software, la parte del procesador est<73> dividida en la CPU (En algunos casos posee una cach<63>) y las unidades de Memoria.
|
|||
|
|
|||
|
|
|||
|
\begin{figure}
|
|||
|
\begin{center} \includegraphics[scale=.6]{./images/ES_Architecture} \end{center}
|
|||
|
\caption{Arquitectura de un Sistema Embebido}\label{es_arch}
|
|||
|
\end{figure}
|
|||
|
|
|||
|
|
|||
|
Al momento de dise<73>ar un Sistema Embebido encontramos las siguientes opciones:
|
|||
|
\begin{itemize}
|
|||
|
\item Componente HW y SW Integrado en un dispositivo semiconductor (SoC): En la actualidad existen muchas compa<70><61>as que fabrican procesadores de 32 bits integrados a una gran variedad de perif<69>ricos, lo cual simplifica el dise<73>o y reduce costos (menos componentes y menos <20>rea de circuito impreso) \footnote{http://www.sharpsma.com, http://www.atmel.com, http://www.cirrus.com, http://www.samsung.com, http://www.freescale.com, etc}.
|
|||
|
|
|||
|
\item Componente SW en un SoC y componente HW en una FPGA: Cuando no existen en el mercado SoC con la cantidad de perif<69>ricos requerida para una determinada aplicaci<63>n, es necesario recurrir a la utilizaci<63>n de dispositivos comerciales que implementen dicha operaci<63>n, en algunas ocaciones el perif<69>rico puede relizar funciones muy espec<65>ficas de modo que no existe en el mercado, la soluci<63>n es entonces implementar estos dispositivos en una FPGA, tambi<62>n se recomienda la utilizaci<63>n de FPGAs en sistemas que requieren una gran cantidad y variedad de perif<69>ricos ya que reduce la complejidad y costo del sistema.
|
|||
|
|
|||
|
\item Componente SW y HW en una FPGA: Esta es tal vez la opci<63>n m<>s econ<6F>mica y flexible, pero la de menor desempe<70>o, ya que al utilizar los recursos l<>gicos de la FPGA para la implementaci<63>n del procesador (softcore) la lngitud de los caminos de interconexi<78>n entre los bloques l<>gicos aumentan el retardo de las se<73>ales . Los procesadores \textit{softcore} m<>s populares en la actualidad son:
|
|||
|
|
|||
|
\begin{itemize}
|
|||
|
\item Microblaze de Xilinx\footnote{http://www.xilinx.com}
|
|||
|
\item Leon de Gaisler Research \footnote{http://www.gaisler.com/}
|
|||
|
\item LatticeMico32 de Lattice Semiconductors\footnote{http://www.latticesemi.com}
|
|||
|
\item OpenRisc \footnote{http://www.opencores.com}
|
|||
|
\end{itemize}
|
|||
|
|
|||
|
\end{itemize}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
\section{Metodolog<EFBFBD>a de Dise<73>o}
|
|||
|
|
|||
|
La Figura \ref{des_flow}, muestra un diagrama de flujo de dise<73>o gen<65>rico para sistemas
|
|||
|
embebidos {\cite{Cor05}}
|
|||
|
|
|||
|
\begin{figure}
|
|||
|
\begin{center} \includegraphics[scale=.55]{./images/design_flow} \end{center}
|
|||
|
\caption{Flujo de Dise<73>o de un Sistema Embebido}\label{des_flow}
|
|||
|
\end{figure}
|
|||
|
|
|||
|
|
|||
|
El proceso comienza con la {\textit{especificaci\'on del sistema}}, en este
|
|||
|
punto se describe la funcionalidad y se definen las restricciones
|
|||
|
f\'{\i}sicas, el\'ectricas y econ\'omicas. Esta especificaci\'on debe ser muy
|
|||
|
general y no deben existir dependencias (tecnol\'ogicas, metodol\'ogicas) de
|
|||
|
ning\'un tipo, se suele utilizar lenguajes de alto nivel, como UML, C++. La
|
|||
|
especificaci\'on puede ser verificada a trav\'es de una serie de pasos de
|
|||
|
an\'alisis cuyo objetivo es determinar la validez de los algor\'{\i}tmos
|
|||
|
seleccionados, por ejemplo, determinar si el algoritmo siempre termina, los
|
|||
|
resultados satisfacen las especificaciones. Desde el punto de vista de la
|
|||
|
re-utilizaci\'on, algunas partes del funcionamiento global deben tomarse de
|
|||
|
una librer\'{\i}a de algor\'{\i}tmos existentes.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Una vez definidas las especificaciones del sistema se debe realizar un
|
|||
|
modelamiento que permita extraer de estas la funcionalidad. El modelamiento es
|
|||
|
crucial en el dise<73>o ya que de \'el depende el paso existoso de la
|
|||
|
especificaci\'on a la implementaci\'on. Es importante definir que modelo
|
|||
|
matem\'atico debe soportar el entorno de dise<73>o. Los modelos m\'as utilizados
|
|||
|
son: M\'aquinas de estados finitos, diagramas de flujos de datos, Sistemad de
|
|||
|
Eventos Discretos y Redes de Petri. Cada modelo posee propiedades
|
|||
|
matem\'aticas que pueden explotarse de forma eficiente para responder
|
|||
|
preguntas sobre la funcionalidad del sistema sin llevar a cabo dispendiosas
|
|||
|
tareas de verificaci\'on. \ Todo modelo obtenido debe ser verificado para
|
|||
|
comprobar que cumple con las restricciones del sistema.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Una vez se ha obtenido el modelo del sistema se procede a determinar su
|
|||
|
{\textit{arquitectura}}, esto es, el n\'umero y tipo de componentes y su
|
|||
|
inter-conexi\'on. Este paso no es m\'as que una exploraci\'on del espacio de
|
|||
|
dise<EFBFBD>o en b\'usqueda de soluciones que permitan la implementaci\'on de una
|
|||
|
funcionalidad dada, y puede realizarse con varios criterios en mente: Costos,
|
|||
|
confiabilidad, viabilidad comercial.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Utilizando como base la arquitectura obtenida en el paso anterior las tareas
|
|||
|
del modelo del sistemas son mapeadas dentro de los componentes. Esto es,
|
|||
|
asignaci\'on de funciones a los componentes de la arquitectura. Existen dos
|
|||
|
opciones a la hora de implementar las tareas o procesos:
|
|||
|
\begin{enumerate}
|
|||
|
\item Implementaci\'on Software: La tarea se va a ejecutar en un procesador.
|
|||
|
\item Implementaci\'on Hardware: La tarea se va a ejecutar en un sistema
|
|||
|
digital dedicado.
|
|||
|
\end{enumerate}
|
|||
|
|
|||
|
Para cumplir las especificaciones del sistema algunas tareas deben ser
|
|||
|
implementadas en Hardware, esto con el f\'{\i}n de no ocupar al procesador en
|
|||
|
tareas c\'{\i}clicas, un ejemplo t\'{\i}pico de estas tareas es la
|
|||
|
generaci\'on de bases de tiempos. La decisi\'on de que tareas se implementan
|
|||
|
en SW y que tareas se implementan en HW recibe el nombre de
|
|||
|
{\textit{particionamiento}}, esta selecci\'on es fuertemente dependiente de
|
|||
|
restricciones econ\'omicas y temporales.
|
|||
|
|
|||
|
|
|||
|
Las tareas Software deben compartir los recursos que existan en el sistema
|
|||
|
(procesador y memoria), por lo tanto se deben hacer decisiones sobre el orden
|
|||
|
de ejecuci\'on y la prioridad de estas. Este proceso recibe el nombre de
|
|||
|
{\textit{planificaci\'on}}. En este punto del dise<73>o el modelo debe incluir
|
|||
|
informaci\'on sobre el mapeo, el particionamiento y la planificaci\'on del
|
|||
|
sistema.
|
|||
|
|
|||
|
|
|||
|
Las siguientes fases corresponden a la implementaci\'on del modelo, para esto
|
|||
|
las tareas hardware deben ser llevadas al dispositivo elegido (ASIC o FPGA) y
|
|||
|
se debe obtener el $''$ejecutable$''$ de las tareas software, este proceso
|
|||
|
recibe el nombre de {\textit{s\'{\i}ntesis}} HW y SW respectivamente, as\'{\i}
|
|||
|
mismo se deben sintetizar los mecanismos de comunicaci\'on.
|
|||
|
|
|||
|
|
|||
|
El proceso de prototipado consiste en la realizaci\'on f\'{\i}sica del
|
|||
|
sistema, finalmente el sistema f\'{\i}sico debe someterse a pruebas para
|
|||
|
verificar que se cumplen con las especificaciones iniciales.
|
|||
|
|
|||
|
Como puede verse en el flujo de dise<73>o existen realimentaciones, estas
|
|||
|
realimentaciones permiten depurar el resultado de pasos anteriores en el caso
|
|||
|
de no cumplirse las especificaciones iniciales
|
|||
|
|
|||
|
\subsection{Herramientas Software de libre distribuci<63>n \textit{GNU toolchain}}
|
|||
|
En el mercado existe una gran variedad de herramientas de desarrollo para Sistemas Embebidos,
|
|||
|
sin embargo, en este estudio nos centraremos en el uso de las herramientas de libre distribuci<63>n;
|
|||
|
esta elecci<63>n se debe a que la mayor<6F>a de los productos comerciales utilizan el toolchain de GNU\footnote{http://www.gnu.org} internamente y proporcionan un entorno gr<67>fico para su f<>cil manejo. Otro factor considerado a la hora de realizar nuestra elecci<63>n es el econ<6F>mico, ya que la mayor<6F>a de los productos comerciales son costosos y poseen soporte limitado. Por otro lado, el toolchain de GNU es utilizado ampliamente en el medio de los dise<73>adores de sistemas embebidos y se encuentra un gran soporte en m<>ltiples foros de discusi<73>n (ver Figura \ref{tools}).
|
|||
|
|
|||
|
|
|||
|
\begin{figure}[h]
|
|||
|
\begin{center} \includegraphics[scale=.7]{./images/embedded-linux-tool-trends-sm} \end{center}
|
|||
|
\caption{Tendencia de utilizaci<63>n de herramientas de desarrollo}\label{tools}
|
|||
|
\end{figure}
|
|||
|
|
|||
|
\subsection{Componentes del \textit{GNU toolchain} }
|
|||
|
|
|||
|
\subsection{GNU binutils\cite{A1}}
|
|||
|
Son una colecci<63>n de utilidades para archivos binarios y estan compuestas por:
|
|||
|
|
|||
|
\begin{itemize}
|
|||
|
\item \textbf{addr2line} Convierte direcciones de un programa en nombres de archivos y n<>meros de l<>nea. Dada una direcci<63>n y un ejecutable, usa la informaci<63>n de depuraci<63>n en el ejecutabe para determinar que nombre de atchivo y n<>mero de lpinea est<73> asociado con la direcci<63>n dada.
|
|||
|
\item \textbf{ar} Esta utilidad crea, modifica y extrae desde ficheros. Un fichero es una colecci<63>n de otros archivos en una estructura que hace posible obtener los archivos individuales miembros del archivo.
|
|||
|
\item \textbf{as} Utilidad que compila la salida del compilador de C (GCC).
|
|||
|
\item \textbf{c++filt} Este program realiza un mapeo inverso: Decodifica nombres de bajo-nivel en nombres a nivel de usuario, de tal forma que el linker pueda mantener estas funciones sobrecargadas (overloaded) ``from clashing''.
|
|||
|
\item \textbf{gasp} GNU Assembler Macro Preprocessor
|
|||
|
\item \textbf{ld} El \textit{linker} GNU combina un n<>mero de objetos y ficheros, re-localiza sus datos y los relaciona con referencias. Normalmente el <20>ltimo paso en la construcci<63>n de un nuevo programa compilado es el llamado a ld.
|
|||
|
\item \textbf{nm} Realiza un listado de s<>mbolos de archivos tipo objeto.
|
|||
|
\item \textbf{objcopy} Copia los contenidos de un archivo tipo objeto a otro. \textit{objcopy} utiliza la librer<65>a GNU BFD para leer y escribir el archivo tipo objeto. Permite esccribibr el archivo destino en un formato diferente al del archivo fuente.
|
|||
|
\item \textbf{objdump} Despliega informaci<63>n sobre archivos tipo objeto.
|
|||
|
\item \textbf{ranlib} Genera un <20>ndice de contenidos de un fichero, y lo almacena en <20>l.
|
|||
|
\item \textbf{readelf} Interpreta encabezados de un archivo ELF.
|
|||
|
\item \textbf{size} Lista el tama<6D>o de las secciones y el tama<6D>o total de un archivo tipo objeto.
|
|||
|
\item \textbf{strings} Imprime las secuencias de caracteres imprimibles de almenos 4 caracteres de longitud.
|
|||
|
\item \textbf{strip} Elimina todos los s<>mbolos de un archivo tipo objeto.
|
|||
|
|
|||
|
\end{itemize}
|
|||
|
|
|||
|
\subsection{GNU Compiler Collection\cite{Wik}}
|
|||
|
El \textit{GNU Compiler Collection} normalmente llamado GCC, es un grupo de compiladores de lenguajes de programaci<63>n producido por el proyecto GNU. Es el compilador standard para el software libre de los sistemas operativos basados en Unix y algunos propietarios como Mac OS de Apple.
|
|||
|
|
|||
|
|
|||
|
\subsubsection{Lenguajes}
|
|||
|
GCC soporta los siguientes lenguajes:
|
|||
|
\begin{itemize}
|
|||
|
\item \textbf{ADA}
|
|||
|
\item \textbf{C}
|
|||
|
\item \textbf{C++}
|
|||
|
\item \textbf{Fortran}
|
|||
|
\item \textbf{Java}
|
|||
|
\item \textbf{Objective-C}
|
|||
|
\item \textbf{Objective-C++}
|
|||
|
\end{itemize}
|
|||
|
|
|||
|
\subsubsection{Arquitecturas}
|
|||
|
\begin{itemize}
|
|||
|
\item \textbf{Alpha}
|
|||
|
\item \textbf{ARM}
|
|||
|
\item \textbf{Atmel AVR}
|
|||
|
\item \textbf{Blackfin}
|
|||
|
\item \textbf{H8/300}
|
|||
|
\item \textbf{System/370, System/390}
|
|||
|
\item \textbf{IA-32 (x86) and x86-64}
|
|||
|
\item \textbf{IA-64 i.e. the "Itanium"}
|
|||
|
\item \textbf{Motorola 68000}
|
|||
|
\item \textbf{Motorola 88000}
|
|||
|
\item \textbf{MIPS}
|
|||
|
\item \textbf{PA-RISC}
|
|||
|
\item \textbf{PDP-11}
|
|||
|
\item \textbf{PowerPC}
|
|||
|
\item \textbf{SuperH}
|
|||
|
\item \textbf{SPARC}
|
|||
|
\item \textbf{VAX}
|
|||
|
\item \textbf{Renesas R8C/M16C/M32C}
|
|||
|
\item \textbf{MorphoSys}
|
|||
|
\end{itemize}
|
|||
|
Como puede verse GCC soporta una gran cantidad de lenguajes de programaci<63>n, sin embargo, en el presente estudio solo lo utilizaremos como herramienta de compilaci<63>n para C y C++. Una caracter<65>stica de resaltar de GCC es la gran cantidad de plataformas que soporta, esto lo hace una herramienta Universal para el desarrollo de sistemas embebidos, el c<>digo escrito en una plataforma (en un lenguaje de alto nivel) puede ser implementado en otra sin mayores cambios, esto elimina la dependencia entre el c<>digo fuente y el HW\footnote{Esto recibe el nombre de re-utilizaci<63>n de c<>digo}, lo cual no ocurre al utilizar lenguaje ensamblador.
|
|||
|
|
|||
|
Por otro lado, el tiempo requerido para realizar aplicaciones utilizando C o C++ disminuye, ya que no es necesario aprender las instrucciones en assembler de una plataforma determinada; adem<65>s, la disponibilidad de librer<65>as de m<>ltiples prop<6F>sitos reduce a<>n m<>s los tiempos de desarrollo, permitiendo de esta forma tener bajos tiempos \textit{time to market} y reducir de forma considerable el costo del desarrollo. Una consecuencia de esto se refleja en el n<>mero de desarrolladores en un grupo de trabajo, en la actualidad casi el 60\% de las empresas desarrolladoras de dispositivos embebidos tiene grupos con menos de 10 desarrolladores \ref{group}.
|
|||
|
|
|||
|
|
|||
|
\begin{figure}[h]
|
|||
|
\begin{center} \includegraphics[scale=.2]{./images/vdc_embedded_dev_company_size} \end{center}
|
|||
|
\caption{N<EFBFBD>mero promedio de desarrolladores por compa<70><61>a. Fuente Venture Development Corp}\label{group}
|
|||
|
\end{figure}
|
|||
|
|
|||
|
\subsection{GNU Debugger\cite{Wik}}
|
|||
|
El depurador oficial de GNU (GDB), es un depurador que al igual que GCC tiene soporte para m<>ltiples lenguajes y plataformas. GDB permite al usuario monitorear y modificar las variables internas del programa y hacer llamado a funciones de forma independiente a la ejecuci<63>n normal del mismo. Adem<65>s, permite establecer sesiones remotas utilizando el puerto serie o TCP/IP. Aunque GDB no posee una interfaz gr<67>fica, se han desarrollado varios front-ends como DDD o GDB/Insight. A continuaci<63>n se muestra un ejemplo de una sesi<73>n con gdb.
|
|||
|
|
|||
|
\footnotesize
|
|||
|
\begin{lstlisting}[firstnumber=40]
|
|||
|
GNU gdb Red Hat Linux (6.3.0.0-1.21rh)
|
|||
|
Copyright 2004 Free Software Foundation, Inc.
|
|||
|
GDB is free software, covered by the GNU General Public License, and you are
|
|||
|
welcome to change it and/or distribute copies of it under certain conditions.
|
|||
|
Type "show copying" to see the conditions.
|
|||
|
There is absolutely no warranty for GDB. Type "show warranty" for details.
|
|||
|
This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db
|
|||
|
library "/lib/libthread_db.so.1".
|
|||
|
|
|||
|
(gdb) run
|
|||
|
Starting program: /home/sam/programming/crash
|
|||
|
Reading symbols from shared object read from target memory...done.
|
|||
|
Loaded system supplied DSO at 0xc11000
|
|||
|
This program will demonstrate gdb
|
|||
|
|
|||
|
Program received signal SIGSEGV, Segmentation fault.
|
|||
|
0x08048428 in function_2 (x=24) at crash.c:22
|
|||
|
22 return *y;
|
|||
|
(gdb) edit
|
|||
|
(gdb) shell gcc crash.c -o crash -gstabs+
|
|||
|
(gdb) run
|
|||
|
The program being debugged has been started already.
|
|||
|
Start it from the beginning? (y or n) y
|
|||
|
warning: cannot close "shared object read from target memory": File in wrong format
|
|||
|
`/home/sam/programming/crash' has changed; re-reading symbols.
|
|||
|
Starting program: /home/sam/programming/crash
|
|||
|
Reading symbols from shared object read from target memory...done.
|
|||
|
Loaded system supplied DSO at 0xa3e000
|
|||
|
This program will demonstrate gdb
|
|||
|
24
|
|||
|
Program exited normally.
|
|||
|
(gdb) quit
|
|||
|
\end{lstlisting}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
\subsection{C Libraries}
|
|||
|
Adicionalmente es necesario contar con una librer<65>a que proporcione las librer<65>as standard de C: stdio, stdlib, math; las m<>s utilizadas en sistemas embebidos son:
|
|||
|
|
|||
|
\begin{itemize}
|
|||
|
\item \textbf{glibc\footnote{http://www.gnu.org/software/libc/}} Es la librer<65>a C oficial del proyecto GNU. Uno de los inconvenientes al trabajar con esta librer<65>a en sistemas embebidos es que genera ejecutables de mayor tama<6D>o que los generados a partir de otras librer<65>as, lo cual no la hace muy atractiva para este tipo de aplicaciones.
|
|||
|
\item \textbf{uClibc\footnote{http://uclibc.org/}} Es una librer<65>a dise<73>ada especialmente para sistemas embebidos, es mucho m<>s peque<75>a que \textbf{glibc}.
|
|||
|
\item \textbf{newlib\footnote{http://sources.redhat.com/newlib/}} Al igual que \textbf{uClibc}, est<73> dise<73>ada para sistemas embebidos. El t<>pico ``Hello, world!'' ocupa menos de 30k en un entorno basado en newlib, mientras que en uno basado en glibc, puede ocupar 380k \cite{BG}.
|
|||
|
\item \textbf{diet libc\footnote{http://www.fefe.de/dietlibc/}} Es una versi<73>n de \textit{libc} optimizada en tama<6D>o, puede ser utilizada para crear ejecutables est<73>ticamente enlazados para linux en plataformas alpha, arm, hppa, ia64, i386, mips, s390, sparc, sparc64, ppc y x86\_64.
|
|||
|
\end{itemize}
|
|||
|
|
|||
|
|
|||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|||
|
% SECCION Obtenci<63>n y utilizaci<63>n del GNU toolchain
|
|||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|||
|
|
|||
|
\section{Obtenci<EFBFBD>n y utilizaci<63>n del \textit{GNU toolchain}}
|
|||
|
|
|||
|
El primer paso en nuestro estudio consiste en tener una cadena de herramientas funcional que soporte la familia de procesadores a utilizar. La arquitectura sobre la cual realizaremos nuestra investigaci<63>n es la ARM (Advanced Risc Machines), ya que un la m<>s utilizada en la actualidad por los dise<73>adores de sistemas embebidos (ver figura \ref{arch}) y se encuentran disponibles una gran variedad de herramientas para esta arquitectura. Existen dos formas de obtener la cadena de herramientas GNU:
|
|||
|
|
|||
|
\begin{figure}[h]
|
|||
|
\begin{center} \includegraphics[scale=.8]{./images/embedded-processor-trends-sm} \end{center}
|
|||
|
\caption{Tendencia del mercado de procesadores para sistemas embebidos. Fuente:\cite{Lin05} }\label{arch}
|
|||
|
\end{figure}
|
|||
|
|
|||
|
\begin{enumerate}
|
|||
|
\item Utilizar una distribuci<63>n precompilada: Esta es la via m<>s r<>pida, sin embargo, hay que tener cuidado al momento de instalarlas, ya que debe hacerse en un directorio con el mismo \textit{path} con el que fueron creadas. por ejemplo \textit{/usr/local/gnutools}; si esto no se cumple, las herramientas no funcionar<61>n de forma adecuada.
|
|||
|
\item Utilizar un script de compilaci<63>n: Existen disponibles en la red una serie de \textit{scripts} que permiten descargar, configurar, compilar e instalar la cadena de herramientas, la ventaja de utilizar este m<>todo es que es posible elegir las versiones de las herramientas instaladas, al igual que el directorio de instalaci<63>n. En este estudio utilizaremos los \textit{scripts} creados por Dan Kegel \cite{DK06}.
|
|||
|
\end{enumerate}
|
|||
|
|
|||
|
\subsection{Conceptos Previos}
|
|||
|
Antes de hablar sobre el uso de las herramientas GNU hablaremos sobre varios conceptos que deben quedar claros; estos son: El flujo de dise<73>o software, y el formato ELF.
|
|||
|
|
|||
|
\subsubsection{El formato \textbf{ELF}}
|
|||
|
|
|||
|
El formato ELF (\textit{Executable and Linkable Format}) Es un st<73>ndard para objetos, librer<65>as y ejecutables. Como puede verse en la figura \ref{elf1} el formato ELF est<73> compuesto por varias secciones (\textit{link view}) o segmentos (\textit{execution view}). Si un programador est<73> interesado en obtener informaci<63>n de secciones sobre tablas de s<>mbolos, c<>digo ejecutable espec<65>fico o informaci<63>n de enlazado din<69>mico debe utilizar \textit{link view}. Pero si busca informaci<63>n sobre segmentos, como por ejemplo, la localizaci<63>n de los segmentos \textit{text} o \textit{data} debe utilizar \textit{execution view}. El encabezado describe el layout del archivo, proporcionando informaci<63>n de la forma de acceder a las secciones \cite{MLH98}.
|
|||
|
|
|||
|
\begin{figure}[h]
|
|||
|
\begin{center} \includegraphics[scale=.4]{./images/ELF_Link_exec1} \end{center}
|
|||
|
\caption{Tendencia del mercado de procesadores para sistemas embebidos. Fuente:\cite{Lin05} }\label{elf1}
|
|||
|
\end{figure}
|
|||
|
|
|||
|
|
|||
|
Las secciones pueden almacenar c<>digo ejecutable, datos, informaci<63>n de enlazado din<69>mico, datos de depuraci<63>n, tablas de s<>mbolos,comentarios, tablas de strings, y notas. Las secciones m<>s importantes son las siguientes:
|
|||
|
|
|||
|
\begin{itemize}
|
|||
|
\item \textbf{.bss} Datos no inicializados. (RAM)
|
|||
|
\item \textbf{.comment} Informaci<63>n de la versi<73>n.
|
|||
|
\item \textbf{.data y .data1} Datos inicializados. (RAM)
|
|||
|
\item \textbf{.debug} Informaci<63>n para depuraci<63>n simb<6D>lica.
|
|||
|
\item \textbf{.dynamic} Informaci<63>n sobre enlace din<69>mico
|
|||
|
\item \textbf{.dynstr} Strings necesarios para el enlacedin<69>mico
|
|||
|
\item \textbf{.dynsym} Tabla de s<>mbolos utilizada para enlace din<69>mico.
|
|||
|
\item \textbf{.fini} C<>digo de terminaci<63>n de proceso.
|
|||
|
\item \textbf{.init} C<>digo de inicializaci<63>n de proceso.
|
|||
|
\item \textbf{.line} Informaci<63>n de n<>mero de l<>nea para depuraci<63>n simb<6D>lica.
|
|||
|
\item \textbf{.rodata y .rodta1} Datos de solo-lectura (ROM)
|
|||
|
\item \textbf{.shstrtab} Nombres de secciones.
|
|||
|
\item \textbf{.symtab} Tabla de s<>mbolos.
|
|||
|
\item \textbf{.text} Instrucciones ejecutables (ROM)
|
|||
|
\end{itemize}
|
|||
|
|
|||
|
Para aclarar un poco este concepto consideremos el siguiente c<>digo:
|
|||
|
|
|||
|
|
|||
|
\begin{lstlisting}
|
|||
|
#include <stdio.h>
|
|||
|
|
|||
|
int main(void)
|
|||
|
{
|
|||
|
int i; // Variable no inicializada
|
|||
|
int j = 2; // Variable inicializada
|
|||
|
for(i=0; i<10; i++){
|
|||
|
printf("Printing %d\n", i*j); // Caracteres constantes
|
|||
|
j = j + 1;
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
\end{lstlisting}
|
|||
|
|
|||
|
|
|||
|
En el ejemplo observamos que tenemos dos variables, una sin inicializar (\textit{i}) y otra inicializada (\textit{j}); estas variables estar<61>n en las secciones \textit{.bss} y \textit{.data} respectivamente, as<61> mismo los caracteres ``Printing `` Estar<61>n incluidos en la secci<63>n \textit{.rodata} ya que son datos que no cambian a lo largo de la ejecuci<63>n del programa. Las instrucciones que forman el programa residen en la secci<63>n \textit{.text}. A continuaci<63>n se muestra la informaci<63>n de este archivo una vez compilado, utilizando la herramienta \textit{objdump} de los utilitarios binarios \textit{binutils} y m<>s espec<65>ficamente el comando:
|
|||
|
|
|||
|
\textit{objdump -h hello}
|
|||
|
|
|||
|
|
|||
|
\begin{lstlisting}
|
|||
|
hello: file format elf32-littlearm
|
|||
|
|
|||
|
Sections:
|
|||
|
Idx Name Size VMA LMA File off Algn
|
|||
|
0 .interp 00000014 000080f4 000080f4 000000f4 2**0
|
|||
|
CONTENTS, ALLOC, LOAD, READONLY, DATA
|
|||
|
1 .hash 00000050 00008108 00008108 00000108 2**2
|
|||
|
CONTENTS, ALLOC, LOAD, READONLY, DATA
|
|||
|
2 .dynsym 000000f0 00008158 00008158 00000158 2**2
|
|||
|
CONTENTS, ALLOC, LOAD, READONLY, DATA
|
|||
|
3 .dynstr 0000008a 00008248 00008248 00000248 2**0
|
|||
|
CONTENTS, ALLOC, LOAD, READONLY, DATA
|
|||
|
5 .init 00000010 000082f4 000082f4 000002f4 2**2
|
|||
|
CONTENTS, ALLOC, LOAD, READONLY, CODE
|
|||
|
7 .text 0000017c 00008348 00008348 00000348 2**2
|
|||
|
CONTENTS, ALLOC, LOAD, READONLY, CODE
|
|||
|
8 .fini 0000000c 000084c4 000084c4 000004c4 2**2
|
|||
|
CONTENTS, ALLOC, LOAD, READONLY, CODE
|
|||
|
9 .rodata 00000010 000084d0 000084d0 000004d0 2**2
|
|||
|
CONTENTS, ALLOC, LOAD, READONLY, DATA
|
|||
|
10 .eh_frame 00000004 000084e0 000084e0 000004e0 2**2
|
|||
|
CONTENTS, ALLOC, LOAD, READONLY, DATA
|
|||
|
16 .data 0000000c 000105ac 000105ac 000005ac 2**2
|
|||
|
CONTENTS, ALLOC, LOAD, DATA
|
|||
|
17 .bss 00000004 000105b8 000105b8 000005b8 2**0
|
|||
|
ALLOC
|
|||
|
18 .comment 00000094 00000000 00000000 000005b8 2**0
|
|||
|
CONTENTS, READONLY
|
|||
|
\end{lstlisting}
|
|||
|
En el item 9, se observa la informaci<63>n correspondiente a la secci<63>n \textit{.rodata}, la primera columna corresponde al tama<6D>o de la secci<63>n, en este caso 16 bytes, las columnas 2 y 3 corresponden a la direcci<63>n de ejecuci<63>n (VMA) y a la direcci<63>n de carga (LMA) respectivamente. La columna 4 indica la direcci<63>n dentro del ejecutable donde se encuentra almacenada esta informaci<63>n, en este caso la \textit{0x000004d0}, utilizando la herramienta \textit{hexdump} podemos ver el contenido de esa direcci<63>n en el archivo ejecutable:
|
|||
|
|
|||
|
\textit{hexdump -C hello | grep -i 000004d0}
|
|||
|
|
|||
|
\begin{lstlisting}
|
|||
|
000004d0 50 72 69 6e 74 69 6e 67 20 25 64 0a 00 00 00 00 |Printing %d.....|
|
|||
|
\end{lstlisting}
|
|||
|
|
|||
|
|
|||
|
\subsection{Flujo de dise<73>o software}
|
|||
|
|
|||
|
En la figura \ref{toolchain_flow} se ilustra la secuencia de pasos que se realizan desde la creaci<63>n de un archivo de texto que posee el c<>digo fuente de una aplicaci<63>n hasta su implementaci<63>n en la tarjeta de desarrollo.
|
|||
|
|
|||
|
|
|||
|
\begin{figure}[h]
|
|||
|
\begin{center} \includegraphics[scale=.6]{./images/SW_design_flow} \end{center}
|
|||
|
\caption{Tendencia del mercado de procesadores para sistemas embebidos. Fuente:\cite{Lin05} }\label{toolchain_flow}
|
|||
|
\end{figure}
|
|||
|
|
|||
|
A continuaci<63>n se realiza una breve descripci<63>n de los pasos necesarios para generar un ejecutable para un sistema embebido:
|
|||
|
|
|||
|
\begin{enumerate}
|
|||
|
\item \textbf{Escritura del c<>digo fuente:} Creaci<63>n del c<>digo fuente en cualquier editor de archivos de texto.
|
|||
|
\item \textbf{Compilaci<EFBFBD>n:} Utilizando el compilador gcc se compila el c<>digo fuente; vala la pena mencionar que en este punto el compilador solo busca en los encabezados (\textit{headers}) de las librer<65>as la definici<63>n de una determinada funci<63>n, como por ejemplo el \textit{printf} en el archivo \textit{stdio.h}. Como resultado de este paso se obtiene un archivo tipo objeto.
|
|||
|
\item \textbf{Enlazado:} En esta etapa se realizan dos tareas:
|
|||
|
\begin{enumerate}
|
|||
|
\item Se enlazan los archivos tipo objeto del proyecto, junto con las librer<65>as, si una determinada funci<63>n no es edfinida por ninguna de las librer<65>as pasadas como par<61>metro al linker, este generar<61> un error y no se generar<61> el ejecutable.
|
|||
|
\item Se define la posici<63>nes f<>sicas de las secciones del ejecutable tipo ELF, esto se realiza a trav<61>s de un link de enlazado el cual define de forma expl<70>cita su localizaci<63>n.
|
|||
|
\end{enumerate}
|
|||
|
\item \textbf{Extracci<EFBFBD>n del archivo de programaci<63>n} En algunas aplicaciones es necesario extraer <20>nicamente las secciones que residen en los medios de almacenamiento no vol<6F>til y eliminar las dem<65>s secciones del ejecutable. Esto se realiza con la herramiento \textit{objcopy}, la cual, permite generar archivos en la mayor<6F>a de los formatos soportados por los programadores de memorias y procesadores, como por ejemplo S19 e Intel Hex.
|
|||
|
\item \textbf{Descarga del programa a la plataforma}. Dependiendo de la plataforma existen varios m<>todos para descargar el archivo de programaci<63>n a la memoria de la plataforma de desarrollo:
|
|||
|
\begin{enumerate}
|
|||
|
\item Utilizando un \textit{loader}: El \textit{loader} es una aplicaci<63>n que reside en un medio de almacenamiento no vol<6F>til y permite la descarga de archivos utilizando el puerto serie o una interfaz de red.
|
|||
|
\item Utilizando el puerto JTAG: El puerto JTAG (Joint Test Action Group) proporciona una interfaz capaz de controlar los registros internos del procesador, y de esta forma, acceder a las memorias de la plataforma y ejecutar un programa residente en una determinada posici<63>n de memoria.
|
|||
|
\end{enumerate}
|
|||
|
|
|||
|
\item \textbf{Depuraci<EFBFBD>n} Una vez se descarga la aplicaci<63>n a la plataforma es necesario someterla a una serie de pruebas con el f<>n de probar su correcto funcionamiento. Esto se puede realizar con el depurador GNU (GDB) y una interfaz de comunicaci<63>n que puede ser un puerto serie o un adaptador de red.
|
|||
|
|
|||
|
\end{enumerate}
|
|||
|
|
|||
|
\section{Makefile}
|
|||
|
Como pudo verse en la secci<63>n es necesario realizar una serie de pasos para poder descargar una aplicaci<63>n a una plataforma embebida. Debido a que las herramientas GNU solo poseen entrada por consola de comandos, es necesario esribir una serie de comandos cada vez que se realiza un cambio en el c<>digo fuente, lo cual resulta poco pr<70>ctico. Para realizar este proceso de forma autom<6F>tica se cre<72> la herramienta make, la cual recibe como entrada un archivo que normalmente recibe el nombre de \textit{Makefile} o \textit{makefile}. Un ejemplo de este tipo de archivo se muestra a continuaci<63>n:
|
|||
|
|
|||
|
\begin{lstlisting}[numbers=left]
|
|||
|
SHELL = /bin/sh
|
|||
|
|
|||
|
basetoolsdir = /home/at91/gcc-3.4.5-glibc-2.3.6/arm-softfloat-linux-gnu
|
|||
|
bindir = ${basetoolsdir}/bin
|
|||
|
libdir = ${basetoolsdir}/lib/gcc/arm-softfloat-linux-gnu/3.4.5
|
|||
|
|
|||
|
CC = arm-softfloat-linux-gnu-gcc
|
|||
|
AS = arm-softfloat-linux-gnu-as
|
|||
|
LD = arm-softfloat-linux-gnu-ld
|
|||
|
OBJCOPY = arm-softfloat-linux-gnu-objcopy
|
|||
|
|
|||
|
CFLAGS =-mcpu=arm920t -I. -Wall
|
|||
|
LDFLAGS =-L${libdir} -l gcc
|
|||
|
|
|||
|
OBJS = \
|
|||
|
main.o \
|
|||
|
debug_io.o \
|
|||
|
at91rm9200_lowlevel.o \
|
|||
|
p_string.o
|
|||
|
|
|||
|
ASFILES = arm_init.o
|
|||
|
|
|||
|
LIBS=${libdir}/
|
|||
|
|
|||
|
all: hello_world
|
|||
|
|
|||
|
hello_world: ${OBJS} ${ASFILES} ${LIBS}
|
|||
|
${LD} -e 0 -o hello_world.elf -T linker.cfg ${ASFILES} ${OBJS} ${LDFLAGS}
|
|||
|
${OBJCOPY} -O binary hello_world.elf hello_world.bin
|
|||
|
|
|||
|
clean:
|
|||
|
rm -f *.o *~ hello_world.*
|
|||
|
|
|||
|
PREPROCESS.c = $(CC) $(CPPFLAGS) $(TARGET_ARCH) -E -Wp,-C,-dD,-dI
|
|||
|
|
|||
|
%.pp : %.c FORCE
|
|||
|
$(PREPROCESS.c) $< > $@
|
|||
|
\end{lstlisting}
|
|||
|
|
|||
|
En las l<>neas 3-5 se definen algunas variables globales que ser<65>n utilizadas a lo largo del archivo; en las l<>neas 7 - 10 se definen las herramientas de compilaci<63>n a utilizar, espec<65>ficamente los compiladores de C (CC), de assembler (AS), el linker (LD) y la utilidad objcopy. A partir de la l<>nea 15 se definen los objetos que forman parte del proyecto, en este caso: \textit{main.o, debug\_io.o, at91rm9200\_lowlevel.o y p\_string.o}; en la l<>nea 21 se definen los archivos en assembler que contiene el proyecto, para este caso \textit{arm\_init.o}. Las l<>neas 12 y 13 definen dos variables especiales que se pasan directamente al copm<70>lador de C (CFLAGS) y al liniker (LDFLAGS)
|
|||
|
|
|||
|
|
|||
|
En las l<>neas 25, 27 y 31 aparecen unas etiquetas de la forma: \textit{nombre:} estos labels permiten ejecutar de forma independiente el conjunto de instrucciones asociadas a ellas, por ejemplo, si se ejecuta el comando:
|
|||
|
\\ \bigskip
|
|||
|
\textit{make clean}\\ \bigskip
|
|||
|
make ejecutar<61> el comando:\\ \bigskip
|
|||
|
\textit{rm -f *.o *~ hello\_world.*}
|
|||
|
|
|||
|
Observemos los comandos asociados a la etiqueta \textit{hello\_world:} En la misma l<>nea aparecen \textit{\${OBJS} \${ASFILES} \${LIBS}} esto le indica a la herramienta \textit{make} que antes de ejecutar los comandos asociados a este label, debe realizar las acciones necesarias para generar \textit{\${OBJS} \${ASFILES} \${LIBS}} o lo que es lo mmismo: \textit{main.o, debug\_io.o, at91rm9200\_lowlevel.o, p\_string.o, arm\_init.o y libgcc.a}. \textit{make} tiene predefinidas una serie de reglas para compilar los archivos .c la regla es de la forma:
|
|||
|
|
|||
|
\begin{lstlisting}
|
|||
|
|
|||
|
.c.o:
|
|||
|
$(CC) $(CFLAGS) -c $<
|
|||
|
.c:
|
|||
|
$(CC) $(CFLAGS) $@.c $(LDFLAGS) -o $@
|
|||
|
|
|||
|
\end{lstlisting}
|
|||
|
|
|||
|
Lo cual le indica a la herramienta make que para generar un archivo \textit{.o} a partir de uno \textit{.c} es necesario ejecutar \textit{\$(CC) \$(CFLAGS) -c \$<}; de aqui la importancia de definir bien la variable de entorno \textit{CC} cuando trabajamos con compiladores cruzados\footnote{Un compilador cruzado genera c<>digo para una plataforma diferente en la que se est<73> ejecutando, por ejemplo, genera ejecutables para ARM pero se ejecuta en un x86}. Hasta este punto al ejecutar el comando: \textit{make hello\_world}, \textit{make} realizar<61>a las siguientes operaciones: \\
|
|||
|
|
|||
|
\begin{lstlisting}
|
|||
|
arm-softfloat-linux-gnu-gcc -mcpu=arm920t -I. -Wall -c -o main.o main.c
|
|||
|
arm-softfloat-linux-gnu-gcc -mcpu=arm920t -I. -Wall -c -o debug_io.o debug_io.c
|
|||
|
arm-softfloat-linux-gnu-gcc -mcpu=arm920t -I. -Wall -c -o at91rm9200_lowlevel.o at91rm9200_lowlevel.c
|
|||
|
arm-softfloat-linux-gnu-gcc -mcpu=arm920t -I. -Wall -c -o p_string.o p_string.c
|
|||
|
arm-softfloat-linux-gnu-as -o arm_init.o arm_init.s
|
|||
|
\end{lstlisting}
|
|||
|
|
|||
|
En las l<>neas 28 se realiza el proceso de enlazado; al \textit{linker} se le pasan los par<61>metros:
|
|||
|
\begin{itemize}
|
|||
|
\item \textbf{-e 0}: Punto de entrada , utilice 0 como s<>mbolo para el inicio de ejecuci<63>n.
|
|||
|
\item \textbf{-o hello\_world.elf}: Nombre del archivo de salida \textit{hello\_world}
|
|||
|
\item \textbf{-T linker.cfg}: Utilice el archivo de enlace \textit{linker.cfg}
|
|||
|
\item \textbf{\${ASFILES} \${OBJS} \${LDFLAGS}}: Lista de objetos y librer<65>as para crear el ejecutable.
|
|||
|
\end{itemize}
|
|||
|
|
|||
|
En la l<>nea 29 se utiliza la herramienta \textit{objcopy} para generar un archivo binario (\textit{-O binary}) con la informaci<63>n necesaria para cargar en una memoria no vol<6F>til.
|
|||
|
|
|||
|
|
|||
|
|