Author Topic: Choosing my SBC hardware.  (Read 10302 times)

0 Members and 3 Guests are viewing this topic.

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18885
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: Choosing my SBC hardware.
« Reply #25 on: May 30, 2025, 09:47:53 am »
Oh, but RPi still reference the Debian OS names for their own like bookworm. Presumably that is what it is anyway. One thing that leaves me wondering is that the RPi5 specifically: Currently there is no support to Raspberry Pi 5 as it doesn't have enough support in upstream Linux. Says https://wiki.debian.org/RaspberryPiImages

But PI OS is Debian based sharing its names....
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18885
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: Choosing my SBC hardware.
« Reply #26 on: May 30, 2025, 09:29:44 pm »
Well Im struggling to get my kvaser adapter to be recognized in linux (debian), downloaded drivers and followed instructions. I'm assuming that to connect to a cheap CAN adapter that is actually on a serial port via USB is going to be worse and certainly won't work with socket CAN and QT. But the lattepanda (got one arriving tomorrow) has a serial port. So I am probably going to end up using one of the serial ports on the lattepanda and connecting my own microcontroller with the bosch MCAN controller in it to interface. I expect that QT will be easier to setup with a real local UART than a CAN port that is on the end of a chain of three different comms systems.
 

Offline Karel

  • Super Contributor
  • ***
  • Posts: 2539
  • Country: 00
Re: Choosing my SBC hardware.
« Reply #27 on: June 01, 2025, 06:36:33 am »
But the lattepanda (got one arriving tomorrow) has a serial port.

You do know that the RPI has a serial port as well?
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18885
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: Choosing my SBC hardware.
« Reply #28 on: June 01, 2025, 12:26:41 pm »
Yes I know, now that I will roll my own CAN bus adapter that can work as a real time coprocessor for the system it's irrelevant what board I use.
 

Online Psi

  • Super Contributor
  • ***
  • Posts: 12588
  • Country: nz
Re: Choosing my SBC hardware.
« Reply #29 on: June 01, 2025, 12:35:26 pm »
Well Im struggling to get my kvaser adapter to be recognized in linux (debian), downloaded drivers and followed instructions. I'm assuming that to connect to a cheap CAN adapter that is actually on a serial port via USB is going to be worse and certainly won't work with socket CAN and QT. But the lattepanda (got one arriving tomorrow) has a serial port. So I am probably going to end up using one of the serial ports on the lattepanda and connecting my own microcontroller with the bosch MCAN controller in it to interface. I expect that QT will be easier to setup with a real local UART than a CAN port that is on the end of a chain of three different comms systems.

One thing of note, (i have not checked this exists on every LattePanda versions as there have newer ones), but LattePanda's always included an ATMega MCU on the board as well. This was very useful, as you could design and upload your own code to an MCU already build into the system with IO into the system.
You could design your own power on/off sequences based on sending some UART data to the mcu, or keep an eye on things over USB to the main pc.  etc..

Edit: Looks like both the 3Delta and Sigma have a ATmega32U4 Co-Processor.
« Last Edit: June 01, 2025, 12:50:53 pm by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18885
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: Choosing my SBC hardware.
« Reply #30 on: June 01, 2025, 01:12:17 pm »
Well my main use of a micro controller will be as my own CAN bus adapter, my trusty SAMC series has 2 very nice and capable CAN controllers in them so I won't really have much use for the onboard AVR.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18885
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: Choosing my SBC hardware.
« Reply #31 on: June 01, 2025, 01:45:35 pm »
using the lattepanda option means that I don't need to spend the next year decoding this: https://wiki.qt.io/Cross-Compile_Qt_6_for_Raspberry_Pi into English. As with all Qt stuff what was written for the beginner in terms of instructions clearly is aimed at those with a decade of experience in software development but are new to just Qt.....

I'm considering FLTK again, at least the write stuff in English.
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 5083
  • Country: gb
