Labels

Showing posts with label RPi. Show all posts
Showing posts with label RPi. Show all posts

Sunday, 8 March 2026

Owncloud

 Rationale

I need a central point of cloud storage like Google drive, iCloud, Onedrive (yuk). I use them all to some extent but none of them seem to fit all situations.  If I do have suitable cloud storage I am likely to need more space than the commercial offerings allow for free, and I dont want to be tied to a monthly subscription.

OMV NAS provides a good solution but it isn't integrated into Windows, iOS, Android very well.  It is certainly the right solution for media storage; music, pictures and video collections should remain there.
It doesn't seem appropriate for iOS and Android devices, where the underlying storage is hidden.

I would like to be able to choose whether my files are held on the cloud or synced to a local folder and I would like my solution to work outside the home, using SSL.

Consequently my objective is to have a home application, based on PI43/OMV/Docker which looks like iCloud or Googe-drive and allows me to have as much storage as I want.

Selection

There are a variety of Docker based container apps which could be used.  I found it hard to get a feel for them by reading articles or documentation so I tried out a number of solutions.  Docker is perfect for this as I can "spin up" a container and try out the app quickly.  If I dont need to use it further I can remove the container and my system is unchanged, there is no leftover software to remove (or forget).

Before deciding on Owncloud I tried out the following apps.

Syncthing: You can run the app on different computers and it synchronises the chosen folders between them.  I dont really want to have local copies of files on all sharing devices.

Quickshare: Provides you with a central storage file structure.  You can drag and drop groups of files from/to Windows to/from Quickshare.  I dont really want to be using drag&drop all the time.

Picoshare: A very simple app allowing you to drag and drop files to/from a shared folder.  It doesn't have many features.

Chibisafe: The container has Caddy, a reverse proxy manager incorporated so the folders can potentially be used externally.  There is a Chrome add on allowing you to save files directly from your browser.  Copying files using the browser isn't very nice.

Nextcloud: This is a large commercial offering with a free option.  I found it difficult to find appropriate instructions to make a working solution.  The various versions and software used are confusing.

Owncloud: Has a straightforward installation which I can use for testing.  Like iCloud and Gdrive you can manage folder/files in Windows file explorer or iOS files.

In summary, testing owncloud provided me with an excellent way of saving and managing files easily in a home cloud.  Typically files are saved in the cloud rather than synchronised across devices. This fits my initial requirements well.
My testing using SSL / HTTPS didn't go well so I am not sure how useful it will be outside the home.

Installation

My first approach was to use a template provided by OMV.  It is slightly more complicated than previous installs as it creates three containers for owncloud, mariadb and redis (a fast database cache).   I wasn't able to connect to the server this way so I tried some tests using docker cli commands.  After a while I found that I needed to set the "trusted domain" parameter to allow external collections.  I then proceeded with an install following the official documentation.

The skeleton docker compose file has simple builds for three containers owncloud, mariadb and redis.

The default storage volume is on the server SD card,  which needs changing to use the OMV hard drive.
In the ENV file I needed to add my server host name, PI43 and ip address.
Apart from passwords, there were no further changes I needed to make.
I told OMV to start up this environment and I now have three new containers for ownCloud, mariadb and redis.




In Windows when I enter the owncloud URL http://pi43:8080 I see a basic file structure with folders for documents and photos.

I am able to add/change/delete folders and documents using the web client. But this isn't what I want.

I can install the ownCloud Windows client and connect to the owncloud server.  Now if I look at Windows File Explorer I can see my owncloud files.



This is just what I want.  The files are stored in the cloud but accessible locally just where I need them.

Configuration

Next I needed to setup users.  I may open up my own cloud to others but I will be the first and only user initially.  

So far we have used PI43 system SD storage for files which is a VERY bad idea as it would be childsplay to use all available space and kill the server.  Docker compose has a single volume defined for the owncloud system and user data on the SD card with a mount point /mnt/data. When I tried to allocate this to a NAS shared folder, the system started up with an error.
The system starts as the web user "www-data" which doesn't have permissions to use the NAS.

After some failed workaround attempts I decided just put "admin" storage on the NAS and leave owncloud system files on the SD card.  I found that admins directory structure containing "Documents" and "Photos" is located in .../own_files/_data/files/admin/files


So I added a  volume which maps a NAS shared folder to .../own_files/_data/files/admin/files/MyFiles.  

I also setup a user john whose files are located on the NAS shared folder.


Once this is complete I can configure user john in the owncloud windows client and I can see owncloud "MyFiles" for john in Windows File Explorer.  This is perfect, it works just like Gdrive/iCloud


On the iPad I install the owncloud app and use it to configure the user john.
Now I can access MyFiles in the Files app.

For Android I manage files directly using the Android owncloud app.



HTTP vs HTTPS

So far I have accessed owncloud using HTTP.  This works fine if I am using it at home but doesn't work outside my local network.  In itself it is very useful as nearly all my work which requires storage is done at home.

Obviously cloud storage typically works across the internet and it not safe or sensible to use unencrypted HTTP access from outside the home.
I do have encrypted HTTPS access at home for my web-site but my experiments with setting up https within docker and owncloud have not yet been totally successful so I will leave those considerations for another time.

