Author Topic: techniques for writing non blocking code  (Read 17900 times)

0 Members and 1 Guest are viewing this topic.

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 10883
  • Country: gb
    • Having fun doing more, with less
Re: techniques for writing non blocking code
« Reply #25 on: August 01, 2017, 09:30:24 pm »
But both techniques smell

Define smell. Roses smell. Freshly baked bread smells.

Sigh, the standard meaning in the context of code, to wit: https://en.wikipedia.org/wiki/Code_smell
« Last Edit: August 01, 2017, 09:31:58 pm by tggzzz »
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
 

Offline Sal Ammoniac

  • Frequent Contributor
  • **
  • Posts: 964
  • Country: us
    • Embedded Tales Blog
Re: techniques for writing non blocking code
« Reply #26 on: August 01, 2017, 10:06:16 pm »
But both techniques smell

Define smell. Roses smell. Freshly baked bread smells.

Sigh, the standard meaning in the context of code, to wit: https://en.wikipedia.org/wiki/Code_smell

Sorry. Was just pulling your chain.  8) I'm not a big fan of some of these hipster terms such as code smell, refactoring, and technical debt.
Nothing lasts as long as a workaround.
 

Offline John Coloccia

  • Super Contributor
  • ***
  • Posts: 1199
  • Country: us
Re: techniques for writing non blocking code
« Reply #27 on: August 01, 2017, 11:04:42 pm »
Putting a button on an interrupt is perfectly fine.

You can do it, just as you can use asynchronous monostables (like a 74123) in clocked logic circuits. Occasionally there are good reasons for those techniques.

But both techniques smell because they introduce subtle failure mechanisms (analogue and digital), can make it difficult to reason about "edge case" operation of the complete system, and difficult to test in production.

What is the subtle failure? The interrupt fires saying "something changed"...then you debounce the switch in a timer, or whatever your favorite method is....then you re-enable the interrupt. How is that more prone to failure than polling to see that something changed, debouncing and polling some more? If you can't make it reliably work in an interrupt, then you can't make it reliably work polling either. You're just depending on the polling not polling at exactly the wrong time. Either the debounce technique works or it doesn't. The thing that triggers it is not important.
 
The following users thanked this post: KL27x

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 892
  • Country: us
Re: techniques for writing non blocking code
« Reply #28 on: August 01, 2017, 11:38:36 pm »
A war story:

One project I worked on used interrupts to read a few external signals. Most of these were controlled either with hardware debounce or were generated by circuits that had well defined behavior. But one of these was just tied to an uncontrolled input with no hardware debounce. The signal had to do with whether the device was being charged or not, and since that signal wouldn't change very often, not much thought was put into the implementation.

After some time, we noticed that some devices would simply lock up and become unresponsive. These locked devices were still operational, the kernel was still running and in fact, we could still communicate with them remotely. But they weren't responding to  external interrupts any more.

Hmm....

