1

My question is more of educational than an actual coding problem. I tried searching the web, but got little help. I am trying to learn how to write ISR and understand how they interact with user threads.

Consider a situation where, I have an ISR which on getting triggered, will copy data from an interrupt source (UART) to a struct. I have an user thread which would want to read this struct at a later point in time. My questions are two fold: (a) What are different ways to share common data (for eg. a struct) between an ISR and a user thread? (b) In case of a shared struct (as above), how do we perform synchronization between the ISR and the user thread?

Please note: I am new to these topics.

1
  • Sharing your research helps everyone. Tell us what you've tried and why it didn't meet your needs. This demonstrates that you've taken the time to try to help yourself, it saves us from reiterating obvious answers, and most of all it helps you get a more specific and relevant answer. Also see How to Ask – gnat Apr 12 '20 at 20:19
2

For synchronization:

The very problem and the main design reason with such activities, as interrupt processing in ISR, is that they can not be put waiting on releasing of some common lock (mutex, semaphore, whatever named) because no code will do this releasing. When ISR really comes, it shall obtain a context (memory contents, other settings) that is correct for its action: at least, data state is consistent. The only way for doing this is to postpone ISR entering while other parties (as usual code, either userland or kernel) manipulates the data structures that an ISR will touch. That's why all CPUs have means to enable or disable hardware interrupts. This enabling/disabling can be total (all hardware interrupts) or per-interrupt, per-group... this increases performance but doesn't change the main principle.

So, the non-ISR code first shall setup common data structures and configure ISR when respective interrupt can't appear yet (because hardware isn't allowed or CPU prevents this), and, when finished, it enables interrupts. When non-ISR code comes to do anything with common data, it disables the interrupt, works with the common data and reenables the interrupt. That's nearly the only really safe manner with the current CPU style (I could imagine some exotic implementations of other style but they aren't widespread).

The things get more complicated with multiprocessing. When some code disables interrupts on a single hart (CPU, core...), others can still allow ISR to enter. In this case, additional protection of common data is done with spinlocks: if some code acquired a spinlock on some hart, ISR on another hart can wait for spinlock freeing and then start its activity, because code at the first hart isn't stopped and will release the spinlock soon.

There are more details to this in many implementations - for example, some (most Unix-like systems, Windows, etc.) differentiate so-called "top half" (true ISR) and "bottom half" (actions outside of top half but scheduled for futher processing outside of any user process); Windows calls bottom half actions "deferred procedure calls".

I hope you got enough words for further study; I'd recommend you consult to well-known books on operating system design by Andrew Tanenbaum or Morris Bach (or similar books for Windows, I don't know names), respective online courses, etc.

For common data structure design, it's quite goal-specific and no common recommendations can be specified except common conforming to the goal. But I'd expect, considering UART, a kind of cyclic byte buffer.

UPDATE: You have mentioned user thread. Nearly all implementations tend to implement hardware interaction within kernel, at least, due to security reasons - hardware should be protected against malicious actions of arbitrary user, so does OS (userland shall not be able to disable interrupts). There are few exceptions like XWindow servers, though. In common, a kernel driver implements an intermediate between userland and hardware, and all potential problems are isolated within this intermediate.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.