1 / 24

Programación en C para sistemas basados en un microprocesador

Programación en C para sistemas basados en un microprocesador. Una introducción. Objetivos. Recordar los conceptos básicos de un lenguaje de alto nivel Comprender sencillos programas escritos en el lenguaje más empleado: “C”

javan
Download Presentation

Programación en C para sistemas basados en un microprocesador

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Programación en C para sistemas basados en un microprocesador Una introducción

  2. Objetivos • Recordar los conceptos básicos de un lenguaje de alto nivel • Comprender sencillos programas escritos en el lenguaje más empleado: “C” • Comparar las características de “C” con las de Java y el lenguaje ensamblador.

  3. Lenguajes de alto nivel • Basados en el uso de compiladores o intérpretes • Incrementan la productividad (respecto al ensamblador) • Estructuras elegantes de control • Complejas estructuras de datos • Mayor abstracción: • Manejo de la pila: funciones • Memoria física: variables y tipos • Incrementan la seguridad • Programación estructurada (sin branches) • Control de tipos (coherencia de tamaños y signos) • Incrementan la portabilidad (multimáquina) • Se dispone de más bibliotecas que facilitan la programación

  4. ¿Por qué “C”? • Permite un buen control de los recursos de bajo nivel (aunque no tanto como el ensamblador) • Permite la programación estructurada • Es eficiente en velocidad y tamaño (aunque no tanto como un buen programa de un buen programador en ensamblador) • Su uso está muy extendido en programación de sistemas (Linux, Windows, drivers...) • Defecto: es fácil cometer errores: • No está fuertemente tipado ni es orientado a objetos • Permite crear código críptico • Es difícil de dominar con maestría

  5. Traducción a ensamblador • 0200fc linkw %fp,#-4 • 020100 nop • 020102 clrl %fp@(-4) • 020106 moveq #9,%d0 • 020108 cmpl %fp@(-4),%d0 • 02010c bges 00020110 • 02010e bras 00020138 • 020110 moveal %fp@(8),%a0 • 020114 addal %fp@(-4),%a0 • 020118 moveal %fp@(12),%a1 • 02011c addal %fp@(-4),%a1 • 020120 moveb %a0@,%d0 • 020122 extbl %d0 • 020124 moveb %a1@,%d1 • 020126 extbl %d1 • 020128 cmpl %d0,%d1 • 02012a beqs 00020130 • 02012c moveq #1,%d0 • 02012e bras 0002013e • 020130 moveq #1,%d0 • 020132 addl %d0,%fp@(-4) • 020136 bras 00020106 • int stringCmp(char s1[10],char s2[10]) { • int i; • for (i=0; i<10; i++) • { • if (s1[i]!=s2[i]) • { • return 1; • } • } • return 0; • } Variables Locales: seguridad, abstrae memoria y pila Bucle: cómodo y estructurado Escribir cómodamente expresiones complejas Manejo transparente de pila y registros • Parameter s1 is at 8(A7) • Parameter s2 is at 12(A7) • Variable i is at -4(A7) • Return value through -4(A7)

  6. Proceso de compilación Main.asg main.o AS Fichero.c Fichero.s Fichero.o GCC AS LD Fichero.dep Fichero.hcf Fichero.elf OBJDUMP

  7. “C” versus Java • “C” no es un lenguaje orientado a objetos: • No hay clases, objetos, métodos • No hay herencia, polimorfismo (no puede haber 2 funciones con el mismo nombre) • No hay objetos sino variables • No hay métodos de una clase sino funciones • No hay excepciones • “C” no es un lenguaje interpretado • No es “machine-independent”

  8. Puntos comunes con Java (I) • Bloques definidos por llaves • El ámbito de una variable es el bloque más pequeño que contiene su declaración (salvo para los argumentos de una función) • Comentarios: /* ... */ • Tipos comunes: • Los básicos: void, char, int, float • Los modificadores long, short, double, signed y unsigned • Definición de nuevos tipos mediante typedef • Identificadores: case-sensitive, no deben empezar por un número. • Ej: linea5, linea_5, linea_anterior

  9. Puntos comunes con Java (II) • Expresiones comunes: • Los paréntesis son los elementos más prioritarios, seguidos por los operadores unitarios y por los binarios • Operadores aritméticos: + - * / % ++ -- += -= *= /= • I+=5+(5%2); /* I=i+6*/ • Operadores lógicos y relacionales: && || !< <= > >= == != • if ((i>0 && i<10) || (j==0) ) { } • Operadores de bit y de desplazamiento: & | >> << • I=0xf0 & 0x0f; /* I=0 */ • I=j<<3; /* ASL de 3 bits*/

  10. Puntos comunes con Java (III) • Bucles • for (inicialización; condición; iteración) • for (i=0; i<10; i++) { } • for (int i=0;...) /* ERROR */ • while (condición) • while (i<10) { i++; } • Condiciones: • if (<cond>) {} else if (<cond>) {} else { } • if (i<0) { } else if (i<10) { } else { } • switch (variable) { case valor: {} break; default: {} break;}

  11. Tipos enteros : tamaños • El tamaño es dependiente de máquina y de compilador, aunque char es siempre de 8 bits • En el ColdFire, con el compilador GCC: • short int, signed short int, unsigned short int : 16 bits • int, signed int, long int, unsigned long int, signed long int: 32 bits • Las variables globales no son inicializadas nunca en el C del EdColdFire!!

  12. Variables (asm vs. C) • 00030000 00000002 D shi • 00030002 00000004 D li • 00030006 00000004 D si • 0003000a 00000002 D sshi • 0003000c 00000004 D sli • 00030010 00000004 D ui • 00030014 00000002 D ushi • 00030016 00000004 D uli • 0003001c 00000004 B i • 00020100 clrl 0003001c <i> • 00020106 moveq #1,%d0 • 00020108 movew %d0,00030000 <shi> • 0002010e moveq #2,%d0 • 00020110 movel %d0,00030002 <li> • 00020116 clrl 00030006 <si> • 0002011c moveq #1,%d0 • 0002011e movew %d0,0003000a <sshi> • 00020124 moveq #2,%d0 • 00020126 movel %d0,0003000c <sli> • 0002012c clrl 00030010 <ui> • 00020132 moveq #1,%d0 • 00020134 movew %d0,00030014 <ushi> • 0002013a moveq #2,%d0 • 0002013c movel %d0,00030016 <uli> • int i; • short int shi=1; • long int li=2; • signed int si=0; • signed short int sshi=1; • signed long int sli=2; • unsigned int ui=0; • unsigned short int ushi=1; • unsigned long int uli=2; • i=0; • shi=1; • li=2; • si=0; • sshi=1; • sli=2; • ui=0; • ushi=1; • uli=2;

  13. Tipos enteros : tamaños y conversiones • Conversiones implícitas: • Al asignar una variable de un tipo mayor a una variable de tipo menor, se recorta (bits menos significativos) • int i=0xfedbca56; • short int si=i; /* Equivale a si=0xffff */ • Al asignar una variable más pequeña a una mayor, no hay problema • Al asignar entre variables de igual tamaño y distinto signo, no se pierden bits, pero puede variar su interpretación • signed int si=-1; • unsigned int ui; • ui=si; /* ui=65535 */

  14. Punteros (I) • Variables que contienen una dirección de memoria • Como los registros de direcciones Ax: • Permiten acceder indirectamente a otras variables • int i=0; /* La variable i contiene un 0 */ • int *pi; /* declaración de un puntero */ • pi=&i; /* El puntero pi contiene la dirección de la variable i */ • *pi=2; /* La variable i ahora contiene un 2, el puntero pi no se ve alterado */ • i=*pi; /* la variable i sigue conteniendo un 2 */ 0 2 i i $XXX $XXX $XXX $YYY pi pi $YYY $YYY

  15. Punteros (II) • También permiten acceder a posiciones del mapa de memoria de entrada y salida • #define BASE_PUERTO_S 0x40000000 /* Direccion del puerto S */ • unsigned char *puertoS=BASE_PUERTO_S; /* El puntero pi contiene la dirección del puerto de salida */ • *puertoS=0xff; /* Se envía un $FF al puerto de salida */ • En EdColdFire hay funciones para esta labor: • Internamente usan punteros (ver m5272gpio.c) • void set16_puertoS (UWORD valor) • UWORD lee16_puertoE (void) $FF $XX $40000000 $40000000 $40000000 $40000000 puertoS puertoS $YYY $YYY Valor de la variable Posición en memoria Valor de la variable Posición en memoria variable variable

  16. Punteros (III) • Son un mecanismo de bajo nivel, peligroso • Si no se les da un valor adecuado, pueden acceder a posiciones de memoria no deseadas: • int *pi; • Este es un puntero que apunta a un lugar indeterminado, por no estar inicializado • *pi=3; • Como pi puede apuntar a cualquier sitio, podemos estar escribiendo en cualquier punto del mapa de memoria, o incluso fuera de él, (provocando un error de bus o de dirección)

  17. Arrays (I) • Los array son punteros constantes (no variables) que permiten acceder, de una manera indexada, a una zona de memoria reservada por el compilador automáticamente • Dicho puntero constante equivale a la dirección de comienzo del array • Por ser una constante, este puntero no se inicializa; se inicializa el contenido de la zona de memoria apuntada • El índice del primer elemento es el 0, el del segundo elemento es el 1, etc. • Es posible acceder (por error o intencionadamente) a posiciones más allá del tamaño reservado para el array • Para copiar un array en otro es necesario copiar elemento a elemento con un bucle

  18. Arrays (II) • int lista[3]={0,1,2}; int i=3; • El array lista contiene 3 números, la variable i contiene un 3 • lista[1]=lista[2]; • Copia el valor de la posición 2 (que es la última), en la posición 1 (que es la segunda) • lista[i]=0; • ERROR: modifica la variable i (situada en memoria tras el array) array 0 0 $XXX $XXX array 1 2 $XXX+4 $XXX+4 2 2 $XXX+8 $XXX+8 3 0 i $XXX+12 i $XXX+12

  19. Arrays (III) • Los arrays de caracteres se suelen llamar strings. • char asignatura[4]=“SED”; • asignatura[0]=‘T’; • Su tamaño debe ser “la longitud máxima de la cadena de caracteres” + 1, porque su último elemento es un 0 (no el carácter ‘0’). string ‘S’ ‘T’ $XXX $XXX string ‘E’ ‘E’ $XXX+1 $XXX+1 ‘D’ ‘D’ $XXX+2 $XXX+2 0 0 $XXX+3 $XXX+3

  20. Funciones (I) • Permiten dividir un problema en subproblemas • Se implementan como subrutinas • El manejo de la pila y el uso de los registros es automático e invisible al programador • Admiten argumentos de entrada y de salida • Suelen devolver un valor, pero no es obligatorio • Si la función no devuelve nada, al llegar a la última llave, realiza el return automáticamente • Todo programa en C comienza ejecutando la función llamada main, que en sistemas empotrados no suele tener argumentos de entrada o salida

  21. Funciones (II) nombre Argumentos • int suma(int a, int b); • Este es el prototipo de la función, que anticipa al compilador qué argumentos admite • Si el cuerpo de la función está antes de la llamada, el prototipo no es necesario • void main(void){... int s=suma(10,3);... } /* S contendrá ahora un 13*/ • Esta es la llamada a la función para que se ejecute, pasándole 2 parámetros compatibles con lo que establecen el prototipo y el cuerpo de la función • int suma(int a, int b){ return a+b; } • Este es el cuerpo de la función cuya cabecera coincide con el prototipo previo (salvo en el punto y coma final) Tipo del valor que devuelve

  22. Funciones (III) • Una variable, pasada como parámetro a una función, no ve modificado su valor original durante la ejecución (paso por valor, copia local) • Para modificar, dentro de una función, el valor de una variable externa a la función, debemos pasarla por referencia (pasar su dirección) • void suma(int a, int b, int *ps){*ps=a+b;} • Por medio del puntero ps (que contiene la dirección de s), escribimos en s el resultado • void main(void) {... int s; suma(10,3, &s );...} /* s contendrá ahora un 13*/ • Ahora se pasa la dirección de s, para que dentro de la función se pueda acceder a s

  23. Funciones (IV) • Los argumentos de entrada son variables locales al cuerpo de la función (aunque estén fuera de las llaves) • Es posible definir otras variables locales • Las variables locales son temporales (se implementan como direcciones en la pila o como registros) • El valor que se devuelve también suele ser a través de pila o de registro • int suma(int a, int b){ int s=a+b; return s; } • La variable local s sólo puede ser usada dentro de la función suma (ámbito). La función devuelve el contenido de s • int * suma2(int a, int b) { int s=a+b; return &s; } • ERROR: no se puede devolver la dirección de s, porque es local y desaparece cuando se termina de ejecutar la función

  24. Bibliografía • Brian W. Kernighan & Dennis M. Ritchie “The C Programming Language”, Second Edition. Prentice Hall, Inc., 1988. • A. Clements “Microprocessor Systems Design” 3rd ed. PWS-Kent Pub. Co., 1997 • H. Schildt “C: Manual de referencia” , Ed. McGraw Hill, 1989

More Related