Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fast-boot configuration #12

Open
SloMusti opened this Issue Dec 15, 2017 · 17 comments

Comments

Projects
None yet
2 participants
@SloMusti
Copy link
Member

SloMusti commented Dec 15, 2017

The goal of the system in configuration where it boots, takes an image with the camera and goes to sleep to achieve that in minimal time of about 8s.

Average power consumption 200mA, 8s duration is about 0.5mAh per boot cycle and thus photo. This allows for about 30000 photos to be taken with 6x 18650 2900mAh battery, assuming no charge.

One example of implementation:
https://www.raspberrypi.org/forums/viewtopic.php?f=43&t=80421

@SloMusti

This comment has been minimized.

@SloMusti

This comment has been minimized.

Copy link
Member Author

SloMusti commented Dec 18, 2017

It may be a good idea that we make the partition /data as in resin that holds all the images, standalone of the system to avoid corruption. Then to make it read-only and go to sleep

@SloMusti

This comment has been minimized.

Copy link
Member Author

SloMusti commented Dec 18, 2017

@SloMusti

This comment has been minimized.

Copy link
Member Author

SloMusti commented Dec 19, 2017

What investigation I have done with resin: balena-os/balena-os#256 (comment)

@gorankecman

This comment has been minimized.

Copy link

gorankecman commented Dec 20, 2017

Following has been tried:

  1. To disable networking as suggested here: https://raspberrypi.stackexchange.com/questions/38660/what-can-i-remove-from-raspbian-to-boot-faster/39527#39527
    but I was not successful.
  2. I have added quiet to /boot/cmdline.txt and that saved ~1.2s of boot time.
  3. I have tried to follow https://hallard.me/raspberry-pi-read-only/ but got some errors for certain commands and it was not successful at the end. System was still in read-write mode.

More time is needed to analyze boot procedure and to see how we can reduce boot time.

@gorankecman

This comment has been minimized.

Copy link

gorankecman commented Dec 20, 2017

On my Pi system, output of systemd-analyze and systemd-analyze blame commands:

$ systemd-analyze
Startup finished in 2.952s (kernel) + 1min 31.619s (userspace) = 1min 34.571s

$ systemd-analyze blame
10.673s dhcpcd.service
6.631s dev-mmcblk0p2.device
4.979s apt-daily.service
4.910s networking.service
3.822s apt-daily-upgrade.service
3.354s keyboard-setup.service
2.945s dphys-swapfile.service
1.739s systemd-logind.service
1.638s rsyslog.service
1.587s systemd-udev-trigger.service
1.507s triggerhappy.service
1.151s systemd-timesyncd.service
1.146s raspi-config.service
1.140s avahi-daemon.service
1.121s alsa-restore.service
1.104s systemd-udevd.service
1.103s systemd-journald.service
954ms fake-hwclock.service
891ms systemd-fsck-root.service
866ms dev-mqueue.mount
853ms sys-kernel-debug.mount
836ms kmod-static-nodes.service
721ms systemd-modules-load.service
703ms systemd-remount-fs.service
691ms systemd-tmpfiles-setup.service
570ms systemd-fsck@dev-disk-by\x2dpartuuid-db1abe6b\x2d01.service
551ms ssh.service
539ms systemd-update-utmp.service
518ms run-rpc_pipefs.mount
512ms systemd-tmpfiles-setup-dev.service
494ms systemd-journal-flush.service
422ms systemd-sysctl.service
380ms sys-kernel-config.mount
372ms console-setup.service
329ms nfs-config.service
291ms systemd-random-seed.service
291ms plymouth-read-write.service
283ms user@1000.service
256ms plymouth-start.service
164ms boot.mount
162ms systemd-user-sessions.service
145ms rc-local.service
130ms plymouth-quit.service
130ms plymouth-quit-wait.service
117ms systemd-update-utmp-runlevel.service
84ms systemd-tmpfiles-clean.service

@gorankecman

This comment has been minimized.

Copy link

gorankecman commented Dec 20, 2017

