Skip to content

Examen: Parcial 3:2023_05_08:Robótica

Juan Gonzalez-Gomez edited this page May 22, 2023 · 17 revisions

Examen Parcial 3: 2023-05-08. Ingeniería en Robótica Software

  • Tiempo: 60 minutos
  • Descripción: Examen Parcial 3. Laboratorio. Grado de Ingeniería en Robótica Software
  • Fecha: 2023/Mayo/8
  • Temario: Sesiones L8, L9 y L10

Contenido

Enunciado

  • Enunciado (PDF): Enunciado.pdf

  • Plantilla (Zip): Plantillas.zip

  • Tiempo: 1 hora

  • Ficheros a entregar:

    • Del ejercicio 1:
      • random.s
      • 1_main.s
    • Del ejercicio 2:
      • countdown.s
  • Tus programas deben funcionar con sólo esos 3 archivos. No deben depender de ninguno otro (Por tanto, las constantes del sistema operativo las debes definir dentro de ellos)

Programa 1 (6 ptos)

La generación de números aleatorios ha sido uno de los grandes problemas de la computación. Una solución es utilizar sucesiones de números pseudoaleatorios generados a partir de esta expresión:

Xn+1 = (a*Xn + b) mod c

Donde a,b y c son constantes. Xn es un número pseudoaleatorio a partir del cual se calcula el siguiente (xn+1). El valor inicial Xo se denomina semilla

Las operaciones necesarias son la multiplicación, adición y resto (operación módulo). Todas ellas están disponibles en los procesadores RV32IM. Las instrucciones correspondientes son mul, add y rem

Queremos escribir la función random(Xn) que implementa esta expresión. Tiene un único parámetro de entrada, Xn, que es el número pseudoaleatorio actual, y calcula el siguiente usando los coeficientes a=37, b=1373 y c=16

Para probar esta función se utiliza un programa principal que imprime en la consola los 20 primeros números pseudoaleatorios separados por el carácter '-'. Se utiliza como semilla el valor Xo = 3

La salida en la consola debe ser la siguiente:

Figura-1

El código se escribirá en lenguaje ensamblador del procesador RV32IM

Se pide:

a) (3 ptos) Implementar la función random(Xn) en el fichero random.s. Los coeficientes deben estar definidos como las constantes CA, CB y CC en el código. Utilizar la instrucción rem (ver manual) para calcular la operación de módulo

b) (3 ptos) Implementar el programa principal en el fichero 1_main.s. Todas las constantes necesarias para acceder a los servicios del sistema operativo deben estar definidas dentro de este fichero

Programa 2 (4 Ptos)

Nos han contratado como ingenieros software para trabajar en el proyecto Artemis II, que enviará una tripulación a la orbita lunar en 2024. El centro de control de lanzamiento está actualizando sus consolas para usar procesadores RISC-V. Nuestro equipo de ingeniería es el encargado de construir y programar estas nuevas consolas

Nuestro jefe de proyecto nos ha dado la tarea de implementar la función countdown(ini) que muestra una cuenta atrás en un display de 7 segmentos comenzando por el digito ini (0-9). Sólo tiene un parámetro de entrada, y no devuelve ningún valor. Así, si llamamos a la función countdown(3), en el display de 7 segmentos se verán los números 3, 2, 1 y 0. Cada vez que se muestra un dígito, hay que realizar una espera de 500 ms llamando al servicio sleep del sistema operativo

Para mostrar números en el display, otro ingeniero nos ha proporcionado la función digit(n), que muestra el número n en el display (n debe estar en el rango 0-9). Así, digit(7) muestra el número 7 en el display. Esta función se encuentra en el fichero digit.s

Otro ingeniero nos ha proporcionado un programa de pruebas, en el fichero 2_main.s. Este programa pide al usuario el numero de comienzo de la cuenta atrás (0-9), llama a la función countdown() con este número, para iniciar la cuenta atrás en el display, muestra mensajes en la consola y termina. En esta imágen se muestra el resultado una vez finalizada una cuenta atrás de 9:

