Microcontroller software intrerrupts how do they work - microcontroller

I was reading about micro-controller interrupts, and I have a question does the save of the current state happen for software interrupts too or just for hardware interrupts.

Yes. The general concept behind any interrupt is that it can suspend the execution of the underlying program without that program realising it has been interrupted. This requires storing of the CPU and (some) register states and their restoration once the interrupt service routine has completed. The CPU typically has special hardware mechanism for doing this.
Software interrupts share the same mechanism and so the state is saved and restored.
Note, however, that the normal use for software interrupts is on more complex microprocessors where they allow a safe hardware mechanism for moving between privilege modes - e.g. your application and an operating system. On a low level microcontroller they are of little use, as if you already know you want to call the piece of code in the interrupt, you might as well just call it directly as a function.

Typically the state saved is minimal: just enough to restore the previous state when the only action of the ISR is RTI. Usually just the instruction pointer (and code segment) and flags. The whole processor state is not saved, otherwise it would place too much overhead on a time-critical interrupt. It is up the the ISR to save and restore anything more than the bare-bones mechanism of the processor interrupt.

Yes and no, yes as Jon has described, but software interrupts can be used as your interface to the operating system, and for that use case you likely will be setting up registers as parameters into the software interrupt. And expect registers when it returns to be the result.
So software interrupts, can be treated like hardware interrupts and you have to preserve the state, or they can be treated as or used as fancy function calls and you have parameters going in and

In short it's a maybe.
Without knowing the exact example I couldn't say. What gets saved or doesn't get saved really depends on which software is generating/receiving the interrupt.
At low levels there is a lot of concern about speed at which things happen. And hence work that may not need to be done is avoided. Therefore there is no point in "saving your state" if you don't intend to modify it. So it really depends on what exactly we are talking about.
This is where specifications come into play. Operating systems and processors all specify exactly what state they do save and what state they do not save and depending on your specific problem the answer may differ...
#dwelch's answer explains it for Linux. (which is closest to what you were asking for)
#Jon's answer explains it for processors in general.
#weather-vane's answer explains it for micro-controllers.
These are all specific examples. If you were working with FreeRTOS on a micro-controller you would have to probably make your own software interrupt protocol and define it yourself in which case you can choose to save state or leave the responsibility to the caller. In the end, it is just a choice that a programmer that wrote the system made and hence you must go find his notes and read them.
In the end, it is mostly a gentlemen agreement.

Related

Free RTOS context switching

I am a beginner in RTOS programming.I have a query regarding the same.
Query:I understand that context switching happens between various tasks as per priority assigned. I wanted to know how exactly does a higher priority task interrupts a low priority task technically? Does each task is assigned to hardware interrupt pin so that whenever micro-controller is interrupted on that pin by external hardware,the specific task is processed provided it is assigned higher priority when compared to the task that is presently being processed? But practically speaking if there are 128 tasks present in the program it might require 7 hardware pins reserved for interrupts. What is the logic I am missing?
I recommend to read the pretty good docs on https://www.freertos.org e.g. RTOS Fundamentals
I’m sure this will provide a good overview and related details.
Besides that you’ll find out that usually you don’t need external hardware pins to run a multitasking OS.
Free RTOS uses only sys_tick/os_tick hw-interrupt for context switching. This is high precision periodic interrupt configured on any underlying controller
for example on Cortex M:
https://www.keil.com/pack/doc/CMSIS/Core/html/group__SysTick__gr.html
In the interrupt handling of this, FreeRTOS schedular switches the tasks based on the Ready Queue Task list and its priorities.

Why do we use ISR functions with Semaphores?

Hello i have just started using FreeRTOS with STM32. I understand the concept of synchronisation between Tasks or Threads using Semaphores. But what i really dont get is the use of the Semaphores/Mutexes with the Interrupt Service Routine ISR. Why would i use xSemaphoreGiveFromISR() instead of just using xSemaphoreGive() while both of them are mainly used for sync purposes not to interrupt. Also what is the difference between software timers and Interrupts?. I know when and how i should use Interrupts but when would i need to use software timers?
If you dig into the sources you‘ll see the difference between the normal vs. *FromISR API. There are a few more of those. It’s mainly an optimization to minimize execution time in ISRs (if supported by the MCU used) because ISRs should be kept as short as possible.
Also the ISR (calling) context is different to normal task context and the *FromISR API takes care of this.
It’s an implementation detail - just follow the documented rules and you’ll be fine :)
Basically software timers are used to support a couple/many timers using a single HW timer. Often software needs a number of simultaneously running timers e.g. to trigger a number of periodic jobs/actions with differing periods, but HW resources (timers) are limited.
This also applies to the FreeRTOS timer feature using the FreeRTOS systick which usually runs anyway.
Interrupts in general are a different thing. They’re a way how peripheral HW can interact with an connected processor where an application is running.
Well, for instance a HW timer configured accordingly fires up an (HW) interrupt to trigger a software via an ISR to do something on that event.
See also the recommended and comprehensive FreeRTOS documentation.

