Author Topic: How do you select methods to solve the Problem  (Read 1269 times)

0 Members and 1 Guest are viewing this topic.

Offline BlogRahulTopic starter

  • Regular Contributor
  • *
  • Posts: 75
  • Country: in
How do you select methods to solve the Problem
« on: January 10, 2022, 01:26:54 pm »
Hi all, 

Whenever we design a system we have to choose the right method. An embedded system can be designed in different ways.

My list of methods

1. Polling
2. Interrupt
3. State machine
4. multitasking
5. scheduling
6. RTOS

I am sure you must have also used one of these methods for your project. Can you share, which method you used for your projects and why do you think that was best suitable for the project? 

 

Offline madires

  • Super Contributor
  • ***
  • Posts: 7765
  • Country: de
  • A qualified hobbyist ;)
Re: How do you select methods to solve the Problem
« Reply #1 on: January 10, 2022, 03:03:53 pm »
Outsourcing homework? ;)

BTW, all roads lead to Rome.
« Last Edit: January 10, 2022, 03:05:30 pm by madires »
 

Offline BlogRahulTopic starter

  • Regular Contributor
  • *
  • Posts: 75
  • Country: in
Re: How do you select methods to solve the Problem
« Reply #2 on: January 10, 2022, 05:12:34 pm »
Outsourcing homework? ;)

BTW, all roads lead to Rome.
It's not homework. I am asking to share knowledge about practical projects. It's difficult to find specifications for practical projects from 3 to 6.
 

Offline T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 21688
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: How do you select methods to solve the Problem
« Reply #3 on: January 10, 2022, 08:29:19 pm »
I mean, most things will need some mixture of the above.  The whole point of embedded computing is to accept input, compute some function on that against existing state, and producing a state transition and output.

If that's done more or less whenever, it might be polled.  If it should be more coherent, interrupts are likely needed, such as to buffer serial inputs to avoid losing data, or reading ADC or setting DAC to keep phase noise down, etc.

You might need to interrupt a lengthy computation that isn't easy to break up otherwise.  This is partly a fault of poor coding -- strictly in the sense that the problem could be solved with perfectly timed code -- but the effort required to create such code, let alone maintain it through updates (by yourself or others), might far exceed the effort to simply use an interrupt and mind the concurrency issues it creates.  Such code might be computationally efficient, but very much not efficient to develop.

Example, say you have to redraw some objects on screen.  But display updates are slow, maybe it's SPI driven so you have to go through hundreds of pixels, and even at 10Mbps that's hundreds of microseconds.  Meanwhile you have an ADC acquiring, audio let's say, so you definitely can't wait that long between samples.  You could interleave polling with display writes, but how tedious will that get?  What if you have to change the write size (say moving to a 24-bit display from 8 or 16)?  Now all the timing is different.

As for RTOS stuff, depends.  Often you'll have several housekeeping tasks; servicing IO buffers for instance, tracking counters, gathering statistics, logging, etc..  You could arguably say these work together as a cooperative multitasking system, even though it's hard programmed.  It's not much more effort to make it pull those functions from a list and populate the list on init; it's just more work for no purpose.  You really want something like that when the tasks may vary over time, so you need to be able to slot in new operations from time to time.

And with a set of tasks, how they're sequenced or switched is an important question.  If you have very complex tasks, you might even need to interrupt them from time to time; when this is done automatically, it's preemptive multitasking.  Such a system is not easy to write (it often requires assembler to save CPU and machine registers -- not something that can be done purely in C), so you're wise to invest in a proper RTOS in that case.


This is still all within the scope of a finite state machine; the thing is, an FSM scales exponentially with problem scope.  You could for example implement a counter in an FSM, but instead of handling all the state transitions of the counter AND all the other program states (if program and counter states are independent, total states are the product of both!), you might abstract out the counter as a virtual peripheral, so the program machine just produces up/down/reset signals, and reads a compare or overflow or whatever from the counter.  So too, you can have multiple independent, or loosely connected, state machines, and build up a complete system that way, without incurring the exponential complexity -- and making each one modular, so easy to write, modify and test!  And if some of those machines take particularly long to compute their next states, real-time priorities may take over and then you need something like a multitasking RTOS to manage them.

Tim
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 
The following users thanked this post: BlogRahul

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6264
  • Country: fi
    • My home page and email address
Re: How do you select methods to solve the Problem
« Reply #4 on: January 10, 2022, 09:43:59 pm »
In a recent Keyboard / Switch Matrix - H/W Debounce + Multiplexer thread, both polling (dynamic scanning) and interrupt methods for detecting button presses were discussed; and the benefits and downsides of each.

