Products > Programming

programming a single board computer as a machine controller (HMI)

(1/3) > >>

Simon:
What I am looking at is a single board computer - no specific one so only using standard features.
Minimize the OS stuff to speed up boot and keep the user out of the system.
send and receive serial port messages
run some sort of application to display data, menu's etc
save data to files.

Python seems to be the universal thing these days on single board computers. Is it the whole solution, or part of it?

SiliconWizard:
For RPi SBCs, Ultibo is an interesting solution. This is pretty much a baremetal environment with good support for almost all RPi hardware and the most complete I've run into. It requires programming in Pascal.

https://ultibo.org/

I don't know of any similar baremetal (no OS per se) framework for any SBC that would host a Python interpreter.
Baremetal frameworks for SBCs are rare enough already.
Apart from Ultibo, there's also a C++ library (Circle) for the RPi: https://circle-rpi.readthedocs.io/en
(being C++ might be plus for many compared to Pascal, but it's a lot less complete than Ultibo).

For anything other than RPi's, I have never seen anything like that. Doesn't mean it doesn't exist.

Simon:
I can't tie myself to RPi, I'm not sure bare metal is what we want, the whole point was that something with an OS would have support for what we want.

SiliconWizard:

--- Quote from: Simon on October 01, 2023, 08:21:23 pm ---I can't tie myself to RPi, I'm not sure bare metal is what we want, the whole point was that something with an OS would have support for what we want.

--- End quote ---

I see, in that case you can absolutely configure a supported Linux distro on the SBC to boot up with the minimum, enable only the strictly required services, and no desktop environment (this is often what takes the most additional boot up time and resources). Boot times in the order of just a few seconds are possible without much trouble. As this point having a working Python environment should be trivial as well.
So, that will require configuring a number of things manually if you start with the usual "customer" Linux distros that ship with these SBCs, but once it's done you can of course clone it as is in production.

I've used ArchLinux ARM ( https://archlinuxarm.org/ ) on SBCs (supports quite a few), because I'm used to ArchLinux and it's well adapted to preparing minimum Linux systems, but you should be able to do it with Ubuntu or Debian-based distros without much problem. You'll have again to strip them off significantly.

The one thing to really figure out is for the display part of it - install the minimum that can be used via a Python library (if Python is what you'll use) to implement GUIs and do not require a fully-fledged desktop environment.
Nominal had suggested using Qt for this kind of use case, then there's PyQt5 for Python. If he reads this, possibly he can give further guidance on how to setup Qt without a desktop environment, and ideally without X11 either.

Nominal Animal:

--- Quote from: Simon on October 01, 2023, 06:46:07 pm ---What I am looking at is a single board computer - no specific one so only using standard features.
Minimize the OS stuff to speed up boot and keep the user out of the system.
send and receive serial port messages
run some sort of application to display data, menu's etc
save data to files.
--- End quote ---
There are three major choices:
* Debian, Arch, or some other Linux distribution with wide hardware architecture support
* Yocto Project
* Your own minimal distribution; see e.g. OpenEmbedded and Linux from ScratchThe Debian/Arch/Distro approach is to install a minimal system that provides the services your application needs.  You'll probably want to rip out systemd, and use either one of the existing init systems, or write your own, to speed up boot and the system robust enough as an appliance.  See Devuan for non-systemd alternatives like non-systemd udev.

Yocto and OpenEmbedded are designed to help with constructing your own distribution, whereas Linux from Scratch and Beyond shows all the bits and pieces needed to get a working system together.

The next choice is whether you'll run X11, Wayland, or on pure framebuffer (actually DRI with OpenGL ES acceleration, and not a traditional framebuffer).  X will let you run more than one application, and write the UI or entire application in whatever programming language you prefer.  I don't know how well Wayland is supported on armhf or arm64, especially Mali hardware.  Qt supports bare framebuffer (EGLFS plugin for Qt5 or Qt6), and you can use it in a commercial proprietary appliance relying on the GPL or LGPL license; in that case, using Yocto and Python3 for at least the user interface is probably a good idea (as that makes the licensing boundary extremely clear, although dynamic linking is considered a derivation boundary nowadays).  You can always put any performance-sensitive sekret sauce in a dynamically linked native library, and access via Python built-in ctypes module.

Hardware-wise, optimize for I/O ops on small files, and not maximum streaming read/write.  PCIe or SATA SSDs will be your friends here, even for low-power SBCs.  MicroSD cards are dead slow in comparison.


--- Quote from: Simon on October 01, 2023, 06:46:07 pm ---Python seems to be the universal thing these days on single board computers. Is it the whole solution, or part of it?
--- End quote ---
If you have any performance-sensitive stuff, you'll want to do it in native machine code, and using C or C++ for these is quite common.

Using Python for the user interface makes development cycle easier and faster, because you won't need to build the software before running it.  The Qt project has a somewhat straightforward Yocto + Qt Embedded toolchain, where your development machine uses a standard X+Qt environment, but the target on plain OpenGL ES with no X.  If you do run an X server, you can also use GTK+ via gobject introspection bindings, i.e. gir, with Python.  Basically, both GTK+ and Qt are very 'native-like' in Python.  I even prefer to use their UI builder interfaces at runtime, constructing the user interface widgets from an XML file instead of generating the code to do so, but this can slow the UI coming up initially by a second or so, mostly because of the large number of I/O ops.  See Glade for GTK+ for a GUI editor that can generate such XML .ui files, and Designer for Qt.  (In case someone claims you need a commercial Qt license, skip their mistaken beliefs, and go read e.g. this instead.)

Also, I personally love the idea of the UI being something knowledgeable end users could tinker with, using only an SSH client and a text editor, without risking the entire device, as long as they keep a backup copy of the original Python code and UI files, of course.  While Tux is my mascot, it is not my idol, and I've done a lot of proprietary work too; the dynamic linking when using open Python UI code and any proprietary processing in native-only dynamic libraries is also a valid copyright license/derivation boundary, so it is an interesting option even for proprietary appliances.

The appliance is always run using a dedicated user account, not as root, unless one is an idiot.  Compared to a standard desktop Linux system, the GUI application replaces the 'greeter', the application that displays the standard login form.  You do not necessarily need a window or session manager at all. Isolating the UI under a single user account also means that if you set up your init system right, you can simply kill all processes running as that user, and restart X and the GUI application, without having to reboot the system if something hangs up –– for example, if your main GUI process crashes.

Using X and multiple windows means that you can extend your UI with external programs, which can help keep individual parts simple, and ensure you utilize multi-core SoCs to their fullest.  Even though these SBCs don't have desktop-like amounts of CPU power, they can still shift a lot of data around, so do not be too wary about using pipes and Unix domain socket pairs to move data between processes.

As to serial stuff, you'll want to use termios instead of any serial library: the libraries are all crappy, and the termios interface already exposes everything you need.  If you have dedicated devices, like USB-Serial dongles, use udev and udev rules to generate symlinks in /dev, and use those symlinks names directly without any lookup/serial port search nonsense.  With Python, you'll want to use a separate thread for each serial port, or even two threads if using asynchronous messaging instead of a conversational request-response interface.

I seriously believe the same regarding USB bulk transfers and usbfs /dev/usb/nnn/mmm interface –– avoiding libusb altogether ––, but saying that out aloud will probably start a flamewar.

Navigation

[0] Message Index

[#] Next page

There was an error while thanking
Thanking...
Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod