i2s Mems Microphone on RaspberryPi -> Balena

Trying to add audio support for my Camera application.
In raspbian I use Alsa Mixer and this guide to get it going simply.

Hoping to recreate this within a container, just wondering if anyone has successfully enabled an i2s device, or if this is outside the possibility of balenaOS today.

Hi there – thanks for posting. It looks like this uses the GPIO interface to connect to the Pi – if that’s correct, there shouldn’t be anything keeping that from working. You can read more about GPIO interfaces and balena here: https://www.balena.io/docs/learn/develop/hardware/gpio/

Give that a try and let us know how it goes for you!

All the best,

Following up:

Fairly stuck on this as it requires a custom kernel module.
Basic steps are found here: https://github.com/adafruit/Raspberry-Pi-Installer-Scripts/tree/master/i2s_mic_module

Option to use DPKG

~1) $ sudo apt install dkms raspberrypi-kernel-headers

  1. $ sudo dpkg -i snd-i2s-rpi-dkms_0.0.2_all.deb

For this to work, remember to modify these first:
/boot/config.txt -> dtparam=i2s=on
/etc/modules -> snd-bcm2835
remember to reboot

  1. sudo modprobe snd-i2s_rpi rpi_platform_generation=0

Option to use provided makefile

sudo make install

Option for using DKMS

Download .deb file

sudo cp -R . /usr/src/snd-i2s_rpi-0.0.2 (or whatever version number declared on dkms.conf is)
sudo dkms add -m snd-i2s_rpi -v 0.0.2

Build and load

sudo dkms build -m snd-i2s_rpi -v 0.0.2
sudo dkms install -m snd-i2s_rpi -v 0.0.2

All of the issues are mainly coming down to lack of /lib/modules/uname/build folder exisitng

Additionally concerned about /etc/module and not starting at boot
Raspberrypi-kernel-headers does install successfully

I’m continuing a variety of methods including balena provide kernel-module-build but am a bit of a beginner, any guidance would be much appreciated. The microphone is essential to the app.

Using https://github.com/balena-os/kernel-module-build

and This Kernel Module

All I did was replace “example module” with the above module.

Build.sh returned error “Could not find headers for ‘raspberry-pi’ at version ‘2.54.2+rev1.dev’, run ./build.sh”

Any ideas on where I am going wrong?

hey there,

I think you are on the right track here, ie, copying the module sources into the example module folder. The kernel headers are available. The build script loops over all the available headers and tries to match it.

It eventually finds it

Could not find headers for 'raspberry-pi' at version '2.54.2+rev1.dev', run ./build.sh list

Could not find headers for 'raspberry-pi' at version '2.54.2+rev1.dev', run ./build.sh list

Could not find headers for 'raspberry-pi' at version '2.54.2+rev1.dev', run ./build.sh list

Building images/raspberry-pi/2.54.2+rev1.dev/kernel_modules_headers.tar.gz...
--2020-10-08 06:25:38--  https://files.balena-cloud.com/images/raspberry-pi/2.54.2%2Brev1.dev/kernel_modules_headers.tar.gz

Resolving files.balena-cloud.com (files.balena-cloud.com)...,,, ...
Connecting to files.balena-cloud.com (files.balena-cloud.com)||:443... 

HTTP request sent, awaiting response... 
200 OK
Length: 12246790 (12M) [binary/octet-stream]

Saving to: ‘kernel_modules_headers.tar.gz’

     0K ........

I agree this is not the best UX, so I will add an issue to make the messages more intuitive. thanks for the feddback.

Can you confirm that this eventually works for you too please?

I can confirm it gets past downloading kernel headers.

Gets to kernel building

As it finished MODPOST reports 0 modules

When i go into the container and try run.sh
I am unable to load modules

I have enabled dtparam i2s and sound in device configuration. Do you have any other ideas on how I can move forward? Let me know if i can provide more information

Hi, can you do this change in the Makefile and try again:

-obj-$(CONFIG_SND_I2S_RPI) := $(MOD_NAME).o
+obj-m+= $(MOD_NAME).o


This made some progress!

However the .ko file isnt there when I ssh in and try and run it manually.

I know it has some dependencies, maybe I should run them first?



I had a Respeaker HAT working fine on my Pi, my repo was here GitHub - richbayliss/resin-seeed-voicecard: A simple example of using the Seeed ReSpeaker voicecard with Resin.io but it’s out of date now. The issue you’re facing here looks more like a problem with the modules being in the wrong place. I would try running the container and inspecting the filesystem to see where the Dockerfile put them. If they’re missing, that’s your problem, and if they’re in the wrong place then you can adapt your Dockerfile appropriately.

if anyone has successfully enabled an i2s device, or if this is outside the possibility of balenaOS today.

In answer to your original question, this is doable and possible as a container but you just need to consider the facts of container-based processes and work with/around those. You seem to be on the right track here though :+1:

Thanks Rich! I’ll check out your repo and dig more. I’m definitely getting closer, slowly XD…

The support so far has been incredibly value. I’ll post an update as I move along.


I got the microphone working after making this change in the Makefile.
+obj-m+= $(MOD_NAME).o

I noticed that the order in which modules load tend to have an effect on their configuration. Wondering if there is a way to change this within balena…

Additionally, the module does not survive a reboot. The output folder disappears and I cannot load the .ko file.

Trying to work on this by getting persistent storage on the folders in which the module touches, mainly /usr/src/app where the output folder lies, and /proc/asound/ where sound card configuration is.

Hello there,

Thanks for the status update. Good to hear that you got this working.

I believe this might help you with your issue here: Preload Device Tree Overlays?
On this post, my teammate explains how you could bake in the custom dtbo into the image before flashing your RPi. Have you tried that already?

On other news, one of my balena teammates recently gave a presentation to the team on improving this workflow to load kernel modules. Not sure when we will release that feature but it will get easier to load kernel modules.


Hmm, I’m not sure if DT overlays will work because I have a .ko file…

Will look into it a bit more tho.

Glad to hear about more custom kernel support! It is super nuanced as kernels are loaded and compiled in a so many different ways (as I am learning XD)

Right now I can see my soundcard being loaded in /proc/asound/cards
But ALSA does not recognize it even after boot. Pretty much just checking every file that ALSA may interact with to see where the difference lies. I think it may be more of an ALSA issue at this point as my research says once its in /proc/asound/cards. and dmesg gives the thumbs up its loaded.

Hey there,
Glad you are making progress. Maybe you can also reference our audio block here https://github.com/balenablocks/audio for some inspiration to get this going?

hope this is helpful


Adding “ENVUDEV = on” in the Dockerfile

and --devices “/dev/snd:/dev/snd” to docker-compose got ALSA to recognize the sound card.

Thank you Balena Team, this was seriously helpful! I will be posting some documentation about the entire project as I progress which I hope can be helpful.

Thanks for sharing your find Dylan and glad it worked