SATNKernel

antime

Extra Hard Mid Boss
I made a port of the TNKernel real-time kernel to the Saturn, available on GitHub. The kernel is released under a BSD license.

The kernel does not support SMP, but you can run separate instances on both CPUs. API documentation is available on the TNKernel website, the small API changes made should be obvious. You can configure which vectors are used by the kernel in the file tn_port_config.h, and interrupt handlers should be wrapped by the macro found in tn_port_asm.h. I'll post a working example project soon.

Note that the port hasn't been very thoroughly tested, so expect bugs.
 
antime said:
I made a port of the TNKernel real-time kernel to the Saturn, available on GitHub. The kernel is released under a BSD license.

The kernel does not support SMP, but you can run separate instances on both CPUs. API documentation is available on the TNKernel website, the small API changes made should be obvious. You can configure which vectors are used by the kernel in the file tn_port_config.h, and interrupt handlers should be wrapped by the macro found in tn_port_asm.h. I'll post a working example project soon.

Note that the port hasn't been very thoroughly tested, so expect bugs.

Excellent. I've never heard of TNKernel. I've been looking at Contiki myself. I'm going to be tinkering with this as I had the idea to add protothreads.
 
The first example is up.

I'm thinking about adding support for an interrupt stack to reduce RAM requirements (I also ported the kernel to the PIC32 where this feature is sorely needed, the MIPS register context is huge), but otherwise I don't plan on diverging too much from the original sources. But knock yourself out, it's open source for a reason.

I discovered TNKernel while looking at µT-Kernel, TOPPERS and other related projects, but their build systems were fairly convoluted and some had rather bizarre source redistribution terms. While TNKernel isn't a µITRON implementation, it's "inspired" by the specification. More importantly it's small, has a friendly license, is easy to build and the platform-specific bits are easily ported.
 
Nifty! I suppose you worked from the v2.6 code? Some of the ports are a little dated (like the ColdFire port).
 
antime said:
Says so at the top of each file:

Great! Haven't gotten around to decompressing the archives yet... was reading docs over at TNKernel to see what this is/does. Any plans to also port nano-x to the Saturn?
 
Fair enough. I didn't think you were, but it never hurts to ask.
biggrin.gif


For the most part, heavy interfaces like X aren't needed for consoles. Kernels aren't either, but this TNKernel looks lightweight enough to be useful on consoles.
 
Chilly Willy said:
Fair enough. I didn't think you were, but it never hurts to ask.
biggrin.gif
/>

For the most part, heavy interfaces like X aren't needed for consoles. Kernels aren't either, but this TNKernel looks lightweight enough to be useful on consoles.

TNKernel seems to be very light. I'm looking at the documentation along with antime's repository. This will go well with libyaul
smile.gif
 
mrkotfw said:
TNKernel seems to be very light. I'm looking at the documentation along with antime's repository. This will go well with libyaul
smile.gif
/>

Yeah, been checking it out myself... it bares a CONSIDERABLE resemblence to exec.library from AmigaOS. Exec was always the lightest kernel I've ever seen on a PC for what it did. Not claiming anything sinister here - there are worse OSes it could have been influenced by.
wink.gif
 
Similar to does not equal influenced by. There's only so many ways you can skin this particular cat, so there are literally hundreds of real-time kernels for embedded systems that are completely unrelated but nevertheless nearly identical in design and implementation.
 
antime said:
Similar to does not equal influenced by. There's only so many ways you can skin this particular cat, so there are literally hundreds of real-time kernels for embedded systems that are completely unrelated but nevertheless nearly identical in design and implementation.

Does not NECESSARILY equal... but I wouldn't be surprised if the author(s) were Amiga programmer(s) in the past.
wink.gif
/>
biggrin.gif
/>

On the other hand, I WOULD be surprised if they WEREN'T Amiga programmers in the past.
 
Uh huh, a claim based on nothing definitely sounds more plausible than the author's explicitly named inspiration (µITRON).
 
Support for an interrupt stack was added as a configurable option.

Developing the feature really reinforced my opinion that the SH2 is a pretty crap architecture and that Hitachi's processor architects didn't really know what they were doing. A lot of the SuperH system design looks like it was "borrowed" from the 68000, but then changed without fully considering the implications. In this case, there is a small window at the beginning of every interrupt handler where a higher-priority interrupt can trigger and its ISR launched before you have a chance of disabling interrupts. Before interrupts can be disabled, a total of four words must be pushed onto the stack (SR, PC and two work registers) so even with an interrupt stack you must reserve an extra (4*the number of interrupt priority levels used) words of space in every task stack.

In SH3 they solved the problem by adding a global interrupt disable bit that is automatically set when entering an ISR. Which coincidentally is how eg. MIPS works.
 
antime said:
A lot of the SuperH system design looks like it was "borrowed" from the 68000, but then changed without fully considering the implications.
Yeah; I've long regarded it as a "what if the 68000 were more RISCy?" design, and it's probably not a coincidence that several arcade companies switched from 68000 to SuperH in some capacity, though that may simply have more to do with Hitachi being the main 68000 vendor in Japan.
 
antime said:
Support for an interrupt stack was added as a configurable option.

Developing the feature really reinforced my opinion that the SH2 is a pretty crap architecture and that Hitachi's processor architects didn't really know what they were doing. A lot of the SuperH system design looks like it was "borrowed" from the 68000, but then changed without fully considering the implications. In this case, there is a small window at the beginning of every interrupt handler where a higher-priority interrupt can trigger and its ISR launched before you have a chance of disabling interrupts. Before interrupts can be disabled, a total of four words must be pushed onto the stack (SR, PC and two work registers) so even with an interrupt stack you must reserve an extra (4*the number of interrupt priority levels used) words of space in every task stack.

In SH3 they solved the problem by adding a global interrupt disable bit that is automatically set when entering an ISR. Which coincidentally is how eg. MIPS works.

Yeah, I noticed the similarity to the 68000 right off the bat. They stripped out a number of things they thought weren't needed by embedded applications, most notably super/user state. You have one state in the SH2. But for something like a console where you aren't trying to lock out all hacking, that's fine. You don't need a privileged state. The way "immediates" are the handled is often the hardest for newcomers to deal with, and all offsets for data are POSITIVE, so you can only put data AFTER code instead of before it. The range is also pretty short, especially for bytes. Irregardless (
laugh.gif
), I find the SH2 a joy to program in assembly compared to the x86.

As to a higher level exception interrupting your lower-level interrupt handler, that's possible on most platforms and merely something the kernel writers need to keep in mind while writing the handler system. The Amiga fully handled interrupts inside interrupts. Again, compared to the x86, interrupt/exception handling on the SH2 is not that bad.
cool.gif
 
antime said:
Support for an interrupt stack was added as a configurable option.

Developing the feature really reinforced my opinion that the SH2 is a pretty crap architecture and that Hitachi's processor architects didn't really know what they were doing. A lot of the SuperH system design looks like it was "borrowed" from the 68000, but then changed without fully considering the implications. In this case, there is a small window at the beginning of every interrupt handler where a higher-priority interrupt can trigger and its ISR launched before you have a chance of disabling interrupts. Before interrupts can be disabled, a total of four words must be pushed onto the stack (SR, PC and two work registers) so even with an interrupt stack you must reserve an extra (4*the number of interrupt priority levels used) words of space in every task stack.

In SH3 they solved the problem by adding a global interrupt disable bit that is automatically set when entering an ISR. Which coincidentally is how eg. MIPS works.

The SuperH is overall a bad design. I still don't understand why the SuperH was chosen. The only advantage I can see is the compactness of each instruction improving instruction caching and decreasing the size of a program by some factor. Aside from potentially improved instruction caching, it's totally irrelevant to the Saturn. It's more fitting for the 32X, in my opinion. Also, at a quick glance, the SH-2 pipeline is essentially the 5-stage MIPS pipeline.

So to be clear, this is to avoid having to make use the current thread's stack? So all interrupts essentially share the same stack then?
 
Chilly Willy said:
You have one state in the SH2.

That is not an issue. Not being able to atomically disable interrupts is.

As to a higher level exception interrupting your lower-level interrupt handler, that's possible on most platforms and merely something the kernel writers need to keep in mind while writing the handler system.

The hardware makes it impossible.

mrkotfw said:
I still don't understand why the SuperH was chosen.

I may be misremembering, but wasn't the rumour at one point that the original design used NEC CPUs (probably a v810 or similar) and that the switch to Hitachi was more or less done as a personal favour to their chairman? Though given how many other parts of the Saturn were designed and/or manufactured by Hitachi they may just have gotten a good deal.

The only advantage I can see is the compactness of each instruction improving instruction caching and decreasing the size of a program by some factor. Aside from potentially improved instruction caching, it's totally irrelevant to the Saturn. It's more fitting for the 32X, in my opinion. Also, at a quick glance, the SH-2 pipeline is essentially the 5-stage MIPS pipeline.

Reduced memory bandwidth may have been a factor. The classic RISC pipeline probably dates back to the Stanford MIPS/Berkeley RISC projects or some precursor thereof.

So to be clear, this is to avoid having to make use the current thread's stack? So all interrupts essentially share the same stack then?

Yes, otherwise the stack of every task must have enough space for all ISRs. If you have many tasks it starts adding up.
 
antime said:
That is not an issue. Not being able to atomically disable interrupts is.

The hardware makes it impossible.

antime said:
I may be misremembering, but wasn't the rumour at one point that the original design used NEC CPUs (probably a v810 or similar) and that the switch to Hitachi was more or less done as a personal favour to their chairman? Though given how many other parts of the Saturn were designed and/or manufactured by Hitachi they may just have gotten a good deal.

A good deal, initially, yes. Not such a great deal in the long run if you know what I mean. From a very quick glance, it was unwise of them to have chosen the SH-2.

antime said:
Reduced memory bandwidth may have been a factor. The classic RISC pipeline probably dates back to the Stanford MIPS/Berkeley RISC projects or some precursor thereof.

That's actually what I meant to refer to; the classic RISC pipeline taught in school. Other MIPS variants are obviously much more complicated (MIPS 10K comes to mind).

antime said:
Yes, otherwise the stack of every task must have enough space for all ISRs. If you have many tasks it starts adding up.

Great. Makes sense.
 
antime said:
That is not an issue. Not being able to atomically disable interrupts is.

The hardware makes it impossible.

The asserted interrupt sets the interrupt mask to its level. Only a HIGHER interrupt can occur, and then only until the mask reaches 7, then only non-maskable interrupts can occur... and there aren't any on the Saturn. At MOST you can have seven nested ints. Not to say exceptions still can't occur, but that's only an issue of working out bugs in the handler code.

This is EXACTLY the same as interrupts on the 680x0. You set a mask level, and only interrupts of a higher level are serviced. Each interrupt sets the mask to its level so only higher priority interrupts can occur. You don't WANT interrupts disabled as you will hold off HIGHER PRIORITY interrupts. If a level 1 int is being serviced, a level 6 interrupt should STILL BE ALLOWED.
 
Back
Top