After adding quiet to /boot/cmdline.txt this is the output of systemd-analyze critical-chain:

graphical.target @1min 31.444s
└─multi-user.target @1min 31.444s
└─ssh.service @21.366s +571ms
└─network.target @21.351s
└─dhcpcd.service @11.851s +9.484s
└─basic.target @10.539s
└─sockets.target @10.538s
└─dbus.socket @10.510s
└─sysinit.target @10.453s
└─systemd-timesyncd.service @9.571s +867ms
└─systemd-tmpfiles-setup.service @8.652s +815ms
└─local-fs.target @8.553s
└─run-user-1000.mount @30.910s
└─local-fs-pre.target @5.260s
└─keyboard-setup.service @1.482s +3.773s
└─systemd-journald.socket @1.373s
└─-.mount @1.163s
└─system.slice @1.315s
└─-.slice @1.163s

@gorankecman

This comment has been minimized.

Copy link

gorankecman commented Dec 21, 2017

For the future reference, following steps have to be done in order to create Ethernet Gadget from RaspberryPi Zero:

  1. Download Raspbian Lite image and "burn" it to SD card as usual.
  2. Add empty file ssh without any extension to /boot/ directory.
  3. Change file /boot/config.txt and at the end, add the line dtoverlay=dwc2.
  4. Change file /boot/cmdline.txt and after the word rootwait add modules-load=dwc2,g_ether

If Raspbian Jessie is used, everything should work. If Raspbian Stretch is used, SSH has to be enabled through raspi-config.
Connection to RaspberryPi should be possible through SSH (ssh pi@<ipaddress> or ssh pi@raspberrypi.local).

@gorankecman

This comment has been minimized.

Copy link

gorankecman commented Dec 21, 2017

We have following conclusions regarding boot time:

  • Out-of-the-box Arch Linux and Raspbian have similar boot times, difference is about 3-4 seconds
  • There are slight differences in boot times when booting for the first time, after shutdown and reboot. The first-time boot is not critical. Difference between shutdown and reboot is ~1s
  • When making RaspberryPi Ethernet Gadget to connect through USB to the PC (avoid USB ethernet adapter) we have successfully achieved standard boot times of the Raspbian Linux (~23s - ~25s)
Arch Linux - first startup
[alarm@alarmpi ~]$ systemd-analyze 
Startup finished in 13.836s (kernel) + 11.915s (userspace) = 25.752s
[alarm@alarmpi ~]$ systemd-analyze blame
          4.485s dev-mmcblk0p2.device
          2.587s systemd-logind.service
          2.318s systemd-user-sessions.service
          1.814s systemd-tmpfiles-setup.service
          1.673s systemd-resolved.service
          1.526s systemd-update-done.service
          1.385s systemd-journal-flush.service
          1.297s systemd-udev-trigger.service
           951ms systemd-journald.service
           803ms systemd-tmpfiles-setup-dev.service
           693ms systemd-timesyncd.service
           651ms user@1000.service
           626ms sys-kernel-debug.mount
           611ms systemd-update-utmp.service
           582ms ldconfig.service
           544ms systemd-udevd.service
           543ms tmp.mount
           539ms dev-mqueue.mount
           477ms kmod-static-nodes.service
           474ms systemd-remount-fs.service
           419ms systemd-journal-catalog-update.service
           387ms systemd-modules-load.service
           360ms systemd-sysctl.service
           350ms systemd-networkd.service
           312ms sys-kernel-config.mount
           308ms systemd-random-seed.service
           282ms boot.mount
           240ms systemd-sysusers.service