Figura 2

Y en esta animación se muestra el funcionamiento:

Animacion

Se pide:

  • (4 ptos) Implementa la función countdown(ini) en el fichero countdown.s. Todas las constantes que uses deben estar definidas en el mismo fichero. Usa los ficheros digit.s y 2_main.s para probar tu función, pero NO puedes modificarlos

  • Ficheros dados:

Soluciones

Solución al programa 1

  • Fichero random.s:
	.globl random

	#--- Constantes para la generacion de los numeros aleatorios
	#-- (ESPECIFICACIONES)
	.eqv CA 37    #-- Coeficiente a
	.eqv CB 1373  #-- Coeficiente b
	.eqv CC 16    #-- Coeficiente c

	.text
	
 #-------------------------------------------------
 #-- random(n)
 #-- Calcular el siguiente numero aleatorio a partir
 #-- del actual
 #-- ENTRADA:
 #--   * a0 (n): Numero actual
 #-- SALIDA:
 #-    * Devuelve el valor (CA * n + CB) mod CC
 #--------------------------------------------------- 
random:
	
	#-- Calcular siguiente numero aleatorio
	#-- a0 = (A * a0 + b) mod C
	
	#-- Usamos el propio registro a0 para guardar
	#-- los resultados parciales
	li t1, CA
	mul a0, a0, t1  #-- a0 = A * a0
	
	#-- a0 = (A * a0) + B
	li t1, CB
	add a0,a0,t1
	
	#-- Calcular el resto
	#-- a0 = (A * a0 + B) mod C
	li t1, CC
	rem a0, a0, t1
	
	ret
  • Fichero 1_main.s
#--------------------------
# Programa principal       
#--------------------------
#-- Imprimir 20 numeros aleatorios
#----------------------------------

	#-- Servicios del sistema operativo
	.eqv EXIT 10
	.eqv PRINT_INT 1
	.eqv PRINT_CHAR 11
	
	#-- Cantidad de numeros aleatorios a generar
	.eqv N 20
	
	#-- Semilla a utilizar (primer numero de la secuencia)
	.eqv SEMILLA 3
	
	.text
	
	#-- El registro t0 contiene el numero aleatorio
	#-- Inicialmente se comienza con la semilla
	li t0, SEMILLA
	
	#-- En s0 metemos el contador de numeros
	#-- aleatorios
	li s0, N
	
bucle:
	#-- Imprimir numero aleatorio
	mv a0, t0
	li a7, PRINT_INT
	ecall
	
	#-- Imprimir caracter de separacion
	li a0, '-'
	li a7, PRINT_CHAR
	ecall
	
	#-- Calcular el siguiente numero aleatorio
	#-- a partir del actual
	#-- t0 = random(t0)
	mv a0, t0
	jal random
	
	#-- a0 contiene el nuevo numero aleatorio
	#-- Lo metemos en t0
	mv t0, a0
	
	#-- Queda uno menos por generar
	addi s0, s0, -1
	
	#-- Repetir si el contador es distinto de 0
	bne s0, zero, bucle
	
	#-- Llegamos a 0: Hemos terminado!
	
	#-- Terminar
	li a7, EXIT
	ecall

Solución al programa 2

  • Fichero countdown.s:
	.globl countdown

	#-- Servicio SLEEP del sistema operativo
	.eqv SLEEP 32

	#-- Tiempo de espera en microsegundos
	.eqv TIEMPO_MS 500
	
	.text
#---------------------------------------------------------
#-- Funcion de cuenta atras
#-- counddown(ini)
#--
#-- ENTRADAS:
#--   a0: (ini): Valor inicial de la cuenta atrás (0-9)
#-- SALIDAS:
#--   Ninguna
#--------------------------------------------------------

