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

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

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

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

Programación en C para sistemas basados en un microprocesador

Una introducción

Page 2: 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”

• Comparar las características de “C” con las de Java y el lenguaje ensamblador.

Page 3: Programación en C para sistemas basados en un microprocesador Una introducción.

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

Page 4: Programación en C para sistemas basados en un microprocesador Una introducción.

¿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

Page 5: Programación en C para sistemas basados en un microprocesador Una introducción.

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

•Parameter s1 is at 8(A7)•Parameter s2 is at 12(A7)•Variable i is at -4(A7)•Return value through -4(A7)

•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

Page 6: Programación en C para sistemas basados en un microprocesador Una introducción.

Proceso de compilación

Fichero.c GCC Fichero.s AS Fichero.o

LD

Fichero.hcfFichero.elf

Fichero.dep OBJDUMP

main.oASMain.asg

Page 7: Programación en C para sistemas basados en un microprocesador Una introducción.

“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”

Page 8: Programación en C para sistemas basados en un microprocesador Una introducción.

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

Page 9: Programación en C para sistemas basados en un microprocesador Una introducción.

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*/

Page 10: Programación en C para sistemas basados en un microprocesador Una introducción.

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;}

Page 11: Programación en C para sistemas basados en un microprocesador Una introducción.

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!!

Page 12: Programación en C para sistemas basados en un microprocesador Una introducción.

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;

Page 13: Programación en C para sistemas basados en un microprocesador Una introducción.

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 */

Page 14: Programación en C para sistemas basados en un microprocesador Una introducción.

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

$XXX

i

pi

$XXX

$YYY

2

$YYY

i

pi

$XXX

$YYY

Page 15: Programación en C para sistemas basados en un microprocesador Una introducción.

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)

$XX

$40000000puertoS

$40000000

$YYY

$FF

$40000000puertoS

$40000000

$YYY

variableValor de la

variablePosición

en memoria

variableValor de la

variablePosición

en memoria

Page 16: Programación en C para sistemas basados en un microprocesador Una introducción.

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)

Page 17: Programación en C para sistemas basados en un microprocesador Una introducción.

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

Page 18: Programación en C para sistemas basados en un microprocesador Una introducción.

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)

2 $XXX+8 2 $XXX+8

1 $XXX+4 2

array

$XXX+4

0 $XXX 0array $XXX

3 $XXX+12 0 $XXX+12i i

Page 19: Programación en C para sistemas basados en un microprocesador Una introducción.

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’).

‘D’ $XXX+2 ‘D’ $XXX+2

‘E’ $XXX+1 ‘E’

string

$XXX+1

‘S’ $XXX ‘T’string $XXX

0 $XXX+3 0 $XXX+3

Page 20: Programación en C para sistemas basados en un microprocesador Una introducción.

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

Page 21: Programación en C para sistemas basados en un microprocesador Una introducción.

Funciones (II)

• 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

Argumentos

nombre

Page 22: Programación en C para sistemas basados en un microprocesador Una introducción.

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

Page 23: Programación en C para sistemas basados en un microprocesador Una introducción.

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

Page 24: Programación en C para sistemas basados en un microprocesador Una introducción.

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