Arch Linux - after reboot
[alarm@alarmpi ~]$ systemd-analyze 
Startup finished in 7.866s (kernel) + 11.931s (userspace) = 19.797s
[alarm@alarmpi ~]$ systemd-analyze blame
          4.650s dev-mmcblk0p2.device
          1.819s systemd-udev-trigger.service
          1.468s ldconfig.service
          1.261s systemd-resolved.service
          1.008s systemd-udevd.service
           954ms systemd-tmpfiles-setup.service
           878ms systemd-update-utmp.service
           839ms user@1000.service
           783ms systemd-timesyncd.service
           764ms sys-kernel-debug.mount
           742ms systemd-logind.service
           737ms systemd-remount-fs.service
           713ms systemd-journal-flush.service
           713ms systemd-journald.service
           698ms kmod-static-nodes.service
           610ms systemd-modules-load.service
           453ms dev-mqueue.mount
           451ms systemd-journal-catalog-update.service
           381ms systemd-networkd.service
           317ms systemd-user-sessions.service
           310ms sys-kernel-config.mount
           306ms systemd-sysusers.service
           262ms systemd-update-done.service
           262ms systemd-tmpfiles-setup-dev.service
           247ms systemd-sysctl.service
           244ms boot.mount
           242ms systemd-random-seed.service
           147ms tmp.mount
Arch Linux - after shutdown
[alarm@alarmpi ~]$ systemd-analyze 
Startup finished in 8.985s (kernel) + 11.314s (userspace) = 20.300s
[alarm@alarmpi ~]$ systemd-analyze blame
          3.975s dev-mmcblk0p2.device
          1.821s systemd-udev-trigger.service
          1.542s systemd-timesyncd.service
           995ms systemd-resolved.service
           977ms systemd-update-utmp.service
           912ms systemd-update-done.service
           824ms systemd-journald.service
           703ms systemd-journal-flush.service
           660ms systemd-user-sessions.service
           649ms user@1000.service
           619ms dev-mqueue.mount
           610ms ldconfig.service
           577ms sys-kernel-debug.mount
           566ms systemd-remount-fs.service
           534ms systemd-tmpfiles-setup.service
           517ms systemd-udevd.service
           464ms systemd-journal-catalog-update.service
           422ms systemd-logind.service
           403ms tmp.mount
           397ms kmod-static-nodes.service
           363ms systemd-sysctl.service
           343ms systemd-modules-load.service
           338ms systemd-tmpfiles-setup-dev.service
           299ms systemd-networkd.service
           279ms systemd-random-seed.service
           265ms sys-kernel-config.mount
           236ms systemd-sysusers.service
           201ms boot.mount

Ethernet gadget Raspbian output:

pi@raspberrypi:~ $ systemd-analyze 
Startup finished in 1.680s (kernel) + 21.676s (userspace) = 23.357s
pi@raspberrypi:~ $ systemd-analyze blame
         11.750s dhcpcd.service
          2.019s keyboard-setup.service
          1.951s networking.service
          1.744s systemd-modules-load.service
          1.170s kbd.service
          1.006s systemd-logind.service
           994ms dphys-swapfile.service
           991ms console-setup.service
           878ms alsa-restore.service
           759ms systemd-journal-flush.service
           734ms systemd-fsck-root.service
           674ms triggerhappy.service
           636ms systemd-setup-dgram-qlen.service
           608ms fake-hwclock.service
           591ms raspi-config.service
           562ms avahi-daemon.service
           545ms systemd-fsck@dev-disk-by\x2dpartuuid-2691b8e1\x2d01.service
           479ms dev-mqueue.mount
           468ms systemd-udev-trigger.service
           438ms ntp.service
           365ms systemd-tmpfiles-setup.service
           342ms sys-kernel-debug.mount
           303ms kmod-static-nodes.service
           291ms plymouth-read-write.service
           269ms systemd-remount-fs.service
           247ms plymouth-start.service
           246ms rsyslog.service
           204ms sys-kernel-config.mount
           173ms rc-local.service
           149ms systemd-tmpfiles-setup-dev.service
           135ms plymouth-quit-wait.service
           133ms systemd-update-utmp.service
           116ms systemd-user-sessions.service
           109ms systemd-udevd.service
            99ms plymouth-quit.service
            96ms udev-finish.service
            83ms systemd-random-seed.service
            76ms systemd-sysctl.service
            70ms boot.mount
            68ms systemd-update-utmp-runlevel.service
@gorankecman

This comment has been minimized.

Copy link

gorankecman commented Dec 22, 2017