countdown:

	#-- Reservar espacio para la pila
	addi sp,sp,-16
	
	#-- Guardar direccion de retorno
	sw ra,12(sp)
	
	#-- Meter s0 en la pila para cumplir con el convenio
	sw s0, 0(sp)
	
	#-- Usamos s0 como contador
	#-- Inicializar s0
	mv s0, a0

bucle:	
	#-- Mostrar numero actual en el display
	mv a0, s0
	jal digit
	
	#-- Llamar a sleep
	li a0, TIEMPO_MS
	li a7, SLEEP
	ecall
	
	#-- Comprobar si hemos llegado a 0
	beq s0, zero, fin
	
	#-- Decrementar el contdor
	addi s0,s0,-1
	
	#-- Repetir
	b bucle

fin:

	#-- Recuperar s0
	lw s0, 0(sp)

	#-- Recuperar direccion de retorno
	lw ra,12(sp)
	
	addi sp,sp,16
	ret

Evaluación

La evaluación de los programas se hace en dos fases. Cada una vale la mitad de los puntos:

  • Funcionalidad: Se comprueba si el programa funciona, y si cumple con las especificaciones (Nombre del fichero correcto, ensablado sin errores, sin errores en tiempo de ejecución, resultado correcto, variables definidas en sus posiciones de memoria especificadas, etc). Esto se hace mediante un script de test, que automatiza el proceso

  • Código: Se inspecciona visualmente cómo está hecho el código: código limpio, claro, con comentarios, instrucciones correctas, fallos de programación, etc...

Los ejercicios los han corregido los siguientes profesores:

  • Ejercicio 1: Jose Ignacio Pérez. Sin test automáticos
  • Ejercicio 2: Juan González Gómez. Con test automático

TEST automáticos

El script de test para el Ejercicio 2 está disponible, por si quieres probarlo con tus programas para practicar. También está disponible un mini-script para bajarse el rars 1.5 desde el repositorio de github

Preparando el entorno

Estos scripts se han hecho para ejecutarse en la bash de LINUX

Sigue lo siguientes pasos:

  • Crea un directorio donde se realizarán las pruebas. Por ejemplo Parcial-3
  • Pon en ese directorio el programa realizado: countdown.s, o puedes bajarte el fichero ya solucionados: countdown.s
  • Descomprime el archivo TEST2.zip. Se crea el directorio TEST2. Mete ahí el siguiente fichero:
    • rars1_5.jar --> El simulador RARs

En el directorio TEST2 necesitas tener el RARs. Si ya lo tienes descargado copialo a TEST2. Si no lo tienes, ejecuta el script de descarga (get_rars.sh). Estos son los ficheros de la carpeta Test:

obijuan@Hoth:~/Parcial-3/TEST2
$ ls
digit.s  get_rars.sh  main_TB.s  servicios.s  system.h  TEST-a.sh  test.h

Ejecutamos el script get_rars.sh:

obijuan@Hoth:~/Parcial-3/TEST2
$ ./get_rars.sh 
--2023-05-22 10:45:15--  https://github.com/TheThirdOne/rars/releases/download/v1.5/rars1_5.jar
Resolving github.com (github.com)... 140.82.121.4
[....]
rars1_5.jar                100%[======================================>]   1,76M  9,79MB/s    in 0,2s    
2023-05-22 10:45:16 (22,3 MB/s) - ‘rars1_5.jar’ saved [1843878/1843878]

Para realizar la prueba hay que ejecutar el script TEST-a.sh:

obijuan@Hoth:~/Parcial-3/TEST2
$ bash TEST-a.sh

Esta es la salida:

-----Ejecutando TEST-a-1-----
> ✅️ rars1_5.jar existe
> ✅️ countdown.s existe

> ➡️  PROBANDO: countdown.s
java -jar rars1_5.jar nc me ic 300 main_TB.s ../countdown.s digit.s

> COMPROBANDO VALORES recibidos
> ✅️ Convenio OK!

> Ciclos de ejecución: 134
> ✅️ El programa termina llamando a EXIT

------FIN-------