Turns out the mcu used for this project has a race condition in the silicon for its GPIO interrupt generation. If edges arrived in the right order and sufficiently quickly, the interrupt hardware would lock up and cease to sense external changes. WTF?  :palm: It turned out that there was a firmware workaround (which is how the OEM fixed the problem, which still doesn't appear in their errata), but it's very cumbersome and involves loops inside the interrupt handler.

The moral of this story might be to avoid mcus with dodgy silicon, or maybe to avoid using GPIO interrupts without hardware debounce, but I think the real lesson is to expect the unexpected--especially when tying interrupts to external signals.
 
The following users thanked this post: JPortici

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 10883
  • Country: gb
    • Having fun doing more, with less
Re: techniques for writing non blocking code
« Reply #29 on: August 01, 2017, 11:49:45 pm »
Putting a button on an interrupt is perfectly fine.

You can do it, just as you can use asynchronous monostables (like a 74123) in clocked logic circuits. Occasionally there are good reasons for those techniques.

But both techniques smell because they introduce subtle failure mechanisms (analogue and digital), can make it difficult to reason about "edge case" operation of the complete system, and difficult to test in production.

What is the subtle failure? The interrupt fires saying "something changed"...then you debounce the switch in a timer, or whatever your favorite method is....then you re-enable the interrupt. How is that more prone to failure than polling to see that something changed, debouncing and polling some more? If you can't make it reliably work in an interrupt, then you can't make it reliably work polling either. You're just depending on the polling not polling at exactly the wrong time. Either the debounce technique works or it doesn't. The thing that triggers it is not important.

You need to do failure analysis, and that depends on identifying all the components, hardware and software, in the complete system. Thereafter you can consider how they can completely or partially fail, and how the system will react.

I suggest you should look at comp.risks to see subtle and unexpected failure modes in systems, including real-time systems created by intelligent and dedicated people. Comp.risks as a very high SNR, appears roughly weekly, and the last 30 years archives can be found at http://catless.ncl.ac.uk/Risks/
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
 

Offline John Coloccia

  • Super Contributor
  • ***
  • Posts: 1199
  • Country: us
Re: techniques for writing non blocking code
« Reply #30 on: August 02, 2017, 01:55:26 am »
Putting a button on an interrupt is perfectly fine.

You can do it, just as you can use asynchronous monostables (like a 74123) in clocked logic circuits. Occasionally there are good reasons for those techniques.

But both techniques smell because they introduce subtle failure mechanisms (analogue and digital), can make it difficult to reason about "edge case" operation of the complete system, and difficult to test in production.

What is the subtle failure? The interrupt fires saying "something changed"...then you debounce the switch in a timer, or whatever your favorite method is....then you re-enable the interrupt. How is that more prone to failure than polling to see that something changed, debouncing and polling some more? If you can't make it reliably work in an interrupt, then you can't make it reliably work polling either. You're just depending on the polling not polling at exactly the wrong time. Either the debounce technique works or it doesn't. The thing that triggers it is not important.

You need to do failure analysis, and that depends on identifying all the components, hardware and software, in the complete system. Thereafter you can consider how they can completely or partially fail, and how the system will react.

I suggest you should look at comp.risks to see subtle and unexpected failure modes in systems, including real-time systems created by intelligent and dedicated people. Comp.risks as a very high SNR, appears roughly weekly, and the last 30 years archives can be found at http://catless.ncl.ac.uk/Risks/

So what's the subtle failure mechanism? Maybe it's because my background is software that I don't consider any of these subtleties to be big deals, or difficult to handle, or whatever, but it seems pretty darn straightforward to me. Interrupt says something changed, software properly debounces, and life goes on. If that doesn't work, then it also won't work if you're polling because you can always poll at exactly the wrong time. You're just masking the problem and turning a 1 in 1,000 failure into a 1 in 10,000 failure.

I think the article that was posted makes some argument that edges can come in that may trigger an interrupt but won't be caught polling. Big deal. Bad/noisy/spurious edges can come in that trigger both. What then? One way or another, you need to decide what kind of signal means pushed and what kind doesn't, and then design your hardware and software around that.

There are lots of scenarios where monitoring in an interrupt is NOT an appropriate solution, but that's really beside the point. For example, if you're monitoring multiple buttons that can be pushed simultaneously and can't mask each other, then you either need robust hardware debouncing or polling. That said, the idea that monitoring in an interrupt is inherently bad is just complete nonsense. What's inherently bad is bad design where hardware, software and design requirements aren't working in harmony with each other.
 
The following users thanked this post: HackedFridgeMagnet

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 9482
  • Country: my
  • reassessing directives...
Re: techniques for writing non blocking code
« Reply #31 on: August 02, 2017, 06:01:15 am »
But both techniques smell
Define smell. Roses smell. Freshly baked bread smells.
Sigh, the standard meaning in the context of code, to wit: https://en.wikipedia.org/wiki/Code_smell
neither polling or interrupt method listed in the definition. i guess you just made up your own defintion. most of the definitions are relating to code redundancy/inefficiency which in turn means codes that havent been refactored or analyzed properly. those are anti-definition of KISS principle.
if something can select, how cant it be intelligent? if something is intelligent, how cant it exist?
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 18879
  • Country: nl
    • NCT Developments
Re: techniques for writing non blocking code
« Reply #32 on: August 02, 2017, 06:33:13 am »
Putting a button on an interrupt is perfectly fine.

You can do it, just as you can use asynchronous monostables (like a 74123) in clocked logic circuits. Occasionally there are good reasons for those techniques.

But both techniques smell because they introduce subtle failure mechanisms (analogue and digital), can make it difficult to reason about "edge case" operation of the complete system, and difficult to test in production.

What is the subtle failure? The interrupt fires saying "something changed"...then you debounce the switch in a timer, or whatever your favorite method is....then you re-enable the interrupt. How is that more prone to failure than polling to see that something changed, debouncing and polling some more? If you can't make it reliably work in an interrupt, then you can't make it reliably work polling either. You're just depending on the polling not polling at exactly the wrong time. Either the debounce technique works or it doesn't. The thing that triggers it is not important.
Why would you want to use an interrupt if you are going to poll anyway? If you use an interrupt the way you describe then somewhere the software has to check (poll) the state of the flag that interrupt has set. Then it needs to deal with debouncing as well. It sounds complicated and in some cases I rather have less interrupts running when I have the microcontroller handle some realtime signal processing.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 10883
  • Country: gb
    • Having fun doing more, with less
Re: techniques for writing non blocking code
« Reply #33 on: August 02, 2017, 08:15:04 am »
Putting a button on an interrupt is perfectly fine.

You can do it, just as you can use asynchronous monostables (like a 74123) in clocked logic circuits. Occasionally there are good reasons for those techniques.

But both techniques smell because they introduce subtle failure mechanisms (analogue and digital), can make it difficult to reason about "edge case" operation of the complete system, and difficult to test in production.

What is the subtle failure? The interrupt fires saying "something changed"...then you debounce the switch in a timer, or whatever your favorite method is....then you re-enable the interrupt. How is that more prone to failure than polling to see that something changed, debouncing and polling some more? If you can't make it reliably work in an interrupt, then you can't make it reliably work polling either. You're just depending on the polling not polling at exactly the wrong time. Either the debounce technique works or it doesn't. The thing that triggers it is not important.

You need to do failure analysis, and that depends on identifying all the components, hardware and software, in the complete system. Thereafter you can consider how they can completely or partially fail, and how the system will react.

I suggest you should look at comp.risks to see subtle and unexpected failure modes in systems, including real-time systems created by intelligent and dedicated people. Comp.risks as a very high SNR, appears roughly weekly, and the last 30 years archives can be found at http://catless.ncl.ac.uk/Risks/

So what's the subtle failure mechanism? Maybe it's because my background is software that I don't consider any of these subtleties to be big deals, or difficult to handle, or whatever, but it seems pretty darn straightforward to me.

Ah, right, that explains a lot. I presume your expertise is in digital hardware, otherwise I won't be able to point you in the right direction within a reasonable time. An analogy to get you started thinking in the right direction...

Most software is written in a way that presumes that control flows linearly, and that the control flow is the only thing that can mutate memory and i/o. That specifically includes the compilers, which have widely misunderstood and misapplied constructs for situations where that isn't the case. Prime example: C on multicore processors with multiple levels of cache and shared memory, where compiler and/or program bugs are legion.

Most digital hardware is constructed in a way that presumes changes only occur at specific instants, due to the clocked synchronous methodology. It is very very difficult to design unclocked asynchronous logic where inputs can change at any instant. Predictable design is, with significant effort and understanding, possible if you consider two inputs that can change asynchronously w.r.t. each other. With three or more it is effectively impossible. In addition, the design tools make it effectively impossible, since they habitually "optimise out" the necessary constructs inserted, e.g. Karnaugh map bridging terms.

Interrupts in software systems have the same effect as adding an extra core to a processor. They are analogous to turning a clocked synchronous hardware design into an asynchronous digital design.

And that doesn't even consider the timing implications of having your code arbitrarily suspended, which is analogous to the potentially infinite delay due to metastable behaviour in a synchroniser.
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
 

Offline Bruce Abbott

  • Frequent Contributor
  • **
  • Posts: 616
  • Country: nz
    • Bruce Abbott's R/C Models and Electronics
Re: techniques for writing non blocking code
« Reply #34 on: August 02, 2017, 09:01:40 am »
What's inherently bad is bad design where hardware, software and design requirements aren't working in harmony with each other.
Agreed. You can't say which method is best without looking at the entire system.

Quote from: DVX
Currently when a button input change is detected the program branches to a routine which then waits in a loop until the button is released. To keep things simple the code is blocking, it just waits until the button level changes to show it no longer pressed down. I read button level changes and do screen updates by calling routines with in the button waiting loop but there has to be a better way.
What is the problem with how you are doing it now?
 

Offline Vtile

  • Frequent Contributor
  • **
  • Posts: 993
  • Country: fi
  • Ingineer
Re: techniques for writing non blocking code
« Reply #35 on: August 02, 2017, 09:15:29 am »
What's inherently bad is bad design where hardware, software and design requirements aren't working in harmony with each other.
Agreed. You can't say which method is best without looking at the entire system.

Quote from: DVX
Currently when a button input change is detected the program branches to a routine which then waits in a loop until the button is released. To keep things simple the code is blocking, it just waits until the button level changes to show it no longer pressed down. I read button level changes and do screen updates by calling routines with in the button waiting loop but there has to be a better way.
What is the problem with how you are doing it now?
It freezes the system until the button is released. That is how it looks to me.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 10883
  • Country: gb
    • Having fun doing more, with less
Re: techniques for writing non blocking code
« Reply #36 on: August 02, 2017, 09:26:30 am »
What's inherently bad is bad design where hardware, software and design requirements aren't working in harmony with each other.
Agreed. You can't say which method is best without looking at the entire system.

As I explicitly pointed out in the message to which Coloccia replied, you do indeed need to consider all components in a system. But "working in harmony" is insufficient, albeit pleasing.

However Coloccia's point is quite revealing. He is considering how things work; professional engineers have to prove how things work, and consider system behaviour when (not if) things fail.

If you are, say, making traffic light controllers for children's toy cars sets, you probably don't have to consider the failures mechanisms in much detail. But if you are developing real traffic light controllers, you sure do!
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
 

Offline Kalvin

  • Super Contributor
  • ***
  • Posts: 1806
  • Country: fi
  • Embedded SW/HW.
Re: techniques for writing non blocking code
« Reply #37 on: August 02, 2017, 10:05:17 am »
One way of achieving a deterministic and a robust system is to use time-triggered software architecture:

https://www.safetty.net/products/publications/pttes

In a time-triggered system there are no interrupts which would interrupt the program execution. There may be a timer-based, deterministic interrupt which will run the actual program. The main program loop will consist only of while (1) loop with the sleep() function which will keep the system in a low-power mode when it is not executing the code. The system is built using state machines and the program will be run to completion within each timer tick. Essentially the system will use only periodic polling to interact with external buttons and other peripherals. Instead of using a timer interrupt, the main program can be constructed so that it will wait for a periodic timer overflow, which will then start the program execution.

Using this time-triggered software architecture one can create a system which is easy to debug and which will perform deterministically. These techniques are used in systems that require robust software execution.
 

Offline John Coloccia

  • Super Contributor
  • ***
  • Posts: 1199
  • Country: us
Re: techniques for writing non blocking code
« Reply #38 on: August 02, 2017, 10:25:55 am »
What's inherently bad is bad design where hardware, software and design requirements aren't working in harmony with each other.
Agreed. You can't say which method is best without looking at the entire system.

As I explicitly pointed out in the message to which Coloccia replied, you do indeed need to consider all components in a system. But "working in harmony" is insufficient, albeit pleasing.

However Coloccia's point is quite revealing. He is considering how things work; professional engineers have to prove how things work, and consider system behaviour when (not if) things fail.

If you are, say, making traffic light controllers for children's toy cars sets, you probably don't have to consider the failures mechanisms in much detail. But if you are developing real traffic light controllers, you sure do!

We do safety critical software and have probably forgotten more about proving a system works than most engineers know.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 10883
  • Country: gb
    • Having fun doing more, with less
Re: techniques for writing non blocking code
« Reply #39 on: August 02, 2017, 10:26:48 am »
One way of achieving a deterministic and a robust system is to use time-triggered software architecture:

https://www.safetty.net/products/publications/pttes

In a time-triggered system there are no interrupts which would interrupt the program execution. There may be a timer-based, deterministic interrupt which will run the actual program. The main program loop will consist only of while (1) loop with the sleep() function which will keep the system in a low-power mode when it is not executing the code. The system is built using state machines and the program will be run to completion within each timer tick. Essentially the system will use only periodic polling to interact with external buttons and other peripherals. Instead of using a timer interrupt, the main program can be constructed so that it will wait for a periodic timer overflow, which will then start the program execution.

Using this time-triggered software architecture one can create a system which is easy to debug and which will perform deterministically. These techniques are used in systems that require robust software execution.

A quick scan of that book shows nothing I disagree with; remarkable :)