Re: Choosing my SBC hardware.
« Reply #32 on: June 01, 2025, 02:22:42 pm »
Have you also considered ZimaBlades?  :o :o :o
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18885
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: Choosing my SBC hardware.
« Reply #33 on: June 01, 2025, 04:16:05 pm »
They have no storage and no RAM, their default setup seems to be a bundle of wires before you attach anything to them that is actually the outside world but good to know that there are other x86 boards out there.
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 8349
  • Country: fi
    • My home page and email address
Re: Choosing my SBC hardware.
« Reply #34 on: June 01, 2025, 04:51:01 pm »
Note that Makerbase CANable 2 is a low-cost ($17) isolated USB to CAN adapter, supported by Linux SocketCAN, which you can use via QtCANBus and its socketcan plugin, or write your own AF_CAN socket code.  As it is an USB device, the SBC hardware architecture doesn't matter much, as long as it is supported by the Linux kernel.

You set up the CAN bus similar to any other network (ifconfig et al., for example), and the application does not need to worry about device names or paths.  If you write your own low-level socketCAN code, it is very similar to TCP/IP networking code.  Both raw sockets (AF_CAN, SOCK_RAW, CAN_RAW) and broadcast-managed sockets (AF_CAN, SOCK_DGRAM, CAN_BCM) are available.

Key point: you can use the same USB-CAN adapter on your development host, and write the application software there; you don't need to develop on the target architecture, as long as you test thoroughly.  (With C and C++, it's mostly assumptions about int size/range and such that bite you; better use <stdint.h> explicit-size intN_t, uintN_t, et cetera.)
It also means you can switch SBCs even across architectures, without having to rewrite your application.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18885
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: Choosing my SBC hardware.
« Reply #35 on: June 02, 2025, 06:04:03 am »
Yes that is an option. As I said isolation is all well and good but I can easily render it useless ;) but it's worth the extra 5 bucks.

What is slcan? I'm sure I have seen that elsewhere, something to do with a can bus adapter on a serial link? Unfortunately I have no OS programming skills as of yet other so I don't want to mess with drivers myself.

The advantage of my own controller would be that I can pre-disect CAN open for example and possibly carry out other functions that benefit from the real time nature of a micro controller. I don't know if time stamping is done well by cheap adapters but as I already have a body of CAN code written up I know I have all of this and some functions could be done by the micro instead of the main system having loads more messages delivered to it and having to work it all out. The main PC device would just see the actual data and status of the CAN system. For example, I keep track of the heartbeat messages from all nodes, I can either send those straight through or as I have time stamps on all messages received with a resolution of 16µs I can simply tell the PC the overall bus status.

I may also need the odd button or encoder input which a micro already acting as CAN bus bridge can also handle although I did once vow that each function would be it's own micro but then this is a single standard item so making up something specific makes sense.
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 8349
  • Country: fi
    • My home page and email address
Re: Choosing my SBC hardware.
« Reply #36 on: June 02, 2025, 08:55:00 am »
As I said isolation is all well and good but I can easily render it useless ;) but it's worth the extra 5 bucks.
I use isolators for all sorts of purposes, and get ridiculed for it here! ;D

It's mostly that wall warts without protective ground (like USB power supplies) tend to have a different 0V output potential that those that do (like desktop and laptop power supplies), because we do not have polarized (live and neutral) sockets, they're both live.  So, connecting an SBC to the same wall socket than my computer/laptop does not mean they have the same 0V ("GND") reference potential; it can differ by a couple of hundred volts.  Also, when you need a low-noise frontend for some stuff, even if they share a ground it is a darn nice way to isolate the power domains, stopping the digital noise from affecting the frontend – especially nice when using batteries for the frontend (for ad-hoc tooling, which is what I often do).  TI ISO67xx and ISO77xx also do automatic voltage level translation, too.