Al terminar se queda esperando a que apretemos ENTER

El script es muy básico, y no detecta toda la casuistica, pero sí permite detectar las violaciones de las ESPECIFICACIONES

Autores

Licencia

Enlaces

Página principal


Sesiones de Prácticas

P1: Simulador RARs

L1: Práctica 1-1. RARs
L2: Práctica 1-2. Ensamblador
L3: Práctica 1-3. Variables

P2: E/S mapeada. Llamadas al sistema

L4: Pract 2-1. E/S mapeada
L5: Práctica 2-2: Inst. ecall
L6: Prác 2-3: Cadenas

P3: Bucles y Saltos condicionales

L7: Práct 3-1: Bucles y saltos
L8: Práct 3-2: Cadenas II

P4: Subrutinas

L9: Pract 4-1: Subrut. Nivel-1
L10: Pract 4-2: La pila
L11: Pract 4-3: Recursividad

P5: Memoria Dinámica

L12: Pract 5-1. Heap. Listas

VÍDEO DE DESPEDIDA

Ejercicios de examen

Simulacro examen 1
GISAM. Ordinario. 2019-Dic-11
GISAM. Extra. 2020-Jul-03
GISAM. Ordinario. 2021-Ene-21
GISAM. Ordinario. 2022-Ene-10
GISAM. Extra. 2022-Jun-29
GISAM. Parcial 1. 2022-Oct-26
GISAM. Parcial 2. 2022-Nov-30
GISAM. Parcial 3. 2022-Dic-21
GISAM. Parcial 1. 2023-Oct-09
GISAM. Parcial 2. 2023-Nov-11
GISAM. Parcial 3. 2023-Dic-20
GISAM. Extra. 2024-Jun-17
GISAM. Parcial 1. 2024-Oct-14
GISAM. Parcial 2. 2024-Nov-13
GISAM. Parcial 3. 2024-Dic-16
TELECO. Ordinario. 2019-Dic-13
TELECO. Extra. 2020-Jul-07
TELECO. Ordinario. 2021-Ene-21
TELECO. Extra. 2021-Jul-02
TELECO. Ordinario. 2022-Ene-10
TELECO. Extra. 2022-Jun-29
TELECO. Ordinario. 2023-Ene-10
TELECO. Extra. 2023-Jun-29
TELECO. Parcial 1. 2023-Oct-20
TELECO. Parcial 2. 2023-Nov-17
TELECO. Parcial 3. 2023-Dic-22
TELECO. Extra. 2024-Jun-17
TELECO. Parcial 1. 2024-Oct-10
TELECO. Parcial 2. 2024-Nov-21
TELECO. Parcial 3. 2024-Dic-19
Robótica. Ordinario. 2020-Jun-1
Robótica. Extra. 2020-Jul-13
Robótica. Ordinario. 2021-Mayo-20
Robótica. Extra. 2021-Junio-16
Robótica. Parcial 1. 2022-Feb-25
Robótica. Parcial 2. 2022-Abril-1
Robótica. Parcial 3. 2022-Mayo-6
Robótica. Parcial 1. 2023-Feb-27
Robótica. Parcial 2. 2023-Mar-27
Robótica. Parcial 3. 2023-May-08
Robótica. Parcial 1. 2024-Feb-26
Robótica. Parcial 2. 2024-Mar-20
Robótica. Parcial 3. 2024-May-06
Robótica. Extra. 2024-Junio-24
Datos. Parcial 1. 2023-Oct-09
Datos. Parcial 2. 2023-Nov-15
Datos. Parcial 3. 2023-Dic-20
Datos. Parcial 1. 2024-Oct-09
Datos. Parcial 2. 2024-Nov-13

SOLUCIONES

Práctica 1: Sesiones 1,2 y 3
Práctica 2: Sesiones 4, 5 y 6
Práctica 3: Sesiones 7 y 8
Práctica 4: Sesiones 9, 10 y 11
Práctica 5: Sesión 12

Clone this wiki locally