Blog Image


About the blog

In this blog I will keep track of projects I develop though out this year and may be in the future. For now it is juts a testing ground for developing the blog itself but I hope as I put more material it will become a good place for me to hold information.

Silent boot with splash Raspberry PI

Pi Stuff Posted on 08 Feb, 2023 13:09:38
sudo nano /boot/cmdline.txt
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty3 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait loglevel=3 quiet logo.nologo

add "disable_splash=1" to /boot/config.txt
add "disable_overscan=1" to /boot/config.tx

place an image as splashscreen

install fbi: sudo apt install fbi 
Creat the service file:  /etc/systemd/system/splashscreen.service 
Edit the service file to have the following content:

Description=Splash screen

ExecStart=/usr/bin/fbi -d /dev/fb0 --noverbose -a /opt/splash.png


Change location of the image accordengly.
Enable the service: sudo systemctl enable splashscreen

Minimal kiosk

Pi Stuff Posted on 16 Jan, 2023 10:19:03


Install the lite version of raspbian and make it boot to console with autoogin.

sudo apt-get update -qq

sudo apt-get install --no-install-recommends xserver-xorg-video-all \
  xserver-xorg-input-all xserver-xorg-core xinit x11-xserver-utils \
  chromium-browser unclutter

# Go to: Boot Options > Console Autologin
sudo raspi-config

Next edit /home/pi/.bash_profile to automatically start the gui. There’s a check for the bash context first, so you don’t accidentally start chromium whenever you ssh in. This below may not be needed.

if [ -z $DISPLAY ] && [ $(tty) = /dev/tty1 ]

The last bit is to setup /home/pi/.xinitrc to run chromium whenever you run startx. Here’s the full list of chromium arguments.

#!/usr/bin/env sh
xset -dpms
xset s off
xset s noblank

unclutter &
chromium-browser \
  --window-size=1920,1080 \
  --window-position=0,0 \
  --start-fullscreen \
  --kiosk \
  --incognito \
  --noerrdialogs \
  --disable-translate \
  --no-first-run \
  --fast \
  --fast-start \
  --disable-infobars \
  --disable-features=TranslateUI \
  --disk-cache-dir=/dev/null \
  --overscroll-history-navigation=0 \

It disables the cursor and screensaver. Then runs chromium with *all* of the flags. Set to the website which you want to display. And set --window-size to the size of your display (it’s horizontal first and vertical after the comma).

You may also want to uncomment disable_overscan=1 in /boot/config.txt so that the pi boots up using the full display.

Now whenever the pi boots up it’ll go into the console then on into chromium. If you want to exit you can hit Alt+F4, then enter startx to start up the browser again.

omxplayer to stream

Pi Stuff Posted on 26 Sep, 2022 15:51:59

omxplayer “rstp://user:pass@host:port/path/subpath” –avdict rtsp_transport:tcp –no-osd –live –with-info –stats;

Cross Compiling From Linux to Raspberry PI

C/C++ Programming, Linux, Pi Stuff Posted on 11 Jan, 2022 20:34:02


Before you start you need to make sure the following is installed:

apt-get install git rsync cmake libc6-i386 lib32z1 lib32stdc++6

Let’s cross compile a Pie!

Start with making a folder in your home directory called raspberrypi.

Go in to this folder and pull down the ENTIRE tools folder you mentioned above:

git clone

You wanted to use the following of the 3 ones, gcc-linaro-arm-linux-gnueabihf-raspbian, if I did not read wrong.

Go into your home directory and add:

export PATH=$PATH:$HOME/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin

to the end of the file named ~/.bashrc

Now you can either log out and log back in (i.e. restart your terminal session), or run . ~/.bashrc in your terminal to pick up the PATH addition in your current terminal session.

Now, verify that you can access the compiler arm-linux-gnueabihf-gcc -v. You should get something like this:

