agrego practicas

This commit is contained in:
2026-10-31 11:14:30 -03:00
parent 392cf493d1
commit f4f56db493
50 changed files with 1899 additions and 0 deletions
+347
View File
@@ -0,0 +1,347 @@
/* =========================================================================
* PROYECTO: Sistema de Registro y Telemetría para el Nanosatélite "Andrómeda-1"
* -------------------------------------------------------------------------
* CONTEXTO:
* La Agencia Espacial Experimental está desarrollando el software de a bordo
* para su próximo nanosatélite. El sistema necesita gestionar memoria de
* forma dinámica y eficiente debido a los recursos limitados del microcontrolador
* y a la naturaleza impredecible de las ráfagas de datos en órbita.
*
* OBJETIVO:
* Diseñar e implementar un programa en lenguaje C que resuelva los siguientes
* módulos de gestión de memoria dinámica requeridos por la estación de tierra:
*
* 1. Vector Dinámico Básico (Canales de Sensores):
* Pide al operador un número N de canales activos, utiliza malloc para
* reservar un arreglo de enteros con las lecturas iniciales, muéstralo en
* consola y libera correctamente la memoria con free al terminar.
*
* 2. Cadenas Dinámicas (Identificadores de Misión):
* Escribe una función que reciba una cadena estática (char *) con el nombre
* de código del satélite, calcule su longitud exacta, reserve espacio
* dinámicamente con malloc, copie la cadena y devuelva el nuevo puntero
* dinámico para ser registrado en los logs del sistema.
*
* 3. Estructura Dinámica (Buffer de Archivos de Telemetría):
* Define una struct Archivo que contenga dos campos: size_t tamano y
* uint8_t *datos. Escribe una función que reciba el tamaño deseado y reserve
* memoria dinámicamente tanto para la estructura en sí como para su búfer
* interno de datos binarios.
*
* 4. Redimensionamiento con realloc (Stream de Datos en Tiempo Real):
* Crea una rutina que lea números enteros (paquetes de telemetría) desde
* la consola de forma indefinida hasta una condición de parada. Almacénalos
* en un arreglo dinámico que duplique su tamaño cada vez que se llene
* utilizando realloc para optimizar el almacenamiento.
*
* 5. Estructuras Anidadas Dinámicas (Subsistemas del Satélite):
* Crea una estructura principal (por ejemplo, MisionEspacial) que contenga
* un puntero a un arreglo dinámico de subestructuras (representando varios
* subsistemas como energía, propulsión y comunicación). Asegúrate de
* implementar un protocolo estricto de liberación en orden inverso
* (primero las subestructuras internas y sus recursos, luego el arreglo
* principal) para evitar fugas de memoria (memory leaks) críticas en órbita.
*
* REQUISITOS TÉCNICOS:
* - Uso obligatorio de las funciones de <stdlib.h> (malloc, realloc, free).
* - Validación de punteros (verificar que no sean NULL tras cada reserva).
* - Código limpio, modularizado en funciones y bien comentado.
* ========================================================================= */
#include <stddef.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct{
size_t size;
uint8_t *datos;
}TelemetryFile;
typedef struct{
TelemetryFile base;
size_t offset;
}TelemetryArray;
typedef struct{
int n_chanels;
int* chanels;
TelemetryFile* telemetry_file;
TelemetryArray telemetry_array;
}ProgramData;
void print_menu(ProgramData *);
void print_data(ProgramData *);
void get_nchanels(ProgramData *);
void get_chanels(ProgramData *);
void get_telemetry_file(ProgramData *);
TelemetryFile* telemetry_file_create(size_t fs);
void telemetry_file_free(ProgramData *);
void get_telemetry_data(ProgramData *);
bool telemetry_array_is_full(ProgramData *);
void telemetry_array_alloc(ProgramData *);
void telemetry_array_free(ProgramData *);
void telemetry_array_set(ProgramData *, uint8_t data);
void free_data(ProgramData*);
void pause(void);
int main(void){
ProgramData data = {
.n_chanels = 0,
.chanels = NULL,
.telemetry_file = NULL,
.telemetry_array = {
.base = {
.size = 0,
.datos = NULL
},
.offset = 0
}
};
print_menu(&data);
free_data(&data);
return 0;
}
void print_menu(ProgramData* ref_data){
int option = 0;
int exit = 0;
system("clear");
printf("MENU DE OPCIONES\n");
printf("\t 1- Cargar canales\n");
printf("\t 2- Mostrar Datos\n");
printf("\t 3- Crear archivo de telemetría\n");
printf("\t 4- Recibir telemetria\n");
printf("\t 5- Salir\n");
scanf("%d", &option);
switch (option) {
case 1:
get_nchanels(ref_data);
get_chanels(ref_data);
break;
case 2:
print_data(ref_data);
break;
case 3:
get_telemetry_file(ref_data);
break;
case 4:
get_telemetry_data(ref_data);
break;
case 5:
exit = 1;
break;
}
if(!exit){
print_menu(ref_data);
}
}
void get_telemetry_data(ProgramData *ref_data){
system("clear");
printf("RECEPCION DE TELEMETRIA\n");
uint8_t read_data;
do{
printf("\nIngresar valor (0 para terminar):");
scanf("%" SCNu8, &read_data);
//printf("Se ha leido: %" SCNu8 "\n", read_data);
if(read_data > 0){
telemetry_array_set(ref_data, read_data);
}
}while(read_data > 0);
}
bool telemetry_array_is_full(ProgramData *ref_data){
uint8_t* start_add = ref_data->telemetry_array.base.datos;
if(start_add == NULL){
return true;
}
uint8_t* end_add = start_add + ref_data->telemetry_array.base.size;
uint8_t* test_add = start_add + ref_data->telemetry_array.offset;
return test_add >= (end_add);
}
void telemetry_array_alloc(ProgramData *ref_data){
//Si esta vacio reserva espacio para uno.
if(ref_data->telemetry_array.base.datos == NULL){
ref_data->telemetry_array.base.datos = malloc(sizeof(uint8_t));
if(ref_data->telemetry_array.base.datos == NULL){
perror("Error asignando memoria para streaming de telemetria.");
exit(1);
}
ref_data->telemetry_array.base.size = 1;
ref_data->telemetry_array.offset = 0;
return;
}
uint8_t* result = realloc(ref_data->telemetry_array.base.datos, ref_data->telemetry_array.base.size * 2);
if(result == NULL){
perror("Error reasignando memoria para streaming de telemetria.");
exit(1);
}
ref_data->telemetry_array.base.datos = result;
ref_data->telemetry_array.base.size *= 2;
printf("La nueva capacidad es: %zu \n", ref_data->telemetry_array.base.size);
}
void telemetry_array_free(ProgramData *ref_data){
if(ref_data->telemetry_array.base.datos == NULL){
free(ref_data->telemetry_array.base.datos);
ref_data->telemetry_array.base.datos = NULL;
}
}
void telemetry_array_set(ProgramData *ref_data, uint8_t data){
if(telemetry_array_is_full(ref_data)){
printf("Esta lleno, vamos a agrandar \n");
telemetry_array_alloc(ref_data);
}
*(ref_data->telemetry_array.base.datos + ref_data->telemetry_array.offset) = data;
ref_data->telemetry_array.offset += 1;
}
void get_telemetry_file(ProgramData *ref_data){
size_t fs;
system("clear");
printf("CREAR ARCHIVO DE TELEMETRIA\n");
printf("\tEnter de size in bytes:");
scanf("%zu", &fs);
telemetry_file_free(ref_data);
ref_data->telemetry_file = telemetry_file_create(fs);
}
void telemetry_file_free(ProgramData *ref_data){
if(ref_data->telemetry_file != NULL){
if(ref_data->telemetry_file->datos != NULL){
free(ref_data->telemetry_file->datos);
ref_data->telemetry_file->datos = NULL;
}
free(ref_data->telemetry_file);
ref_data->telemetry_file = NULL;
}
}
TelemetryFile* telemetry_file_create(size_t fs){
TelemetryFile* telemetry_file = malloc(sizeof(TelemetryFile));
if(telemetry_file == NULL){
perror("Error creating telemetry file.");
exit(1);
}
telemetry_file->size = fs;
telemetry_file->datos = malloc(sizeof(uint8_t)*fs);
if(telemetry_file->datos == NULL){
free(telemetry_file);
telemetry_file = NULL;
perror("Error allocating memory for the buffer to telemetry file.");
exit(1);
}
return telemetry_file;
}
void get_nchanels(ProgramData* ref_data){
system("clear");
int n_chanels = 0;
printf("Cantidad de canales: ");
scanf("%d", &n_chanels);
ref_data->n_chanels = n_chanels;
}
void get_chanels(ProgramData* ref_data){
if(ref_data->chanels != NULL){
free(ref_data->chanels);
ref_data->chanels = NULL;
}
ref_data->chanels = malloc(sizeof(int)*ref_data->n_chanels);
if(ref_data->chanels == NULL){
perror("No se pudo reservar memoria para los canales.");
exit(1);
}
for(int i=0; i < ref_data->n_chanels; i++){
int chanel;
printf("Frecuacia en Mhz del canal%d:", i);
scanf("%d", &chanel);
*(ref_data->chanels + i) = chanel;
}
}
void print_data(ProgramData* ref_data){
system("clear");
printf("DATOS DEL PROGRAMA\n");
printf("Cantidad de canales: %d\n", ref_data->n_chanels);
for (int i=0; i < ref_data->n_chanels; i++){
printf("\t CH %d Mhz\n", *(ref_data->chanels + i));
}
if(ref_data->telemetry_file != NULL){
printf("Archivo de telemetria creado. Size: %zu bytes.\n", ref_data->telemetry_file->size);
}
printf("Datos de telemetria: ");
for(size_t i=0; i < ref_data->telemetry_array.offset; i++){
printf("%" SCNu8 ", ", *(ref_data->telemetry_array.base.datos + i));
}
if(ref_data->telemetry_array.base.size == 0){
printf("No hay datos.");
}
printf("\n");
pause();
}
void free_data(ProgramData* ref_data){
if(ref_data->chanels){
free(ref_data->chanels);
}
telemetry_file_free(ref_data);
telemetry_array_free(ref_data);
}
void pause(void){
// 1. Limpiamos el búfer por si quedó algún caracter pendiente del scanf anterior
int c;
while ((c = getchar()) != '\n' && c != EOF);
// 2. Mostramos el mensaje y esperamos a que el usuario presione Enter de verdad
printf("Presione Enter para continuar...\n");
getchar();
}
BIN
View File
Binary file not shown.