Skip to content

Commit

Permalink
Refactor debugging console to use a queue, fix damn race condition in…
Browse files Browse the repository at this point in the history
… screen buffer
  • Loading branch information
masonticehurst committed Feb 16, 2024
1 parent ecb4e5a commit c124755
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 115 deletions.
23 changes: 15 additions & 8 deletions eRINA_STM32F7/erina_stm32f7.gpr
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
with "config/erina_stm32f7_config.gpr";
with "config/stm32_hal_config.gpr";

project eRINA_STM32F7 is
project ERINA_STM32F7 is

for Target use "arm-eabi";
for Runtime ("Ada") use "embedded-" & stm32_hal_config.DEVICE & "disco";

for Source_Dirs use ("src/", "src/rina", "src/net", "src/net/stm32", "config/");
for Object_Dir use "obj/" & eRINA_STM32F7_Config.Build_Profile;
for Runtime ("ada") use "embedded-" & Stm32_Hal_Config.Device & "disco";
for Source_Dirs use ("src", "src/rina", "src/net", "src/net/stm32", "config");
for Object_Dir use "obj/" & Erina_Stm32F7_Config.Build_Profile;
for Create_Missing_Dirs use "True";
for Exec_Dir use "bin";
for Main use ("demo.adb");

package Compiler is
for Default_Switches ("Ada") use eRINA_STM32F7_Config.Ada_Compiler_Switches & "-mno-unaligned-access";
for Default_Switches ("ada") use Erina_Stm32F7_Config.Ada_Compiler_Switches & "-mno-unaligned-access";
end Compiler;

package Binder is
Expand All @@ -25,7 +24,15 @@ project eRINA_STM32F7 is
end Install;

package Builder is
for Global_Configuration_Pragmas use "gnat.adc";
for Global_Configuration_Pragmas use "gnat.adc";
end Builder;

end eRINA_STM32F7;
package Ide is
for Connection_Tool use "st-util";
for Communication_Protocol use "remote";
for Connection_Config_File use "../../../../../../usr/share/openocd/scripts/board/stm32f7discovery.cfg";
for Program_Host use "localhost:4242";
end Ide;

end ERINA_STM32F7;

10 changes: 5 additions & 5 deletions eRINA_STM32F7/src/net/receiver.adb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ with Net.Protos.Dispatchers;
with Net.Headers;
with Network;
with Debug;
with GUI;

package body Receiver is

Expand Down Expand Up @@ -35,19 +36,18 @@ package body Receiver is
Count : Net.Uint64 := 0;
begin

Debug.Console.Print (Debug.Info, "Initializing Ethernet Controller...");
Debug.Print (Debug.Info, "Initializing Ethernet Controller...");

-- Wait until the Ethernet driver is ready.
Ada.Synchronous_Task_Control.Suspend_Until_True (Ready);

Debug.Console.Print (Debug.Info, "Ethernet Controller Initialized!");

Debug.Print (Debug.Info, "Ethernet Controller Initialized!");
-- Loop receiving packets and dispatching them.
Min_Receive_Time := Us_Time'Last;
Max_Receive_Time := Us_Time'First;

loop

