Question about context switching in RTOS

Question about context switching in RTOS.

I want to develop a basic embedded RTOS for a microcontroller.

The hardware stack is small but I have direct access to it.

On each context switch I can save the hardware stack associated to the current program and load it into the programs memory space.

The problem is this could take a long time - I could also split up the sections of the hardware stack for each thread but then each program only gets 2-3 function calls before they enter into another programs stack.

What is the best way to program this?

Other urls found in this thread:

nommu.org/memory-faq.txt
nescc.sourceforge.net/
twitter.com/NSFWRedditVideo

Lmao get a load of this nerd

From a real-time researcher: remember that "real-time" is not equal to "real-fast". Backing up and restoring the stack properly is almost definitely the right thing to do--reliability should be key in an RTOS so you *definitely* never want to let one misbehaving program mess up another's stack.

Adding to this: a good RTOS will minimize the number of context switches to begin with. Also, even a fairly hefty stack shouldn't take more than a couple microseconds to swap into main memory on any reasonable architecture. That should be well within the safety margins of your robot/camera/whatever

>real-time researcher
Sounds interesting. What exactly do you do? What kinds of technologies do you work with?

Why? Real time is mostly an impossible pipe dream. Unless you want your controller to pretty much do one basic thing over and over.

I'm just a grad student, I'm fairly new to real-time, but have plenty of osdev experience from prior work in computer security. My current research is mostly focusing on GPU management in real-time systems (conclusion so far: you don't, thanks to NVIDIA's proprietary drivers). I've also done some work on reducing cache/memory contention on multicore embedded systems.

So, I've been working with various single-board computers with GPUs, including NVIDIA's Jetson boards and occasionally some stuff from freescale.

What about you? I don't recall having ever encountered someone asking real-time questions on Sup Forums before.

>Real time is mostly an impossible pipe dream
This is a fairly common misconception from people who haven't encountered stuff from the real-time community.

The basic concept behind real-time is simple: say you have a function that runs, on average, in 5 milliseconds, but sometimes can take 200 milliseconds. A better system from a real-time point-of-view may have an average time of 10 milliseconds, but would only take 15 milliseconds at worst.

Do you really think it's impossible to design systems like that? (I would hope not)

Generally, real-time work will do things like use (slightly) more costly scheduling and resource management within the OS in order to reduce elements of randomness that can contribute to unpredictable performance.

Aside from that, there's some brilliant theoretical results relating to scheduling that have come out of the academic real-time community.

How do you split up memory space? In an embedded environment program memory is small - the easiest solution is just give a memory range for each program. but this isn't the most efficient use of memory.

Interesting thread guys. I don't know much about realtime oses, but from the Wikipedia page would it mean that the only context switches come directly from hardware interrupts?

If that's the case then isn't it non-realtime if you don't service the request before the next interrupt comes in?

Not that guy but I found this a fascinating read:

nommu.org/memory-faq.txt

Honestly, that's a very platform and system-specific question. What type of programs are you wanting to support? Are you writing a loader for executable files, or are you just writing a library-like OS that allows users to register functions?

If you're going for a "traditional" OS that allows people to run ELF binaries, for example, then you'll probably have no way around over-allocating memory. Additionally, if you care about handling a program which incorrectly overflows its stack, then you may have no choice but to have stack protection of some sort. Does your microcontroller have an MMU?

Sorry for interrupting your consumer electronics circle jerk, I apologize for assuming this board was anything more then webdevs and amdvintel shitposting.

no MMU, the micro is 8 bit. There isn't a loader but that could be incorporated but initially I was just going to write a library-like OS with each task in an infinite loop.

Yeah, true "real-time" is almost always used by hardware, and will be most important in systems like airplanes or power plants where responding to something on time is just as important as doing the logically correct thing in software.

Some microcontroller real-time systems aren't even OSs in the traditional sense, and may only do polling--that allows you to do some really cool things like only have a single loop in the entire program, and updating state of multiple subroutines one step at a time, in each loop iteration.

Hm, here's what I might do in that case:

Allocate each function a very tiny stack, and save as much memory as you can for a heap allocator. For example, have 1KB stacks for each function, and then every time your OS preempts, check to make sure that the stack pointer isn't over 1KB greater than the base of that particular function's stack.

It's not a perfect mechanism by far, but it's at least a small sanity check so you could potentially fail early and warn users about the error. Scale up the stack size as much as you can depending on your platform's available memory. 4k is always good if you can get it. The Linux kernel only uses 8k stacks, after all.

So, as long as you have your small stacks for each function, you should have a pool of remaining memory that you can write a heap allocator for. That's kind of beyond what I feel like describing on Sup Forums, but K&R chapter 8.7 has a good example you can try to adapt (I'm assuming you're using C and pirate K&R if you don't have a hardcopy). The main thing that you'll need to do in your allocator for an RTOS is fail early if you have to.

The last thing to remember is that an RTOS doesn't need to be able to handle every workload. For example, if someone's registering a new function to run in your RTOS, it's okay to return a "fail" condition if you're out of 1KB stacks.

Sorry, I meant for you

On second thought, a much simpler way to organize this would be to start by writing the heap allocator, and then allocate your small function stacks out of the heap. You'll still need to encourage users to allocate as much as possible on the heap rather than on the stack, but there's definitely no reason to limit the number of concurrent tasks to some arbitrary value beyond what can fit in memory.

I keep spamming this thread, but I also realized that an 8-bit system would probably be fine even with 256 *byte* stacks. It probably has 16-bit addresses, so you could still fit 128 pointers on each function's stack.

wtf is this and how did it get posted on 4chans consumer electronics board??

Nesc and TinyOs are optimized for this sort of thing.

nescc.sourceforge.net/

It lets you do asynchronous programming a lot easier.

>What about you?

Recent CompE bachelors grad, in my first job doing firmware programming (microcontrollers). It's what I planned on going into when I was in college, but now I'm not sure I like it...

How did you get into OS stuff? Do you think playing around with an RTOS is a good introduction? Or should I start with something more complex, like the Linux kernel?

How could you graduate with a CompE degree and not know the basics of operating systems at a hardware level?

I was in a cube farm "enterprise" java-tupe job and hated it, so I started building my own OS as a way to cut down to computing at its core, basically because I wanted a break from high level design by committee shit. Eventually I got a good chance to work in low-level security and jumped on that. And now that I'm going back to grad school I made sure to do something that lets me work with kernels and hardware because it's what I like. I'd go to vocational school and become a plumber before being a Java monkey again, no joke.

I'd honestly recommend trying to make a regular old OS if you're not familiar with kernel programming already, rather than jumping straight into RTOSs, but it sounds like you already know enough to make your way forward. If you'd rather gain more overarching (and more fun) approach to OSs in general, I wouldn't jump right into the Linux kernel, you'll just get bored and/or lost. Instead, I'd start by following a tutorial like the BrokenThorn OS tutorial (Google it) until you get through memory allocation at least.

Sadly, microcontrollers often just don't give you enough room to work. If you were using a cheap ARM chip it would be much more enjoyable I'm sure.

(tons of typos because I'm on my phone now)