I use state machines extensively to implement small-screen menu systems on embedded targets.  I keep the state descriptor structures in Flash, so that very little RAM is needed to implement the actual menu.  (Think of something like a 0.9" OLED display with 128x64 pixels or 16×4 characters, with a couple of buttons for changing entries, and one to three buttons for selecting and entry and possibly changing the value associated with the entry.)
I also often use ELF object file format features (especially sections) to gather such menu entries (albeit in an unspecified order) across many source files into a single data structure.  Not perfectly portable, but all the targets and toolchains I'm interested in use ELF object files during the build stage.

In pure software projects, state machines are extensively used in lexers and parsers; typically via Lex or Flex (that generate state machine based C code for lexical analysis as needed for parsers, interpreters, and compilers).

My scientific specialty is computational material physics toolmaking, i.e. simulators, visualizers, sonifiers, etc.  In Linux, I use both symmetric multitasking (running code on similar cores, typically CPU cores) and asymmetric multitasking (running code on different types of CPU cores, or on both CPU and GPU cores), but also distributed computing (with code running in parallel on physically separate computers and communicating with each other).  I could rant for hours about this, especially how very few tools currently handle the communications and computation in parallel, asynchronously; instead, they typically compute first, then communicate, and so on, wasting resources and taking more wall clock real time than would be necessary, because us programmers are not that good at this stuff.

I don't use RTOSes: on the electronics side, I'm just a hobbyist, and it is easier and cheaper for me to combine a Linux workstation communicating with USB to a dedicated microcontroller that does the realtime stuff, with their combined system achieving what I want.  I like to use Teensies for the microcontroller stuff, especially since an USD $20 Teensy 4.0 supports high speed USB (480 Mbit/s), and I can trivially achieve > 200 Mbit/s (25+ Mbytes/s) even using USB Serial (USB bulk transfers are even better).

For that reason, I don't write my own schedulers.  I do sometimes use postponed work queues, where an interrupt signals work that needs to be done (but immediately returns, keeping the interrupt-caused jitter to a minimum), but some kind of main loop handles that work.  In hosted (non-embedded) environments, especially in Linux, I just let the kernel schedulers do their thing, and just make sure I don't make assumptions about scheduling (so that the end user can manage the CPU and I/O priorities themselves as needed).

I do not select the method or approach.  I evaluate several, often letting my subconscious chew on it during I sleep, and then test them using small test programs that verify the core logic and/or operations.  I have literally thousands of these, although I only keep the most recent couple of hundred at hand.  Each one is in their own directory, with either the test program describing the thing, or with a README and associated text/Maxima/Maple/Octave/PDF files describing the thing.  I often find stuff in these using grep -e pattern -R root-of-my-test-program-tree/.

In other words, I'm not so smart that I can offhand say what method to use for a given program: I must think about it, and work it out, for each case.  I'm often wrong, too, and discover an even better solution a few days later than my initial suggestion.

After over a couple of decades experience and having done all sorts of different programming stuff –– that's why I have so many of them, and typically add several each week; about 80-120 per year ––, and having tried many thousands of different approaches, I do have some experience to guide my initial guesses, and base my approaches on.  There are greybeards here whose experience vastly, vastly, exceeds mine; but because after the initial learning curve, we all tend to approach things as "there is no single correct answer, and knowing different solution methods to this problem is useful because similar things crop up all the time", we can and do discuss these things as colleagues –– or even co-conspirators in sneaky/efficient problem-solving.  (As opposed to the woefully common, "let's throw this stuff at the wall and see what sticks" approach, where developers write code that seems to work but even the developers cannot tell how or why.)

This is something even a new programmer can do.  The point is to keep ones mind open, and realize that there is no single correct answer: almost everything is a balance of various factors, and subject to change when the context changes.  We learn continuously, every single one of us, and never ever know "enough".  Some say to keep humble, but as you can see, I'm not very humble here; it's just that the world is vast, and us humans small.

Thus, describing or presenting ones problem to colleagues to consider or help with, is a very, very important skill.  Typical error is describing only the problems related to the currently selected solution method, instead of providing the background of the underlying problem that is to be solved, and the reasons this solution approach was chosen, and only then the "surface problem" encountered along that solution approach.  Listing attempted alternatives helps shortcut the discussion, although then it is important to also include the reason why each rejected alternative was rejected.  Being systematic and analytic here is paramount.
If the problem is one that hasn't already been discussed thoroughly, and does not have oodles of online resources to read to discover solution approaches for, a well-formed question typically attracts even the old mages and greybeards.  Not just here, mind you; also in academia and professional work.
 
The following users thanked this post: BlogRahul

Offline madires

  • Super Contributor
  • ***
  • Posts: 7765
  • Country: de
  • A qualified hobbyist ;)
Re: How do you select methods to solve the Problem
« Reply #5 on: January 11, 2022, 03:54:48 pm »
1. Polling
2. Interrupt

In many cases you'll do both.

3. State machine

It's an overrated term because any program is some sort of state machine.

4. multitasking
5. scheduling
6. RTOS

Those three are related to each other. Scheduling means that CPU resources are shared between processes/tasks/threads and a scheduler controls that. And that scheduler also enables multitasking. An RTOS is basically a scheduler plus some additional framework for controlling and sharing things. So all three are more or less the same, just with a different abstaction layer. Any solution which is more complex than a simple program loop will incorporate those methods or a subset of them.
 
The following users thanked this post: netmonk, BlogRahul


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf