Disable console over Serial in Dev on RPi3?

I am working on a Raspberry Pi3 and using a serial connection over GPIOs 6, 8, and 10 to communicate with a hardware board using G-codes. In prod, this is working fine, but the dev OS seems to offer a console over these pins, which is disrupting the communication. Because of this, I’m not able to use the development image which would be really nice since it has some great features.

My question is how can I disable the console over serial in dev? These settings don’t seem to be in either config files, since my prod and dev configs are identical.

Here is some information about the two ‘devices’ (same device actually, just swapping sd’s):

Prod versions:
>HOST OS VERSION: Resin OS 2.0.8+rev1 (prod)
Dev versions:

HOST OS VERSION: Resin OS 2.0.8+rev1 (dev)


FROM resin/raspberrypi3-python:3.5-slim-20170705
WORKDIR /usr/src/app
COPY ./src/requirements.txt ./requirements.txt
RUN apt update
RUN apt-get install gcc
RUN pip install -r requirements.txt
COPY . ./
. CMD [“python”,“src/start_server.py”]

This is also my first project with Resin, Containers, and Pi so, if you see something else I might be missing, any other advice or guidance on best practices is more than welcome.

Thank you!!

1 Like

I believe you can ssh into the development image and use systemctl disable serial-getty to disable the serial console which should free it up, however one of the device team would know more, @agherzan @floion

Hi, yes you can if you first ssh to your machine and then do the following steps:

  1. First disable read-only rootfs:
    # mount -o remount,rw /

  2. Then mask the serial getty service:
    # systemctl mask serial-getty@serial0.service

Then reboot the board and you should be all set.


@floion @Page
I had the same problem and this solution works. I have a few question though :

  • Are the remount and reboot only necessary to persist the service state or are they necessary to stop the service ?
  • I tried systemctl stop serial-getty@ttyAMA0.service which didn’t produce any error, but didn’t free my serial port. Is it necessary to do the operation on serial0 and not on ttyAMA0 to make it work ?

Hi, the remount is needed for persistency reasons.
Yes, you need to mask the serial-getty@serial0 and not the ttyAMA0 one as systemd uses the first one to spawn a getty over.

1 Like

This manip worked on a ResinOS 2.2.0+rev1 (dev), but now when I switch the MicroSD card for a ResinOS 2.3.0+rev1 (dev) and I do the exact same commands :

# mount -o remount,rw /
# systemctl mask serial-getty@serial0.service
# systemctl mask serial-getty@ttyAMA0.service
# reboot 
# cat /dev/serial0
# cat /dev/ttyAMA0

I get no output. As soon as I put back the ResinOS 2.2.0 card in the raspberry,

# cat /dev/serial0
# cat /dev/ttyAMA0

give me the expected output stream.

Any clue why this is happening ? or what should I look for ?

So, you masked the service(s) and then you say that cat’ing the device gave you the expected output? What expected output is that?

We have a sensor plugged on the GPIO of the Raspberry, it’s writing clear text data readable on /dev/ttyAMA0. The sensor doesn’t require any driver or lib.

Also I have to say, our whole work on raspberries using resin.io is about collecting data from this sensor.

I’ve just tried on a 2.2.0 prod ResinOS, where I can see /dev/serial1 is linking to /dev/ttyAMA0 but I can’t get anything with cat on these.

To be clear : all my tests are on the same device where I just switch the card.

Please tell me if you need antyhing more to figure this out.

Just to clarify,
is it working on 2.2.0 or not? Earlier you said it used to work on 2.2.0

Working on 2.2.0 dev after following your steps, not working on 2.2.0 prod (where I can’t follow the steps, right ?)

On the .prod image, there is no need to do these operations as the serial connection is left untouched for users to use.

So with regards to serial connection, a .prod image is a .dev image with these steps done.

Ok, so what could explain the different behaviours on different ResinOS ?

On Resin OS 2.2.0+rev1 (dev) (host OS or inside a Debian 8 container) :

root@94c9c84:/# cat /dev/ttyAMA0
HCHC 000129343 \
HCHP 000000063 \

On same device, on Resin OS 2.2.0+rev1 (prod) (inside a Debian container since host is not reachable) :

root@e51bd75:/# cat /dev/ttyAMA0
(nothing displayed)

Do you have any overlay loaded in any of the images?

Let’s talk only about ResinOS without any docker image maybe, since it’s reproductible this way.

UPDATE : Hey, I think I have some idea :

Sometimes /dev/serial0 is linked to /dev/ttyAMA0, and sometimes it’s not, it’s /dev/serial1 which is linked to /dev/ttyAMA0. And you told me a month ago that what is important is masking the serial-getty@serialx, not masking the serial-getty@ttyAMA0.

So maybe the first step would be to check which /dev/serialx is linked to /dev/ttyAMA0, masking serial-getty@serial0 won’t do the trick every time.

Well it’s a theory for dev OS though, not for prod OS, except if you mask the yourself building the OS.

UPDATE 2 : I’ve just tried on a "Resin OS 2.0.8+rev1 (dev) " masking everything and rebooting, but I can’t display anything cat’ing all /dev.

So it would mean only one version of Resin OS is allowing me to see data on /dev/ttyAMA0, so I know it looks like I’ve installed something special on this card, but I have not.

Is it possible something installed in the Docker image influence what’s happening on the host ?

So far I thought the only interactions where :

  • volumes (containers writing datas visible by host in volume directories)
  • ports (you set a port mapping so each listening container port corresponds to a listening host port).

Are there low level interactions which would allow some process running in the container to write on /dev/ttyAMA0 from the container ?

UPDATE : one thing I’ve just learnt is the baudrate has to be set to 1200 to receive anything.

So on the working card, if I do stty -F /dev/ttyAMA0 9600, my cat doesn’t display anything, and if I set back to 1200, it works back, clearly it’s a necessary condition. And stty may persist the baudrate setting somewhere, since it’s always working on our first card, even after reboot.

Knowing this, I’ve tried to set baudrate on my other cards with no sucess.

Ok, this time I think I got it (can’t test right now). So, the answer would be “no Docker layers won’t influence what’s happening on the host” but RESIN_HOST_CONFIG_* application variables set in “Fleet Configuration > Application config variables” will !

So in my case, the 3 things to do (only 2 in prod ResinOS) to make the serial port readable were :

  1. Disabling port services (watching carefully the serial0/serial1 links or disabling everything) :

    mount -o remount,rw /
    systemctl mask serial-getty@ttyAMA0.service
    systemctl mask serial-getty@serial0.service
    systemctl mask serial-getty@serial1.service

  2. setting the baudrate to a lower value using “stty” (which seems to be a persistent setting through reboots).

  3. Configuring some variables in /boot/config.txt through “Fleet Configuration > Application config variables” in resin.io :

    RESIN_HOST_CONFIG_dtoverlay pi3-miniuart-bt
    RESIN_HOST_CONFIG_enable_uart 1


Great. I dd ask you about any loaded overlays :slight_smile:
The overlay you loaded switches bluetooth from the main full serial port over to the other serial port, leaving ttyAMA0 available for your device to use and send data over to the pi.

Mmmm ok, so that’s what you meant by “overlay”… To me you were talking about some docker layer (one of Docker storage driver is called “overlayfs”).

Cool, glad things are sorted now.

@Tristan107 in this context Raspberry Pi Device Tree Overlays. They modify the behaviour of the system quite a bit, as you see it as well, so knowing what overlays are enabled makes a big difference, and helps us debug. So for example here the pi3-miniuart-bt was the relevant device tree overlay, which changes the availability of the serial port.

(Also, I think you don’t need the enable_uart setting anymore, just the pi3-miniuart-bt setting. I think…)