I am happy that I have something useful here; owncloud will be a great help in organising my storage across devices which is becoming lost and fragmented.

I do have wireguard setup on my mobile devices, it only takes a second to setup a VPN connection to home.  This allows me to use owncloud without hindrance.  Other users / devices would need to be setup to give other people access.




Tuesday, 20 January 2026

PI43 : OMV : Docker

Intro

A key reason for choosing OMV for my NAS is that it also provides an environment for docker containers.  Although docker is widely used I know little about it and it seems likely that I can benefit from using it on my new server.

I searched for suitable application which have been packaged for docker which I might find useful.  My initial list included Jellyfin (a media player), pihole (an ad blocker) and opencloud/nextcloud (dropbox replacement).

Installation

There are lots of docker install tutorials.  I needed to pick one which installs docker using OMV7.  I found a good youtube video from db tech

The first step is to install omv-extras, which gives you a list of plugins that can be added into OMV.  In addition to docker, I was directed to add OMV scripts and docker-compose "extras".

Next I setup three OMV shared folders for compose, backup and data.  I had a problem setting up the compose share, with OMV repeatedly complaining it couldn't do it.  After some time I discovered that my drive is formatted with NTFS as it was formatted for Windows storage. I moved the docker compose share to the linux OS SD card and the system was happy again.

With the pre-requisites complete I could click on the "install docker" button to create my system.  Finally I setup a user, dockuser, which should be able to to manage my system.




Although we used OMV to install docker and will use the it to create containers we do have access to docker through the command line so OMV doesn't get in our way of using any docker capability.

Overall this was a very straightforward install using OMV, with very little technical thought involved.



Sample Application 

The tutorial I followed used a simple web app docuwiki as an example to get started.  This was very helpful though not useful.  It shows that you start by cut-and-pasting the container definition into docker compose, defining disk storage, allocating ports and setting userids.  You then "spin up" the container; software is downloaded, configured and the app starts.  It is wonderfully straightforward and the app is independent of the local system and any complications or dependencies related to it.  The one constraint is that containers are architecture dependant.  Many / most images seem to have an arm64 version which is what my RPI requires.

 Bittorrent

For a proper test I setup the Transmission bittorrent server.  I can use this to replace an old version I have on an old server.  

Step 1 is to create a container definition and copy the docker compose definition from the linuxserver site.
I created a Samba shared folder for transmission files in OMV.
I then amended the docker compose definition for my own UID, GID, Timezone and my storage volume.  I didn't need to change any of the port numbers.



I then started the transmission container. As usual the software is downloaded, configured and then initialised.  


PI43 port 9091 allows you to see the transmission web interface so that you can add torrents to download files.

As the downloads are saved to a Samba I can access and copy them to any device.

In fact I dont need to use the web interface as I have a windows Transmission client which I use for managing torrents.

On the new transmission system I now have lots of space for downloads.  It turns out that my downloads can be 5-10 times faster than the old system, upto 10MBps.

Pi-hole

Pi-hole is a popular ad-blocker.  I have tried it before but it didn't seem to work well for me.  Setting it up in a docker container enables me to start and stop it at will.  As usual I pasted a default configuration into docker-compose.  In this case I had to make a small change to set the HTTP port to 8081.


The container comes up cleanly and I can signon to the web interface to see what is happening.


Initially pi-hole doesn't do any work.  I tested it by pointing the iPad at PI43 for its DNS and the iPad continued to work ok.  I then changed the router so it pointed to PI43 for its DNS.  Now all devices use pi-hole.

It works well, it doesn't interfere with normal browser operation and shows blank spaces instead of adverts in web pages.  If I want I can take down pihole and devices will use google DNS (8.8.8.8) instead.

Jellyfin


I am most interested in setting up Jellyfin as a media server.  It is widely used and liked.  The configuration is very simple, I just need to set up a shared drive for movies and tvseries.

Once the container had been started I could sign on to the admin interface on browser port 8096.
There is an admin user to setup and confirmation is required for movies and tvseries as the initial folders.

Installing the Jellyfin client on a PC is easy.  For some reason Samsung make it slightly complicated to install the app on the TV but I googled a solution.

Jellyfin provides a very professional interface, as good as Prime or Netflix.  It finds a thumbnail image for shows and is pretty good at discovering descriptions about individual episodes to help you choose what to watch.

I can add shows easily by copying them across to the Jellyfin shared folder.

I will call this my killer app, it makes docker worthwhile.






Thursday, 15 January 2026

PI43 : Open Media Vault : NAS : Backups

 Intro


I have had a new Raspberry Pi 4 sitting in a drawer and an urge to look at Linux again so I thought it would be a good time to set it up.  The particularly good feature of RPI4 is that it doesnt need a fan.  I have a smart electric blue metal case for it which can dissipate heat and keep it safe.  As usual I will run it headless.  I could probably have a reasonable experience using a desktop but I have an RPI5 waiting which will be better suited.

I  want PI43 to do something useful for me and I aim to leave it as a server switched on and unattended.  I already have a web server, application server and database server.