And I'm not ashamed to admit that they also act as a nice barrier when I do something utterly stupid, like accidentally supplying 12V instead of 5V to the target device; that only blows the target device and the isolator (and its frontend/drivers), not my computers or the rest of the USB adapter.  My-own-bacon protectors!

What is slcan?
It is the name of the Linux serial line CAN driver that supports CAN adapters using serial and USB-serial, implementing only sending and receiving frames in hardware, and talk to the host using LAWICEL ASCII protocol.  Summary of the differences among various adapters here

You can use either the LAWICEL ASCII protocol to talk to these, or use the slcand daemon from the github.com/linux-can/can-utils package to bridge them to socketCAN.  With slcand in use, you can fully use them via socketCAN.

Note that you don't normally need those sources, as most Linux distros have these packaged, usually as can-utils.  The code is not architecture-specific, and should work on all architectures supported by the Linux kernel.

The advantage of my own controller would be that I can pre-disect CAN open for example and possibly carry out other functions that benefit from the real time nature of a micro controller. I don't know if time stamping is done well by cheap adapters but as I already have a body of CAN code written up I know I have all of this and some functions could be done by the micro instead of the main system having loads more messages delivered to it and having to work it all out. The main PC device would just see the actual data and status of the CAN system.
Sure!  If you use a microcontroller with native USB (like my current favourite, Teensy 4.x), you can program it to use the LAWICEL ASCII protocol, or your own.

I personally prefer to use multiple USB serial endpoints, so I can use one for the datagrams in some fixed format (noting that Teensy 4.x supports USB 2.0 High Speed, so you have plenty of bandwidth, and datagrams can be up to 512 bytes long), and the other for command and control.

I may also need the odd button or encoder input
Just add an USB HID endpoint exposing itself as a keyboard or joystick or gamepad, and the kernel will handle them, providing to your Qt application as events.
Or you could use a three USB serial endpoints, and use the third one for UI events.