For the future reference, in order to enable console output, UART should be enabled:

  • Add enable_uart=1 to file /boot/config.txt
    Connect USB-to-UART converter on the Raspberry Pi zero (TX, RX and GND) and configure serial terminal to 115200-8-N-1.
@gorankecman

This comment has been minimized.

Copy link

gorankecman commented Dec 22, 2017

After disabling following services:

dhcpcd.service
networking.service
keyboard-setup.service

we have reduced boot time to:

pi@raspberrypi:~ $ systemd-analyze 
Startup finished in 864ms (kernel) + 8.123s (userspace) = 8.987s

Service is disabled by executing following commands:

sudo systemctl stop <service_name>
sudo systemctl disable <service_name>

Additionally, quiet is added to /boot/cmdline.txt.

@gorankecman

This comment has been minimized.

Copy link

gorankecman commented Dec 22, 2017

Next step is to execute the script to take a photo with the camera at startup and to mark the time. For this, we need to figure out how to startup Pi without the need to type the password.

@gorankecman

This comment has been minimized.

Copy link

gorankecman commented Dec 25, 2017

For documentation purposes:
In order to measure time since login to the first image made, we need to boot Pi without entering login credentials. Since we are currently accessing console through UART, we need to change startup service /lib/systemd/system/serial-getty@.service
Find line:
ExecStart=-/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM
and modify it to:
ExecStart=-/sbin/agetty --autologin pi --keep-baud 115200,38400,9600 %I $TERM

This will prevent Pi from asking for login credentials.

@gorankecman

This comment has been minimized.

Copy link

gorankecman commented Dec 25, 2017

For documentation purposes:
With new init system used - systemd, we needed a way how to execute scripts at startup. In order to do that, we need to create, enable and start service which will be executed during the boot procedure.
First, we need to create file /lib/systemd/system/cameratest.service.
This file should contain following (for bash script):

[Unit]
Description=Camera Test Service
After=multi-user.target

[Service]
Type=idle
ExecStart=/bin/bash /home/pi/test_script.sh

[Install]
WantedBy=multi-user.target

All the paths in the service and script should be absolute paths.
Then, we need to start and enable the service by executing following commands:

sudo systemctl daemon-reload
sudo systemctl enable cameratest.service
sudo systemctl start cameratest.service

After reboot, the system should execute test_script.sh.
In order to measure the time needed to take the first photo, we can create bash script as follows:

#!/bin/bash

raspistill -o /home/pi/startup_image.jpg
systemd-analyze > /home/pi/log.txt
cat /proc/uptime >> /home/pi/log.txt
@gorankecman

This comment has been minimized.

Copy link

gorankecman commented Dec 25, 2017

According to the latest log, startup lasts 9.789s and the first photo is captured after 16.13s.

pi@raspberrypi:~$ cat log.txt
Startup finished in 863ms (kernel) + 8.925s (userspace) = 9.789s
16.13 4.23

Next step is to execute shutdown after taking the photo and to measure how much time we need from the startup until the system shuts down.

@gorankecman

This comment has been minimized.

Copy link

gorankecman commented Dec 26, 2017

After testing with shutdown included in the script following results are acquired:

Startup finished in 864ms (kernel) + 8.903s (userspace) = 9.768s
16.10 4.24 //16.10s is up time since startup until taking the photo is finished.

From the waveform attached, shutdown time can be derived to be ~6s.
shutdown

@gorankecman

This comment has been minimized.

Copy link

gorankecman commented Dec 26, 2017

For documentation purposes:
In case when the network is not available and gpio utility is not installed by default, we can use direct writing to files in order to control GPIO pins.
First we have to execute following commands to set which GPIO pin we want to use (in this case GPIO 16) and which direction that pin should be (output in this case):

sudo echo "16" > /sys/class/gpio/export
sudo echo "out" > /sys/class/gpio/gpio16/direction

Then we can write to this GPIO by executing following commands:

sudo echo "1" > /sys/class/gpio/gpio16/value
sudo echo "0" > /sys/class/gpio/gpio16/value

More info available here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.