A few ideas come up repeatedly, a media server (jellyfin), a backup server (rsync), NAS (openmediavault), cloud server (OpenCloud) and containerised applications (docker).

As OpenMediaVault will potentially work well as a backup or cloud server and allows me to use docker I will set it up and see whether it meets my needs.  It will need external USB HDD or SSD.  If I had an M.2 hat for PI43 I could have faster SSD storage, but I dont think I need it.  I will use an existing Samsung 1TB HDD.  I was concerned this wouldn't be appropriate for a NAS, but confirmed that it wont be spinning continually so it should be fine.


OMV Install

pidiylab.com and pimylifeup have simple detailed tutorials on setting up OMV. I mainly followed the pimylifeup tutorial as it mentioned that I need to use RPI OS Bookworm version (rather than Trixie, the latest version) with the current release OMV7 in November 2025. (OMV8 supporting Trixie, the latest version came out in December).

Using RaspberryPi Imager, I created a new Bookworm SD card build and set PI43 up with an ethernet static address.

OMV is installed using a couple of scripts.  It has a very simple web interface allowing me to configure disks, file-systems, sharing protocols, shared folders users and permissions.

I connected a 1TB Samsung M3 USB portable HDD which have previously used for backups. 
I then enabled Samba in OMV, setup a shared folder on the samsung drive and created a backup user.
I also set the "spin down" time to 5 minutes and enabled S.M.A.R.T. drive monitoring.

The Samsung drive was half full of old backups so I moved them across to the shared folder using linux file move command.  I can now access the "samsung backup" shared folder from Windows file explorer  and from RPIs using a mount command.




NASmusic

Now I have lots of storage readily available to my local users / systems I setup a CIFS/SMB shared folder NASmusic  to contain my music library.  Initially I just copied a load of music across so it is sitting there waiting for me to use it from whatever device I choose.  In due course I can consolidate my music in this one place and use it for various home music players.

Review

At its simplest, all I have done is setup a Samba folder on PI43 which I can easily access from Windows.  I can also use it on iPad (using Files), Android (Samsung MyFiles) and Linux (mount command).  OMV improves on basic Samba by letting me setup multiple shared folders on the same drive through a simple interface.  I can easily setup users and permissions for appropriate access.  Usually with Samba I faff around each tiime I need to access a drive.  OMV makes Samba a lot more friendly.

The OMV install hasn't "taken over" the server, I still have the usual PI OS capabilities available to me.  It is a bit more than an app and a less than an OS.

Backup

My first use for the OMV NAS is to improve my existing RPI backup arrangements. Until now backups have been totally inadwuate based on very occasional rpi-clone system copies and sometimes copying zipped directory structures to other systems.  Even if a backup exists I have trouble finding it.

rsync is a widely used command line utilitiy for linux backups.  It is used to copy directory structures to another drive.   A regular backup will only copy any changed files across, so it doesn't use very amounts of storage.  It is perfectly suited to use Samba shares on a remote devices.

I found a suitable simple tutorial at jumpcloud and started to setup a backup for PI40, which is most in need of attention.  You specify a starting directoy (/home/pi in the example), folders you want to exclude and the target Samba folder.

You can run this script as often as you like and it will mirror any file/folder additions/changes/deletions across.  You can also specify a "dry-run" option which just shows you what would be backed up.  This makes it very easy to get the syntax and arguments just like you want them.

However there is a better way to use rsync.  rync can use ssh to communicate with the backup server.  I just needed to make sure that PI40 had ssh credentials for automatic signon to PI43.  After that I didn't need to worry about Samba shares.  Veronica Explains provided an enjoyable tutorial.

I quickly setup a simple backup.

After a little more trial and error I setup script to backup important PI40 folders that I didn't want to lose.
They backup to a folder PI40 on the samsung_backup share.


Finally I added this script as a CRON job to run monthly



Outro

We now have a new server which makes its storage available for easy use by other systems.
We also have a solid backup system which makes it easy to backup RPI files on a regular basis.

Saturday, 18 October 2025

Digital Picture Frame II

Intro

Whilst playing with options for my DPF on the iPad I came across an article in LXF describing a simple RPI python slideshow app. Sadly it was the last LXF (Linux format) magazine edition dated July 2025 and was rather nostalgic.  I have enjoyed many of their articles over the last ten years but I guess everone/everything changes over time.

I have a small Samsung TV which functions as an RPI screen and I noticed when experimenting with mirroring my iPad to the TV that it provides an unobtrusive display which can be on in the background and looked at from time to time.

If I attach the screen to my RPI application server (PI41) I have a basic system to use for a PoC to see whether I prefer it to my other DPF versions.

Proof of Concept

The python app requires a desktop GUI to display images and PI41 doesn't have one installed as I usually use it "headless".
My first job was to change over from RPI OS Lite to the desktop version.  I botched it somewhat just adding packages until LXDE worked. I also had to plug in keyboard/mouse to PI41.
I then installed the python pygame module and I was able to display a sample image on the screen and it looked fine.

 I was happy with PoC progress so I setup a Samba share to my database server (PIP) giving me access to my art gallery images.  The image gallery has smaller lower resolution images making them suitable for web loading.  They are fixed height of 922 pixels which fits fits very well, without scaling on the RPI screen which is 1920p wide x 1080p high.