Because the endpoints are separate character devices (that you can give persistent names using a trivial udev rule), it also means you can use a separate thread for each, using Qt events to propagate events to the main UI thread, or mutex-protected shared variables (just don't keep it locked for long).  This makes a huge difference in responsivity and performance, especially with multi-core SBCs.  Keeping the main Qt UI thread to just the UI events and not doing any "work" in it at all makes the UI extremely responsive even on slower SBCs; and using separate threads for the different types of communications buses not only allows you to use more of the cores, but it also lets the kernel schedule the treads optimally.  When data becomes available, the thread can be scheduled immediately, without waiting for the "next time slice".  It is a pattern that works extremely well with Linux SBCs.



Consider an example UI + MCU, where you have a single UI pushbutton controlling a LED or a relay.

The bad way to do this is to have the UI button handler write a command to the MCU whenever it is pushed on or off.

The optimal (but over-engineered for such trivial example) way to do this is to have two worker threads.  One thread sends commands to the MCU, and the other receives (status) responses from the MCU.  There are three commands: Query, On, and Off.  Each command is associated with a "line number", or rather an arbitrary numeric identifier chosen by the host, and will result in the MCU responding with a status block containing that identifier.  For this simple example, the status block is trivial, as it only contains the identifier and the state of the LED or relay.

When the program starts, the writer thread sends a Query command.  (Note that it is best to start the second worker, reader first, and only send that Query when the reader thread is ready; you can trivially use a Semaphore for this.  A mutex won't do, because they need to be unlocked by the same thread that locked them.)
When the reader thread receives the status block, it uses the Qt (thread-safe) sendEvent() to send the status update event to your main UI window.  In the window class implementation, you have a handler receiving the event, updating the button state to reflect whether it is on or off.  Default the button state to disabled (and not reacting to clicking), because before the first state event, we don't know whether it is on or off, and which command clicking on the button would generate.

Thereafter, whenever the button is pressed, it sends an event or queues a message to the writer thread to send an On or Off command, based on its current state.
Clicking on the button does not change its state (becoming pressed or released).  This means that quickly clicking on the button twice, too quickly for the MCU to respond in between, will result in two On commands, or two Off commands; never On + Off nor Off + On.
It is only when the reader thread posts the event to the UI thread that the UI thread updates the button state to reflect the device state.

One might think that having the UI button react to the press/click with such a latency (which is only a couple of milliseconds for such trivial cases, but can be human noticeable for more complex actions, especially those that require a remote response –– say a response from the engine management system) would annoy the user, but in practice, such a button tends to feel much more real: you can trust its state to reflect the real world, instead of the UI.

The numbering of commands and responses is useful when some commands involve remote work or timeouts.  Then, the two worker threads maintain a list of pending commands with timestamps (and timeout times) –– In Linux, best use CLOCK_BOOTTIME for real-world timeout times –– and one of them, or perhaps a third thread, does the cleanup/removal and sending the timeout/lost event to the UI thread.

In Linux, if you decrease the per-thread stack size to something reasonable (I use 4*PTHREAD_STACK_MIN), the cost of a thread is very small; basically just some RAM, even on small SBCs.  Using many rather than multiplexing work to a single thread is not only more effective (because you then use more of multi-core processor), but can also simplify the code, as long as you use thread-safe inter-thread communication methods; semaphores for async state changes, mutex locks, and condvars (with an associated mutex) for lists, queues, and arrays.  Qt does provide some that are thread-safe, plus mutexes, semaphores and condvars, but you can also use the pthread ones between worker threads.  You only need to use the Qt thread-safe ones when talking between the UI thread and a worker thread.  The Linux process schedulers are pretty darn well written, and even on a dual-core SBC having a dozen threads in a single application is no problem at all.  If well written along the lines I described above, where threads block on waiting for a message or input or output (instead of polling!), they tend to be faster and use the resources more fully than single-threaded applications.

Of course, that means you need to be proficient with multithreaded/parallel processing.  For me, it was just a change in mindset, releasing my expectations about the order of things, and moving to an event-based thinking model.  It works exceptionally well for user interfaces, too.



Apologies for the wall of text, but I had lots to say.  Hopefully at least some of it is useful!  If not, I hope you skipped most of it.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18885
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: Choosing my SBC hardware.
« Reply #37 on: June 02, 2025, 09:39:31 am »
Ah, I see. I have a cheap (waveshare?) USB/CAN adapter but if I query available ports with "ifconfig -a" I just see a serial port. I'll have to have a look at that.

Threading wise I am way behind you. I have no idea how any of this is done yet. I get the principle of multiple threads and that if I can break things down into multiple threads it will spread he load and let stuff be more responsive but that is it at the moment.

So I booted up my lattepanda, runs windowz 10 slowly as I'd expect with only 2GB of RAM and goodness knows what that SSD actually is. Installed the recommended Ubuntu on it and my god what a peice of garbage. As soon as I connected the wifi the mouse is leaving artefacts all over the screen but it's due an update when I get back tonight so might sort itself out. Ultimately I won't be using the desktop.

Not very impressed with the power up sequence. when power is applied you have to wait for the blue light on the processor module to go out before pressing power, yea sure, try telling some oaf in the street that who just wants to use his machine. I'm sure it will be fine as they'd have to plug the machine into its power source first before they get round to starting the HMI.
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 8349
  • Country: fi
    • My home page and email address
Re: Choosing my SBC hardware.
« Reply #38 on: June 02, 2025, 12:10:34 pm »
Note that slcand doesn't really do the translation itself; it simply opens the device, and sets a tty line discipline that connects it to socketcan network.  It then just sits there, waiting for a signal to exit (poorly done, using one-second sleeps instead of sigwaitinfo()), after which it simply resets the line discipline (tearing down the socketCAN device) and closes the socket.

Ah, I see. I have a cheap (waveshare?) USB/CAN adapter but if I query available ports with "ifconfig -a" I just see a serial port. I'll have to have a look at that.
USB-CAN-A, USB ID 1a86:7523?

It uses its own binary protocol (described here under Documentation), so it isn't supported by slcand (source) –– or rather, the ASCII format line discipline that the kernel drivers use to connect it to the socketCAN network.

CANable 2 is open source (I linked to the MakerBase one above), and uses the ASCII protocol and does work with socketCAN via slcand.  If you want, you can omit slcand in your own program, and instead do what slcand does, keeping the socket open for the lifetime of the application. 

With very little work, you can make your own application (scan and) open/attach and detach/close CAN devices when desired, too: all you need to do, is open the device (fd = open(path-to-device, O_RDWR | O_NOCTTY | O_CLOEXEC)) set the serial/tty properties (termios settings), then attach the N_SLCAN (17) line discipline using an ioctl(fd, TIOCSETD, N_SLCAN) call.
To detach (and when the application exits), use ioctl(fd, TIOCSETD, N_TTY) to revert it to a normal serial device, reset the original termios settings (flushing buffers, using tcflush(fd, TCIOFLUSH), and close the open descriptor using close(fd).

Note: If you use an USB 2.0 hub (with a "transaction translator" (name?), so that the host connection is high speed even when downstream devices are high or full speed or a mix), you definitely can use more than one adapter just fine.  USB 1.1 Full Speed is limited to 12 Mbit/s (or about 8 Mbit/s payload data in practice).
If you use e.g. eudev (or systemd with udev), you can use libudev to get low-latency notifications on device events, so don't need to scan (except at startup).

If you use an udev rule for supported USB adapters, you can add a symlink e.g. /dev/slcan-vendor^model^serial or some such, and then trivially list them all using scandir("/dev/", &namelist, filter, NULL), where
Code: [Select]
int filter(const struct dirent *ent) { return !strncmp(ent->d_name, "slcan-", 6); }i.e. returns nonzero for the names that match the slcan- prefix.  As the symlink name contains the vendor and model and serial in separable format, you can trivially generate the user-visible adapter names to select.  Perhaps a menu with currently known possible devices, checkboxable to enable, with a bottom entry "Rescan"?

Anyway, it would definitely be possible to add a new line discipline, say N_BINCAN (31), with a straightforward kernel driver adding support for Waveshare-like USB adapters to socketCAN.  The slcan kernel driver sources are at drivers/net/can/slcan/ (link to Linux kernel sources at Bootlin Elixir Cross Referencer), and is less than a thousand lines of C including whitespace and comments.  The key is the struct tty_ldisc_ops and struct net_device_ops defined drivers/net/can/slcan/slcan-core.c: everything is event-driven, and these are the callbacks the kernel uses to transfer data.

If I wasn't mentally broken the way I am, I'd whip up a driver and push it upstream.. but I am not able to anymore.

Threading wise I am way behind you. I have no idea how any of this is done yet. I get the principle of multiple threads and that if I can break things down into multiple threads it will spread he load and let stuff be more responsive but that is it at the moment.
I really like pthreads (native kernel-managed Linux threads).  It's not perfect, for example needing to initialize a pthread_attr_t structure to override the default stack size to something more reasonable can be annoying, but it is very comfy to me.  Then again, I've been using it for over two decades for real work...

Understanding the event-driven programming model is extremely important, as is the fact that ordering of accesses varies regardless of the one you think when writing it, unless you enforce it with either locking (mutexes, condition variables, semaphores, rwlocks) or thread-safe atomic operations (on systems with coherent caching).  Qt provides some thread-safe operations, and its own wrappers around the locking primitives; so does glib when using gtk.  You also avoid global variables (unless protected by locks), and instead prefer thread/work-specific dynamic allocations.  So better get comfy with malloc/realloc/free, too!

Also, to minimize boot time, look for an SBC that supports PCIe (NVMe) SSDs, and then pick one with the best random 4k read rate you can (considering price and availability and such).  That gives you a lot of leeway on systems integration, i.e. how much you need to optimize the boot process; you'll definitely see the difference.  Unexpected poweroff protection is difficult (mostly due to syncing to storage needing some real-world time to complete), but software power-off is very easy nowadays in Linux.  Usually, the physical power-on button is internally also wired to emit a please-power-off input event, which takes care of this on e.g. laptops, but does lead to the delayed-power-LED-turning-off effect.  If you do expect power to be cut off unexpectedly, consider a supercap or similar to give the necessary time window to shutdown cleanly; this too can be optimized via scripts, for example immediately turning off all USB ports (if they have power control), the display, etc., killing unneeded processes, before forcibly syncing and unmounting the storage device.
 

Online tggzzz

  • Super Contributor
  • ***
  • Posts: 23122
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Choosing my SBC hardware.
« Reply #39 on: June 02, 2025, 01:59:35 pm »
Threading wise I am way behind you. I have no idea how any of this is done yet. I get the principle of multiple threads and that if I can break things down into multiple threads it will spread he load and let stuff be more responsive but that is it at the moment.

Beginners tend to use threads too much, and often end up diddling thread priorities to work around today's problem (and re-introduce last week's problem). Thread priorities should be limited to "ISR", "emergency panic", and "everything else".

Much better to use an event driven architecture with an explicit FSM, where events are passed through mailboxes/FIFOs between between FSM execution contexts. Analogy: synchronisers between hardware clock domains.

An event is any single item that needs to be processed, e.g. an input captured in an interrupt routine, or a command from a front panel FSM, or the processing result, or output to be done etc. Each event is completely processed before processing the next event, thus avoiding all sorts of problems.

Debug the FSMs on your PC using mock events created in your test harness.

Debug the i/o and ISRs etc on your target hardware, with the events in FIFOs being directed to your logging on the PC.

When those are OK separately, drop the FSMs into the target hardware, and monitor the FIFOs to see what's happening in the real operating environment. Done properly, such logging can be extremely fast and left enabled in production systems - invaluable during system integration :)
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 
The following users thanked this post: spostma

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 8349
  • Country: fi
    • My home page and email address
Re: Choosing my SBC hardware.
« Reply #40 on: June 02, 2025, 03:08:28 pm »
Beginners tend to use threads too much, and often end up diddling thread priorities to work around today's problem (and re-introduce last week's problem).
I agree what you wrote in a microcontroller or realtime environment, but when using pthreads, that means standard Linux/POSIXy userspace application or service.
If you even think you need to change thread priorities to fix some issue there, you're doing something very wrong.

(I have only done that in very rare specific circumstances and only to fine-tune performance by ensuring that if there are more active threads than cores, a specific worker thread has priority.  I do often run entire processes nice'd and ionice'd to run in the background when resources are otherwise idle only.)
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 8349
  • Country: fi
    • My home page and email address
Re: Choosing my SBC hardware.
« Reply #41 on: June 02, 2025, 03:28:41 pm »
Let's take a look at slcand source as an example case.

On line 421 or thereabouts, you see a loop commented with "The Big Loop",
    while (slcand_running)
        sleep(1);
This is a bad pattern.  Not horribly bad, but not good either.

Actually, that particular one is kinda buggy.  slcand_running absolutely needs to be volatile, and as it is modified by a signal handler, preferably volatile sig_atomic_t (like exit_code is).

This is related to the bad beginner pattern of using too many threads that tggzzz mentioned, in the sense that in Linux/Unix/POSIXy fully hosted systems like here, the signals are delivered asynchronously using any thread within the process.  Here, it's like all the work is done in the "worker threads" (signal handlers), with the main thread having nothing to do.  (Again, the purpose of slcand is to just keep the device open with N_SLCAN line discipline; it does not actually read/see/write any of the CAN data at all.)

A better pattern, similar to using a finite state machine, would be to discard the signal handlers, and instead use a loop based on sigwaitinfo().  At the beginning of the program, the signals are blocked first,
    static const int signals[] = { SIGINT, SIGTERM, SIGHUP, SIGALRM, SIGCHLD, SIGUSR1 };
    sigset_t  sigs;
    sigemptyset(&sigs);
    for (size_t i = 0; i < sizeof signals / sizeof signals[0]; i++)
        sigaddset(&sigs, signals[i]);
    sigprocset(SIG_BLOCK, &sigs);

Then, instead of the loop, we wait for any of those signals to arrive,
    siginfo_t  info;
    int signum;
    do {
        signum = sigwaitinfo(&sigs, &info);
        // Note: We can safely ignore any errors (signum==-1) here, and do.
    } while (signum <= 0);
the signal number is in signum, and e.g. info.si_pid contains the process ID that sent the signal, 0 for kernel.

After the loop, the signals are still blocked –– sigwaitinfo() and sigtimedwait() "temporarily atomically unblock-block" the signals –– so receiving another signal during cleanup won't affect the application/service cleanup at all.  Plus, this way you don't need to worry about EINTR errors (that occur for "slow" calls like reading or writing to files/sockets/pipes, and that thread is used to deliver a signal to the process).

So, I do agree that deciding what to move to a separate thread effectively does take some experience.
« Last Edit: June 02, 2025, 03:32:46 pm by Nominal Animal »
 
The following users thanked this post: SiliconWizard

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 8349
  • Country: fi
    • My home page and email address
Re: Choosing my SBC hardware.
« Reply #42 on: June 02, 2025, 06:37:25 pm »
Apologies for spammin' the thread, but I feel this is worth reading:

With GUI toolkits like Qt and GTK and FLTK and others (except for SDL and Curses), the toolkit takes control of the main thread, and simply calls back to your own code whenever there is an event to be handled.

We absolutely do not want to do anything time-consuming in that thread, because the UI is effectively stalled for the duration of handling each event in your own code.  This is less important when you use X11 or Wayland, since the stall only affects that one process (application), and anyway the server buffers some user actions separately of event handling.  It is extremely important if you run a single-app "kiosk" mode, say fullscreen Qt over raw framebuffer/DRI.

Thus, in any GUI application running on a Linux SBC, be that on raw framebuffer or under a window manager and server, each application doing network/serial I/O or heavy computation should have at least one separate worker thread.

For example programs we often skip threads, and use the main thread.  That's fine, but I'm talking here about "proper" applications that you could sell, and be proud of the quality too.

As an example, when opening some file that needs to be parsed, the file open dialog, when Open button is pressed, can actually cause a new thread to be created for parsing the file, with main window having an info/progress bar somewhere.  The thread reads and processes the file, sending regular updates (a dozen to a hundred all told, no need to be exact) of the progress as UI toolkit events to the info/progress bar widget in the main thread (using thread-safe event interfaces).  When the file has been read and parsed, the handles are passed as an UI toolkit event to the main application or main window, and the thread exits (which usually involves sending an UI event to the main application with the thread handle as a parameter, so that the main application can reap the defunct thread; this ensures its stack etc. is freed then and there, and does not just lie unused until the process exits).

When we discuss things like whether you should use one or more threads when sending and receiving datagrams, that depends on the protocol and your needs, in my opinion.  For synchronous query-response protocols, where you cannot have more than one query "in flight" at any time, one thread suffices.  For IP networking, it depends on what kind of work is done on a per-peer/server/client basis; I've done both single-thread-nonblocking and thread-per-client myself.

But if nothing else, understanding that with Qt/Gtk/FLTK/etc., the main thread is owned by the toolkit running its own event loop and only calling to your code to deliver events; and that any possibly blocking work or work that can take some time, really should be done in a different thread and not in the main thread event handler itself, is crucial.  The single threaded approach will work on fast desktop computers under window manager, well for most examples even, but for proper GUI application development, you end up having to work with threads at some point.  I say, as early as possible, because then you also get the feel, the intuitive understanding, via experimentation and trial and error, of how to best use separate threads, and when to combine several threads into one for example by using poll() or ppoll() (better than select()) and so on.
« Last Edit: June 02, 2025, 06:41:21 pm by Nominal Animal »
 

Offline Karel

  • Super Contributor
  • ***
  • Posts: 2539
  • Country: 00
Re: Choosing my SBC hardware.
« Reply #43 on: June 03, 2025, 08:52:44 am »

If the time consuming part uses a loop, you often can get away by periodically calling QCoreApplication::processEvents() (at least to prevent graphical artefacts)  8)
But I agree that using QThread is better, it's just that it requires more code.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18885
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: Choosing my SBC hardware.
« Reply #44 on: June 05, 2025, 06:28:58 am »
So the Lattepanda has no alternative input to the power on button, How do you embed this into a device if the use has to press the power button on the board itself. There appear to the through hole pads for the power and reset buttons where connectors could go but there are filled with solder so scrap that idea.
 