Using built-in specs. COLLECT_GCC=arm-linux-gnueabihf-gcc COLLECT_LTO_WRAPPER=/home/tudhalyas/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../libexec/gcc/arm-linux-gnueabihf/4.7.2/lto-wrapper Target: arm-linux-gnueabihf Configured with: /cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.b uild/src/gcc-linaro-4.7-2012.08/configure –build=i686-build_pc-linux-gnu –host=i686-build_pc- linux-gnu –target=arm-linux-gnueabihf –prefix=/cbuild/slaves/oort61/crosstool-ng/builds/arm-l inux-gnueabihf-raspbian-linux/install –with-sysroot=/cbuild/slaves/oort61/crosstool-ng/builds/ arm-linux-gnueabihf-raspbian-linux/install/arm-linux-gnueabihf/libc –enable-languages=c,c++,fo rtran –disable-multilib –with-arch=armv6 –with-tune=arm1176jz-s –with-fpu=vfp –with-float= hard –with-pkgversion=’crosstool-NG linaro-1.13.1+bzr2458 – Linaro GCC 2012.08′ –with-bugurl= –enable-__cxa_atexit –enable-libmudflap –enable-libgom p –enable-libssp –with-gmp=/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-rasp bian-linux/.build/arm-linux-gnueabihf/build/static –with-mpfr=/cbuild/slaves/oort61/crosstool- ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static –with-mpc =/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux- gnueabihf/build/static –with-ppl=/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf -raspbian-linux/.build/arm-linux-gnueabihf/build/static –with-cloog=/cbuild/slaves/oort61/cros stool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static –wi th-libelf=/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/a rm-linux-gnueabihf/build/static –with-host-libstdcxx=’-L/cbuild/slaves/oort61/crosstool-ng/bui lds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static/lib -lpwl’ –ena ble-threads=posix –disable-libstdcxx-pch –enable-linker-build-id –enable-plugin –enable-gol d –with-local-prefix=/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-li nux/install/arm-linux-gnueabihf/libc –enable-c99 –enable-long-long Thread model: posix gcc version 4.7.2 20120731 (prerelease) (crosstool-NG linaro-1.13.1+bzr2458 – Linaro GCC 2012.08 )

But hey! I did that and the libs still don’t work!

We’re not done yet! So far, we’ve only done the basics.

In your raspberrypi folder, make a folder called rootfs.

Now you need to copy the entire /liband /usr directory to this newly created folder. I usually bring the rpi image up and copy it via rsync:

rsync -rl –delete-after –safe-links pi@192.168.1.PI:/{lib,usr} $HOME/raspberrypi/rootfs

where 192.168.1.PI is replaced by the IP of your Raspberry Pi.

Now, we need to write a cmake config file. Open ~/home/raspberrypi/pi.cmake in your favorite editor and insert the following:

SET(CMAKE_SYSTEM_NAME Linux) SET(CMAKE_SYSTEM_VERSION 1) SET(CMAKE_C_COMPILER $ENV{HOME}/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-gcc) SET(CMAKE_CXX_COMPILER $ENV{HOME}/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++) SET(CMAKE_FIND_ROOT_PATH $ENV{HOME}/raspberrypi/rootfs) SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

Now you should be able to compile your cmake programs simply by adding this extra flag: -D CMAKE_TOOLCHAIN_FILE=$HOME/raspberrypi/pi.cmake.

Using a cmake hello world example:

git clone cd cmake-hello-world mkdir build cd build cmake -D CMAKE_TOOLCHAIN_FILE=$HOME/raspberrypi/pi.cmake ../ make scp CMakeHelloWorld pi@192.168.1.PI:/home/pi/ ssh pi@192.168.1.PI ./CMakeHelloWorld

I have taken the above from stackoverflow:

I did not managed to get the cmake to work as the pkg-config seem to have problems identifying where the libraries are and it was adding my libraries from teh host computer rather than the target ones. But following the same instructions it did worked fine when making my own call to the compiler and adding all the paths and libraries manually to the command.

How to clone Raspberry Pi SD Card on Linux and shrink it to actual size

Linux, Pi Stuff Posted on 07 Jun, 2021 12:05:03

This is a copy past from another person you can find the original blog here:
I am making a copy here is I can find it easy and in case the original disappear of the web.

On Linux you can use dd to make a backup from SD card. Reverse if and of (i.e. to where they point – source and destination) afterwards to restore, but be careful not to restore to a wrong disk. It will be destroyed without a warning!!!

First use fdisk to get the device id of you SD card (check the size)

fdisk -l

then use dd to make a diskimage (change /dev/sdb with what you found with fdisk -l):

dd bs=4M if=/dev/sdb of=image1-`date +%d%m%y`.img

or this to make a compressed image:

dd bs=4M if=/dev/sdb | gzip > image1-`date +%d%m%y`.img.gz

The process will take some time. After the image is created you will notice that it’s too big(size of a SD card). To shrink it we will use a perfect script that I found on github here called PiShrink.

PiShrink is a bash script that automatically shrink a pi image that will then resize to the max size of the SD card on boot. This will make putting the image back onto the SD card faster and the shrunk images will compress better.


chmod +x
sudo mv /usr/local/bin

Usage example