I decided to initially display all images within a folder in my slideshow rather than using the MySQL database containing image, gallery and file information.  Setting up a loop to display the images was straightforward, based on the LXF magazine example.

I was very pleased with the result.  Folders contain a variety of images from different galleries or exhibitions and it is easy to spend a little while looking at images as they attract your attention briefly.  Images look really good on the TV screen; they are a good size and have good quality colours.

Improvements

Choose a gallery

Now we are happy this is a good idea we have various jobs to turn the slideshow into a practical system.  Firstly, I need to be able to control which gallery folder is displayed.  There are about fifteen folders in total each containing about 50-100 images and I want to choose one folder rather than cycle round them all.  Initially I thought that adding websocket processing was the natural way forward but I couldn't easily work out how to run the slideshow and have the websocket waiting for instructions concurrently.

The program which loops round to display files in a folder is called pictureframe.py.  I set it up to read a parameter file picframe.parm which contains the name of the folder to be displayed.  It reads picframe.parm after each image is displayed and, if the folder changes, pictureframe.py loads a new set of images and starts to display them.
A second simple python script, picparm.py, takes a single command line argument, the name of a folder, and saves it to picframe.parm.

It is now an easy task to create a webpage which has a list of folders/galleries as buttons.  When a button is pressed the webpage uses a websocket to invoke picparm.py and change the folder being displayed.  This mechanism has been tried and tested on my music control web pages.


Display Tweak

The Samsung TV screen with a HDMI connection to the RPI has a screen resolution of 1920x1080.  I Rather than display the image as fullscreen using pygame I display a window 1840x1036 which allows me to add the images descriptive file name as a window caption. The image itself is always 922 pixels high which fits nicely into 1036 pixel window height when centred. 

Start and stop the display

The slideshow runs on a RPI desktop but I have no intention of using the attached keyboard to start and stop it.  After a few minutes writing python I was irritated by using the screen / keyboard directly.  The first remote desktop I tried was XRDP, an RDP implementation for RPI.  However it gave me a copy of the console rather than allowing me to "take over" the real one.  Most RPI users choose VNC.  I installed TigerVNC on Windows to communicate with VNC on RPI and this allowed me to stop using the attached keyboard and mouse.

However, I dont really want to do anything at the computer to start the slideshow.  I need RPI to automatically load and run pictureframe.py at startup.  Firstly we can setup RPI to automatically boot into the GUI using raspi-config

Then, in the LXDE GUI preferences, we can add pictureframe.py in autostart to run when the system starts up.

Now, as soon as the system startup our slideshow starts based on the most recent parameter file.


In fact I dont want to have a "stop" option anymore.  I add an extra parameter mode, "pause" or "resume",  to pictureframe.parm.  If pictureframe.py  sees "pause" in the parameter file it loops round until the parameter is changed to "resume" and the screen image doesn't change at all.

We add a "pause/resume" button to the web page so that we can stop and start the display from any browser device.

More enhancements

I am not sure how quickly to change display images so that I can look at them in enough detail, without getting bored.  I have started up with options to display for 5,10,20,60 seconds.  I added an extra line to pictureframe.parm containing the desired interval and added a command line parameter "time" to update the value in python.  I then added buttons in the webpage for each interval.

I also want to see in the browser what the current display parameters are.  I added a "status" parameter to pictureparm.py which returns current parameter values.  I then setup a field in the web page to display the output.


Finally, I added a randomiser, so that we dont start with the same picture each time we display a gallery.  Pictures are still in the same order but we can start with any one.

Outro

I am happy with my latest slideshow.  I like the larger images displayed on the Study TV.  Also you dont need to focus on them - they are just there.  You can control the display from any device and it doesn't require any thought to start / stop or change display.  Unlike the previous slideshows I have actually been using this one.

Saturday, 15 January 2022

Christmas Lights Improvements last year

 For the past few years I have set up music controlled colourful Xmas lights using Lightshow Pi software (LSPi) running on a Raspberry Pi RPi.  LSPi software hasn't changed in the past three years but it still works and support is still available from enthusiastic users, particularly SoftwareArtist.  I started my updates for Xmas early in December 2021 which helped me produce something useful in time for Xmas day.

Last year I ran the music (MPD) and LSPi on the same server.  My RPi server used for this application had a disastrous SD card failure during the year so I needed to reinstall software on my shiny new RPi4 application server (PI41) this December.  Luckily LSPi configuration was backed up and my notes on installation was up to date.  Currently the MPD music player is active on my web server (PI40) along with the web pages to select and play music.  

LSPi Installation is well documented on reddit.  I followed  the instructions, which have been updated for RPi4.  I encountered one error in building "rpi-audio-levels" which the helpful SoftwareArtist on reddit provided a solution for.  Once I updated RPi firmware, LSPi installation worked fine and I was able to test that LSPi on PI40 was controlling GPIO output properly.

The LSPi configuration required for my setup is quite simple.  Music is streamed in from MPD on PI40 and RGB output provided on three GPIO pins.  The sample LSPi configuration file has detailed explanatory comments for all the options but my cutdown file only requires a few.
The most important command is "stream_command_string" which causes LSPi to listen to the music being played on PI40 by MPD.  Clearly MPD needs to be setup with a streaming output on port 8000 to achieve this in mpd.conf