I particularly like the way the author has adopted the "design pattern" method of structuring each chapter, and that each pattern contains a section about reliability and safety implications.

But I don't like the way the C code is formatted: it uses up too much vertical space, thus splitting the code across more pages than necessary :)
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
 

Offline Kalvin

  • Super Contributor
  • ***
  • Posts: 1806
  • Country: fi
  • Embedded SW/HW.
Re: techniques for writing non blocking code
« Reply #40 on: August 02, 2017, 10:42:14 am »
One way of achieving a deterministic and a robust system is to use time-triggered software architecture:

https://www.safetty.net/products/publications/pttes

In a time-triggered system there are no interrupts which would interrupt the program execution. There may be a timer-based, deterministic interrupt which will run the actual program. The main program loop will consist only of while (1) loop with the sleep() function which will keep the system in a low-power mode when it is not executing the code. The system is built using state machines and the program will be run to completion within each timer tick. Essentially the system will use only periodic polling to interact with external buttons and other peripherals. Instead of using a timer interrupt, the main program can be constructed so that it will wait for a periodic timer overflow, which will then start the program execution.

Using this time-triggered software architecture one can create a system which is easy to debug and which will perform deterministically. These techniques are used in systems that require robust software execution.

A quick scan of that book shows nothing I disagree with; remarkable :)

