[bootlin/training-materials updates] master: Boot time: new lab for hardware measurement of boot time (7cef1307)

Michael Opdenacker michael.opdenacker at bootlin.com
Sun May 26 23:17:29 CEST 2019


Repository : https://github.com/bootlin/training-materials
On branch  : master
Link       : https://github.com/bootlin/training-materials/commit/7cef1307972584da14c24aef88383a190dcaa41f

>---------------------------------------------------------------

commit 7cef1307972584da14c24aef88383a190dcaa41f
Author: Michael Opdenacker <michael.opdenacker at bootlin.com>
Date:   Sun May 26 23:17:29 2019 +0200

    Boot time: new lab for hardware measurement of boot time
    
    Signed-off-by: Michael Opdenacker <michael.opdenacker at bootlin.com>


>---------------------------------------------------------------

7cef1307972584da14c24aef88383a190dcaa41f
 lab-data/boot-time/arduino/stopwatch/stopwatch.ino | 100 +++++++++++
 .../arduino/test-7segment/test-7segment.ino        |  61 +++++++
 ...fmpeg-first-frame-completion-log-and-gpio.patch |  81 +++++++++
 .../boot-time-hardware-measurement.tex             | 185 +++++++++++++++++++++
 .../nano-7segment.png                              | Bin 0 -> 182899 bytes
 labs/boot-time-hardware-measurement/nano-final.png | Bin 0 -> 184349 bytes
 mk/boot-time.mk                                    |   1 +
 7 files changed, 428 insertions(+)