I found by trial and error the pin_modes, pwm_range and attenuate_pct settings to give a pleasing range of colours on the output.  We need to set preshow_configuration to null to avoid a few seconds delay before the lightshow starts.  I was grateful that this solution avoids the syncing problems I have previously experienced with the lights being a secnd or two behind the music.  The current solution is quite impressive, RPi is calculating Fast Fourier Transforms (FFTs) in real time to determine music frequencies and using these to calculate pwm duty cycles.

The second improvement I made this year was to "finalise" my MOSFET setup.  I use MOSFETs to increase the RPI GPIO voltage to 12V and provide the current that MOSFETs need to drive the 5050 LED strip. Previously a breadboard solution provided this facility.  My track record in transferring working breadboard configurations to perfboard has been abysmal so although the circuit is quite straightforward I was very careful to draw out a design, check it, cut wires to length and find the necessary components before I started.  I colour-coded the RGB wires and on completion made sure the wires were tidy then put labels on the connections.  





I am rather proud of the results, it works a treat and I will probably keep the lights setup all year round.

Thursday, 31 December 2020

Christmas lights : lightshowpi

 I have a very simple some coloured  5050 LED strips which provide a very colourful addition to Christmas.  Lightshowpi (LSPi) is wonderful Raspberry Pi (RPi) software which analyses music and allows you to configure lights accordingly.  I think most people use it with relays and big external displays but I prefer a small indoor spectacle when listening to Christmas songs.  My LSPi setup tends to change each year and this years effort works well.

The Raspberry Pi has rubbish sound quality through the headphone jack.  This year I attached a USB audio card which only cost about £5 and provides a signal quality which I can send through my hi-fi (is it still called that) to play pleasant sounding music.  It is possible to spend a more money (£60-£130) on an RPi DAC HAT or high quality USB audio but this is quite acceptable to me.

All my music is accessible using the venerable linux music player daemon (MPD) on an RPi which has a share to network attached storage (NAS) and can stream radio stations.  I use a web interface to mpd  so I can select, play and manage music from a browser.  LSPi is quite happy playing an http or icecast stream from MPD and I can direct its output to the USB audio card.

Previously I used bluetooth connection from RPi/MPD to my hifi but this makes synchronisation a little tricky as bluetooth introduces a selay of 2-3 seconds.  When playing sound through the USB card LSPi synchronisation is much better and I can see the colours changing in time with the notes.

The 4 colour LED strip runs at 12V and requires three GPIO pin signals to control Red, Green and Blue output.  The RPi can only provide 5V, limited current output so I have a simple setup with MOSFETs driving the LED strip with an external power supply.





Tuesday, 30 June 2020

Bare Metal program test

Previously we have managed to implement terminal i/o and libraries into our bare metal environment but as yet there is no breakthrough on setting up stdin, stdout or file i/o.  I will write more if / when problems are resolved but in the meantime we should try some programs.

Our simple starting point is to check whether a number is prime.
The first cut was to loop round trying all possible divisors upto the square root of the subject number.
The program was written on an RPi running linux first.  Then it was transferred to WSL where we compile using arm-none-eabi-gcc for bare metal.  In its simplest form it was quick to implement and test.
The bare metal programs we previously had working were re-organised so that the initial program (notmain.c) sets up uart i/o.  It calls a function jmain.c, which is intentionally not called main to avoid the compiler misinterpreting it.  jmain.c contains our program code with printf statements replaced by uart_puts to output strings to the serial terminal.

The second iteration improves the algorithm slightly, don't test even divisors, make test_prime() a function.  We also loop to ask the user for prime numbers.  We change the linux version of the program so it is easy to convert:
  use sprintf(buffer,.......); printf(buffer); if variable values need to be output for uart_puts convesion
  use gets(buffer); sscanf(buffer,.....) for input so uart_gets can be added on conversion.
Now we can easily enter and test programs under linux before a minimal conversion to run bare metal.


It is much more appropriate to calculate lots of prime numbers.  The program was amended to ask the user now many primes are required.  These are then calculated and printed.  To allow a flexible number of primes malloc is used to create an array of upto 1,000,000 primes which can then be calculated and printed on the screen.  
Previously I had no luck in implementing printf but for some unknown reason this started working so I updated my program to use printf and scanf, which makes life simpler.

To calculate 1,000,000 takes approximately 30 minutes on bare metal RPI 1B.



Monday, 15 June 2020

Bare Metal C - libraries

Introduction

In my last bare metal C post I was able to complete a hello world program so that our RPI1B can do terminal input /output.  It was quite an achievement to dispense with our operating system and establish communications with the program running on hardware.

Now I could carry on in that direction and write everything else I need in C, it would include memory management, device drivers, utility functions and all the other things that C programmers can usually take for granted.  Life is too short for that so I recognise what I really need is a library, in particular the C-Library which provides so many basic necessities of C life.