if Packet.Is_Null then
Net.Buffers.Allocate (Packet);
end if;
Expand All @@ -60,7 +60,7 @@ package body Receiver is
if Ether.Ether_Type =
Net.Headers.To_Network (Net.Protos.ETHERTYPE_ARP)
then
Debug.Console.Print (Debug.Info, "ARP Packet Received");
Debug.Print (Debug.Info, "ARP Packet Received (" & Network.Ifnet.Rx_Stats.Ignored'Image & ") total");
Net.Protos.Arp.Receive (Network.Ifnet, Packet);
elsif Ether.Ether_Type =
Net.Headers.To_Network (Net.Protos.ETHERTYPE_RINA)
Expand Down
2 changes: 1 addition & 1 deletion eRINA_STM32F7/src/rina/board.adb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ package body Board is
procedure Pressed is
begin
STM32.Board.All_LEDs_On;
Debug.Console.Print(Debug.Info, "Button pressed!");
Debug.Print(Debug.Info, "Button pressed!");
end Pressed;
end Button_Handler;
end Board;
152 changes: 77 additions & 75 deletions eRINA_STM32F7/src/rina/debug.adb
Original file line number Diff line number Diff line change
@@ -1,96 +1,98 @@
with Bitmapped_Drawing;
with STM32.Board;
with GUI;

package body Debug is

procedure Print (Debug_Level : in Debug; Msg : in String) is
M : Message;

-- These line variables shouldn't be confused with the array of lines that are drawn to the screen
-- This is specifically for strings that are too long to fit on a single line, so they can be broken up
Lines_Count : constant Positive := (Msg'Length + (Max_Characters_Per_Line - 1)) / Max_Characters_Per_Line;
Lines : array(1 .. Lines_Count) of String(1 .. Max_Characters_Per_Line);
Line_Start : Positive := Lines'First;
begin
for I in 1 .. Lines_Count loop
-- Calculate the start of the next line segment. If it's the last segment, it may be shorter.
if Line_Start + Max_Characters_Per_Line - 1 <= Msg'Length then
Lines(I) := Msg(Line_Start .. Line_Start + Max_Characters_Per_Line - 1);
else
-- Last segment, potentially shorter than Max_Characters_Per_Line
declare
Last_Segment : constant String := Msg(Line_Start .. Msg'Last);
Padded_Last_Segment : constant String(1 .. Max_Characters_Per_Line) := (Last_Segment & (Last_Segment'Length + 1 .. Max_Characters_Per_Line => ' '));
begin
Lines(I) := Padded_Last_Segment;
end;

-- Damn why can't it be this simple
-- Lines(I) := Msg(Line_Start .. Msg'Length) & (others => ' '); -- Fill the rest with spaces
end if;
-- Prepare for the next segment
Line_Start := Line_Start + Max_Characters_Per_Line;
end loop;

for I in Lines'Range loop
M.Msg := Lines(I);
M.Level := Debug_Level;

-- Any lines after the first don't have the debug heading
if I > 1 then
M.Cont := True;
end if;

if Messages.Full then
Messages.Pop;
end if;

Messages.Push (M);
end loop;
end Print;

protected body Console is
procedure Print (Debug_Level : in Debug; Msg : in String) is
currentLine : constant Natural :=
(CURRENT_CONSOLE_POSITION.Y - 100) / FONT_HEIGHT; -- zero indexed
Foreground : HAL.Bitmap.Bitmap_Color;
Background : HAL.Bitmap.Bitmap_Color;
begin
procedure Render is
Foreground : HAL.Bitmap.Bitmap_Color;
Background : HAL.Bitmap.Bitmap_Color;
Pos : HAL.Bitmap.Point := Starting_Point;
Msg : Message;
begin
for I in 0 .. Messages.Size - 1 loop
Msg := Messages.Peek (Queue_Max(I));
Pos := (Starting_Point.X, Starting_Point.Y + I * (Font_Height + Line_Padding));

Foreground :=
(case Debug_Level is when Info | Error => HAL.Bitmap.White,
(case Msg.Level is when Info | Error => HAL.Bitmap.White,
when Warning => HAL.Bitmap.Black);

Background :=
(case Debug_Level is when Info => HAL.Bitmap.Blue,
(case Msg.Level is when Info => HAL.Bitmap.Blue,
when Warning => HAL.Bitmap.Yellow, when Error => HAL.Bitmap.Red);

-- Restart X position to start
Pos.X := Starting_Point.X;

if currentLine > MAX_LINES then
-- Shift console lines up
for I in 1 .. MAX_LINES loop
CopyLine (I, I - 1, I = MAX_LINES);
end loop;

-- Adjust Y position to overwrite the last line
CURRENT_CONSOLE_POSITION.Y :=
CURRENT_CONSOLE_POSITION.Y - FONT_HEIGHT - LINE_PADDING;
if not Msg.Cont then
-- Draw debug prefix
Bitmapped_Drawing.Draw_String
(Buffer => GUI.Screen_Buffer.all,
Start =>
GUI.Scale
((Pos.X, Pos.Y)),
Msg => Msg.Level'Image, Font => BMP_Fonts.Font8x8,
Foreground => Foreground, Background => Background);

-- Offset X position for debug level header
Pos.X := Pos.X + GUI.MeasureText (Msg.Level'Image, BMP_Fonts.Font8x8).Width;
end if;

-- Draw debug prefix
Bitmapped_Drawing.Draw_String
(Buffer => GUI.Screen_Buffer.all,
Start =>
GUI.Scale
((CURRENT_CONSOLE_POSITION.X, CURRENT_CONSOLE_POSITION.Y)),
Msg => Debug_Level'Image, Font => BMP_Fonts.Font8x8,
Foreground => Foreground, Background => Background);

-- Draw actual message text
Bitmapped_Drawing.Draw_String
(Buffer => GUI.Screen_Buffer.all,
Start =>
GUI.Scale
((CURRENT_CONSOLE_POSITION.X +
GUI.MeasureText (Debug_Level'Image, BMP_Fonts.Font8x8).Width +
LINE_PADDING * 2,
CURRENT_CONSOLE_POSITION.Y)),
Msg => Msg, Font => BMP_Fonts.Font8x8, Foreground => HAL.Bitmap.White,
((Pos.X + Line_Padding,
Pos.Y)),
Msg => Msg.Msg, Font => BMP_Fonts.Font8x8, Foreground => HAL.Bitmap.White,
Background => HAL.Bitmap.Black);

-- Move the Y position down for the next message
CURRENT_CONSOLE_POSITION.Y :=
CURRENT_CONSOLE_POSITION.Y + FONT_HEIGHT + LINE_PADDING;

STM32.Board.Display.Update_Layer (1, True);
end Print;

procedure CopyLine
(SrcLineNumber : in Natural; DstLineNumer : in Natural;
DeleteSrc : in Boolean)
is
-- TODO: Cleanup later...
srcToPoint : constant HAL.Bitmap.Point :=
(0,
Natural'Min
(CONSOLE_STARTING_POINT.Y +
(FONT_HEIGHT + LINE_PADDING) * SrcLineNumber,
GUI.Board_Resolution.Height - 2));
dstToPoint : constant HAL.Bitmap.Point :=
(0,
Natural'Min
(CONSOLE_STARTING_POINT.Y +
(FONT_HEIGHT + LINE_PADDING) * DstLineNumer,
GUI.Board_Resolution.Height - 2));
srcRect : constant HAL.Bitmap.Rect :=
(Position => srcToPoint, Width => GUI.Board_Resolution.Width,
Height => FONT_HEIGHT + LINE_PADDING);
begin
HAL.Bitmap.Copy_Rect
(Src_Buffer => GUI.Screen_Buffer.all, Src_Pt => srcToPoint,
Dst_Buffer => GUI.Screen_Buffer.all, Dst_Pt => dstToPoint,
Width => GUI.Board_Resolution.Width,
Height => FONT_HEIGHT + LINE_PADDING, Synchronous => True);
if DeleteSrc then
HAL.Bitmap.Fill_Rect
(Buffer => GUI.Screen_Buffer.all, Area => srcRect);
end if;
STM32.Board.Display.Update_Layer (1, True);
end CopyLine;
end Console;

end loop;
end Render;
end Debug;
29 changes: 17 additions & 12 deletions eRINA_STM32F7/src/rina/debug.ads
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
with HAL.Bitmap;
with BMP_Fonts;
with Queues;

package Debug is
type Debug is (Error, Warning, Info);

FONT_HEIGHT : constant Natural :=
Font_Height : constant Natural :=
BMP_Fonts.Char_Height (Font => BMP_Fonts.Font8x8);
MAX_LINES : constant Natural := 20;
LINE_PADDING : constant Natural := 2;
Max_Characters_Per_Line : constant Positive := 50;
Line_Padding : constant Natural := 4;
Starting_Point : constant HAL.Bitmap.Point := (0, 100);
Max_Messages : constant := 14;

protected Console is
procedure Print (Debug_Level : in Debug; Msg : in String);
procedure CopyLine
(SrcLineNumber : in Natural; DstLineNumer : in Natural;
DeleteSrc : in Boolean);
private
CONSOLE_STARTING_POINT : HAL.Bitmap.Point := (0, 100);
CURRENT_CONSOLE_POSITION : HAL.Bitmap.Point := (0, 100);
end Console;
type Message is record
Msg : String(1 .. Max_Characters_Per_Line);
Level : Debug;
Cont : Boolean := False;
end record;

type Queue_Max is mod Max_Messages;
package Message_Queue is new Queues (Queue_Max, Message);
Messages : Message_Queue.Queue;

procedure Print (Debug_Level : in Debug; Msg : in String);
procedure Render;
end Debug;
31 changes: 20 additions & 11 deletions eRINA_STM32F7/src/rina/demo.adb
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,42 @@ with Network;
with STM32;
with STM32.Board;
with Debug;
with Ada.Real_Time; use Ada.Real_Time;

procedure Demo is
Period : constant Time_Span := Milliseconds(1 / GUI.Frame_Rate * 1000);
Next_Render : Time := Clock;
begin
GUI.Initialize;
Network.Initialize;
STM32.Board.Configure_User_Button_GPIO;
STM32.Board.Initialize_LEDs;
STM32.Board.All_LEDs_Off;

-- Keep board from immediately terminating
-- Render loop keeps the board from immediately terminating
loop
Textures.Print (Textures.PSU.Bitmap, (5, 10));

GUI.Print ("eRINA Debug", (80, 15));

GUI.Print
("Ignored Packets: " & Network.Ifnet.Rx_Stats.Ignored'Image,
(80, 30));

GUI.Print
("Status: ",
("Status: ",
(80, 45));

GUI.Print
("Waiting for enrollment request",
("Waiting for enrollment request",
(145, 45));

delay Duration(1.0 / GUI.Frame_Rate);
Textures.Print (Textures.PSU.Bitmap, (5, 10));

GUI.Print
("Ignored Packets: " & Network.Ifnet.Rx_Stats.Ignored'Image,
(80, 30));

Debug.Render;
GUI.Update;

-- Set activation time of next render in loop
Next_Render := Next_Render + Period;

delay until Next_Render;
end loop;
end Demo;
end Demo;
4 changes: 1 addition & 3 deletions eRINA_STM32F7/src/rina/gui.adb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ package body GUI is

procedure Update is
begin
STM32.Board.Display.Update_Layer (1, True);
STM32.Board.Display.Update_Layer (1);
end Update;

procedure Print (Msg : in String; Pos : in HAL.Bitmap.Point) is
Expand All @@ -31,8 +31,6 @@ package body GUI is
(Buffer => Screen_Buffer.all, Start => Scale ((Pos.X, Pos.Y)),
Msg => Msg, Font => BMP_Fonts.Font8x8, Foreground => Foreground,
Background => Background);

Update;
end Print;

procedure Initialize is
Expand Down

0 comments on commit c124755

Please sign in to comment.