Browse Source

a temporary workaround for handling concurrent access to the UART when it is used for trace output:
- write data directly to the FIFO in PsUart.SendChar
- use spin lock in PsSerials.Port.SendChar

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@7982 8c9fc860-2736-0410-a75d-ab315db34111

eth.morozova 7 years ago
parent
commit
a2bd0a4a7c
2 changed files with 28 additions and 5 deletions
  1. 6 1
      ARM/ARM.A2/Zynq.PsSerials.Mod
  2. 22 4
      ARM/ARM.A2/Zynq.PsUart.Mod

+ 6 - 1
ARM/ARM.A2/Zynq.PsSerials.Mod

@@ -1,11 +1,13 @@
 MODULE PsSerials; (** AUTHOR "Timothée Martiel, 11/2017"; PURPOSE "Serial interface for Zynq PS UARTs"; *)
 MODULE PsSerials; (** AUTHOR "Timothée Martiel, 11/2017"; PURPOSE "Serial interface for Zynq PS UARTs"; *)
 
 
-IMPORT Platform, BootConfig, Modules, Strings, PsUartMin, PsUart, Serials, Objects;
+IMPORT Platform, BootConfig, Modules, Strings, PsUartMin, PsUart, Serials, Objects, Machine;
 
 
 TYPE
 TYPE
 	Port = OBJECT (Serials.Port)
 	Port = OBJECT (Serials.Port)
 	VAR
 	VAR
 		uart: PsUart.UartController;
 		uart: PsUart.UartController;
+		
+		sendCharLock := FALSE : BOOLEAN;
 
 
 		PROCEDURE & Init (id: LONGINT);
 		PROCEDURE & Init (id: LONGINT);
 		BEGIN
 		BEGIN
@@ -46,8 +48,11 @@ TYPE
 
 
 		PROCEDURE SendChar(char: CHAR; VAR res: LONGINT);
 		PROCEDURE SendChar(char: CHAR; VAR res: LONGINT);
 		BEGIN
 		BEGIN
+			Machine.AcquireObject(sendCharLock);
 			(*! use Yield0 method to make sure no low-level lock is acquired here - required when used as trace output *)
 			(*! use Yield0 method to make sure no low-level lock is acquired here - required when used as trace output *)
 			PsUart.SendChar(uart, char, TRUE, Yield0, res);
 			PsUart.SendChar(uart, char, TRUE, Yield0, res);
+		FINALLY
+			Machine.ReleaseObject(sendCharLock);
 		END SendChar;
 		END SendChar;
 
 
 		PROCEDURE Send(CONST buf: ARRAY OF CHAR; ofs, len: LONGINT; propagate: BOOLEAN; VAR res: LONGINT);
 		PROCEDURE Send(CONST buf: ARRAY OF CHAR; ofs, len: LONGINT; propagate: BOOLEAN; VAR res: LONGINT);

+ 22 - 4
ARM/ARM.A2/Zynq.PsUart.Mod

@@ -309,10 +309,20 @@ VAR
 		res: error code, 0 in case of success
 		res: error code, 0 in case of success
 	*)
 	*)
 	PROCEDURE SendChar*(uart: UartController; ch: CHAR; propagate: BOOLEAN; onBusy: UartMin.BusyLoopCallback; VAR res: LONGINT);
 	PROCEDURE SendChar*(uart: UartController; ch: CHAR; propagate: BOOLEAN; onBusy: UartMin.BusyLoopCallback; VAR res: LONGINT);
-	TYPE ArrayOfChar1 = ARRAY 1 OF CHAR;
+	BEGIN
+		(*! for the moment just write directly to the FIFO *)
+		res := 0;
+		WHILE uart.open DO
+			IF ~(UartMin.XUARTPS_SR_TNFUL IN uart.regs.sr) THEN
+				uart.regs.fifo := ORD(ch); RETURN;
+			END;
+		END;
+		
+		res := UartMin.Closed;
+	(*TYPE ArrayOfChar1 = ARRAY 1 OF CHAR;
 	BEGIN
 	BEGIN
 		(*!TODO: do not use interrupts here to avoid problems when SendChar is used for trace output *)
 		(*!TODO: do not use interrupts here to avoid problems when SendChar is used for trace output *)
-		Send(uart, SYSTEM.VAL(ArrayOfChar1,ch), 0, 1, propagate, onBusy, res);
+		Send(uart, SYSTEM.VAL(ArrayOfChar1,ch), 0, 1, propagate, onBusy, res);*)
 	END SendChar;
 	END SendChar;
 
 
 	(**
 	(**
@@ -507,13 +517,21 @@ VAR
 	PROCEDURE Show*;
 	PROCEDURE Show*;
 	BEGIN
 	BEGIN
 		IF uarts[0] # NIL THEN
 		IF uarts[0] # NIL THEN
-			Trace.StringLn("PS UART0 registers:");
+			Trace.StringLn("PS UART0:");
 			PrintRegisters(uarts[0].regs);
 			PrintRegisters(uarts[0].regs);
+			Trace.String("rxBufRdPos="); Trace.Int(uarts[0].rxBufRdPos,0); Trace.Ln;
+			Trace.String("rxBufWrPos="); Trace.Int(uarts[0].rxBufWrPos,0); Trace.Ln;
+			Trace.String("txBufRdPos="); Trace.Int(uarts[0].txBufRdPos,0); Trace.Ln;
+			Trace.String("txBufWrPos="); Trace.Int(uarts[0].txBufWrPos,0); Trace.Ln;
 			Trace.Ln;
 			Trace.Ln;
 		END;
 		END;
 		IF uarts[1] # NIL THEN
 		IF uarts[1] # NIL THEN
-			Trace.StringLn("PS UART1 registers:");
+			Trace.StringLn("PS UART1:");
 			PrintRegisters(uarts[1].regs);
 			PrintRegisters(uarts[1].regs);
+			Trace.String("rxBufRdPos="); Trace.Int(uarts[1].rxBufRdPos,0); Trace.Ln;
+			Trace.String("rxBufWrPos="); Trace.Int(uarts[1].rxBufWrPos,0); Trace.Ln;
+			Trace.String("txBufRdPos="); Trace.Int(uarts[1].txBufRdPos,0); Trace.Ln;
+			Trace.String("txBufWrPos="); Trace.Int(uarts[1].txBufWrPos,0); Trace.Ln;
 			Trace.Ln;
 			Trace.Ln;
 		END;
 		END;