views:

376

answers:

2

I find myself in a situation where I need to work on a embedded, real-time system at work without much prior knowledge. I've done a fair amount of research online, but found nothing satisfactory, so I'm now turning my attention to books.

I've seen this StackOverflow page but I'm not sure if the books that it points to are what I'm looking for. Here are some specific questions that I've accumulated on the job but am still clueless on: (this is a linux system, BTW)

  • User mode vs Kernel mode. I get that kernel mode is a privileged mode, is faster and so on, but how exactly do I get myself into kernel mode and program in it? Why do I need to go from user mode then to kernel mode? What is a proxy?

  • Task vs ISR context. Why is it called task context? If I'm in an ISR context already and receive another interrupt, do I exit my current ISR context immediately? If I'm in task context, can I prevent an ISR context from occurring?

  • Context switch. Does this refer to Task<->ISR switch or user mode <-> kernel mode switch? Why is this expensive?

  • Device drivers. Why do I need a user mode driver and a separate kernel mode driver?

  • Re-entrancy. Does this refer to different threads accessing the same function or is this related to ISR context?

I'm looking for a book that will shed some light on these questions. I certainly hope this is all standard material and I'm not asking obscure questions!

Many thanks for your input.

+1  A: 

Well, exact answers will depend on exactly what sort of Linux real-time system you are using (Vanilla Linux with real-time threads? RTAI? Xenomai? Something else?), but here's my attempt to answer:

  • Kernel mode is code that is running "inside the kernel", i.e. in the kernel's address space, so that it has direct access to kernel objects, etc. The typical way to get your code into the kernel would be to write a device driver, since device drivers run in the kernel. Your user-land code would then interact with the device driver to tell it what to do (often via read/write or ioctl() calls on a file descriptor).

  • I assume "Task context" means the context of a running thread or process, and "ISR context" means the context of an interrupt. If you're currently in an interrupt and another interrupt occurs, what happens will depend on the two interrupts' relative priorities. If the second interrupt has a higher interrupt priority, it will interrupt the first interrupt, execute, and the the first interrupt will continue after the second interrupt has completed. If the second interrupt has a lower (or equal?) priority, it will not execute until the first interrupt has completed. (assuming it is a single-core system, of course... on a multicore system the two interrupts might execute in parallel on different cores!)

  • A context switch refers to any time the CPU stops executing one stream of code and starts executing another. It's (somewhat) expensive because the current state of the CPU (i.e. all the registers) have to be saved out to RAM, and then all the register for the other context have to be loaded in from RAM, before execution of the new context can resume.

  • You typically want to keep as much code as possible in the user mode code, simply because any bugs that occur in kernel code can be quite devastating (i.e. they can kill the entire OS, not just the local process). The rule is: only put into the kernel side things that absolutely have to be there, and ideally only things that are dead simple and very hard to mess up. Everything else goes into userland. (Another reason is that there are severe limitations on what you can safely do in kernel code: e.g. no C++, no floating point math, no exceptions, dynamically allocating and freeing memory is possible but discouraged, etc)

  • Re-entrancy can apply to multiple threads or threads vs ISRs or even multiple ISRs. Re-entrancy can occur whenever a function can be executed while the function is already executing.

Jeremy Friesner
I'm not sure sort of Linux I'm dealing with; to be honest I thought there was just one "Linux", eg. the kernel, that everyone used and that was it! (until you just pointed this out, that is...)Do you know of any books that talk about this sort of stuff? My main concern was not to get specific answers to the questions I had listed, but to get some guidelines on how I can teach myself about all this. If you could list some books that helped you get to this point, I'd find it very helpful.
psa
Intel Architecture Programmers Reference Manual ( www.intel.com/products/processor/manuals/ ) has exactly what you spec, which is what the answers would arrive at in some part of the conversation. There are other brands, but to get to the point that book and others like it in any brand do nothing but get to the point. Stray too far from that and you might as well engage a Masters Thesis subject on Data Structures.
Nicholas Jordan
+1  A: 

Since you are targeting Linux which still isn't what most would consider a true real time operating system although it is getting pretty close, I think you might want to check out the Linux System Programming and Linux Device Drivers O'Reilly books.

As for your questions, in my view these aren't exclusively real-time problems and are just systems programming questions. Regardless, I will take a stab at answering them.

  • The CPU has different rings of protection. The Kernel runs at ring 0 which means it can run any instruction it and do anything it wants. User mode applications (and the rest of the operating system) runs at a higher ring and thus must trap into the kernel to request that certain operations be performed on its behalf. If you're code rarely needs to ask the kernel to do anything, running in user land can be nearly as fast as running code directly in the kernel.

  • An ISR is just a function. It is not associated with a specific task and thus lacks the ability to be put to sleep by the OS and woken up later. Because of this the code of an ISR must avoid calling functions that result in the calling thread being put to sleep pending some resource becoming available later. While ISRs may be interrupted by a higher priority interrupt, they sometimes temporarily disable interrupts. This is generally frowned upon since it can increase the latency of other higher priority interrupts.

  • Context switches are expensive because the state of a task that was running must be saved and the state of the soon to be running task must be restored. Additionally, other features of the processor like the TLB and cache get flushed and must be repopulated before the system can run at maximum efficiency again.

  • User mode device drivers are easier to debug since you can use GDB and all the same tools you use to debug a normal application. Plus its harder to bring down the whole system when you avoid tinkering with the kernel. Depending upon what kind of hardweare you are writing a driver for, you might not even need a kernel mode device driver if there is an existing facility to expose your hardware to user space (like there is for PCI or USB).

  • Both situations you describe deal with re-entrancy.

Tim Kryger
My main concern was finding a couple books that would systematically teach me these things, rather than getting answers to the specific questions I listed, but thanks for answering them anyway :P Do you know of any other books you can recommend? eg. systems programming books that talk about these things? If you had to teach yourself the stuff that you just explained to me, where would you turn to? Please don't say 'go back to school and sit through some classes' :)
psa
The Linux Device Drivers book in combination with a good operating systems foundation would just about cover all your questions. While I'm not going to suggest you go back to school, you may want to check out the webcast UC Berkeley has of their OS class. http://webcast.berkeley.edu/course_details.php?seriesid=1906978341
Tim Kryger