I particularly like the way the author has adopted the "design pattern" method of structuring each chapter, and that each pattern contains a section about reliability and safety implications.

But I don't like the way the C code is formatted: it uses up too much vertical space, thus splitting the code across more pages than necessary :)

Yes, the ideas and the concepts in the book are very sound and practical. The source code formatting could be made more compact, but I do not find that too annoying.
 

Offline Kalvin

  • Super Contributor
  • ***
  • Posts: 1806
  • Country: fi
  • Embedded SW/HW.
Re: techniques for writing non blocking code
« Reply #41 on: August 02, 2017, 11:00:42 am »
Another recommended book for the embedded designers is "Practical UML Statecharts in C/C++", 2nd ed by Miro Samek. The concepts are well presented, although I do not really like the actual implementation, but the book provides a usable starting point for the actual implementation and framework. Anyway, this is a good book for those who want to learn about hierarchical state machines, embedded systems architecture and framework, and possibly want get some good ideas when implementing their own framework. Like I said earlier, I do not really like the actual implementation, but otherwise the book will provide valuable information for every embedded designer who wants to improve their systems architecture.

Together with this book "Practical UML Statecharts in C/C++", and the previous book I mentioned https://www.safetty.net/products/publications/pttes one can build a nice, small, portable, responsive and robust embedded framework.
« Last Edit: August 02, 2017, 11:03:52 am by Kalvin »
 

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: techniques for writing non blocking code
« Reply #42 on: August 02, 2017, 02:04:14 pm »
The Two-culture Problem