However the C library makes operating system calls to the linux (or other) kernel whenever it need assistance in completing functions and I decided I didn't want an Operating System!  I didn't want the large amounts of useful and useless code that comes with it.  So our mission is to provide, ie write, the code needed by the C library.

C runtime


We also need to initialise the C environment which is the function of C-runtime (crt0.o). This is fairly easy and we deal with  it first. Brian Sidebothan provide an excellent description in part 2 of his Valvers Bare Metal C tutorial.  At its simplest we just have to setup a stack pointer so that C can use a stack.  This is set to the program load address 0x8000 on RPI1B.  The program is loaded in addresses from 0x8000 upwards and the stack uses memory downwards towards 0x0000. A second job that is required is to initialise variables to 0, which is a C standard requirement.  The variables are stored in the BSS segment and a small C program (cstartup) can be written to set values in the segment.

Library stubs


The tutorial goes on to explain how we can start using library functions and uses malloc (memory allocation) function to demonstrate.  Compiling a C program containing malloc functions gives an error "_sbrk" not found.  This is a low level function which we need to provide ourselves.  Luckily we can use a working example from newlib.  We copy this to a file c-stubs.c, compile without errors, and we can request / use memory allocated to our program.  In fact newlib contains a list of system calls which the C library expects.  Many of these are just dummy stubs with the function call and no code so you still have to do some work yourself.

Test Program


To demonstrate that I now have a working C library capability I use malloc and strcpy (string copy) in my "Hello World" program.  The program is based on David Welch's UART tutorial example with Valvers additions to use libraries.  The linker script and bss initialisation was a little difficult to write but David Welch comes to the rescue with his explanation of linking requirements.  RPI has simplified linking requirements as all code and data is incorporated into kernel.img and loaded into memory.  Initialising BSSS is not required - although I tested the program successfully both with and without initialisation.


Tuesday, 9 June 2020

RPi Bare Metal C - Hello World

Background

Bare metal programming has a back to nature feel about it.  We have unimagineable amounts of software, interacting in complex ways when we want to use computer hardware.
On 8-bit processors such as PIC or Atmega you are very close.  A processor chip has a data sheet which you can use to see how you place instructions in memory so they will execute.  You add your own peripheral devices and are responsible for programming them.
The Arduino IDE allows you to program in C on small systems like Uno or ESP8266.  They are not far removed from the hardware, but have thorny implementation details removed and a simple setup/loop framework provided for your C programs.
For "real computers",32-bit or 64-bit devices which run linux (or Windows),  and are capable of running many tasks simultaneously you are far, far removed from the hardware.

Bare Metal computing on RPi allows you to rediscover the hardware in all its gory glory.
Programming in assembler is a mugs game but in fact only a tiny amount of standard assembler code is required.  Once the C environment is setup and you have a cross comiler to hand, you can write C programs without an OS.

Environment


My starting point is a RPi 1B.  RPI2 or RPI3 would be suitable but I don't need their extra power or complexity.
Not all startup steps on RPi devices are open source, we do know that after initialising hardware an RPi1B loads a program kernel.img from a FAT formatted SD card and starts the ARM processor.
Our focus is to compile an appropriate program, name it kernel.img and place it on an SD card so that it will execute.

We need a cross-compiler that will generate ARM code so I find it most practical to use GCC on Windows under WSL.

A variety of like-minded people have kindly provided tutorials.  They include valversJake Sandler, osdevS Matyukevich, BZT and David Welch have put a lot of work into explaining the intracacies to help you get started.
For RPI1B David Welch's tutorial is absolutely perfect.  His writeups are short but packed with pertinent details and his examples work faultlessly.

Blinking LEDs

Our first problem, as we start our program is that our bare RPIB has no software drivers.  As is traditional on embedded systems our objective will be to make an LED blink.

David Welch's example blinker01 provides an assembler code stub and linking script so that the program is loaded at location x8000 and initialises stack pointers and registers for C.  The C program then takes over and initialises GPIO16 (connected to "OK ACT" LED on board).
GPIO header details need to be included in the program to provide appropriate addresses for controlling the GPIO sub-system.  Finally GPIO16 is configured, enabled and set to 0/1 causing the LED to blink.

This is a huge step forward; we are running a program without any external threads or libraries, directly controlling the hardware.  In fact the executable kernel.img is only 148 bytes.  

Hello World

This is the traditional first program for most environments, printing out a message on the screen.  It is so much easier to develop programs when you have a method of communicating back to the user what is happening.  Flashing LEDs quickly lose their sparkle when they are the only way you have of understanding what the processor is doing.
Of course we don't have a screen to write output to.  We certainly don't want to delve into controlling the RPI HDMI output and GPU at this stage, but luckily we can use the RPI inbuilt UART (GPIO14/GPIO15) to send to a terminal/minicom/Putty session.  The GPIO TX/RX and GND pins were connected to an FTDI connector with a USB cable attached to Putty on the PC.

My first attempts at programming the UARt failed to work,  I don't know why.  I tried different tutorials, RPIs, compiler options, terminal connections, all without success.
On reading that the mini-UART is easier to program I tried this instead.  I was relieved and amazed when I put David Welch's UART01.bin on the SDcard and started it up to find it works perfectly, displaying digits as fast as it can.  The C program includes UART headers and initialises the UART.  It then has a simple putc function to output characters.
It is a small extra job to read input from the terminal session and echo characters out to the screen.  We can now do terminal I/O, another huge step forward.

Bootloader

Each time I want to test a program I have to take it out of the RPI, copy across a new kernel.img, replace in RPI and restart.  This quickly becomes irritating.  The marvellous David Welch has written a simple bootloader program.
To use this you put bootloader06.bin as kernel.img on the SDcard.  Now whenever you power up RPI a bootloader is started.  The bootloader waits for a program to be transferred across the serial link using xmodem file transfer.  I used minicom or ExtraPutty to transfer the file.  Pressing 'g' causes the program to run.  To use a different program simply power cycle the RPI and load another executable.
This is another huge step forward for me.  It gives me a practical environment to work in.


Saturday, 6 June 2020

Linux AV

In May I had a note from Virgin Media, my ISP, to say that azorult, some malware, was present on a device using my internet connection. It was helpful of them to provide this but not specific enough for me to isolate the problem.

azorult is malware often spread by phishing, infection could occur from clicking on bad links. Information on the internet doesn't pin it down particular types of device.  My devices include PCs, ipads, android phones, rpi, music devices, ip cameras.  There are also visitors with other devices.

My first step was to warn home users to stay alert as a warning has been received.  I then needed to check virus protection on my systems is uptodate.  For hardware devices, there isn't much I can do.  Virus checking on phones is done automatically and Windows devices have updates applied automatically.  That means my main effort was geared towards Linux.

I don't generally virus check RPi systems as they have very limited external connectivity.  In this case, since infection is potentially inside the LAN I need to review them.  There dont appear to be many virus scanners appropriate to linux, Clamav, which is owned by Cisco seemed to be good and widely used.

On installation the software runs freshclam to download virus signature database files.  You then use clamscan on a file selection to check for viruses.   I ran a complete check on RPi SD cards and saved the results.  Mostly the checks worked well.  I had problems with the newest RPi 3+ running buster and split the scan down into chunks to narrow down the problem, which then "went away".  RPI 1+ had insufficient memory for a scan so I created a samba share for the root drive and successfully scanned from RPI 3+.

Results were encouraging, no viruses were found.  That leaves me with some confidence that I don't currently have a problem and have taken responsible efforts to protect us.

Thursday, 28 May 2020

Linux FrameBuffer

I found a 4" touchscreen for RPi in my cupboard the other day.  I actually purchased it 3 years ago and had forgotten about.  I thought I should try it out and see what it can do.  It turns out to be a Waveshare 480x320 touchscreen.  Initially I wanted to use it for output/display.  I certainly don't want to run Xwindows on it so I needed to find out what is possible.

Installation


I plugged it in to an RPi 2B and installed the driver software. I run RPi servers headless and I was pleasantly suprised to see that the RPi console startup messages  are displayed.  It looks nice but isn't useful as the screen / characters are very small and I don't have the ability to type in to the console or login.



Display Text


To send output to a terminal it is easiest to do if the device is logged in.  Using raspi-config we can tell linux to login to the console as pi at startup.  We can now easily display messages, e.g.:
  echo ‘Hello little screen’ > /dev/tty1

To clear the screen or display text at specific positions we use control characters.  I have a fondness for these from my DEC PDP-11 programming days when a DEC VT100 was considered an excellent screen and I used it extensively.  I can clear the screen with:
 echo -e '\e[2J\e[1;1H' > /dev/tty1


Images and videos

It is surprisingly simple to play videos on the frame buffer with vlc:
 vlc starwars.avi > /dev/fb0
VLC can actually display images such as:
 vlc AtTheBeach.jpg /dev/fb0


As everything is a file in linux I can take a screen snapshot with:
 cat /dev/fb0  > screenshot.raw
and then redisplay it later with:
 cat screenshot.raw > /dev/fb0

However the best way to display images is to install the package fbi (framebuffer image) which gives you lots of image capabilities.




C Programs using the Framebuffer

A great tutorial is provided by Raspberry Compote explaining how to use the framebuffer in a C program.  It makes the whole process fairly straightforward.

Step 1 is to interrogate Linux to obtain characteristics of the device, in our case a 480x320 32bpp screen.
This is followed by a program to create a memory map for the buffer in RAM and write pixels to it.  Again it isn't very complicated and you end up with a pattern on your screen.

After that you need to investigate formats, palettes and colours in a little detail so that you can use the best approach for your application.  In practice, for your own programs an 8 bit format is preferred.  You have 16 basic colours provided and you can define the remaining 240 colours in the palette as needed.

Image formats and processing can become very complicated so C programs are probably best suited to displaying patterns, but it is great to have a bit-mapped screen available.

As a quick test I wrote a C program to display a grid on the screen and incorporated with the colour display.


Lvgl

In this post we are concentrating mainly on outputting to the framebuffer, however, its value lies in being a touch screen.  For touch screen usage we will be using lvgl (little versatile graphics library). As an introduction I found a great demo which uses lvgl to write a number of objects ("widgets") to the screen, for example text and buttons.  A subsequent blog will describe progress on touch related functions.