MPI_Isend /Irecv: Is it possible to access the sendbuffer on unused memory-locations in the meanwhile

I would like to speedup my MPI- Program with the use of asynchronous communication. But the used time remains the same. The workflow is as followed.
before:
1. MPI_send/ MPI_recv Halo (ca. 10 Seconds)
2. process the whole Array (ca. 12 Seconds)
after:
1. MPI_Isend/ MPI_Irecv Halo (ca. 0,1 Seconds)
2. process the Array (without Halo) (ca. 10 Seconds)
3. MPI_Wait (ca. 10 Seconds) (should be ca. 0 Seconds)
4. process the Halo only (ca. 2 Seconds)
Measurements showed that the communication and processing the Array-core nearly take the same time for common workloads. So asynchronism should nearly hide the communication time.
But it dosn't.
One fact - and I thinks this could be the problem - is that the sendbuffer is also the array the calculations are made on. Is it possible that MPI serializes the memory-access although communication ONLY accesses the Halo (with derived datatype) and the computation ONLY accesses the core (only reading) of the array???
Does anybody know if this is for sure the reason?
Is it maybe implementation-dependend (I'm using OpenMPI)?
Thanks in advance.
It isn't the case that MPI serializes the memory accesses in the user code (that's beyond the library's power to do, in general), and it is true that what exactly does happen is implementation specific.
But as a practical matter, MPI libraries don't do as much communication "in the background" as you might hope, and this is particularly true when using transports and networks like tcp + ethernet, where there's no meaningful way to hand off communication to another set of hardware.
You can only be sure that the MPI library is actually doing something when you're running MPI library code, eg in an MPI function call. Often, a call to any of a number of MPI calls will nudge an implementations "progress engine" that keeps track of in-flight messages and ushers them along. So for instance one thing you can quickly do is to make calls to MPI_Test() on the requests within the compute loop to make sure things start happening well before the MPI_Wait(). There is of course overhead to this, but this is something that's easy to try to measure.
Of course you could imagine the MPI library would use some other mechanism to run things behind the scenes. Both MPICH2 and OpenMPI have played with separate "progress threads" which execute separately from the user code and do this ushering along in the background; but getting that to work well, and without tying up a processor while you're trying to run your computation, is a genuinely difficult problem. OpenMPI's progress threads implementation has long been experimental, and in fact is temporarily out of the current (1.6.x) release, although work continues. I'm not sure about MPICH2's support.
If you are using infiniband, where the network hardware has a lot of intelligence to it, then prospects brighten a bit. If you are willing to leave memory pinned (for the openfabrics), and/or you can use a vendor-specific module (mxm for Mellanox, psm for Qlogic), then things can progress somewhat more rapidly. If you're using shared memory, than the knem kernel module can also help with intranode transport.
One other implementation-specific approach you can take, if memory isn't a big issue, is to try to use eager protocols for sending the data directly, or send more data per chunk so fewer nudges of the progress engine are needed. What eager protocols means here is that data is automatically sent at send time, rather than just initiating a set of handshakes which will eventually lead to the message being sent. The bad news is that this generally requires extra buffer memory for the library, but if that's not a problem and you know the number of incoming messages is bounded (eg, by the number of halo neighbours you have), this can help a great deal. How to do this for (eg) shared memory transport for openmpi is described on the OpenMPI page for tuning for shared memory, but similar parameters exist for other transports and often for other implementations. One nice tool that IntelMPI has is an "mpitune" tool that automatically runs through a number of such parameters for best performance.
The MPI specification states:
A nonblocking send call indicates that the system may start copying
data out of the send buffer. The sender should not modify any part of the
send buffer after a nonblocking send operation is called, until the
send completes.
So yes, you should copy your data to a dedicated send buffer first.

Serial Comms dies in WinXP

A bit of history: We have an application, which was originally written many years ago (1998 is the first date in PVCS but the app is about 5 years older than that as it originally was a DOS program). This application communicates with a piece of hardware via serial. When we got to Windows XP we started receiving reports of the app dying after a short time of running. It seems that the serial comms just 'died' and the app was left in a stuck state. The only way to recover from this situation was to restart the application.
The only information I can find regarding this problem was apparently the Windows Message system would miss that information was received, the buffer would fill and the system would get stuck. This snippet of information was left in a old word document, but there's no evidence to back this up. It also mentions that this is only prevalent at high baud rates (115200+).
The solution was to provide customers with USB->Serial converters along with the hardware.
Today: We are working on a new version of the hardware that will run across a network as well as serial ports. So to allow me to work on the network code, minus the actual hardware we are using a VSCOM NetCom113 device. It also installs a virtual comm port on the users (ie: mine) machine.
Now I have got the network code integrated with the app, it appears that the NetCom device exhibits the same behaviour as a physical commport. This is undesirable as I need the app to run longer than ~30 seconds.
Google turns up zero problems that we experience.
I was wondering:
Has anyone experienced this before? If so what did you do to fix/workaround the problem?
Does anyone have any suggestions as to whether the original author of the document is correct and what I can do to test the theory?
Unfortunately I can't post code as the serial code is tightly couple with the rest of the system, though if you have questions regarding it I can answer questions about it.
Updates:
The code is written using Win32 Comm routines - so I am using CreateFile, ReadFile. There's also judicious calls to GetOverlappedResult.
It's not hanging per se, it's just that the comms stops. You can access the menus, click the buttons, but nothing can interact with the connected hardware. Using realterm you can see that no data is coming in or going out.
I think the reference to the windows message is that the problem is internal to windows. Data has arrived but the kernal has missed it and thus not told the rest of the system about it.
Flow control is not used.
Writing a 'simple' test is difficult due the the fact that the code is tightly coupled and the underlying protocol is quite complex and would require a lot of work.
Are you using DOS-style serial code, or the Win32 CreateFile approach?
If the former, be very suspicious: if at all possible I'd convert to the latter.
If the latter, do you know on what kind of system call it's hanging? Are you in a blocking read call? or an overlapped I/O call? or waiting on an event? (I'm not sure I have enough experience to help, but those are the kinds of questions that come to mind)
You might also check into the queue size, which you can set with the SetupComm function.
I don't buy the "Windows Message system" stuff -- it sounds fishy; you can write good Win32 serial i/o code that never uses Windows messages.
edit: does your Overlapped I/O use events? I seem to remember something about auto-reset events occasionally missing their trigger... check your overlapped I/O calls very carefully to see whether you're handling the possible outcomes properly. Perhaps there's a way to make your code more robust by automatically cancelling the overlapped i/o and restarting another read. (I assume the problem is in the read half, not the write half?)
edit 2: A suggestion: assuming the win32 side has missed a byte or packet, and your devices are in deadlock because they're both expecting each other to respond to something, can you tweak the other side of the serial I/O to regularly send some type of "ping" packet with an incrementing counter? (and log the ping packets on the PC side; that way you can see whether you've missed any)
Are you sure you have your flow control set up correctly? DTR, RTS, etc...
-Adam
i have written apps that use usb / bluetooth serial ports and have never had an issue. with bluetooth i have seen bit rates (sustained) of 800,000 bps for long periods of time. most people don't properly implement the port.
My serial port
Not sure if this is a possibility for you, but if you could re-write the code using C#.NET you'd have access to the SerialPort class there. It might remedy your problem. I know a lot of legacy code based around the Win32 API for hardware I/O ports tended to fail in XP due to timing (had a small bit of experience with MIDI).
In addition, I don't know if you can use the Win32 method of Serial Port access in Vista, so that might shut out future MS OSes from being able to use your code.