There are two very definite views of interrupts depending on whether or not you are working with real time systems or bigger information processors, but!

Consider for a moment the way that non-interrupt-using programs are debugged and tested. They are taken through a standard sequence of inputs and actions. Such programs always produce the same outputs for the same explicit inputs (if they don’t we generally suspect a hardware fault of some kind)

Now consider a program with a number of interrupt routines. In this case the exact sequence of events depends on the exact timing as well as the order of the interrupts. Perhaps an error only makes itself known when interrupt.54632110459 occurs while interrupt routine@0xdeadbead is working after interrupt routine@0xdeadbeaf.

What. The. Frog.  :wtf: :wtf: :wtf:

You can see that because the interrupts are caused by the outside world the number of ways that the program can execute the instructions is huge and the potential for undiscovered unwanted interactions is also huge.

And if look at cases, they exponentially grow as a tree.

So, someone not involved in RT believes that the interrupt-driven environment is hard not to think about interrupts as a blessing (really ?) , but I wonder ... how can you trust it?
 

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: techniques for writing non blocking code
« Reply #43 on: August 02, 2017, 02:11:28 pm »
You can also believe that you can successfully write interrupt handlers for all of the hardware devices that need to be use and ensure that they all interact to just the right degree.

Good in theory, but!

Actually in practice this isn’t as easy as it sounds and any bug that does get into the system can be next to impossible to find.