$ sudo pi.img
e2fsck 1.42.9 (28-Dec-2013)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/loop1: 88262/1929536 files (0.2% non-contiguous), 842728/7717632 blocks
resize2fs 1.42.9 (28-Dec-2013)
resize2fs 1.42.9 (28-Dec-2013)
Resizing the filesystem on /dev/loop1 to 773603 (4k) blocks.
Begin pass 2 (max = 100387)
Begin pass 3 (max = 236)
Begin pass 4 (max = 7348)
The filesystem on /dev/loop1 is now 773603 blocks long.

Shrunk pi.img from 30G to 3.1G

Kernel Module

Pi Stuff Posted on 08 Feb, 2019 16:14:55

Real time interrupts and operating systems are not generally compatible. For operating systems it is needed to poll the pin which one is willing to work as an interrupt but this is not real time and generally speaking is not very CPU deficient. For this purpose a Kernel module can be inserted which can handle this as real time as possible. I needed to make an interrupt in a raspberry pi to be able to count encoder signals, the following tutorial is the ins and outs of how I achieved this.

Firstly install the latest Raspbian (I have done this tutorial with Raspbian Stretch Lite) I will also mention here that I recommend using a none X server operating system as some of the print calls from kernel you may not see them if you are in a X server OS:

Once downloaded you can burn the image to a micro SD card using DiskImager in windows:

Then insert the SD card on the Raspberry PI (I used PI3) and boot from the micro SD card. Make sure the PI is connected to the internet.

In the command line run the following commands:

# The usual update routine

apt-get update -y
apt-get upgrade -y

# Update the kernel!


# Get rpi-source

sudo wget -O /usr/bin/rpi-source

# Make it executable

sudo chmod +x /usr/bin/rpi-source

# Tell the update mechanism that this is the latest version of the script

/usr/bin/rpi-source -q –tag-update

# Get the kernel files thingies.


At this point you should have all the needed components to start compiling a kernel module.

So lets start by looking at a simple Hello World kernel module:

# Create a new directory enter it.

mkdir hello
cd hello

# Crete a file named hello.c and edit it

nano hello.c

# Edit the file to have the following lines of code in it.

#include <linux/module.h>
#include <linux/kernel.h>

int hello_init(void)
pr_alert(“Hello World :)\n”);
return 0;

void hello_exit(void)
pr_alert(“Goodbye World!\n”);

# Save the file and exit nano

Ctrl+X (and follow the on screen options)

# Make a Makefile for compiling

nano Makefile

# Edit it as follow.

obj-m := hello.o

# save file and exit

Ctrl+X (and follow the on screen options)

# Compile and load kernel module

make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
insmod hello.ko

That is it. You have mounted your first kernel module. it does nothing but it is a start.


The interrupt module I made looks like this:

#include <linux/device.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/time.h>
#include <linux/fs.h>
#include <linux/uaccess.h>

#define GPIO_FOR_INT_SIGNAL_2 17
#define DEV_NAME “rfrpi”
#define BUFFER_SZ 512


/* Last Interrupt timestamp */
static struct timespec lastIrq_time;
static unsigned long lastDelta[BUFFER_SZ];
static int pRead;
static int pWrite;
static int wasOverflow;

static int gCounter = 0;

