1
0
mirror of git://projects.qi-hardware.com/nn-usb-fpga.git synced 2025-01-10 07:40:15 +02:00
nn-usb-fpga/course/.docs/cambio_categoria/chapter1.tex~

513 lines
32 KiB
TeX
Raw Normal View History

2010-09-13 03:57:04 +03:00
\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.