Thus, interruts are not a blessing since they drive you to go nut (especially if you are under pressure, as when your boss gives you a deadline, because of time-to-market) :D
 

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 9482
  • Country: my
  • reassessing directives...
Re: techniques for writing non blocking code
« Reply #44 on: August 02, 2017, 02:39:43 pm »
You can see that because the interrupts are caused by the outside world the number of ways that the program can execute the instructions is huge and the potential for undiscovered unwanted interactions is also huge.
are you saying avoid using interrupt at all? not just necessarily switch, interrupt like sensors, glitches or pulses from external hardware, lcd pin (just as in the OP) and anything for detecting unpredictable outside events? just because it will open infinite possibilities of entry points in the program? that there will be no way of telling to client that it will work or not? are you going to poll tens of input pins because interrupt method is an abomination? is it like that?

edit: how are you going to time 2 consecutive events at greater accuracy, for example calculating rpm for a high speed motor or velocity of a bullet? while at the same time the processor need to do other complex stuffs? just to give you a picture.

if something can select, how cant it be intelligent? if something is intelligent, how cant it exist?
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 10883
  • Country: gb
    • Having fun doing more, with less
Re: techniques for writing non blocking code
« Reply #45 on: August 02, 2017, 02:43:42 pm »
Actually in practice this isn’t as easy as it sounds and any bug that does get into the system can be next to impossible to find.
Thus, interruts are not a blessing since they drive you to go nut (especially if you are under pressure, as when your boss gives you a deadline, because of time-to-market) :D

Yes indeed. During development any such rare problems are usually ignored, since at that point there are common/frequent bugs to remove.

Here's an infamous classic that all embedded software engineers need to understand: https://catless.ncl.ac.uk/Risks/19.49.html#subj1 Note that both technical factors and human factors were involved, and that the engineers were knowledgeable and dedicated.