Online Psi

  • Super Contributor
  • ***
  • Posts: 12588
  • Country: nz
Re: Choosing my SBC hardware.
« Reply #45 on: June 05, 2025, 12:19:05 pm »
So the Lattepanda has no alternative input to the power on button, How do you embed this into a device if the use has to press the power button on the board itself. There appear to the through hole pads for the power and reset buttons where connectors could go but there are filled with solder so scrap that idea.

Are you sure, im pretty sure there is a header for the power on pins.
Which lattepanda did you get?

Pretty sure the ATMega32 has access to power on too, being able to power on/off the full system from the co-pro was kinda the entire point of it.
« Last Edit: June 05, 2025, 12:31:36 pm by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18885
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: Choosing my SBC hardware.
« Reply #46 on: June 05, 2025, 05:52:10 pm »
https://docs.lattepanda.com/content/1st_edition/hardware_introduction/

Well there was a header there or at least pads for one, but the asshole have filled them in with solder. It is not a production solution to try and take the solder out to put a connector or wires in there. I don't think the micro controller has access but then we are back into the territory of assholes that are clueless and would be better not wasting our time. Why would I even want to replace a simple wire with a simple wire and a micro controller program I never needed but for their stupidity. Every time I think I have found something better I just discover a whole different version of fucking stupid problems!
 

