Another week, another feature: we now have hardware interrupts working! Software interrupts are comparatively easier to handle, as the user task can decide when they occur; by contrast, a hardware interrupt can strike anytime, so your context switch needs to be prepared.
To soften the blow, we used the Vectored Interrupt Controllers (VIC) within the TS-7200 system-on-chip. These function as interrupt service routine jump tables with the added benefit of a built-in priority mechanism; proper initialization permitting, they will automatically turn off all interrupts at higher priority. Handy indeed.
It's futile to handle hardware interrupts unless you actually do something with them, so we've also put together the ClockServer(). This special user task receives notification of timer interrupts from ClockNotifier(), which in turn waits upon those interrupts using the new AwaitEvent() system call. When a task calls AwaitEvent(), the kernel keeps track of which event the caller is waiting on. Upon a hardware interrupt, the ARM jumps to our KernelEnter() in IRQ mode, does all of that wonderful context-switching-related stuff, then looks up the current interrupt in the VIC. The VIC provides the address of a handler function; for instance, interrupts from Timer 3 are handled by TimerHandler(). These handlers take care of waking up the appropriate tasks by reinserting them onto the priority queues.
Of course, we've omitted a few details; you can always poke around our source code to fill in the blanks.
Showing posts with label context switch. Show all posts
Showing posts with label context switch. Show all posts
Thursday, June 18, 2009
Thursday, May 28, 2009
Task #4, I Choose You!
After another code/blackboard sprint this morning, we're proud to announce a working implementation of basic scheduling along with a few simple system calls. (Like fork() - I hear that one's pretty important.)
We use FIFO scheduling with a preset number of queues, each representing a given priority level; the kernel picks the ready task at the highest priority, runs it, then places it at the back of the queue at its priority level. Since low priority tasks can easily be starved by high priority tasks, this may seem like an embarrassingly stupid scheduling algorithm - until you realize that this is embedded real-time programming, where we alone decide exactly which tasks run at each priority level.
For your amusement, here are some development statistics so far.
ARM assembly: 50 lines, 25 hours
C: 250 lines, 5 hours
There's a point about language expressiveness, ease of debugging, and programmer productivity here that I'm going to completely ignore in favour of getting some much-needed sleep. We'll try to get some terminal output screenshots up in the next few days.
We use FIFO scheduling with a preset number of queues, each representing a given priority level; the kernel picks the ready task at the highest priority, runs it, then places it at the back of the queue at its priority level. Since low priority tasks can easily be starved by high priority tasks, this may seem like an embarrassingly stupid scheduling algorithm - until you realize that this is embedded real-time programming, where we alone decide exactly which tasks run at each priority level.
For your amusement, here are some development statistics so far.
ARM assembly: 50 lines, 25 hours
C: 250 lines, 5 hours
There's a point about language expressiveness, ease of debugging, and programmer productivity here that I'm going to completely ignore in favour of getting some much-needed sleep. We'll try to get some terminal output screenshots up in the next few days.
Labels:
assembly,
C,
context switch,
kernel,
real-time
Wednesday, May 27, 2009
Context switching works!
Welcome to the PsychOS blog! We'll be keeping a diary of our successes and failures throughout the length of the real-time programming course. If you want to know more about the course, the architecture we are using, or you are just wondering what PsychOS means, look at our wiki page.
Before we could do anything, we had to spend countless hours digging through the ARM reference manual and the circuit board user guide. We started working on the kernel from scratch this week and today we finally managed to get the first step done - the context switching...
Since Monday, we wasted over 20 hours getting the context switching working properly because of a stupid bug. The user task completed a system call successfully once, but failed horribly the second time. Evan eventually figured out that the processor mode wasn't properly restored upon exiting the kernel from a system call... High five! :) All we have left to do is to implement a few other system calls besides Pass() and the first kernel assignment will be done!
Before we could do anything, we had to spend countless hours digging through the ARM reference manual and the circuit board user guide. We started working on the kernel from scratch this week and today we finally managed to get the first step done - the context switching...
Since Monday, we wasted over 20 hours getting the context switching working properly because of a stupid bug. The user task completed a system call successfully once, but failed horribly the second time. Evan eventually figured out that the processor mode wasn't properly restored upon exiting the kernel from a system call... High five! :) All we have left to do is to implement a few other system calls besides Pass() and the first kernel assignment will be done!
Labels:
context switch,
kernel,
PsychOS,
real-time,
wiki
Subscribe to:
Posts (Atom)