/* Define GPIOs for RX signal */
static struct gpio signals[] = {
{ GPIO_FOR_RX_SIGNAL, GPIOF_IN, “RX Signal” }, // Rx signal

/* Later on, the assigned IRQ numbers for the buttons are stored here */
static int rx_irqs[] = { -1, -1 };

* The interrupt service routine called on every pin status change
static irqreturn_t rx_isr(int irq, void *data)
struct timespec current_time;
struct timespec delta;
unsigned long ns;

delta = timespec_sub(current_time, lastIrq_time);
ns = ((long long)delta.tv_sec * 1000000)+(delta.tv_nsec/1000);
lastDelta[pWrite] = ++gCounter;//;ns;

pWrite = ( pWrite + 1 ) & (BUFFER_SZ-1);
if (pWrite == pRead) {
// overflow
pRead = ( pRead + 1 ) & (BUFFER_SZ-1);
if ( wasOverflow == 0 ) {
printk(KERN_ERR “RFRPI – Buffer Overflow – IRQ will be missed”);
wasOverflow = 1;
} else {
wasOverflow = 0;

* The interrupt service routine called on every pin status change
static irqreturn_t int2_isr(int irq, void *data)
if (gpio_get_value(signals[0].gpio))
lastDelta[pWrite] = –gCounter;//;ns;
lastDelta[pWrite] = ++gCounter;//;ns;

pWrite = ( pWrite + 1 ) & (BUFFER_SZ-1);
if (pWrite == pRead) {
// overflow
pRead = ( pRead + 1 ) & (BUFFER_SZ-1);
if ( wasOverflow == 0 ) {
printk(KERN_ERR “RFRPI – Buffer Overflow – IRQ will be missed”);
wasOverflow = 1;
} else {
wasOverflow = 0;

static int rx433_open(struct inode *inode, struct file *file)
return nonseekable_open(inode, file);

static int rx433_release(struct inode *inode, struct file *file)
return 0;

static ssize_t rx433_write(struct file *file, const char __user *buf,
size_t count, loff_t *pos)
return -EINVAL;

static ssize_t rx433_read(struct file *file, char __user *buf,
size_t count, loff_t *pos)
// returns one of the line with the time between two IRQs
// return 0 : end of reading
// return >0 : size
// return -EFAULT : error
char tmp[256];
int _count;
int _error_count;

_count = 0;
if ( pRead != pWrite ) {
_count = strlen(tmp);
_error_count = copy_to_user(buf,tmp,_count+1);
if ( _error_count != 0 ) {
printk(KERN_ERR “RFRPI – Error writing to char device”);
return -EFAULT;
pRead = (pRead + 1) & (BUFFER_SZ-1);
return _count;

static struct file_operations rx433_fops = {
.owner = THIS_MODULE,
.open = rx433_open,
.read = rx433_read,
.write = rx433_write,
.release = rx433_release,

static struct miscdevice rx433_misc_device = {
.name = DEV_NAME,
.fops = &rx433_fops,

* Module init function
static int __init rfrpi_init(void)
int ret = 0;
printk(KERN_INFO “%s\n”, __func__);

pRead = 0;
pWrite = 0;
wasOverflow = 0;

// register GPIO PIN in use
ret = gpio_request_array(signals, ARRAY_SIZE(signals));

if (ret) {
printk(KERN_ERR “RFRPI – Unable to request GPIOs for RX Signals: %d\n”, ret);
goto fail2;

// Register IRQ for this GPIO
ret = gpio_to_irq(signals[0].gpio);
if(ret < 0) {
printk(KERN_ERR “RFRPI – Unable to request IRQ: %d\n”, ret);
goto fail2;
rx_irqs[0] = ret;
printk(KERN_INFO “RFRPI – Successfully requested RX IRQ # %d\n”, rx_irqs[0]);
ret = request_irq(rx_irqs[0], rx_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_DISABLED, “rfrpi#rx”, NULL);
if(ret) {
printk(KERN_ERR “RFRPI – Unable to request IRQ: %d\n”, ret);
goto fail3;

// Register IRQ for second GPIO
ret = gpio_to_irq(signals[1].gpio);
if(ret < 0) {
printk(KERN_ERR “RFRPI – Unable to request IRQ: %d\n”, ret);
goto fail2;
rx_irqs[1] = ret;
printk(KERN_INFO “RFRPI – Successfully requested RX IRQ # %d\n”, rx_irqs[1]);
ret = request_irq(rx_irqs[1], int2_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_DISABLED, “rfrpi#rx”, NULL);
if(ret) {
printk(KERN_ERR “RFRPI – Unable to request IRQ: %d\n”, ret);
goto fail3;

// Register a character device for communication with user space

return 0;

// cleanup what has been setup so far
free_irq(rx_irqs[0], NULL);
free_irq(rx_irqs[1], NULL);

gpio_free_array(signals, ARRAY_SIZE(signals));
return ret;

* Module exit function
static void __exit rfrpi_exit(void)
printk(KERN_INFO “%s\n”, __func__);


// free irqs
free_irq(rx_irqs[0], NULL);
free_irq(rx_irqs[1], NULL);

// unregister
gpio_free_array(signals, ARRAY_SIZE(signals));

MODULE_DESCRIPTION(“Linux Kernel Module for rfrpi shield”);


The Makefile for it is as follow:

obj-m = krfrpi.o
KERNEL_DIR ?= /lib/modules/$(shell uname -r)/build
MODULE_DIR := $(shell pwd)

.PHONY: all

all: modules



rm -f *.o *.ko *.mod.c .*.o .*.ko .*.mod.c .*.cmd *~
rm -f Module.symvers Module.markers modules.order
rm -rf .tmp_versions

Once this module is mounted it makes a file at /dev/rfrpi this file can be dumped with cat /dev/rfrpi or you can read it in a c program as follow:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>

int main(int argc, char ** argv) {
int fd;
char buf[256];

fd = open(“/dev/rfrpi”, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) {
perror(“open_port: Unable to open /dev/rfrpi – “);

// Turn off blocking for reads, use (fd, F_SETFL, FNDELAY) if you want that
fcntl(fd, F_SETFL, 0);

int n = read(fd, (void*)buf, 255);
if (n < 0) {
perror(“Read failed – “);
return -1;
} else if (n == 0) {
printf(“No data on port\n”);
else {
buf[n] = ‘\0’;
printf(/*”%i bytes read : %s” */”%15s”/*, n*/, buf);
//printf(“i’m still doing something”);

return 0;


Step by step on how to compile a kernel module:

Raspberry PI Interrupt example:

Article on Raspberry PI module kernel programming:

Information on GPIO.h header file. Very good for general reference.

Compiling RaspiVid Only

Pi Stuff Posted on 20 Jun, 2018 15:40:09

To build raspivid and only raspivid then the following command should do it (assuming your repo ( clone is in ~/userland):

gcc -o myraspivid RaspiVid.c RaspiCamControl.c RaspiPreview.c RaspiCLI.c \ -I$HOME/userland -I$HOME/userland/host_applications/linux/libs/bcm_host/include \ -L/opt/vc/lib -lbcm_host -lvcos -lpthread -lmmal_core -lmmal_util -lmmal_vc_client

Streaming Video from raspberry PI

Pi Stuff Posted on 20 Jun, 2018 14:22:09

tested with

  • RasPi 3B with Raspbian Jessie, IPv4 address
  • Ubuntu 16.04 client, IPv4 address

raspivid options used:

option explanation
-pf baseline use baseline profile (no B-frames) which reduces delay
-b 1000000 bitrate (1MBit/s)
-g 30 GOP (group of pictures) size of 30, i.e. send an I-frame every second
-ih inline headers: send SPS and PPS headers with each I-frame

live TCP streaming on RasPi

RasPi is listening (-l) and keeps (-k) listening after a TCP session terminated. RasPi’s own (local) IPv4 address is specified.

pi@raspberrypi:~ $ raspivid -t 0 -n -b 1000000 -g 30 -ih -pf baseline -w 640 -h 480 -fps 30 -l -o tcp://

Drawback: after client terminates, raspivid terminates too. So you might want to wrap it with an endless bash script loop

pi@raspberrypi:~ $ while :; do raspivid -t 0 -n -b 1000000 -g 30 -ih -pf baseline -w 640 -h 480 -fps 30 -l -o tcp:// ; done

remote client

Now, on remote client, vlc is opening and terminating TCP stream:

$ vlc -v tcp/h264://

UDP streaming remote client

Start remote client first, otherwise it could miss the H.264 SPS/PPS which are needed for decoding the stream. Client is waiting for incoming packets on UDP socket:

$ vlc -vvv udp/h264://@:1234


RasPi is pushing UDP packets to the client.

without nc

pi@raspberrypi:~ $ raspivid -t 0 -n -b 1000000 -g 30 -ih -pf baseline -w 640 -h 480 -fps 30 -o udp://

while client port is not available, you see error messages like mmal: Failed to write buffer data (3294 from 14539)- aborting but they do not do any harm.

with nc

I think, this is no longer needed.

pi@raspberrypi:~ $ raspivid -t 0 -n -b 1000000 -g 30 -ih -pf baseline -w 640 -h 480 -fps 30 -o – | nc -p 1904 -u 1234

passing video to

pi@raspberrypi:~ $ raspivid -t 10000 -n -b 1000000 -g 30 -ih -pf baseline -w 1920 -h 1080 -fps 30 -o – | gst-launch-1.0 fdsrc ! ‘video/x-h264,profile=baseline, width=1920, height=1080’ ! h264parse ! mp4mux ! filesink location=test.mp4

RTSP streaming

there is a session concept + time stamping (RTP) included. several transport protocols are possible: UDP, TCP and HTTP tunnelled.


# raspivid -t 0 -n -b 1000000 -g 30 -ih -pf baseline -w 640 -h 480 -fps 30 -o – | cvlc -v stream:///dev/stdin –sout ‘#rtp{sdp=rtsp://:8554/}’ :demux=h264

$ vlc -v rtsp://

further steps

RTSP streaming has many more options like:

  • http tunnelling to stream through a firewall
  • specifying user and password for stream protection

there are alternative RTSP streaming servers out like:

  • live555
  • gst-rtsp-server

Next »