fix 0.3.3 OTA update flow for pi (#2048)

* feat: Conver from the copy all bytes over to file-file transer

* use pi-beep

* fix minor mistakes

* recursive rm

* add fs resize

Co-authored-by: BluJ <mogulslayer@gmail.com>
This commit is contained in:
Aiden McClelland
2022-12-15 13:50:21 -07:00
committed by GitHub
parent 4ac61d18ff
commit 3b226dd2c0
5 changed files with 41 additions and 107 deletions

View File

@@ -62,11 +62,11 @@ format:
sdk:
cd backend/ && ./install-sdk.sh
embassyos-raspi.img: all raspios.img cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast
embassyos-raspi.img: all raspios.img cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast cargo-deps/aarch64-unknown-linux-gnu/release/pi-beep
! test -f embassyos-raspi.img || rm embassyos-raspi.img
./build/raspberry-pi/make-image.sh
lite-upgrade.img: raspios.img cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast $(BUILD_SRC) eos.raspberrypi.squashfs
lite-upgrade.img: raspios.img cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast cargo-deps/aarch64-unknown-linux-gnu/release/pi-beep $(BUILD_SRC) eos.raspberrypi.squashfs
! test -f lite-upgrade.img || rm lite-upgrade.img
./build/raspberry-pi/make-upgrade-image.sh
@@ -176,3 +176,6 @@ backend: $(EMBASSY_BINS)
cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast:
./build-cargo-dep.sh nc-broadcast
cargo-deps/aarch64-unknown-linux-gnu/release/pi-beep:
./build-cargo-dep.sh pi-beep

View File

@@ -1,6 +1,5 @@
use std::cmp::Ordering;
use std::path::Path;
use std::time::{Duration, Instant};
use std::time::Duration;
use divrem::DivRem;
use proptest_derive::Arbitrary;
@@ -8,92 +7,24 @@ use tokio::process::Command;
use tracing::instrument;
use crate::util::{FileLock, Invoke};
use crate::{Error, ErrorKind, ResultExt};
use crate::{Error, ErrorKind};
lazy_static::lazy_static! {
static ref SEMITONE_K: f64 = 2f64.powf(1f64 / 12f64);
static ref A_4: f64 = 440f64;
static ref C_0: f64 = *A_4 / SEMITONE_K.powf(9f64) / 2f64.powf(4f64);
static ref EXPORT_FILE: &'static Path = Path::new("/sys/class/pwm/pwmchip0/export");
static ref UNEXPORT_FILE: &'static Path = Path::new("/sys/class/pwm/pwmchip0/unexport");
static ref PERIOD_FILE: &'static Path = Path::new("/sys/class/pwm/pwmchip0/pwm0/period");
static ref DUTY_FILE: &'static Path = Path::new("/sys/class/pwm/pwmchip0/pwm0/duty_cycle");
static ref SWITCH_FILE: &'static Path = Path::new("/sys/class/pwm/pwmchip0/pwm0/enable");
}
pub const SOUND_LOCK_FILE: &'static str = "/etc/embassy/sound.lock";
struct SoundInterface {
use_beep: bool,
guard: Option<FileLock>,
}
impl SoundInterface {
#[instrument]
pub async fn lease() -> Result<Self, Error> {
let guard = FileLock::new(SOUND_LOCK_FILE, true).await?;
if Command::new("which")
.arg("beep")
.invoke(ErrorKind::NotFound)
.await
.is_ok()
{
Ok(SoundInterface {
use_beep: true,
guard: Some(guard),
})
} else {
tokio::fs::write(&*EXPORT_FILE, "0")
.await
.or_else(|e| {
if e.raw_os_error() == Some(16) {
Ok(())
} else {
Err(e)
}
})
.with_ctx(|_| (ErrorKind::SoundError, EXPORT_FILE.to_string_lossy()))?;
let instant = Instant::now();
while tokio::fs::metadata(&*PERIOD_FILE).await.is_err()
&& instant.elapsed() < Duration::from_secs(1)
{
tokio::time::sleep(Duration::from_millis(1)).await;
}
Ok(SoundInterface {
use_beep: false,
guard: Some(guard),
})
}
}
#[instrument(skip(self))]
async fn play_pwm(&mut self, note: &Note) -> Result<(), Error> {
let curr_period = tokio::fs::read_to_string(&*PERIOD_FILE)
.await
.with_ctx(|_| (ErrorKind::SoundError, PERIOD_FILE.to_string_lossy()))?;
if curr_period == "0\n" {
tokio::fs::write(&*PERIOD_FILE, "1000")
.await
.with_ctx(|_| (ErrorKind::SoundError, PERIOD_FILE.to_string_lossy()))?;
}
let new_period = ((1.0 / note.frequency()) * 1_000_000_000.0).round() as u64;
tokio::fs::write(&*DUTY_FILE, "0")
.await
.with_ctx(|_| (ErrorKind::SoundError, DUTY_FILE.to_string_lossy()))?;
tokio::fs::write(&*PERIOD_FILE, format!("{}", new_period))
.await
.with_ctx(|_| (ErrorKind::SoundError, PERIOD_FILE.to_string_lossy()))?;
tokio::fs::write(&*DUTY_FILE, format!("{}", new_period / 2))
.await
.with_ctx(|_| (ErrorKind::SoundError, DUTY_FILE.to_string_lossy()))?;
tokio::fs::write(&*SWITCH_FILE, "1")
.await
.with_ctx(|_| (ErrorKind::SoundError, SWITCH_FILE.to_string_lossy()))?;
Ok(())
}
#[instrument(skip(self))]
async fn stop_pwm(&mut self) -> Result<(), Error> {
tokio::fs::write(&*SWITCH_FILE, "0")
.await
.with_ctx(|_| (ErrorKind::SoundError, SWITCH_FILE.to_string_lossy()))
Ok(SoundInterface { guard: Some(guard) })
}
#[instrument(skip(self))]
pub async fn close(mut self) -> Result<(), Error> {
@@ -109,7 +40,6 @@ impl SoundInterface {
note: &Note,
time_slice: &TimeSlice,
) -> Result<(), Error> {
if self.use_beep {
Command::new("beep")
.arg("-f")
.arg(note.frequency().to_string())
@@ -117,21 +47,6 @@ impl SoundInterface {
.arg(time_slice.to_duration(tempo_qpm).as_millis().to_string())
.invoke(ErrorKind::SoundError)
.await?;
} else {
if let Err(e) = async {
self.play_pwm(note).await?;
tokio::time::sleep(time_slice.to_duration(tempo_qpm) * 19 / 20).await;
self.stop_pwm().await?;
tokio::time::sleep(time_slice.to_duration(tempo_qpm) / 20).await;
Ok::<_, Error>(())
}
.await
{
// we could catch this error and propagate but I'd much prefer the original error bubble up
let _mute = self.stop_pwm().await;
return Err(e);
}
}
Ok(())
}
}
@@ -164,15 +79,8 @@ where
impl Drop for SoundInterface {
fn drop(&mut self) {
let use_beep = self.use_beep;
let guard = self.guard.take();
tokio::spawn(async move {
if !use_beep {
if let Err(e) = tokio::fs::write(&*UNEXPORT_FILE, "0").await {
tracing::error!("Failed to Unexport Sound Interface: {}", e);
tracing::debug!("{:?}", e);
}
}
if let Some(guard) = guard {
if let Err(e) = guard.unlock().await {
tracing::error!("Failed to drop Sound Interface File Lock: {}", e);

View File

@@ -2,10 +2,30 @@
set -e
(
while true; do
beep -r 2 -l 80 -d 20
sleep 60
done
) &
if grep 'cb15ae4d-03' /boot/cmdline.txt; then
BLOCK_COUNT=$(tune2fs -l /dev/mmcblk0p3 | grep "^Block count:" | awk '{print $3}')
BLOCK_SIZE=$(tune2fs -l /dev/mmcblk0p3 | grep "^Block size:" | awk '{print $3}')
cat /dev/mmcblk0p3 | head -c $[$BLOCK_COUNT * $BLOCK_SIZE] > /dev/mmcblk0p4
echo Transfer files across
e2fsck -f -y /dev/mmcblk0p4
while ! resize2fs /dev/mmcblk0p4; do
e2fsck -f -y /dev/mmcblk0p4
done
mkdir -p /media/origin
mkdir -p /media/dest
mount -r /dev/mmcblk0p3 /media/origin
mount -w /dev/mmcblk0p4 /media/dest
rsync -acvAXUH --info=progress2 --delete --force /media/origin/ /media/dest/
umount /media/origin
umount /media/dest
rm -rf /media/origin
rm -rf /media/dest
echo Setting up boot to use other partition
sed -i 's/PARTUUID=cb15ae4d-03/PARTUUID=cb15ae4d-04/g' /boot/cmdline.txt
sync
reboot

View File

@@ -26,9 +26,11 @@ sudo mount $TARGET_NAME $TMPDIR/
sudo mkdir -p $TMPDIR/update
sudo unsquashfs -f -d $TMPDIR/update eos.raspberrypi.squashfs
sudo cp ./cargo-deps/aarch64-unknown-linux-gnu/release/pi-beep $TMPDIR/usr/local/bin/beep
sudo cp ./build/raspberry-pi/033-upgrade.sh $TMPDIR/usr/local/bin/033-upgrade.sh
sudo cp ./build/raspberry-pi/033-upgrade.service $TMPDIR/etc/systemd/system/033-upgrade.service
sudo ln -s /etc/systemd/system/033-upgrade.service $TMPDIR/etc/systemd/system/multi-user.target.wants/033-upgrade.service
sudo cp ./cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast $TMPDIR/usr/local/bin
sudo cp ./build/raspberry-pi/nc-broadcast.service $TMPDIR/etc/systemd/system/nc-broadcast.service
sudo ln -s /etc/systemd/system/nc-broadcast.service $TMPDIR/etc/systemd/system/multi-user.target.wants/nc-broadcast.service

View File

@@ -28,6 +28,7 @@ sudo mkdir $TMPDIR/media/embassy/
sudo ENVIRONMENT=$ENVIRONMENT make V=1 install ARCH=aarch64 OS_ARCH=raspberrypi DESTDIR=$TMPDIR --debug
sudo sed -i 's/raspberrypi/embassy/g' $TMPDIR/etc/hostname
sudo sed -i 's/raspberrypi/embassy/g' $TMPDIR/etc/hosts
sudo cp ./cargo-deps/aarch64-unknown-linux-gnu/release/pi-beep $TMPDIR/usr/local/bin/beep
sudo cp cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast $TMPDIR/usr/local/bin
sudo cp backend/*.service $TMPDIR/etc/systemd/system/
sudo mkdir -p $TMPDIR/etc/embassy