Skip to content

Commit

Permalink
[Prototyping] Reading CPU cycles from CYCCNT
Browse files Browse the repository at this point in the history
We can read the number of CPU cycles, sleep cycles, ld/str waits, etc.
Uses STM32F4's, rarely documented DWT.

Further, various "backports" from main firmware to prototyping.
  • Loading branch information
mbeckersys committed Jul 18, 2017
1 parent 8095410 commit 5f2ec66
Show file tree
Hide file tree
Showing 13 changed files with 541 additions and 93 deletions.
1 change: 1 addition & 0 deletions prototyping/pixracer/src/config/config.ads
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ package Config is

MAIN_TICK_RATE_MS : constant := 10; -- Tickrate in Milliseconds

With_SD_Log : constant Boolean := False;

end Config;
12 changes: 10 additions & 2 deletions prototyping/pixracer/src/driver/cpu.adb
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,26 @@ with HIL.GPIO;
with HIL.Clock;
with HIL.SPI;
with HIL.UART;
with HIL.I2C;
with HIL.Random;
with Ada.Real_Time; use Ada.Real_Time;

package body CPU is

package body CPU with SPARK_Mode is

-- configures hardware registers
procedure initialize is
startup_time : constant Ada.Real_Time.Time := Ada.Real_Time.Clock;
begin
-- Configure GPIO
HIL.Clock.configure;
HIL.GPIO.configure;
HIL.Random.initialize;
HIL.UART.configure;
HIL.GPIO.configure;
HIL.SPI.configure;
-- HIL.I2C.initialize;
delay until startup_time + Ada.Real_Time.Milliseconds (200);
HIL.I2C.initialize;

end initialize;

Expand Down
87 changes: 64 additions & 23 deletions prototyping/pixracer/src/main.adb
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,19 @@ with LED_Manager;
with Buzzer_Manager;
with SDLog;
with ULog;
with STM32.DWT;

package body Main is

ENDL : constant String := (Character'Val (13), Character'Val (10));

procedure Initialize is
success : Boolean := False;
t_next : Ada.Real_Time.Time;
logret : Logger.Init_Error_Code;
begin
CPU.initialize;

STM32.DWT.Enable_Cycle_Counter;

Logger.init (logret);
Logger.log_console (Logger.INFO, "---------------");
Logger.log_console (Logger.INFO, "CPU initialized");
Expand All @@ -40,8 +41,12 @@ package body Main is
Logger.log_console (Logger.INFO, "Initializing NVRAM...");
NVRAM.Init;

Logger.log_console (Logger.INFO, "Start SD Logging...");
Logger.Start_SDLog;
if With_SD_Log then
Logger.log_console (Logger.INFO, "Start SD Logging...");
Logger.Start_SDLog;
else
Logger.log_console (Logger.INFO, "SD Log disabled in config.");
end if;

-- self checks
Logger.log_console (Logger.INFO, "Self-Check NVRAM...");
Expand Down Expand Up @@ -72,18 +77,25 @@ package body Main is


procedure Run_Loop is
-- data : HIL.SPI.Data_Type (1 .. 3) := (others => 0);
-- data_rx : HIL.UART.Data_Type (1 .. 1) := (others => 0);
loop_time_start : Time := Clock;
loop_period : constant Time_Span := Milliseconds (MAIN_TICK_RATE_MS);
loop_next : Time := Clock;

-- gleich : Ada.Real_Time.Time;
-- song : constant Buzzer_Manager.Song_Type := (('c',6),('d',6),('c',6),('f',6));
type prescaler is mod 100;
p : prescaler := 0;
PRESCALER : constant := 100;
type prescaler_t is mod PRESCALER;
p : prescaler_t := 0;

type prescaler_gps is mod 20;
pg : prescaler_gps := 0;
mgps : ULog.Message (ULog.GPS);

-- loop measurements
cycle_begin : Unsigned_32;
cycles_sum : Unsigned_32 := 0;
cycles_avg : Unsigned_32;
cycles_min : Unsigned_32 := Unsigned_32'Last;
cycles_max : Unsigned_32 := Unsigned_32'First;
begin
LED_Manager.Set_Color ((HIL.Devices.RED_LED => False, HIL.Devices.GRN_LED => True, HIL.Devices.BLU_LED => False));
LED_Manager.LED_blink (LED_Manager.SLOW);
Expand All @@ -105,33 +117,62 @@ package body Main is
mgps.lat := 48.15;
mgps.lon := 11.583;
mgps.alt := 560.0;
mgps.gps_week := 1908;
mgps.gps_msec := 0;
mgps.gps_year := 1908;
mgps.gps_month := 1;
mgps.gps_sec := 0;
mgps.fix := 0;
mgps.nsat := 8;

loop
loop_time_start := Clock;
cycle_begin := STM32.DWT.Read_Cycle_Counter;

p := p + 1;
if p = 0 then
Logger.log_console (Logger.INFO, "Logfile size " & SDLog.Logsize'Img & " B");
end if;

pg := pg + 1;
if pg = 0 then
mgps.t := Ada.Real_Time.Clock;
mgps.lat := mgps.lat - 0.1;
mgps.gps_msec := mgps.gps_msec + 100;
Logger.log_sd (msg_level => Logger.SENSOR, message => mgps);
if With_SD_Log then
if p = 0 then
Logger.log_console (Logger.INFO, "Logfile size " & SDLog.Logsize'Img & " B");
end if;

-- fake GPS message to test SD log
pg := pg + 1;
if pg = 0 then
mgps.t := Ada.Real_Time.Clock;
mgps.lat := mgps.lat - 0.1;
mgps.gps_sec := mgps.gps_sec + 1;

Logger.log_sd (msg_level => Logger.SENSOR, message => mgps);
end if;
end if;

-- LED heartbeat
LED_Manager.LED_tick (MAIN_TICK_RATE_MS);
LED_Manager.LED_sync;

declare
cycle_end : constant Unsigned_32 := STM32.DWT.Read_Cycle_Counter;
cycles_loop : constant Unsigned_32 := cycle_end - cycle_begin;
begin
cycles_sum := cycles_sum + cycles_loop;
cycles_min := (if cycles_loop < cycles_min then cycles_loop else cycles_min);
cycles_max := (if cycles_loop > cycles_max then cycles_loop else cycles_max);

if p = 0 then
-- output
cycles_avg := cycles_sum / PRESCALER;
logger.log_console
(Logger.INFO, "Loop min/avg/max cyc: " &
Unsigned_32'Image(cycles_min) &
Unsigned_32'Image(cycles_avg) &
Unsigned_32'Image(cycles_max));
-- reset
cycles_sum := 0;
cycles_min := Unsigned_32'Last;
cycles_max := Unsigned_32'First;
end if;
end;

-- wait remaining loop time
delay until loop_time_start + Milliseconds (MAIN_TICK_RATE_MS);
loop_next := loop_next + loop_period;
delay until loop_next;
end loop;
end Run_Loop;

Expand Down
Loading

0 comments on commit 5f2ec66

Please sign in to comment.