diff --git a/mpu_user_console_etu/labo5_mpu_user_console_etu/src/mpu_user_console_etu.c b/mpu_user_console_etu/labo5_mpu_user_console_etu/src/mpu_user_console_etu.c
index 3e7bd270e72639dfc2f82c957c590746be578ba9..27e16844ac1468844e082c022f6ba119151bfe07 100644
--- a/mpu_user_console_etu/labo5_mpu_user_console_etu/src/mpu_user_console_etu.c
+++ b/mpu_user_console_etu/labo5_mpu_user_console_etu/src/mpu_user_console_etu.c
@@ -55,17 +55,19 @@ void MemManage_Handler()
 	// Acknowledge du registre CFSR
 	SCB->CFSR = 0xFFFF;
 
-
 // Instructions assembleur foncionnelles
 //	__asm volatile(
-//			"mrs r0, psp\n"
-//			"ldr r1, =user_starting_address\n" // recup le pointeur vers l'adresse de retour souhaitée
-//			"ldr r1, [r1]\n"			// deref le pointeur pour recup l'adresse de retour
+//	    "mrs r0, psp\n"                    // Charger la valeur du pointeur de pile du processus (PSP) dans r0
+//	    "ldr r1, =user_starting_address\n" // Charger l'adresse de user_starting_address dans r1
+//	                                       // Cette adresse est actuellement stockée comme une valeur immédiate
+//	    "ldr r1, [r1]\n"                    // Dé-référencer le pointeur pour obtenir la véritable adresse de retour
+//	                                       // Maintenant, r1 contient l'adresse souhaitée de retour
 //	);
 
-// Instruction assembleur : Crée un hardfault
+
+// Instruction assembleur, erreur : crée un hardfault
 //	__asm volatile(
-//			"str r1, [r0, #24]\n"
+//		    "str r1, [r0, #24]\n"               // Stocker la valeur de r1 à l'adresse PSP + 24 (espace réservé pour le registre PC)
 //	);
 }
 
@@ -84,10 +86,10 @@ void test_user_mode()
 	int n;
 
 	for (n=0; n<3; n++);	// OK
-//	LPC_GPIO2->FIOPIN=0xaa;	// not OK (read only)
+	LPC_GPIO2->FIOPIN=0xaa;	// not OK (read only)
 	a=LPC_GPIO2->FIOPIN;	// OK
 	a=*p_sram2;				// OK (unprivileged read only)
-//	*p_sram2=5;				// not OK (privileged only for writing)
+	*p_sram2=5;				// not OK (privileged only for writing)
 	n=LPC_TIM0->TC;			// not OK (privileged access only)
 }
 struct __FILE { int handle; /* Add whatever you need here */ };
diff --git a/mpu_user_console_etu/labo5_mpu_user_console_etu/src/user_cmd.c b/mpu_user_console_etu/labo5_mpu_user_console_etu/src/user_cmd.c
index 0905fd257988326730be5fcce818ccd6b6596447..af382e021eec6a9d2055395093cd50b449daf72e 100644
--- a/mpu_user_console_etu/labo5_mpu_user_console_etu/src/user_cmd.c
+++ b/mpu_user_console_etu/labo5_mpu_user_console_etu/src/user_cmd.c
@@ -17,9 +17,30 @@
 									"<8 characters hexadecimal address>=<8 characters hexadecimal value> for writing\n");
 bool is_supervisor_mode=false;
 
+extern uint32_t * error_adresses;
+extern uint32_t * error_codes;
+extern uint32_t error_count;
+
+extern void switch_to_user_mode();
+
 void SVC_Handler()
 {
-	// to be filled for exercise 4
+	// Si le mode superviseur est actif
+	if (is_supervisor_mode)
+	{
+		// Passe en mode utilisateur
+		switch_to_user_mode();
+	}
+	else
+	{
+		// Active le mode superviseur en écrivant 0 dans le registre controle
+		__asm volatile(
+				"mov r0, #0\n"
+				"msr control, r0\n"
+				);
+	}
+
+	is_supervisor_mode = !is_supervisor_mode;
 }
 
 
@@ -34,41 +55,59 @@ void exec_user_read_write()
 	fflush(stdin);
 	fscanf(stdin, "%s",str);
 
-	for (i=0; i<strlen(str); i++)
+	// Si l'utilisateur entre la commande switch
+	if (strcmp(str, "switch") == 0)
+	{
+		__asm volatile("svc 0\n");
+	}
+	// Si l'utilisateur entre la commande status
+	else if (strcmp(str, "status") == 0)
 	{
-		if (str[i] == ',')
+		PRINT("Error list (total : %d) :\n", error_count);
+		for (int i = 0; i < error_count; i++)
 		{
-			if (i==0 || ++coma_nb>1)
+			PRINT("%d) Error address : %d | Code : %d\n", i, error_adresses[i], error_codes[i]);
+		}
+	}
+	// Si l'utilisateur entre n'importe quelle autre commande
+	else
+	{
+		for (i=0; i<strlen(str); i++)
 			{
-				PRINT_SYNTAX_ERROR();
-				return;
+				if (str[i] == ',')
+				{
+					if (i==0 || ++coma_nb>1)
+					{
+						PRINT_SYNTAX_ERROR();
+						return;
+					}
+					str[i]=0;
+					value_idx=i+1;
+				} else if (!isxdigit(str[i]))
+				{
+					PRINT_SYNTAX_ERROR();
+					return;
+				}
 			}
-			str[i]=0;
-			value_idx=i+1;
-		} else if (!isxdigit(str[i]))
+		if ((coma_nb&(i<2)) || i>17)
 		{
 			PRINT_SYNTAX_ERROR();
+			PRINT("(Bad length!)");
 			return;
 		}
-	}
-	if ((coma_nb&(i<2)) || i>17)
-	{
-		PRINT_SYNTAX_ERROR();
-		PRINT("(Bad length!)");
-		return;
-	}
 
-	sscanf(str, "%x", &addr);
-	if (!coma_nb)					// if read
-	{
-		PRINT("reading address: 0x%08x\n", addr);
-		PRINT("value read: 0x%08x\n", *(unsigned *)addr);
-	}
-	else							// write
-	{
-		sscanf(str+value_idx, "%x", &value);
-		PRINT("writing address: 0x%08x with 0x%08x\n", addr, value);
-		*(unsigned *)addr=value;
+		sscanf(str, "%x", &addr);
+		if (!coma_nb)					// if read
+		{
+			PRINT("reading address: 0x%08x\n", addr);
+			PRINT("value read: 0x%08x\n", *(unsigned *)addr);
+		}
+		else							// write
+		{
+			sscanf(str+value_idx, "%x", &value);
+			PRINT("writing address: 0x%08x with 0x%08x\n", addr, value);
+			*(unsigned *)addr=value;
+		}
 	}
 }