Wednesday, 22 April 2020

Floureon IPCAM

A little while ago I purchased a very cheap Floureon Wifi IP Camera webcam.  It comes with a short user guide to setup the device.  You start by downloading the Camhi software onto your phone or ipad.  The webcam has wifi and ethernet connections.  You introduce the handheld device to the webcam by holding them physically close together and allowing the ipad to start an audio dialog with the webcam to establish its ip address.  Once they have "paired" in this rather novel fashion you can look at the camera output on the ipad and swipe in any direction on the screen to pan/tilt the camera so that it shows what you want to see.  The picture quality is detailed and clear with good colour, sound is also available, I found the movement functions tedious.  You can take snapshots or record videos and optionally save them to an SD card. I couldn't find any further details about the webcam online so at face value you have a very nice webcam with an interface to a handheld device.

My current application requirement is to provide a nightime garden webcam to look for activity, particularly from foxes.  I need to record video when motion is detected in the picture so that it can be looked at the next day.   I have a Raspberry pi noir webcam which isn't being terribly useful for this purpose although it did previously carry out great service as a puppy cam in our kitchen.

As the supplied CamHi software doesn't have the functions we require (in particular motion based recording), it is necessary to find other ways to access the webcam via its network interface. A very helpful open source site ispyconnect provides details of URLs which can be used to access webcams.  We know our ip address 192.168.0.175 and user/password admin:admin.
To take a snapshot from the camera we can use a chrome URL:
 http://admin:admin@192.168.0.175/snap.jpg
To stream a video from the camera we can Open a network stream in vlc with:
 rtsp://admin:admin@192.168.0.175/1/h264major
The video can be streamed at a lower resolution with:
 rtsp://admin:admin@192.168.0.175/2/h264major

For the picamera we have previously used linux motion software very successfully to process a video stream and record only when motion is detected.  We can utilise the stream coming from the webcam by specifying in motion.conf configuration file netcam_url the rtsp streaming address.  Once we restart the motion service (on RPi pi34) we can view camera output at http://pi34:8081.

I am quite keen to be able to be able to control pan/tilt from linux or PC.  I found that I can login to its network interface http://192.168.0.175.


In addition to showing the camera view it allows me to use pan and tilt.  "Left and right", "up and down" buttons cause the camera to scan throughout its range.  You can view two streams, full detail  (1280x720) or smaller (640x352).  There are 8 preset positions you can setup.

The settings tab is informative, allowing you to see/set many more features on the camera (e.g. turn IR on / off).  The network page includes settings for ONVIF, which is already on at port 8080.  This should allow me to use a general purpose ONVIF client to control the camera.  ispyconnect has a suitable client Agent DVR which I could install on Windows.


After a little experimentation I was able to setup the camera in ispy Agent UI and see the camera.  It also gives me a device service URL http://192.168.0.175:8080/onvif/devices .  Using Ispy PTZ controls are a bit better.

I was now ready to try out the solution.  It turns out, quite reasonably, that infra red light reflects well off glass (which is designed to let optical wavelengths through) so attempts at a setup inside were not successful.  As the weather is good I took the IPCAM outside and set it up in the garden.  Using the web interface I set the IR leds on continuously.  I setup linux motion software to record when movement is detected.  I set the sensitivity quite high to capture small changes, and I did capture various moths / insects whizzing by, but I did also see the fox doing his/her evening walk across the garden just before midnight.  The motion software worked well, it only recorded about 5 minutes video overnight so it isn't onerous to look through the recording.







Tuesday, 21 April 2020

Pi-Lite

It is a little strange to be posting about Pi-Lite.  It is a Raspberry Pi add-on which I received in 2015.  I picked it up and tried it out after a gap of a few years and I was again struck by what a lovely little product it is.  It came from a company called Ciseco which folded in about 2017 so the original documentation is no longer available.  However Matt Hawkins produced a tutorial I used at the time for familiarisation and he (his site anyway) is still around so I was able to find what I needed.

The board is simply a set of 14x9 monochrome LEDs which can be used to display images or scrolling text.  It is connected to the RPi using a serial UART and just needs to be plugged straight in to the RPi or 4 pin TX, RX, 5V and GND connections.  LEDs are controlled by an ATmega328 chip on the board which accepts commands input from the serial port and changes the displays accordingly. You can program individual pixels, bars, or download a 14x9 pixel image using commands.  By default information downloaded is treated as text characters and scrolls across the display as a message, which you can speed up or slow down.

To try out the board you start up minicom, a simple terminal emulator.  Any text you type in is displayed on the Pi_lite as scrolling text.  It makes more sense to control the display using a program and python-serial is a good way of doing this.  Matt Hawkins / Ciseco provide some good demos.  A stock ticker and weather report would have been fun but their data sources no longer work.

Pi-Lite doesn't have to be connected to an RPi, it works equally well on a PC serial port (with appropriate convertor).   Of course you may not be satisfied with the commands provided on the ATmega328 and will probably have already realised this is an Arduino processor.  You can modify the inbuilt program using the Arduino IDE to amend the Pi-Lite sketch.  Alternatively you can write your own sketch using the Pi-Lite Arduino library to control the display however you want.