process scheduling question

For example, a process waiting for
disk I/O to complete will sleep on the
address of the buffer header
corresponding to the data being
transferred. When the interrupt
routine for the disk driver notes that
the transfer is complete, it calls
wakeup on the buffer header. The
interrupt uses the kernel stack for
whatever process happened to be
running at the time, and the wakeup is
done from that system process.
Can you please explain the last line in the paragraph which I have emphasised. It is about waking up the process which has been waiting for some event to occur and thus has slept. This para is from Galvin. By the way can you suggest some good book or link for studying unix operating systems?
Thanks.
There is some process running at the time the interrupt is received. The kernel doesn't change over to some other process context to handle it -- that would take time -- it just does what's necessary in the current context, and lets the scheduler know that the next time it schedules, the waiting process is ready to proceed.
There are a number of good internals books around. I'm fond of the various McKusick et al books, like The Design and Implementation of the FreeBSD Operating System.
Maurice Bach's Design of the Unix Operating System is the most well-known and comprehensive book on the subject.
The I/O completion interrupt will be executed as soon as the disk signals the end of the transfer. This is done regardless of what the kernel is currently doing. Interrupt handlers are usually very small and self-contained. Therefore it is faster to re-use the current runtime environment (stack, CPU state, etc) instead of doing a full context switch to a separate thread. On the down side this means that interrupt handlers are only allowed to do very limited things, like setting a flag somewhere else, or enqueing a work item. Also, they have to clean up very carefully after themselves, so that the running process is not disturbed.
Eric Raymond's 'The Art of Unix Programming' , should be read to understand the Unix philosophy and culture.To actually know and appreciate the reasons behind its design.

Resources