Descarga la aplicación para disfrutar aún más
Esta es una vista previa del archivo. Inicie sesión para ver el archivo original
/** @file SimIntegrador2.c * * @date 12 de noviembre de 2019 * @version 1.0 * * @authors Vazquez Saraullo, Federico Alejandro. * * @brief Archivo fuente que simula a los puertos 0x400 y 0x401, y se utiliza * para validar el programa del ejercicio 2 de los integradores. Los * resultados esperados son: * * A0 A1 A2 A3 A4 A5 A6 A7 * P0 0 (1) 0 0 (1) 0 0 0 * P1 0 0 0 0 0 0 0 0 * P2 0 0 0 0 0 0 0 0 * P3 0 0 0 0 0 0 0 0 * P4 0 0 0 (2) 0 0 0 0 * P5 0 0 0 0 0 0 0 0 * P6 0 0 0 0 0 0 0 0 * P7 0 0 0 0 0 0 0 0 * P8 0 0 0 0 0 0 0 0 * P9 0 0 0 0 0 0 0 0 * P10 0 0 0 0 0 0 0 0 * P11 0 0 0 0 0 0 (1) (1) * P12 0 0 0 0 0 0 0 0 * P13 0 0 0 0 0 0 0 0 * P14 0 0 0 0 0 0 0 0 * P15 0 0 0 0 0 (1) 0 0 * P16 0 0 0 0 0 0 0 0 * P17 0 0 0 0 0 0 0 0 * P18 0 0 0 0 0 0 0 0 * P19 0 0 (1) 0 0 0 0 0 * P20 0 0 0 0 0 0 0 0 * P21 0 0 0 0 0 0 0 0 * P22 0 0 0 0 (3) 0 0 0 * P23 0 0 0 0 0 0 0 0 * P24 0 0 0 0 0 0 0 0 * P25 0 0 0 0 0 0 0 0 * P26 0 0 0 0 0 0 0 0 * P27 0 0 0 0 0 0 0 0 * P28 0 0 0 0 0 0 0 0 * P29 0 0 0 0 0 0 0 0 * P30 0 0 0 0 0 0 0 0 * P31 (1) 0 0 0 0 0 0 0 * * El/los pisos desde el cual/es se llamó mayor cantidad de veces a los * ascensores: P22. * * Listado de cantidad de pisos desde los cuales no fue llamado cada * ascensor: * A0 31 * A1 31 * A2 31 * A3 31 * A4 30 * A5 31 * A6 31 * A7 31 * * Mayor valor de la matriz: 3. * * @note Solo se pueden habilitar los puertos con dirección 0x400 y 0x401. Los * demás puertos se toman como que no están disponibles en la PC. */ /** \addtogroup Simulador para ejercicio 2 de los integradores. * @{ */ /*==================[inclusiones]============================================*/ #include <stdio.h> /*==================[macros]=================================================*/ /** @def PUERTO_BASE * @brief Dirección base del puerto 0x400 disponible según este simulador.*/ #define PUERTO_BASE 0x400 /** @def CANT_ELEM_VEC(x) * @brief Macro para calcular la cantidad de elementos de un vector "X".*/ #define CANT_ELEM_VEC(x) (sizeof(x) / sizeof(x[0])) /*==============================[Tipos de datos]=============================*/ typedef enum{ FIN_OFF, FIN_ON }finStatus_t; typedef enum{ SINC_EQUAL_00, SINC_NOT_EQUAL_01, SINC_NOT_EQUAL_10, SINC_EQUAL_11 }sincStatus_t; typedef enum{ PISO0, PISO1, PISO2, PISO3, PISO4, PISO5, PISO6, PISO7, PISO8, PISO9, PISO10, PISO11, PISO12, PISO13, PISO14, PISO15, PISO16, PISO17, PISO18, PISO19, PISO20, PISO21, PISO22, PISO23, PISO24, PISO25, PISO26, PISO27, PISO28, PISO29, PISO30, PISO31 }numPi_t; typedef enum{ ASCE0, ASCE1, ASCE2, ASCE3, ASCE4, ASCE5, ASCE6, ASCE7 }numAs_t; typedef enum{ DESHABILITADO, HABILITADO, ERROR_ESTADO }portStatus_t; typedef struct{ unsigned int dir; portStatus_t estado; }puerto_t; typedef enum{ OK, ERROR1, ERROR2, ERROR3 }estadoActivacion_t; /*==================[declaración de variables internas]======================*/ /**@var dirPuertos * @brief Vector que almacena la dirección y estado de los puertos, los cuales * están inicialmente deshabilitados.*/ static puerto_t dirPuertos[] = { { .dir = PUERTO_BASE, .estado = DESHABILITADO}, { .dir = PUERTO_BASE + 1, .estado = DESHABILITADO} }; /*==================[definición de funciones internas]=======================*/ /** @fn unsigned char ArmarDatoPuerto (unsigned int port, numPi_t np, numAs_t na, sincStatus_t sinc, finStatus_t fin ) * @brief Permite armar un valor de 8 bits según el puerto que se desea leer. * Se piden los datos de bits de fin, sincronismo, número de ascensor y * número de piso, aunque devuelve solo lo necesario para el puerto * solicitado. * @return unsigned char Dato armado para ser enviado al puerto. */ unsigned char ArmarDatoPuerto (unsigned int port, numPi_t np, numAs_t na,\ sincStatus_t sinc, finStatus_t fin ) { /* Declaraciones locales */ unsigned char valor; /* Cuerpo de la función*/ switch(port){ case PUERTO_BASE: valor = ( ((((unsigned int) np) & 0x07) << 5 ) + \ ((((unsigned int) sinc) & 0x03) << 3) + \ (((unsigned int) na) & 0x07) ); break; case (PUERTO_BASE + 1): valor = ( (((unsigned int) fin) << 7 ) + \ ((((unsigned int) np) & 0x18) >> 3) ); break; default:valor = 0; } return valor; } /** @fn int BuscarPuerto (puerto_t portVec[], int cnt, unsigned int port) * @brief Permite buscar en forma secuencial la dirección "port" dentro del vector "portVec" el cual tiene "cnt" elementos. * @return int que vale: * -1: No se encontró al "port" en "porVec". * otro valor: Se encontró. */ int BuscarPuerto (puerto_t portVec[], int cnt, unsigned int port) { /* Declaraciones locales */ int i = 0; int pos = -1; /* Cuerpo de la función*/ while(i < cnt && pos == -1){ if(portVec[i].dir == port){ pos = i; } else{ i++; } } return pos; } /** @fn int ioperm (unsigned int port, unsigned int cant, int accion) * @brief Permite habilitar o deshabilitar una cantidad entera de puertos consecutivos. * @return estadoActivacion_t que vale: * OK: Se habilita/deshabilita correctamente. * ERROR1: Error por valores de cant y/o accion. * ERROR2: Error por dirección del puerto. * ERROR3: Error por direcciones consecutivas de puertos. */ int ioperm (unsigned int port, unsigned int cant, int accion) { /* Declaraciones locales */ unsigned int i = 0; int pos; estadoActivacion_t activacion; portStatus_t estadoASetear; /* Cuerpo de la función*/ /*Se guarda el estado a setear. Aunque "estadoASetear" sea enum, admite *valores negativos y mayores a 1.*/ switch(accion){ case 0: estadoASetear = DESHABILITADO; break; case 1: estadoASetear = HABILITADO; break; default: estadoASetear = ERROR_ESTADO; } /*Se validan los parámetros formales.*/ if(cant > 0 && (estadoASetear == HABILITADO || estadoASetear == DESHABILITADO) ){ /*Se hace primero una búsqueda secuencial de la dirección "port" en el *vector "dirPuertos".*/ pos = BuscarPuerto(dirPuertos, CANT_ELEM_VEC(dirPuertos), port); /*Si se encuentra el puerto, se chequea que los puertos consecutivos se *puedan habilitar. Por defecto, se supone que se pueden habilitar hasta *que se demuestre lo contrario.*/ if(pos != -1){ i = 1; activacion = OK; /*Se buscan los puertos consecutivos en el vector "dirPuertos".*/ while(i < cant && activacion == OK){ if((port + i) != dirPuertos[pos + i].dir){ activacion = ERROR3; } else{ i++; } } /*Se habilitan/deshabilitan si es posible.*/ if(activacion == OK){ for (i = 0; i < cant; i++){ dirPuertos[pos + i].estado = estadoASetear; } } } else{ activacion = ERROR2; } } else{ activacion = ERROR1; } return activacion; } /** @fn void MostrarErrorLectura() * @brief Muestra un mensaje de error en caso de que exista uno cuando se usa la función "inb". */ void MostrarErrorLectura() { /* Declaraciones locales */ /* Cuerpo de la función*/ printf("\n\n****************************************************************************************\n"); printf("ERROR. El puerto, por el que desea leer un dato, no existe o no esta habilitado.\n"); printf("****************************************************************************************\n"); } /*Para esta función se consideraron los siguientes casos: * -Datos válidos de pisos 0, 4, 11, 15, 19, 22 y 31. * -Poner varios casos para cada valor para así tener en cuenta la posible * doble lectura innecesaria en el programa de aplicación. * -Bits de sincronismo S0 y S1 cambian entre cada dato válido de 00 a 11 y * viceversa; también cambian de 01 a 10 entre cada dato inválido. * -Bit F en 1 cuando el dato NO es válido para que el usuario solo analice * ese bit si el dato es válido. De no hacerlo, el programa se cierra. * -Bit F en 1 en caso de agotarse los casos.*/ unsigned char inb( int port) { /* Declaraciones locales */ static int orden=0; int pos; unsigned char dato = 0; /*Se verifica que el puerto está habilitado*/ pos = BuscarPuerto(dirPuertos, CANT_ELEM_VEC(dirPuertos), port); if( pos == -1 || dirPuertos[pos].estado == DESHABILITADO){ MostrarErrorLectura(); } else{ switch(port) { case PUERTO_BASE: switch(orden) { case 0: case 1: case 2: case 3: case 4: dato = ArmarDatoPuerto(PUERTO_BASE, PISO0, ASCE0, SINC_NOT_EQUAL_01, FIN_ON); break; case 5: case 6: case 7: case 8: case 9: dato = ArmarDatoPuerto(PUERTO_BASE, PISO0, ASCE1, SINC_EQUAL_00, FIN_OFF); break; case 10: case 11: case 12: case 13: case 14: dato = ArmarDatoPuerto(PUERTO_BASE, PISO0, ASCE0, SINC_NOT_EQUAL_10, FIN_ON); break; case 15: case 16: case 17: case 18: case 19: dato = ArmarDatoPuerto(PUERTO_BASE, PISO4, ASCE3, SINC_EQUAL_11, FIN_OFF); break; case 20: case 21: case 22: case 23: case 24: dato = ArmarDatoPuerto(PUERTO_BASE, PISO0, ASCE0, SINC_NOT_EQUAL_01, FIN_ON); break; case 25: case 26: case 27: case 28: case 29: dato = ArmarDatoPuerto(PUERTO_BASE, PISO19, ASCE2, SINC_EQUAL_00, FIN_OFF); break; case 30: case 31: case 32: case 33: case 34: dato = ArmarDatoPuerto(PUERTO_BASE, PISO0, ASCE0, SINC_NOT_EQUAL_10, FIN_ON); break; case 35: case 36: case 37: case 38: case 39: dato = ArmarDatoPuerto(PUERTO_BASE, PISO15, ASCE5, SINC_EQUAL_11, FIN_OFF); break; case 40: case 41: case 42: case 43: case 44: dato = ArmarDatoPuerto(PUERTO_BASE, PISO0, ASCE0, SINC_NOT_EQUAL_01, FIN_ON); break; case 45: case 46: case 47: case 48: case 49: dato = ArmarDatoPuerto(PUERTO_BASE, PISO22, ASCE4, SINC_EQUAL_00, FIN_OFF); break; case 50: case 51: case 52: case 53: case 54: dato = ArmarDatoPuerto(PUERTO_BASE, PISO0, ASCE0, SINC_NOT_EQUAL_10, FIN_ON); break; case 55: case 56: case 57: case 58: case 59: dato = ArmarDatoPuerto(PUERTO_BASE, PISO11, ASCE7, SINC_EQUAL_11, FIN_OFF); break; case 60: case 61: case 62: case 63: case 64: dato = ArmarDatoPuerto(PUERTO_BASE, PISO0, ASCE0, SINC_NOT_EQUAL_01, FIN_ON); break; case 65: case 66: case 67: case 68: case 69: dato = ArmarDatoPuerto(PUERTO_BASE, PISO4, ASCE3, SINC_EQUAL_00, FIN_OFF); break; case 70: case 71: case 72: case 73: case 74: dato = ArmarDatoPuerto(PUERTO_BASE, PISO0, ASCE0, SINC_NOT_EQUAL_10, FIN_ON); break; case 75: case 76: case 77: case 78: case 79: dato = ArmarDatoPuerto(PUERTO_BASE, PISO22, ASCE4, SINC_EQUAL_11, FIN_OFF); break; case 80: case 81: case 82: case 83: case 84: dato = ArmarDatoPuerto(PUERTO_BASE, PISO0, ASCE0, SINC_NOT_EQUAL_01, FIN_ON); break; case 85: case 86: case 87: case 88: case 89: dato = ArmarDatoPuerto(PUERTO_BASE, PISO31, ASCE0, SINC_EQUAL_00, FIN_OFF); break; case 90: case 91: case 92: case 93: case 94: dato = ArmarDatoPuerto(PUERTO_BASE, PISO0, ASCE0, SINC_NOT_EQUAL_10, FIN_ON); break; case 95: case 96: case 97: case 98: case 99: dato = ArmarDatoPuerto(PUERTO_BASE, PISO22, ASCE4, SINC_EQUAL_11, FIN_OFF); break; case 100: case 101: case 102: case 103: case 104: dato = ArmarDatoPuerto(PUERTO_BASE, PISO0, ASCE0, SINC_NOT_EQUAL_01, FIN_ON); break; case 105: case 106: case 107: case 108: case 109: dato = ArmarDatoPuerto(PUERTO_BASE, PISO0, ASCE4, SINC_EQUAL_00, FIN_OFF); break; case 110: case 111: case 112: case 113: case 114: dato = ArmarDatoPuerto(PUERTO_BASE, PISO0, ASCE0, SINC_NOT_EQUAL_10, FIN_ON); break; case 115: case 116: case 117: case 118: case 119: dato = ArmarDatoPuerto(PUERTO_BASE, PISO11, ASCE6, SINC_EQUAL_11, FIN_OFF); break; case 120: case 121: case 122: case 123: case 124: dato = ArmarDatoPuerto(PUERTO_BASE, PISO0, ASCE0, SINC_NOT_EQUAL_01, FIN_ON); break; case 125: case 126: case 127: case 128: case 129: dato = ArmarDatoPuerto(PUERTO_BASE, PISO0, ASCE0, SINC_EQUAL_00, FIN_ON); break; default: dato = ArmarDatoPuerto(PUERTO_BASE, PISO0, ASCE0, SINC_EQUAL_00, FIN_ON); } break; case (PUERTO_BASE + 1): switch(orden) { case 0: case 1: case 2: case 3: case 4: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO0, ASCE0, SINC_NOT_EQUAL_01, FIN_ON); break; case 5: case 6: case 7: case 8: case 9: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO0, ASCE1, SINC_EQUAL_00, FIN_OFF); break; case 10: case 11: case 12: case 13: case 14: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO0, ASCE0, SINC_NOT_EQUAL_10, FIN_ON); break; case 15: case 16: case 17: case 18: case 19: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO4, ASCE3, SINC_EQUAL_11, FIN_OFF); break; case 20: case 21: case 22: case 23: case 24: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO0, ASCE0, SINC_NOT_EQUAL_01, FIN_ON); break; case 25: case 26: case 27: case 28: case 29: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO19, ASCE2, SINC_EQUAL_00, FIN_OFF); break; case 30: case 31: case 32: case 33: case 34: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO0, ASCE0, SINC_NOT_EQUAL_10, FIN_ON); break; case 35: case 36: case 37: case 38: case 39: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO15, ASCE5, SINC_EQUAL_11, FIN_OFF); break; case 40: case 41: case 42: case 43: case 44: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO0, ASCE0, SINC_NOT_EQUAL_01, FIN_ON); break; case 45: case 46: case 47: case 48: case 49: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO22, ASCE4, SINC_EQUAL_00, FIN_OFF); break; case 50: case 51: case 52: case 53: case 54: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO0, ASCE0, SINC_NOT_EQUAL_10, FIN_ON); break; case 55: case 56: case 57: case 58: case 59: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO11, ASCE7, SINC_EQUAL_11, FIN_OFF); break; case 60: case 61: case 62: case 63: case 64: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO0, ASCE0, SINC_NOT_EQUAL_01, FIN_ON); break; case 65: case 66: case 67: case 68: case 69: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO4, ASCE3, SINC_EQUAL_00, FIN_OFF); break; case 70: case 71: case 72: case 73: case 74: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO0, ASCE0, SINC_NOT_EQUAL_10, FIN_ON); break; case 75: case 76: case 77: case 78: case 79: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO22, ASCE4, SINC_EQUAL_11, FIN_OFF); break; case 80: case 81: case 82: case 83: case 84: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO0, ASCE0, SINC_NOT_EQUAL_01, FIN_ON); break; case 85: case 86: case 87: case 88: case 89: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO31, ASCE0, SINC_EQUAL_00, FIN_OFF); break; case 90: case 91: case 92: case 93: case 94: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO0, ASCE0, SINC_NOT_EQUAL_10, FIN_ON); break; case 95: case 96: case 97: case 98: case 99: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO22, ASCE4, SINC_EQUAL_11, FIN_OFF); break; case 100: case 101: case 102: case 103: case 104: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO0, ASCE0, SINC_NOT_EQUAL_01, FIN_ON); break; case 105: case 106: case 107: case 108: case 109: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO0, ASCE4, SINC_EQUAL_00, FIN_OFF); break; case 110: case 111: case 112: case 113: case 114: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO0, ASCE0, SINC_NOT_EQUAL_10, FIN_ON); break; case 115: case 116: case 117: case 118: case 119: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO11, ASCE6, SINC_EQUAL_11, FIN_OFF); break; case 120: case 121: case 122: case 123: case 124: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO0, ASCE0, SINC_NOT_EQUAL_01, FIN_ON); break; case 125: case 126: case 127: case 128: case 129: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO0, ASCE0, SINC_EQUAL_00, FIN_ON); break; default: dato = ArmarDatoPuerto(PUERTO_BASE + 1, PISO0, ASCE0, SINC_EQUAL_00, FIN_ON); } break; default: dato=0; /*En el caso de que existiese otro puerto habilitado, se devuelve 0.*/ break; } orden ++; } return dato; } /** @} doxygen end group definition */ /*==================[fin del archivo]============================================*/
Compartir