(And that's one of many examples of the high SNR in comp.risks)
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
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 10883
  • Country: gb
    • Having fun doing more, with less
Re: techniques for writing non blocking code
« Reply #46 on: August 02, 2017, 02:51:19 pm »
You can see that because the interrupts are caused by the outside world the number of ways that the program can execute the instructions is huge and the potential for undiscovered unwanted interactions is also huge.
are you saying avoid using interrupt at all? not just necessarily switch, interrupt like sensors, glitches or pulses from external hardware, lcd pin (just as in the OP) and anything for detecting unpredictable outside events? just because it will open infinite possibilities of entry points in the program? that there will be no way of telling to client that it will work or not? are you going to poll tens of input pins because interrupt method is an abomination? is it like that?

To a good first approximation, yes.

I'll make a very limited exception for a regular tick timer, and for panics that result in a controlled shutdown.

Here's an infamous classic that all embedded software engineers need to understand: https://catless.ncl.ac.uk/Risks/19.49.html#subj1

Quote
edit: how are you going to time 2 consecutive events at greater accuracy, for example calculating rpm for a high speed motor or velocity of a bullet? while at the same time the processor need to do other complex stuffs? just to give you a picture.

You capture the time-of-arrival of an event in a hardware counter, and read that time when you get around to processing the event.

Modern embedded processors have such facilities built-in and easy-to-use, e.g. http://www.xmos.com/download/private/XS1-Ports-Specification(X1373A).pdf plus the software primitives to use them effectively, e.g https://www.xmos.com/published/xmos-programming-guide

Note that those processors have no cache and no interrupts - and they are a delight to use due their high performance, simplicity, and predictability.
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
 

Offline Sal Ammoniac

  • Frequent Contributor
  • **
  • Posts: 964
  • Country: us
    • Embedded Tales Blog
Re: techniques for writing non blocking code
« Reply #47 on: August 02, 2017, 04:27:15 pm »
One way of achieving a deterministic and a robust system is to use time-triggered software architecture:

https://www.safetty.net/products/publications/pttes

In a time-triggered system there are no interrupts which would interrupt the program execution. There may be a timer-based, deterministic interrupt which will run the actual program. The main program loop will consist only of while (1) loop with the sleep() function which will keep the system in a low-power mode when it is not executing the code. The system is built using state machines and the program will be run to completion within each timer tick.

I've worked with systems written using techniques like those described in that book and found the pervasive use of state machines makes the code tedious to write and maintain. Since everything is run from a timer interrupt, you have to maintain state yourself between each task invocation and you have to make sure that each task (and each group that runs from the same timer interrupt) doesn't take longer to execute than the timer period. Except for the very first task run when the timer tick interrupt is entered, all other tasks will experience scheduling jitter because the time they start running depends on how long all of the tasks ahead of them in the queue run, and this can vary from one tick to the next.

The code in the book also seems to rely a lot on global variables to pass information from task to task, and that's generally not a good idea.

All-in-all, I prefer to design embedded systems (except for extremely simple ones) using an RTOS with good task synchronization facilities.
Nothing lasts as long as a workaround.
 

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: techniques for writing non blocking code
« Reply #48 on: August 02, 2017, 04:39:16 pm »
is it like that?

umm, it's more like don't abuse of them. A message in the bottle to those who promote theories like "everything interrupts driven". Be warned.

But of course, in avionics interrupts are not completely banned, their use is greatly reduced  :popcorn:
 

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: techniques for writing non blocking code
« Reply #49 on: August 02, 2017, 05:40:14 pm »
yup, with interrupts and tasks competing on shared resources we need mutex (special semaphores) reflecting the relative urgency of these tasks to access the shared resource.

This makes things more complex and more difficult to be analyzed.

Most of the time the combination works fine, and you can believe your system works.  However, very infrequently, it is also possible for an interrupt to occur in the way that it can introduce the perfect scenario of priority inversion and ...

... ops, Shit Happens ... if you aren't aware of consequences, and able to sort it out.

~ ~ ~ ~ ~ ~ ~ ~

interrupts + shared resources(on mutex) = more cares  :D
« Last Edit: August 02, 2017, 06:49:08 pm by legacy »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf