Use UART-A as standard serial port in C++ QT widget application

Trying to write simple test for uarts a,b,c on the base of QT widget C++. Ports b and c work fine.
When opening serial debug port A, command serial_porta = open(“/dev/ttyLP3”, flags) assigns -1 to serial-porta int variable. But if implement the login procedure using the same serial port a for debug and restart application this serial port becomes accessible from the code. And at the same time it also can de used for the debugging. So it opened simultaneously from C++ application and probably from kernel and could be used by both. This phenomena is observed also when release the app and set its container restart policy as “always”. Application successfully starts on power on, but we need login to torizon through the debug com port, then close app and when it restarts automatically everything becomes to work fine.
Is it possible to avoid login procedure and make com a accessible without it and restarting the app?
Thanks.

Greetings @Serghey,

This is an interesting interaction. Since UART B&C works fine I assume this is some weird interaction with UART A being used by the kernel for serial debug and by your C++ application.

Just to understand, do you want to use UART A as the serial debug and use it in your application? Or is disabling the serial debug for UART A an option for you?

As a test for this theory we can try disabling the login as you suggested and see it if helps. On your system edit the systemd service for serial-getty@ttyLP3. This can be done with sudo systemctl edit --full serial-getty@ttyLP3. In this file change the line ExecStart to ExecStart=-/sbin/agetty -a torizon -8 -L %I 115200 $TERM. Then save and close the file and reboot to apply the changes. This change will make it so that on ttyLP3 (UART A) the system auto-logins the console as the torizon user without password prompt. Please take care of the security implications of this. As a side-note other consoles like SSH or the console on the display will still require manual login. That is to say this change only affects the console accessed via UART A.

Best Regards,
Jeremias

Sorry Jeremias,
Please ignore the previous comment, file /etc/systemd/system/serial-getty@ttyLP3.service did not exist by default.
I copied the template and disabled the login procedure as you proposed. Now when the container starts after power on, uarta still not opened from my code. I have to close the app and then when it restarts automatically uarta can be managed from the code. Debug terminal works always.

Just to confirm login is now disabled but you’re still encountering the issue?

I suppose the issue isn’t related to the login but rather the kernel’s usage of the UART as as serial debug. Though only seems to be an issue on startup since restarting the app afterwards as you said fixes the issue.

Some questions:

  • If you make it so that your container doesn’t automatically start on boot. That is to say if you start the container after the system has booted, will this work? Perhaps you can delay the startup of the container till after boot has completed.
  • Do you need serial debug or can it be disabled? Furthermore can you do a quick test and disable serial debug, does this even solve the issue?

Best Regards,
Jeremias

You would need to create a new systemd service that starts your container. In this systemd service you can then use the “Before” or “After” arguments to control the order in which this service is executed relative to other services.

The solutions in this forum would work as well: https://superuser.com/questions/544399/how-do-you-make-a-systemd-service-as-the-last-service-on-boot

Best Regards,
Jeremias

Glad I could help, thank you for sharing your success. This will be useful information for others attempting to do the same.

Best Regards,
Jeremias

I don’t think you needed to do all that.

You just need to create a service file in /etc/systemd/system. Here’s the bare bones skeleton of one:

[Unit]
Description=<description about this service>

[Service]
ExecStart=<script/command which needs to be executed>

[Install]
WantedBy=multi-user.target

Then to make it so that this service starts after another service you can use the After argument which under the Unit section. So to start after serial-getty you can have something like, After= serial-getty@ttyLP3.service.

Finally once your service file is done you can enable it to start automatically on boot via systemctl enable <name of your service>.

Making it so that this service only starts after serial-getty has started. Then to debug your service you can use systemctl status <name of your service> or journalctl -u <name of your service>.

Best Regards,
Jeremias

one more question, not related for this thread:
what is the best way to transfer png image file from windows PS to colibriIMX8 module?
Thanks in advance.

Thank you, Jeremias.
After implement the command : “sudo systemctl edit --full serial-getty@ttyLP” nano shows the content below and there is no ExecStart line there. Please refer to:

[Unit]

Description=Serial Getty on %I

Documentation=man:agetty(8) man:systemd-getty-generator(8)

Documentation=systemd for Administrators, Part XVI

PartOf=dev-%i.device

ConditionPathExists=/dev/%i

After=dev-%i.device systemd-user-sessions.service plymouth-quit-wait.service getty-pre.target

After=rc-local.service

We need at least 3 serial ports for our application and currently trying not to deal with the 4-th colibri serial port since it is not enabled by default and I believe the kernel should be recompiled to make it work.
If start container not automatically uart-a works from code. During automatic start application starts first and just after that login info appears in the debug window. Looks like getty service provides login after container starts. Is it any way to start container after getty automatic login procedure completed?
Of course it will be better to keep the serial debug option until application starts, so better do not completely disable it, especially what we see it is still available after our app starts the second time and they both can access serial at the same time.

Thank you, Jeremias.

do not have experience for service creation in Linux. Tried to follow one to one the following procedure “The best way to make sure our service will execute after all other enabled services is to create your own target and make it run after multi-user.target.”
Just wrote simple script for “my_last_command.sh” to put some message on console. Assumed it should display after automatic logon, but nothing happened. where the error could be? This is procedure which I used taken from the link you shared:

1.Create a target unit /etc/systemd/system/custom.target file with AllowIsolate=yes
[Unit]
Description=My Custom Target
Requires=multi-user.target
After=multi-user.target
AllowIsolate=yes

2.Create you service unit file /etc/systemd/system/last_command.service with After=multi-user.target and WantedBy=custom.target
[Unit]
Description=My custom command
After=multi-user.target

[Service]
Type=simple
ExecStart=/usr/local/bin/my_last_command.sh

[Install]
WantedBy=custom.target

3.Create the /etc/systemd/system/custom.target.wants directory

4.Link your last_command;service into /etc/systemd/system/custom.target.wants
ln -s /etc/systemd/system/last_command.service
/etc/systemd/system/custom.target.wants/last_command.service

5.Reload systemd with systemctl daemon-reload

6.Set the system default target as custom.target
systemctl set-default custom.target

Thank you very much for the great support!

Now debug serial port is accessible from the app after powering on.
We add 1 second delay before starting the container without it port is still unreachable.
Best regards.
Serghey.

That depends. Under development?

I would suggest you use WinSCP and transfer it over SCP.

If I’m not wrong, Windows PowerShell does also support SCP native command, so you can use it as well.

Best regards,
André Curvello

Thank you.

It is development stage, splash screen change.

We used puTTY, also works well.

Best regards,

Serghey.

Glad it worked out!