diff --git a/lab-data/boot-time/arduino/stopwatch/stopwatch.ino b/lab-data/boot-time/arduino/stopwatch/stopwatch.ino
new file mode 100644
index 00000000..31c56c5b
--- /dev/null
+++ b/lab-data/boot-time/arduino/stopwatch/stopwatch.ino
@@ -0,0 +1,100 @@
+/*
+ * TM1637.cpp
+ * A library for the 4 digit display
+ *
+ * Copyright (c) 2012 seeed technology inc.
+ * Website    : www.seeed.cc
+ * Author     : Frankie.Chu
+ * Create Time: 9 April,2012
+ * Change Log :
+ *
+ * Modified by Michael Opdenacker, Bootlin, https://bootlin.com
+ * to display the number of seconds since the Arduino was started.
+ *
+ * The MIT License (MIT)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "TM1637.h"
+#define CLK 2//pins definitions for TM1637 and can be changed to other ports
+#define DIO 3
+TM1637 tm1637(CLK,DIO);
+
+int reset = A0;
+int videoready = A1;
+
+void setup()
+{
+  tm1637.init();
+  tm1637.set(BRIGHTEST);//BRIGHT_TYPICAL = 2,BRIGHT_DARKEST = 0,BRIGHTEST = 7;
+  tm1637.clearDisplay();
+  tm1637.point(false);
+
+  Serial.begin(9600);
+  pinMode(reset, INPUT_PULLUP); // Can't declare pins as pull-down on atmega328p
+  pinMode(videoready, INPUT); // Can't set these as pull-ups as on the other side, BBB GPIO pins are not 5V tolerant
+}
+
+void loop() {
+
+  int resetvalue, videovalue, start_time, elapsed;
+
+  while (true) {
+
+    resetvalue=1024;
+
+    // Waiting for the Beaglebone Black to be resetted (reset taken low)
+    while (resetvalue>100) {
+      resetvalue = analogRead(reset);
+      Serial.print("resetvalue=");
+      Serial.println(resetvalue);
+    }
+
+    // Waiting reset to be released
+    while (resetvalue<100) {
+      resetvalue = analogRead(reset);
+      Serial.print("resetvalue=");
+      Serial.println(resetvalue);
+    }
+
+    start_time=millis();
+    videovalue=0;
+
+    while (videovalue<700) {
+      elapsed = millis() - start_time;
+      if (elapsed > 9999) {
+        tm1637.point(true);
+        tm1637.displayNum(((float) elapsed)/100, 1, false);
+      }
+      else
+        tm1637.displayNum((float) elapsed, 0, false);
+      videovalue = analogRead(videoready);
+      Serial.print("videovalue=");
+      Serial.println(videovalue);
+      delay(10); // Sufficient delay is needed to write to the 7-segment matrix
+
+      // Check a possible reset, meaning we should start over
+      resetvalue = analogRead(reset);
+      if (resetvalue<100 && elapsed>1000) {
+         break;
+      }
+    }
+  }
+}
diff --git a/lab-data/boot-time/arduino/test-7segment/test-7segment.ino b/lab-data/boot-time/arduino/test-7segment/test-7segment.ino
new file mode 100644
index 00000000..b289ff08
--- /dev/null
+++ b/lab-data/boot-time/arduino/test-7segment/test-7segment.ino
@@ -0,0 +1,61 @@
+/*
+ * TM1637.cpp
+ * A library for the 4 digit display
+ *
+ * Copyright (c) 2012 seeed technology inc.
+ * Website    : www.seeed.cc
+ * Author     : Frankie.Chu
+ * Create Time: 9 April,2012
+ * Change Log :
+ *
+ * Modified by Michael Opdenacker, Bootlin, https://bootlin.com
+ * to display the number of seconds since the Arduino was started.
+ *
+ * The MIT License (MIT)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "TM1637.h"
+#define CLK 2//pins definitions for TM1637 and can be changed to other ports
+#define DIO 3
+TM1637 tm1637(CLK,DIO);
+
+void setup()
+{
+  tm1637.init();
+  tm1637.set(BRIGHTEST);//BRIGHT_TYPICAL = 2,BRIGHT_DARKEST = 0,BRIGHTEST = 7;
+  tm1637.clearDisplay();
+  tm1637.point(false);
+}
+
+void loop()
+{
+  float m;
+  while(1)
+  {
+    m=(float) millis();
+    if (m>9999) {
+        tm1637.point(true);
+        tm1637.displayNum(m/100, 1, false);
+    } else {
+        tm1637.displayNum(m, 0, false);
+    }
+  }
+}
diff --git a/lab-data/boot-time/rootfs/data/0001-ffmpeg-first-frame-completion-log-and-gpio.patch b/lab-data/boot-time/rootfs/data/0001-ffmpeg-first-frame-completion-log-and-gpio.patch
new file mode 100644
index 00000000..85c8c6be
--- /dev/null
+++ b/lab-data/boot-time/rootfs/data/0001-ffmpeg-first-frame-completion-log-and-gpio.patch
@@ -0,0 +1,81 @@
+From 294c68c0d0a696ff997363e03dfc7fc430e04ed4 Mon Sep 17 00:00:00 2001
+From: Michael Opdenacker <michael.opdenacker at bootlin.com>
+Date: Fri, 17 May 2019 19:41:49 +0200
+Subject: [PATCH] ffmpeg: first frame completion log and gpio
+
+This writes to the application log  and toggles a GPIO
+after the first frame has been decoded and displayed.
+
+Signed-off-by: Michael Opdenacker <michael.opdenacker at bootlin.com>
+---
+ fftools/ffmpeg.c | 40 ++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 40 insertions(+)
+
+diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
+index 01f04103cf..6e093b843e 100644
+--- a/fftools/ffmpeg.c
++++ b/fftools/ffmpeg.c
+@@ -4648,6 +4648,37 @@ static int transcode_step(void)
+     return reap_filters(0);
+ }
+ 
++// Bootlin hack
++
++static int writefile(const char *filename, const char *s)
++{
++   FILE *f;
++   int r;
++
++   f=fopen(filename, "w");
++
++   if (f==NULL) {
++       av_log(NULL, AV_LOG_ERROR, "Cannot open file: %s\n", filename);
++       return 0;
++   }
++
++   r=fputs(s, f);
++
++   if (r==EOF) {
++       av_log(NULL, AV_LOG_ERROR, "Error writing to file: %s\n", filename);
++       return 0;
++   }
++
++   r=fclose(f);
++
++   if (r==EOF) {
++       av_log(NULL, AV_LOG_ERROR, "Error closing file: %s\n", filename);
++       return 0;
++  }
++
++  return 1;
++}
++
+ /*
+  * The following code is the main loop of the file converter
+  */
+@@ -4659,6 +4690,7 @@ static int transcode(void)
+     InputStream *ist;
+     int64_t timer_start;
+     int64_t total_packets_written = 0;
++    static int framecounter=0;
+ 
+     ret = transcode_init();
+     if (ret < 0)
+@@ -4696,6 +4728,14 @@ static int transcode(void)
+         }
+ 
+         /* dump report by using the output first video and audio streams */
++	// Bootlin hack to signal when the first frame has been decoded
++	if (framecounter++==0) {
++                // Toggle GPIO pin
++                if (writefile("/sys/class/gpio/export", "31\n") && writefile("/sys/class/gpio/gpio31/direction", "out\n"))
++                    writefile("/sys/class/gpio/gpio31/value", "1\n");
++		// Log on console
++		av_log(NULL, AV_LOG_INFO, "First frame decoded!\n");
++	}
+         print_report(0, timer_start, cur_time);
+     }
+ #if HAVE_THREADS
+-- 
+2.17.1
+
diff --git a/labs/boot-time-hardware-measurement/boot-time-hardware-measurement.tex b/labs/boot-time-hardware-measurement/boot-time-hardware-measurement.tex
new file mode 100644
index 00000000..becc95da
--- /dev/null
+++ b/labs/boot-time-hardware-measurement/boot-time-hardware-measurement.tex
@@ -0,0 +1,185 @@
+\subchapter{Measure boot time - Hardware solution}{Objective: measure
+boot time with hardware}
+
+During this lab, we will use a hardware technique to measure boot time,
+from cold boot (or reset) to the instant when the first frame has been
+decoded.
+
+\section{Arduino setup}
+
+Take the Arduino Nano board provided by your instructor. Connect it in
+the middle of the breadboard provided too, so that you can connect
+wires to both sides of the Arduino.
+
+Download the 1.8.9 version of the Arduino IDE from
+\url{https://www.arduino.cc/} (don't use the Arduino
+package in Ubuntu 18.04, as it has issues connecting to the serial port,
+even with root privileges, while the official version works without any problem).
+Extract the archive in \code{/usr/local/}.
+
+Use the provided USB cable to connect the Arduino to your PC, and start the IDE:
+
+\begin{verbatim}
+/usr/local/arduino-1.8.9/arduino
+\end{verbatim}
+
+Now, configure the IDE for your Arduino:
+\begin{itemize}
+\item In \code{Tools}, \code{Board}, select \code{Arduino Nano}
+\item In \code{Tools}, \code{Processor}, select \code{ATmega328p} (or
+      \code{ATmega328p old bootloader} if you have a Nano clone)
+\item In \code{Tools}, \code{Port}, select \code{ttyUSB1} (or
+      \code{ttyUSB0} if the serial line for your Bone Black board is no longer
+      connected.
+\end{itemize}
+
+Now are now ready to use your Arduino board:
+\begin{itemize}
+\item Go to \code{Examples}, \code{01. Basics} and select \code{Blink}.
+      This program allows to blink the LED on the Nano.
+\item Press the \code{Upload} butter and you should see the {\em sketch} work
+(that's how the Arduino community call their programs).
+\item You can now unplug the Arduino and plug it back. The same program
+will be started automatically. Loading a program is just necessary once.
+\end{itemize}
+
+\section{7-segment display setup}
+
+We are going to use a 7-segment display to display time elapsed since
+the last time the Beagle Bone Black board was last reset.
+
+Take the TM1637 module provided by your instructor, and insert its pins
+into the breadboard at a convenient location.
+
+Now, using breadboard wires, connect the \code{GND} pin of the Arduino to one
+of the blue rails of the breadboard, then to the \code{GND} pin of the 7-segment
+module. Please use blue or black wires!
+
+Similarly, connect the \code{5V} pin of the Arduino to the red rail of
+the breadboard, then to the \code{5V} pin of the module. Using red or
+orange wires is recommended too.
+
+Then, you can connect the Arduino \code{D2} pin to the \code{CLK} pin of
+the module, and the \code{D3} pin to the \code{DIO} pin of the module:
+
+\begin{center}
+\includegraphics[width=0.6\textwidth]{labs/boot-time-hardware-measurement/nano-7segment.png}
+\end{center}
+
+Now, let's test your wiring by loading the sketch in
+\code{~/boot-time-labs/arduino/test-7segment/}. Upload and run it.
+
+\section{Configuring Bone Black pins as GPIOs}
+
+Our goal is to measure boot time with the Arduino system, in a way that
+is as accurate as hardware can be, and without having to rely on a slow
+device which is the serial console.
+
+\subsection{Finding a good start signal}
+
+A first possibility would be to watch the 3.3V VDD pins of the Bone
+Black board and start counting when they go high when the board is
+powered on. However, it would be cumbersome to have to power off the
+board each time we wish to make a measurement.
+
+A second possibility is to watch the state of the \code{RESET} signal.
+When this pin goes from high to low, and back to high, it means that the
+board starts booting. That's a good time to start counting, and doing
+it after each reset is a convenient solution.
+
+Look at the Bone Black System Reference and find which pin on the P8 or
+P9 headers is used to expose the \code{SYS_RESET} line.
+
+\subsection{Finding a free pin for the stop signal}
+
+Look at the schematics for the LCD4 cape. Unfortunately, no reference
+manual was ever published for this cape. However, the schematics are
+sufficient to find pins that are not used by the LCD4 cape.
+
+If you look for \code{Bootlin} in the Device Tree Source we provided,
+you can see in the pin definitions sections that we selected pin 13 or
+the P9 headers:
+
+\begin{verbatim}
+// Bootlin: use idle pin as custom GPIO
+0x074 (PIN_OUTPUT | MUX_MODE7)  /* P9_13: uart4_txd_txd.gpio0_31 */
+\end{verbatim}
+
+If you look at the \code{Expansion Header P9 Pinout} table in the
+Board's Reference Manual, you will see that \code{MODE7} allows to get
+GPIO number 31 on P9's pin 13.
+
+Back to the pin for \code{SYS_RESET}, there is nothing to configure to
+get it. It's the only line connected to the pin.
+
+\subsection{Wiring these pins}
+
+We are going the good old wire wrapping technique as shown by the
+instructor to hook up to pins we want to monitor, with a reliable
+connection, but without any soldering.
+
+So, take out the LCD4 cape, find which of its header pins are connected
+to the Bone Black pins we want to monitor, and then use the wire and
+tool provided by the instructor to connect to these pins, because
+re-attaching the LCD4 cape.
+
+On the other end of the cables, your instructor will also give you small
+headers that you can plug into the breadboard holes and do some wiring
+wrapping on them too.
+
+\subsection{Pull up or pull down?}
+
+We need to control the state of the pins we watch when they are not
+driven.
+
+For the \code{SYS_RESET} signal, we are lucky that the ATmega328p CPU
+pins can be configured as pull-down, so we just need to configure them
+in software without having to use our own resistors.
+
+For our custom GPIO pin, there only one choice becase we cannot use
+pull-up. If we used our own resistor, we would have a 5V voltage level
+coming from the Arduino, and the Beagle Bone Black is {\bf not 5V
+tolerant}, as explicited in its manual. Therefore, pull-down is our only
+option. As a consequence, as the Arduino just supports pull-down for
+pins, we will have to use our own pull-down resistors.
+
+Then which Arduino pins to connect to? As the Beagle Bone Black board
+has a 3.3V voltage level, it's best to use the Arduino's Analog pins to
+measure the voltage driven by the Bone Black with precision. We will measure a
+small integer value for 0V, and about 700 (out of a 1024 maximum) for
+3.3V.
+
+So, let's use Arduino pin \code{A0} for reset, and pin \code{A1} for the
+custom GPIO, adding a 1 Kohm pull-down resistor provided by your
+instructor:
+
+\begin{center}
+\includegraphics[width=0.7\textwidth]{labs/boot-time-hardware-measurement/nano-final.png}
+\end{center}
+
+\section{Making ffmpeg drive the custom GPIO}
+
+Once we know how to modify \code{ffmpeg} to write to its output after
+processing the first frame, it's easy to add code that configures our
+custom GPIO line and drives it.
+
+So, modify your Buildroot customizations so that you use the patch
+in
+\code{boot-time-labs/rootfs/data/0001-ffmpeg-first-frame-completion-log-and-gpio.patc}
+instead of the previously used one (look at what it does!).
+
+Rebuild and reflash your root filesystem.
+
+\section{Final version of the Arduino program}
+
+We should now be able to test our full system.  Loading the sketch in
+\code{~/boot-time-labs/arduino/stopwatch/}. Upload and run it.
+
+If things don't work as expected, you can also open the Arduino Serial
+Monitor (in the \code{Tools} menu), and read the pins values that
+displayed there by the program.
+
+Once the system works, is it in line with the software measurements?
+Is it slightly more pessimistic as it's supposed to start counting
+time a few cycles earlier?
+
diff --git a/labs/boot-time-hardware-measurement/nano-7segment.png b/labs/boot-time-hardware-measurement/nano-7segment.png
new file mode 100644
index 00000000..f91e8946
Binary files /dev/null and b/labs/boot-time-hardware-measurement/nano-7segment.png differ
diff --git a/labs/boot-time-hardware-measurement/nano-final.png b/labs/boot-time-hardware-measurement/nano-final.png
new file mode 100644
index 00000000..542b229d
Binary files /dev/null and b/labs/boot-time-hardware-measurement/nano-final.png differ
diff --git a/mk/boot-time.mk b/mk/boot-time.mk
index a000c2f2..9e209d4e 100644
--- a/mk/boot-time.mk
+++ b/mk/boot-time.mk
@@ -34,6 +34,7 @@ BOOT_TIME_LABS = boot-time-goals \
 		boot-time-build-bootloader \
 		boot-time-build-kernel-and-start-system \
 		boot-time-software-measurement \
+		boot-time-hardware-measurement \
 		boot-time-toolchain \
 		boot-time-application \
 		boot-time-init-scripts \




More information about the training-materials-updates mailing list