Online Psi

  • Super Contributor
  • ***
  • Posts: 12588
  • Country: nz
Re: Choosing my SBC hardware.
« Reply #47 on: June 06, 2025, 02:28:15 am »
Can you set the typical bios setting for AC Power Recovery / After Power Loss / Restore on AC Power Loss ?  So that it powers on as soon as it gets power making the button redundant?
For most embedded PC applications you would use that feature.


Or will that not work for your application?
« Last Edit: June 06, 2025, 02:36:51 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 18885
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: Choosing my SBC hardware.
« Reply #48 on: June 06, 2025, 06:51:29 am »
That would work just fine, I'll have a rummage in the bios. The documentation is a bit weak on details. I've not yet seen any clear explanation about how the Arduino system is physically connected to the main system, I guess it's through it's USB. It's a pity these product chase the latest craze. Why put an old AVR on a board that you are advertising as ideal for industrial applications. Put some decent ARM based chip like a SAMC that has was more industrial connectivity like CAN bus. Unless I have to use that Arduino "thing" for hardware reasons it will be completely ignored in favor of a SAMC, then I'll have plenty of low level connectivity.
 

Online Psi

  • Super Contributor
  • ***
  • Posts: 12588
  • Country: nz
Re: Choosing my SBC hardware.
« Reply #49 on: June 07, 2025, 06:21:01 am »
To be fair, you bought the first generation that came out in 2018, back when they were a startup.
And they can't really update it because it needs to stay the same for anyone using it in embedded projects.

But yeah, they still have the ATMega32 on the latest ones. which does seem kinda stupid given what they could use instead.
Greek letter 'Psi' (not Pounds per Square Inch)
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf