Sistemas Embebidos para Tiempo Real Laboratorio 2 - Introducción al lenguaje C (parte II) Resumen En este laboratorio se continuará profundizando el estudio del lenguaje C y se seguirán utilizando las herramientas del laboratorio anterior. Se estudiarán los punteros y su relación con los arreglos, las estructuras y las uniones. Por último se realizará un módulo que será utilizado en los laboratorios siguientes para crear aplicaciones. El laboratorio debe ser completado por cada participante de la clase. Si bien se recomienda el intercambio de ideas entre compañeros, es obligatorio que cada uno realice los trabajos en forma individual en su computadora. Aquellos que ya posean conocimientos de lenguaje C y desarrollo de aplicaciones, podrán asistir a sus compañeros. Al final del laboratorio se debatirá sobre alguna de las soluciones implementadas. Primero se discutirá en grupos, luego cada grupo expondrá en 2 minutos una solución consensuada y finalmente se hará una puesta a punto entre toda la clase. Objetivos Objetivos generales 1. Describir conceptos avanzados del lenguaje C. 2. Crear módulos reutilizables para la creación de aplicaciones más complejas. 3. Emplear herramientas para compilar módulos y luego aplicaciones. Ejecutar dichos programas. Objetivos particulares 1. 2. 3. 4. 5. 6. Definir y utilizar estructuras y uniones. Definir y utilizar arreglos y punteros. Comparar arreglos y punteros, estableciendo diferencias y similitudes. Emplear y manipular cadenas de caracteres. Definir módulo y sus componentes (archivos .h y .c). Explicar la utilización de un módulo. Material • Máquina virtual del curso Actividades a Realizar Punteros Los punteros son un tipo especial de variable que permite acceder al contenido de otras variables, arreglos o posiciones de memoria arbitrarias. Los punteros permiten el pasaje de parámetros por referencia. 1. Escribir una función intercambiar que recibe dos punteros a enteros e intercambia los valores de los enteros entre sí. Para verificar el correcto funcionamiento escribir un programa que imprime los enteros antes y después de invocar la función. 2. Intentar realizar la misma función pasando como parámetros los enteros. Arreglos y cadenas de caracteres 1. Escribir una función que reciba una cadena de caracteres (arreglo de caracteres, tipo char, terminada en null) e imprima la misma omitiendo las vocales. Utilizar primero if-else y otra versión switch-case. 2. Escribir una función que reciba un arreglo de enteros de tamaño MAX_ENTEROS y que imprima los números que sean mayor que el número en la posición anterior del array. Recorrer el arreglo utilizando un índice. En una segunda versión utilizar punteros para la recorrida. Estructuras y uniones • Modificar el código mostrado a continuación para que además de permitir acceder a un registro directamente (es decir todos los bits simultáneamente) y de manera individual a cada uno de los bits, permita acceder a los primeros cuatro bits (primer nibble) y a los siguientes cuatro bits (segundo nibble). typedef union { unsigned char byte; struct { unsigned char bit0 : unsigned char bit1 : unsigned char bit2 : unsigned char bit3 : unsigned char bit4 : unsigned char bit5 : unsigned char bit6 : unsigned char bit7 : } bit; } registro_t; 1; 1; 1; 1; 1; 1; 1; 1; /* Ejemplo de uso */ registro_t reg1; reg1.byte = 5; reg1.bit.bit0 = 0; printf("reg1: %d",reg1.byte); Módulo En muchas aplicaciones es necesario manejar la noción del tiempo. Se dispone de un reloj de tiempo real para el monitoreo, disparo o etiquetado de eventos. Para el seguimiento del tiempo típicamente se utilizan dos métodos: contar los milisegundos transcurridos a partir de cierto instante de tiempo o directamente contar segundos, minutos, horas. Si además interesa la noción del tiempo al pasar de los días o a lo largo del año, se lleva la cuenta de los días, día del mes, mes, etc. Ambos métodos presentan ventajas y desventajas. Escribir un módulo de manejo del tiempo utilizando el segundo método, llevando la cuenta de las horas, minutos, segundos y centisegundos. El tiempo será incrementado usando un temporizador de hardware, aunque en esta versión no será implementado. Más adelante la función que incrementa el tiempo formará parte o será llamada desde la rutina de servicio a la interrupción del temporizador en hardware. A continuación se describen los requerimientos: 1. La interfaz pública incluye funciones para: a) inicializar el reloj b) incrementarlo en 250 ms c) devolver el tiempo actual d) Recordar proveer un archivo de encabezado para ser incluido por otros módulos que utilicen éste. e) ¿Qué utilidad tiene incluir el archivo .h en el archivo .c del propio módulo? 2. Para representar el tiempo definir un nuevo tipo utilizando una estructura para guardar: horas, minutos, segundos, milisegundos. La variable donde se guarda el tiempo actual no será accesible fuera del módulo. 3. Las funciones auxiliares, si las hubiera, deberán ser privadas al módulo. Para verificar el correcto funcionamiento: 1. Escribir un programa, por ejemplo en un archivo pruebatiempo.c, donde se inicialize el reloj, se llame la función para incrementar el tiempo cierta cantidad de veces y lo luego imprima el estado del reloj a pantalla. 2. Experimentar cambiando los modificadores a las variables y a las funciones y verificar si son visibles o no desde otros módulos. Puesta en común 1. Cada equipo expondrá en 2 minutos la solución del ejercicio de módulo. 2. Discusión de las diferentes soluciones. 3. Elección de la interfaz para el módulo timer. Lecturas recomendadas • • • • Brian W. Kernighan, Dennis M. Ritchie, "El Lenguaje de Programación C", Pearson Education, ISBN: 968-880-205-0, 1991. Jack G. Ganssle, “A Firmware Development Standard”, The Ganssle Group, 2007. The Sherrill Group Georgia Institute of Technology, "C Programming Tutorial", accesible en: http://vergil.chemistry.gatech.edu/resources/programming/c-tutorial/toc.html. Brian W. Kernighan , "Programming in C: A Tutorial", accesible en: http://www.lysator.liu.se/c/bwktutor.html. Notas: 1. Algunos de los ejercicios fueron tomados y adaptados de los laboratorios correspondientes del curso "Procesadores Digitales de Señal".