Nov 24, 2021 - Hardening Raspberry Pi

Comments

Hardening a Raspberry Pi

…to prevent potential filesystem issues.

A Raspberry Pi can easily end up with a broken filesystem. This is because it continuesly writes data to /tmp and /var/log (SD cards don’t like that), and hard power offs / reboots aren’t unlikely (the filesystem doesn’t like these). There are three measures to prevent that:

1) Use a good, industrial grade SD card. 2) Move /tmp and /var/log into RAM. 3) Enable full journaling on the filesystem.

Move /tmp and /var/log into RAM

Create a /log directory and add this to your /etc/fstab:

tmpfs   /tmp    tmpfs   nodev,nosuid,noatime,size=256M  0   0
tmpfs   /log    tmpfs   nodev,nosuid,noatime,size=256M  0   0

This creates two temporary RAM based filesystems /tmp and /log with 256Mb. Delete /tmp, reboot, then you can also delete /var/log and ln -s /log /var/log (reboot again)

Note: You’ll loose 512Mb of RAM but for a current 4Gb Raspberry Pi 4 that’s acceptable. Also the logs will be lost after each reboot/crash. If you need them for debugging, remove the softlink /var/log again and create the /var/log directory again.

Enable full journaling on the filesystem

For any other than the root partition it’s enough to add the data=journal option to /etc/fstab. But for the root parition you have to set it as default using tune2fs first:

tune2fs -o journal_data /dev/sda1

(given that /dev/sda1 mounted as /)

Then you add data=journal to /etc/fstab:

/dev/sda1  /               ext4    defaults,noatime,data=journal  0       1

May 9, 2021 - Change domain name to floki.cc

Comments

Changed domain to floki.cc. That’s it.

Finally got around to change the domain name from floki.blog to floki.cc . Still a bit annoyed about myself that I got tricked by the cheap initial price for the .blog domain. After the first year it’s just an utterly rip off.

Lessons learnt: 1) Check the long term domain prices. 2) How to setup redirect from the old domain in nginx:

server {
    listen 80 ;
    listen 443 ;
    server_name www.floki.blog floki.blog;
    return 301 https://floki.cc$request_uri;
}

Mar 30, 2021 - Putting an ATmega328P into sleep

Comments

Putting an ATmega328P into sleep

For a little project I want to take and send measurements roughly about every 10 minutes. It will run on an ATmega328p microcontroller powered by two AA batteries, so power consumption will be an important issue. The ATmega328p is the heart of every Arduino. But the Arduino with all its extra components draws a lot of power. So it has be run “stand alone” (I’ll create another blog post for that later). But the nice thing is, that you can easily program it on an Arduino and then just pop out the chip from the Arduino and put it onto your final circuit board. But it’s not only the extra components of an Arduino which draws unnecessary power, it’s also the constant “awake” state. Therefore the chip has to be put into sleep mode and only wake up every 10min to perform the measurements. In a typical Arduino sketch you would use the delay method to wait. Here’s a way to replace that with a real sleep method.

The code was mostly taken from Wolles Elektronikkiste - Sleep Modes and Power Management. An excellent resource if you want to know more about different microcontrollers, sleep modes and their power consumptions. check it out!

#include <avr/wdt.h>
#include <avr/sleep.h>

// Taken from:
// https://wolles-elektronikkiste.de/en/sleep-modes-and-power-management 

const unsigned int sleepInSec = 10u * 60u; // 10 min

void setup() {
  sleepSetup();
}

void loop() {
  // do something
  // ...

  sleep(sleepInSec);
}

void sleepSetup() {
  cli();
  wdt_reset();
  WDTCSR |= (1<<WDCE) | (1<<WDE);
  WDTCSR = (1<<WDIE) | (0<<WDE) | (1<<WDP3) | (1<<WDP0);
  // 8s / interrupt, no system reset
  sei();
}

void sleep(unsigned int timeInSec) {
  unsigned int rounds = (unsigned int)(timeInSec / 8u);
  for (unsigned int i=0; i<rounds; i++) {
    wdt_reset();
    set_sleep_mode(SLEEP_MODE_STANDBY);
    sleep_mode();
  }
}

ISR(WDT_vect){
}

Note: This is very approximate. It uses the ATmega328p’s maximum sleep time of 8 seconds, and loops over it, so it will only work for sleep times > 8 sec and be only accurate for multiples of 8. But for stuff like doing something every few minutes, that should be good enough.

It needs some setup steps, wrapped in the sleepSetup method, and then you can call sleep(123) instead of delay(123000).

By the way: Furthermore I tried to reduce the power consumption by running the chip at 8 MHz and 3.3 V instead of 16 MHz. But unfortunately I couldn’t get the nRF24L01 component working in this setup. But surprisingly the ATmega328p seems to work fine with 3.3 V even at 16 MHz, although I read you should reduce the clock frequency when running it on 3.3 V. But it’s a pity, as going down to 8 MHz would half the power usage once more. Very roughly speaking it looks you’ll get a reduction in power consumption to roughly 1/2 for using the ATmega328p stand-alone instead of in the Arduino, another 1/2 by using 3.3 V instead of 5 V, another 1/10 by using sleep (standby) and another 1/2 by using 8 MHz instead of 16 MHz. So in total 1/50 (16 MHz) to 1/100 (8 MHz) compared to the Arduino.