Embedded - 307: Big While Loop
Episode Date: October 24, 2019Chris and Elecia explain when and why to use an operating system on a microcontroller (real-time or not). Thank you to our Embedded Patreon supporters, particularly to our corporate patreon, InterWork...ing Labs (iwl.com).
Transcript
Discussion (0)
Hello and welcome.
This is Embedded.
I am Alicia White and my co-host is Christopher White.
Hello.
This week it's just going to be us.
And I think we have some interesting things to talk about, but we're going to talk about ourselves first.
How are you, Christopher?
I'm fine.
You told me not to read the notes, and now you're springing, how am I?
Did you think how am I needed to be in the outline?
Yeah, I don't know. I've got to prepare for a question like that.
You're taking a class.
I'm taking an online course, correspondence correspondence course as they used to be called
yes uh udacity's self-driving car course because i need it for work machine learning it's the way
i'm learning all about machine learning in various exciting and frustrating ways
because it's taught in some of it's very good and some of it is frustrating
but some of the frustration is merely my my approach to learning which tends to be
wait you can't just say that you need to explain it so i'm trying to let go of those feelings and
just let the information enter my brain get forgotten because I didn't really engage with it or understand it fully.
No, it's fine.
It's good.
And I'm spending a lot of time on it, so it can't be terrible or I would have quit.
Yes.
You haven't been bored.
No.
Frustrated, but not bored.
Yeah.
And you decided that we should have new levels in Patreon such that we have to send out pins
to people.
Huge mistake.
Could you explain this?
Would I explain it?
Well, no.
So you wanted trading pins and it took me a long time to understand.
I got like normal.
But that was separate from Patreon.
I just wanted the trading pins and it took me a long time to understand. I got like normal. That was separate from Patreon. I just wanted the trading pins for,
for to give out.
They were cool.
And,
uh,
people do them for,
for other things.
And we had the,
the mugs and the shirts and things.
And I don't know if I thought people would like them.
Uh,
and then we have a bunch left over.
And so I thought as a nice incentive for the,
for the $5 tier,
maybe we could send those out.
And so that's what we did.
$5 a month, not $5 an episode.
Yeah, yeah.
Still pretty reasonable.
And it's really hard to mail them.
Turns out, sorry.
It's not really hard to mail them.
We just had to practice.
And so we do have levels now.
We didn't before.
And people who are at $5,
but who signed up initially, may
not be on the list to get pins. You have to move yourself over.
Yeah. You don't have to pay anymore. You just have to move yourself to the other tier because
you're on the $1 tier paying $5. And so now you have to move yourself to the $5 tier paying
$5.
And put in your address.
Yeah.
We still are missing a lot of addresses.
Which we will prompt people for monthly, I think, probably.
Sure.
Something like that.
And we also have a corporate listener level for corporate patrons, which is like 40 bucks.
Wow, I really should have...
45.
45.
And that's for companies who want to support the show a little more.
We're still not doing formal sponsorships and commercials and stuff, but we're happy to say thank you and mention you.
And so far, our only corporate patron is IWL, Interworking Labs.
All right.
Well, we may do something else with other tiers.
Keep pondering it.
Yeah. And we're hoping at the $5 tier that we will try to send things out twice a year,
but we don't know what those things are at this point.
If you have suggestions for things that would entice yourself or others,
let us know.
Whether it's bonus episodes, which are kind of hard to do,
but I'm open to it, that kind of stuff.
Kate doesn't think you want to hear the short story that I wrote. I still want to
edit two podcasts a week.
And
at any level in
Patreon, you do get a Slack
invite, so you can join
us in our scintillating discussions.
Yeah.
And that's not just us. We don't
actually participate all that much anymore
compared to everybody else.
I do. It depends on how busy I am.
If I'm super busy, I read enough
to make sure everything's going okay.
If I'm not, then I'm there.
And for those of you who are giving us
a couple of bucks every month,
whether it's $1 or $5 or $45,
we really do appreciate it.
It's really, really nice that you like the show enough to give us money.
And to cover the show's expenses, which are not super tiny, but they're not huge.
Depends on how many mics I have to send out a month.
Yeah, right.
One of the discussions that came up in the Slack was someone, I'm not quite sure how it started, but someone wanted to know which RTOS they should use or whether they should use an RTOS at all.
I think it was whether they should use an RTOS. They weren't convinced that they should. I don't think they were fully on board with the concept of an RTOS and why they should use one.
And you did join that discussion pretty early.
I can't remember, but I think so.
And you had a, and I didn't see it until later, you had a lot of things to say and lots of
people had lots of things to say.
Did you happen to copy all the things I said here?
Because I don't remember any of them.
Nope.
Okay, well, that's fine.
But then I suggested we'd actually do a show where we talk about some of the things we talked about and maybe start over on the conversation.
Sure.
And when I said that, you initially balked because you said you're not an RTOS expert, which I'm not either.
Right.
What RTOSs have you used?
Off the top of my head, which is to say in the 30 seconds before the show started, I tried to write down what I remembered.
And ThreadX is the most recent RTOS.
VxWorks, Greenhills, LynxWorks, which I probably don't remember.
It was sort of a Linux-y thing.
It wasn't based on Linux at the time, but it was a Unix-y microkernel thing back in the late 90s.
They later changed themselves to a company called LinuxWorks,
and now they're Linux-based.
Anyway, that was what Procket's router was based on.
LinksOS.
LinksOS.
Anyway.
Embed kind of counts.
Use that.
And I think there's a couple others i'm forgetting but at
least a half a dozen different artas is things that advertise themselves as artas
oh my list is smaller if we're sticking with that um i've used ti's dsp bios
i've used nordic's ble system which doesn't have a name, but it is definitely an RTOS.
I've used a little bit of BusyBox Linux in a couple of places.
PumpkinSalvo, which is just an off-the-shelf, not too complicated RTOS.
PumpkinSalvo?
You pay like one thing of like $800 or $600 and that's it.
And you just, you get the support.
Weird little companies like that, but yes.
I used PSOS in 1998.
Yeah, I think I evaluated PSOS, but I don't think I ended up using it.
And I learned about Micro-COS, the Jean Labrasse book.
And I also learned some from Tannenbaum's OS book,
which I think you had it in class.
I took an OS class in college.
I think I used QNX too, but I can't remember.
I know Cisco used it briefly.
I don't remember if I did much with it other than type make.
Okay, so.
But there's a lot of RTOSs out there.
That was really the point I was trying to make.
We are not experts, and yet we've seen a lot.
And still, I wouldn't call myself an expert in RTOSs.
And if I was going to use an RTOS today, and it needed to be big-ish,
I would go for a free RTOS or RTEMS.
I'm going to change my answer.
I would consider myself something of a small OS expert, but not the RT part.
Because every time I've used one of these, I have not really cared about the response time, which is the real-time part of real-time OSes.
I have in spots.
Have you?
Yeah.
I mean, it's nice that it's bounded a lot of times for certain operations,
but I've never gone in and heavily tuned something
because, oh, this has got to respond.
Maybe with VXWorks we did, but I really can't remember.
Oh, there was a TIBLE one that I remember tuning.
But, yeah.
Well, and when I need serious real-time, I go bare metal.
I don't usually... You're looking at me like I'm crazy, but how do you, actually the question that came up was,
how do you go from an embedded engineer with a few years of non-RTOS experience to thinking about how could an RTOS make my designs better, faster.
Okay. I have an answer for that, but I'll put a pin in it for a second.
Okay.
Oh, I thought you were going to continue.
No, I was going to go in, unless you want to talk about
RTOSes you would want to use going forward.
No, not yet. I had a thought before that though.
Oh, like, well, I mean, I did make a face when you said bare metal,
you'd go bare metal for fast responses. But in reality, several times we've just put that kind of stuff in hardware. Like, oh, is this a safety critical system? We can either have an RTOS and handle the interrupt really quickly and make sure all that stuff's doing deterministic things, which is in software no matter how you how you say it uh we put that in fpga i've done it put it in a smaller
micro control right yeah so put it in a little dedicated piece of hardware and that's that's a
good good thing to do because again the rt part i'm sure it's fine but i've never really engaged
with it that deeply to be really comfortable
with it no matter what people claim especially on different hardware like sometimes i did an x86
and it's like okay there's a whole mess of hardware in between me and and the os we should
definitely get back to the rt part yeah but i think um i think that that's secondary actually
so the question was how do i go from an embedded engineer with a few years of, sounds like, bare metal experience to how can an RTOS make my designs better?
So I was thinking about this morning, and the way I think about an RTOS or an OS, I'm going to stop calling it an RTOS because these are really microcontroller operating systems.
I don't think there's a microcontroller operating system out there that doesn't call itself
an RTOS.
I wouldn't expect so.
That would just be...
Yeah, so I'm going to leave off the
RT part.
When you're making a device, you're making
an application.
And whether you're doing it explicitly
or not, you need an application
framework.
And this is the stuff that handles when things happen, how events are handled, how input is translated from your device sensors to your software, your application software, how you deal with memory and things like that. When you go bare metal, you're doing that all kind of explicitly,
kind of the 10-year-old writing basic,
writing a Dungeons and Dragons program with a lot of printfs and ifs then elfs.
But it's explicit, right? It's hard-coded.
These events happen in certain ways.
And you can go from the 10-year-old printf version of bare metal to the very sophisticated version of bare metal
where you're basically writing an RTOS, right?
So you have an application framework.
So what I think of RTOSs and OSs for micros
is as the application framework,
and it makes your life easier writing an application
to have some of those things, that API, kind of done for you.
That boilerplate stuff of, oh, this is an event handler
and it has an API and it can ship messages and events
to various pieces of my code.
Oh, this is a task manager.
I can divide my application up into multiple tasks
and keep the functionality separated
and keep my code smaller in various areas and isolate things that shouldn't be doing things to other things from each other.
And that kind of thinking leads you to architect your application in a much different way if all that stuff is provided for you.
So I kind of think of the OS as the application framework on micros.
I don't think of it that way on a desktop.
On a desktop, your application framework
sits on top of the OS
and it does things like handle your mouse
and draw windows and all that stuff.
But whereas the OS in that case
is just managing,
is doing the scheduling and stuff,
but you're not involved with it as much.
Does that make sense as an analogy?
It does, yes. And I understand where you're coming from.
But actually, I kind of want to come from a different direction.
Well, I was trying to answer why would you want to use one?
I want to do that too.
Go ahead, fire away.
But someone, and probably it was Jakey Poo, because seriously, I have to say that out loud,
asked if there was some middle ground between a big loop and an RTOS.
And my response to that was, there is all middle ground.
And I felt like the way that I think about going to operating systems has to do
with figuring out where I am on that number line. On one side, you have not even Arduino level, a while one, pull the serial interrupt. Print F.
Print F.
Pull the temperature sensor, print F to the serial port in a blocking fashion.
Yeah, totally do this, do this, do this, do this,
and start over and do those things again forever.
Right.
And then the thing that comes next is to have an interrupt.
Because interrupts are asynchronous.
They don't happen when you expect them to,
and they can make your system faster
because now instead of pulling for your temperature sensor
and then going to the printf,
you can wait for the temperature sensor to say it's done
and then do the printf, which doesn't really help you in that case.
But if you have five other things that you're doing that are coming in asynchronously, you can printf in the main loop and still pick things up in the interrupts or even handle things in the interrupt if you need to push small amounts of data from one place to another.
So now you have interrupts and you have a main loop.
And a lot of people, that's enough.
Now the next thing is when your interrupt isn't based on a physical thing.
It's based on a timer.
And that is where we start talking about operating systems.
To me, the timing system has to do with what makes a real-time operating system be a real-time operating system.
When you have a timer that says, okay, every second I need to send, I need to blink an LED to show that I'm alive.
All right.
You could instead write a scheduler that did that every second and was sort of on top of your loop.
Like if a second has gone by, you blink the light because it's high priority,
and then you run the main loop.
And so to me, there is not a, are you running an RTOS or are you not running an RTOS? There's a, okay, how far are you going into the complexity of separating out your application
into different threads and how they're communicating and what mechanisms they're using for communicating,
how formal that is, how formal your memory management is. is there's so much middle ground between a while loop and Linux.
Yeah, I think we're saying kind of the same thing.
Okay.
Because the bare metal approach, as you write more of it,
you're building your own application framework
that does the things you say.
Scheduling, handling timers,
communication memory. The tricky bit is there's kind of a curve where you can do a little bit of
that, and then you get too much of it, and you really are writing your own RTOS. And it's very
early on in that curve where you're basically writing your own RTOS. And if you're not an OS expert, you probably shouldn't be doing that.
Yeah, yeah, I don't write crappy OS.
It's very popular. Lots of people do it.
And I think a lot of people do it, as you say, they kind of back into it,
thinking, oh, I don't need something that heavyweight.
It's going to be too much hassle to...
Or they have misconceptions about RTOSs and they think this is too big or it's going to lead to a
bunch of complexity, which there's no free lunch. Computers work a certain way and there's only so
many ways to solve these kinds of problems with scheduling code and doing communication
and synchronizing
code. And so you're going to solve
them in the same way everybody else did.
But you're going to have to solve
all your bugs first. But you're going to have to solve all the bugs in it.
Some of which can be very subtle.
Or you can
use one that's been used for
a long time. But that's not to say bare metal's
bad. It's just you really kind of need to think about how complex is this project likely to get.
And if it rises above a certain level, and there are some checkboxes that are pretty simple.
If you're going to do X, you need an RTOS.
Okay, we should say that.
For me, if you're going to do TCP IP, you should use an RTOS.
BLE needs an RTOS. Yeah yeah bluetooth of any kind yeah um generally if you have display with input it's nice because then
you can you can kind of architect you need to do things with priorities
to keep the display interactive while something else is happening.
What other situations?
I've done displays without RTOSes.
They do make it simpler.
If you want dynamic memory, it's nice to have an RTOS because often they handle that it simpler. If you want dynamic memory,
it's nice to have an RTOS
because often they handle that for you,
give you, provide you with byte pools and things.
Yes, because what can happen is
if you have a leak in your thread
and it runs out of its memory,
it can be killed and restarted.
And you recover the whole byte pool,
but you don't have to reset the whole system.
File system?
Oh, file system.
I'm doing a bare metal file system now, and it's killing me.
Yes, file systems, really.
It's nice to have somebody else's file system.
Lots of serial. Anything where there's asynchronous communication, really.
See, serial, that's too small.
I said lots of serial.
If you've got like four different outputs for some reason or something, which happens.
It absolutely does.
But that's an iffy area.
Anything where you've got to keep data flowing at a constant rate to keep up with hardware or
flowing in or out while you're doing other things i would still be in the interrupt land for that
i would still be in dma and use your chip as much as possible well i'm kind of in my back of my head
i have a display oh okay so i'm doing audio with a display or something. Or taking user input to adjust how the audio works.
It is really nice to have a separate thread for users, because they are so slow.
And the thing I like about threads is it's a natural way to organize your code.
When you have the big loop, you end up with a big set of functions.
Or a one big function.
And it gets a little ugly.
State machines. I love having a state machine in a separate thread because if you have to check where you
are each time it's kind of a pain but if you could just go to sleep before you need to go to the next
state okay so that's do you have anything else on that or that kind of no i mean those are things
where if you kind of you should if you're
encountering a problem like that it's like okay i probably need an os and need to convince yourself
that you don't before you before you go down that path and there are really small os's ones that just
handle a couple of threads do a little bit of memory management between them, and
don't take over
all of your RAM.
You don't
have to get the hugest thing, and you don't
have to get something that costs
a lot of money, or
any money. Although
I sometimes like to pay a little bit of money
so I have people to ask questions to.
Yeah, I mean, it depends. If you're a product company, then paying a little bit of money is not usually a problem.
It can get tricky with our tosses because some want money per item and there's negotiations.
But there's a lot out there and it's usually easy to settle on one that's free or has friendly license terms.
Yeah, I would keep looking unless you're doing medical image case.
If you're doing medical, you're paying a lot of money.
Yeah.
Okay, so you need an RTOS when you're doing something complicated
and when you're doing communication to the outside world,
either to users or to complex communication algorithms.
Yeah.
Nodding. Okay.
What about...
I wouldn't say need. I would say I want.
Want. That's true.
Because I've done almost all of those things without that.
You can do almost anything without it.
Bluetooth and TCP IP, maybe not.
But you can do almost anything without it,
but it gets more and more painful the more complex things get.
I mean, if you think about it, like desktop computers.
How fun was it to write programs in the 80s, right,
that did complicated things on a desktop computer
when you maybe had basic or
whatever that's kind of you know if you remember doing that i know you have to be super old
but if you remember doing that it got really ugly really fast if you're trying to do anything
complicated and uh you know desktop computers have moved to multi-threading and all kinds of
complicated application frameworks.
And as software gets more complicated,
it gets more complicated everywhere,
on microcontrollers or desktops,
and you need help.
And the goal is to break it into small pieces
you can test individually,
which if you have a multi-threaded system,
you have a really good place to break apart your system.
And it's not, nobody's saying,
hey, you need to use RTOSes.
They're really complicated, though, and you have to learn a lot.
It's like, no, these are things, this is something that will help you.
Yeah.
It makes your life easier.
There is a learning curve, but it does make your life easier, mostly.
You mentioned embed.
Yeah.
Would you go there to learn about RTOSs?
It's an easy place to go, right? Because
it exists. The dev kits are
widely available and the
development environment is there. It's kind of like
Arduino with an RTOS,
right? So, I mean, if you
just want to play around with something and get experience, that's all
there. And it's got TCP IP and
BLE and all those items.
I think it's got lightweight IP
as the library that they use.
So stuff that you'll encounter elsewhere if you end up using something else.
And you can get used to semaphores and message queues and all that.
Message queues are the best.
Sorry.
See, I don't know how much we should be defining these things,
because they're all pieces.
But one of the things that happened on the Slack was immediate responsive, oh my god, priority inversion.
How do I set up my RTOS to avoid common problems like race conditions, non-re-entry, etc.? etc. So people tend to get really worried about what's called priority inversion,
which I've never encountered in the wild. And I've done a lot. Priority inversion is where
you have two threads. Now a thread is a single unit of execution, and it usually has a function
attached to it. So it's running that function. and they can run, quote, concurrently, even though you only have one processor.
And the RTOS does that by bouncing back and forth between them.
And one problem with that is if you have two things that are operating on the same resource.
So like a serial port?
Like a serial port.
And one of them has a higher priority than the other,
which means, in general,
if there's a question about which one should be running,
the scheduler will choose the one with the higher priority.
But the low-priority task is using the serial port.
And now the high-priority task wants to use the serial port.
But it can't, because the low-priority task... So it now is blocked, waiting for the low-priority task wants to use the serial port. But it can't because it's a low-priority task.
But it can't.
So it now is blocked waiting for the low-priority task,
which is called priority inversion,
because now effectively your high-priority task is low-priority.
And people get all excited about this
because it's in textbooks and it's in homework problems.
And it sounds really scary.
And how do you break it?
And they explain how to break it in in textbooks and it's in homework problems and it sounds really scary. And how do you break it? And they explain how to break it in,
in the textbooks is you can do what's called,
um,
promotion where you take the low priority task.
The scheduler sees as a high priority task waiting for it.
And it promotes it to high priority until it's done with the resource causing
it to finish earlier and,
and leave it, leave the resource available for the higher
priority task quicker.
There's other ways to solve it, too, and most of these operating systems do that stuff.
Or don't do that.
Or you can say, okay, I have a resource with a higher priority task and a lower priority
task.
My lower priority task shouldn't spend much time on it.
You can solve it, yeah. There are many other ways
to solve it. First of all, you shouldn't
write the code so it does that. Right.
But if it's unavoidable, or
you're in a corner, the OS will
help you. And you don't end up
I think there's ways to end up in
deadlock situations this way.
That's usually the problem in homework.
Yeah, because you end up with a medium priority
task that's running. Yes.
And so the low priority task isn't going
because it's lower than the medium.
High priority task isn't going because it's waiting
on the lower. Yeah. And so now you're
totally stuck. Yeah. And so the solution to that
is promote the low priority
one, get out of the situation, and then continue on.
And most of these OSs do that.
So I don't think of that as a big problem,
unless you're writing really weird code
and somehow you're defeating the OS's built-in mechanism to prevent it.
And I've worked on very complicated systems,
and it's never really been an issue.
You're over there and your eye is twitching.
Oh, no. Sorry.
I was just thinking about going back to bare metal.
You can't do something exactly like this.
Sure you can.
You can do something dumb in your interrupt handler.
But it is about doing something dumb in your interrupt handler it's about printing in your interrupt handler or waiting in your interrupt handler for the printer to for the serial port to be free
anytime you're waiting in an interrupt you are trying you're fishing for priority
these weird things that you want to be high priority but you don't want to run really long
so kind of conceptually they're low priority so yeah that gets tricky if they're conception i don't know i'm not following you don't want
them to run a lot you want them to get in and get out yeah um they're they're not high priority as
they're taking up a lot of the system okay it's terrible terrible yeah they're not high volume
that's better yeah um so yeah that that particular problem i don't worry about that much race conditions yes
you should understand how concurrency works and how race conditions occur
if you're gonna use an os you should go ahead you should understand how race conditions and concurrency issues occur if you're doing anything with a big loop that has more than one thread of execution.
State machines, you don't even need threads of execution.
If you have a state machine, having concurrency problems is also pretty easy.
It's about trying to figure out what happens in what order, and if it doesn't happen in that order, are you blocked or can you skip?
So the way around race conditions, OSs usually provide you synchronization primitives.
So things called mutexes, which are mutual exclusion primitives,
which say this resource is currently in use, you can't touch it until it's done.
That prevents two people from accessing, say, the same variable
or the same GPIO or something like that at the same time.
There's semaphores, which signal similarly that something's in use
or there's some number of resources currently in use.
There's message queues, so you can serialize operations.
Those are really nice for displays.
Yeah. Because you can say, okay. Those are really nice for displays. Yeah.
Because you can say, okay, I want to make the window, I want it to be black.
Now I want to put a header on it.
And so you have a queue of them.
You're not just doing it in random order and ending up with your border being underneath your black.
But if you have something, some sort of worker thread, and you've got five different
threads that tell it what to do, you don't just have them all calling into it. It has a queue of
work and the messages get put on in order and those get executed in order. So nobody's jumping
in front of the other one to just, you know, set some variables that control this thread,
which is where you get into trouble, right? It's like, oh, I've got this thread that does this operation,
and I've got these other threads
that want to manipulate it,
and they'll just flip its flags
because it's all a flat memory space,
and it'll change how it operates.
And that's how you get into real trouble
with phrase conditions and things.
So that's pretty solved.
Non-reentrancy, yeah, it's an issue.
So non-reentrancy are some functions that have static memory or use globals,
may have things in a bad state when you try to call two things.
So like strtok, string tokens. You send it in your string, you then ask for the
string that is the first until you get a space, and then you ask
for another one and ask for another one. If you, in another thread, do
the same string token function... It's the same function.
The library only has one thing it's holding at
a time. And it's holding whichever string it got last.
Yeah.
And it's using whichever token it got last.
So you're really hosed.
But all of the other string functions are fine.
Printf is bad.
So the thing about re-entrancy is whatever library you're using is usually documented.
So it'll say this function is not reentrant.
And so you either protect it with a mutex and say,
strtok is only going to get called by one thread at a time until it exits.
Or you maintain state somewhere.
Sometimes the libraries will maintain a big table of state for all these functions
and have thread 0 state, thread one state,
thread two state for str talk and
you can manage it that way. It's gross and ugly.
I mean, that's a much bigger operating system.
Yeah. Well, I think
Nulib does for some of its functions, but
or you avoid, when you're
writing your own functions, avoid keeping any state
in functions, which is a good idea anyway.
Yeah. I mean, when you're using threads, it's an even better idea that anything that is in shared
area between threads should have no associated statics or globals. If you need to have statics
and globals, you can put them in your thread file, but don't put them in any other file you call.
Yeah.
I mean, that's kind of a good policy anyway.
You isolate where you have your globals.
The rule for non-reinterceding your own code is pretty easy to avoid making problems by just don't keep state in there.
And for library functions, they're documented.
And most of the time, you don't want to be calling those sorts of functions on a micro anyway
they're usually big heavyweight functions when they've got statics and things
i don't know if you call out a stir toke on a micro oh well library stuff yes
printf is usually so big that you don't even want to include it. I don't know. Yeah.
Or I build in printf and then toss it into a circular buffer before it goes out my serial port.
Yeah.
And so as long as I do that building as one.
So,
yeah.
Yeah.
I wouldn't be afraid of them because there's kind of well-known or well-solved
OS problems that exist because they still kind of exist in bare metal.
It's just now you don't have anything to help you at all.
Except your wits.
Let's see.
Nathan Jones asked, what is the best RTOS?
Best RTOS was, what did they run on the PDP-11?
I don't know.
Best RTOS.
There is no Best RTOS.
It's a giant parametric search between cost and licensing and ease of setup and ease of use and size.
Size, customizability, features.
Even latency.
I mean, we kind of agreed that the RT part isn't that interesting. But if you're running motors or doing something that has a really hard real-time...
So, let's define what the RT part is. And when you have a real-time operating system, it has a stated latency.
That is the maximum amount of time that it can take to get to your code.
Take to get to your code from what?
So, wow, really, I didn't know this as well as I thought I did. Okay. So you have that. It's the reaction time to an interrupt.
Not just to the interrupt handler,
because that should be very fast,
but from the interrupt handler
to notifying your code and your code running.
Now, if you had a single big loop form,
you could make that time be almost nothing.
If you had a big loop and a timer that said,
okay, run my main thread,
then your latency is the difference between
the maximum time between when your interrupt can go off
to when your timer goes off.
Yeah.
And I think they usually also state context switch time,
which is how long it takes the scheduler to stop executing thread one
and start executing thread two.
Because it's not instantaneous.
It needs to store a bunch of stuff,
and it needs to look and see which thread has to go next.
Both of those numbers are kind of fudgeable,
so they tend
to state, oh, you know, 10 microseconds
latency or whatever.
Assuming you're running from RAM. 20 microseconds
context switches. And, you know, you can easily
write a program
that screws that up.
It's kind of up to you. But that's what the
real-time part is, is they kind of say,
we guarantee that in these circumstances
this is the maximum amount of time that this operation will take to get to execution yes and unless you are doing
something that requires really small times it isn't that important when things were running
at one megahertz and you needed to respond in 500 kilohertz or a small amount of
time, then that was super important. But now, I mean, usually our microprocessors are running
about 10 times faster than we need them to, which is great. You can definitely have a lot of fluffy
code, kind of bad for power, that's why i would go to sleep
and our tosses can help with sleeping go on because your lowest priority thread
if it's running you can be sleeping yeah so it's a very easy way to say oh sleep is a good thing
because if i'm here, I'm doing nothing.
Yeah. Usually the lowest priority thread is usually like idle or something.
My idle thread and my sleep thread are usually the same.
Yeah.
Are there other big questions?
I mean, I'm sure people have lots and lots of questions about which ones.
Oh, what are the project requirements that push upwards from an RTOS toward a Mojave 8 OS?
I would say generally memory protection.
Yeah, that's a big one.
That's usually when you need to run untrusted pieces of software.
You need virtual memory and you need the MMU actually operating,
which is going to push your processor away from Cortex-M4s too.
But when you run applications on a smartwatch,
if other people are writing your applications,
then you should have memory protection.
It is possible.
Is it?
On a Cortex-M3 and 4,
an arm on some of them has what's called an MPU, which is a memory
protection unit, which is not to be confused with an MMU, which is a memory management unit on
big general purpose processors. Memory management unit does virtual memory, that conversion,
address spaces, that kind of thing. MPU allows you to mark certain areas as protected. And so you can
change your RTOS.
I'm not sure.
I think some RTOSes come with this feature
for the MPU,
but it may be that you need to hack it in yourself.
You can have that engaged
such that when you switch threads,
they have different memory areas
on a Cortex-M3 or 4
and they are protected. I m4 only maybe m4
but that's not generally what i consider memory protection it's dicey and there's only a few
entries in the table it's terrifying it's hard um does work but it's not not for the faint of heart
uh but yeah memory virtual memory can push you out of that realm.
Now, some of these RTESs do it.
VxWorks was claiming that they were going to do it in standard VxWorks 20 years ago when I last talked to them.
So I'm hopeful that they have it by now.
But I'm not sure because they didn't by the time the company I was at folded long after we decided not to use them.
So Green Hills does.
Green Hills tends to be very aviation-focused and things like that with their RTOS.
So they do all kinds of crazy stuff.
They have member protection.
They have complete isolation of VMs.
So you can have all of of your ui code be running
linux in one portion of the thing and then your r toss is over on the another all on the same
processor so they did crazy stuff with like containers or something way before it was
popular um so there a lot of these do very sophisticated things they're not all just for
micros so that's another kind of
confusion answering this question.
When would it push out of an RTOS?
Well, you might never push out of an RTOS.
You just might push into a really expensive one.
Yes.
Although Thomas was also asking from the other side.
If you have a very heavyweight
Linux operating system,
how can you decide that it's okay to go smaller?
It's hard to go smaller.
Your application on Linux is going to depend on a whole bunch of OS libraries
and things.
So that'd be a big refactor,
I think.
I mean,
if you go from Raspberry Pi and you're doing something small that doesn't depend on the internet, you probably can move down.
Yeah, you can move down.
It's just...
It's not going to be easy.
Fine, when you're writing on Linux, there's so much available that you use it.
Yeah.
So you're going to find, oh, this file descriptors don't exist.
I need to go.
That's the thing.
It's RTOSs.
And I should have said this up front.
RTOSs are usually strictly
the OS part,
the threads, message queues,
semaphores, scheduling, memory management.
They're not your file system.
They're not your network code.
They don't come with any of that.
But we said if you had network code,
you should have an RTOS.
Right.
But the problem is, they don't come with it.
Not always. Some do now.
Yeah, or they're associated
with it.
Some do, you're right.
Usually, if you go with free RTOS,
you're also going to use LWIP
or something like that, which is another library for networking.
Definitely, the Bluetooth stuff doesn't come with any of them, because those are all the chip vendors.
Well, that's why I said I did Nordics Bluetooth, because it was like they made the library, and I really didn't care about the operating system.
But usually, they don't have much of a file system support, right?
Or USB.
USB is another one where you need an RTOS.
So that's unfortunately a consideration.
It's not a consideration.
You're just doomed, right?
I mean, if you decide you need an RTOS for USB,
you also need to go out and get USB.
Sorry.
Which your vendor may have.
They may have, or they may have a partnership with some other thing.
That's pretty common.
Usually it's an ecosystem around each our toss it's like oh thread x and we've also got file x and we've got net x and we've got usb x i assume you know whatever uh
and you gotta buy all those things um and there's a lot of free stuff too. So it's fine.
So if you were
doing a heavyweight Linux OS
and you had
something that didn't depend
heavily on the complex
resources. If it depended on GPIOs
that's fine.
But if it depended on network
and...
Then I wouldn't,
I would stay in Linux.
If it
was simple, then
yeah, you probably can go.
If you're just doing GPIOs
and serial and
SPI and I2C, that should all
move pretty easily.
And then here is one of the reasons
that I end up sometimes not using an RTOS
when I should.
Bootloaders
and component management.
Yeah.
If you have an RTOS, your
image is larger. If you're pushing your
image over
some form of error,
then
you have to minimize it
so that it doesn't take forever to load.
Didn't you tell me you had some widget around here
that takes eight hours to flash that's firmware?
Yes, yes.
Because I don't know what they did wrong.
It's headphones I have.
It's wireless headphones.
And they were really cool.
But then they upgraded their app
and then the app said,
oh, you need to upgrade the firmware
before the app works with your headphones now
because they're out of sync.
Your phone app?
Yeah.
Upgraded, okay.
Phone app upgraded.
And then they say, do the firmware upgrade.
Oh, and by the way, it'll take eight hours
and your phone has to be next to the thing at all times.
And does it, I think it does it over BLE
in whatever the slowest data rate ble is capable of
because i don't know it's weird they screwed something up but yeah bad uh yeah and many
artas don't have any help for you for bootloading you just it be the artas becomes part of your
image and you have to have a separate bootloader. No, the RTOS is just an application.
I mean, it gets started in your code, usually.
Yeah.
Right, okay, it's time to start the ThreadX scheduler after I've set everything up.
So it's not like Linux, where it all boots up and you get a bash shell.
You've got main, and you've got to set up your stuff,
and then say, okay, ThreadX, now it's your turn to go. And usually you are loading all of your microcontroller's stuff.
You are not doing components.
Like in Linux, I can apt-get install extra components or update components.
It's all usually a monolithic image, right?
Right.
So with an RTOS, it's usually a monolithic image.
Although, again, we're saying that as though it's one thing.
You go everywhere from barely a tiny scheduler that you can get online to...
Something that looks almost like Linux.
Busy box.
Yeah.
Then you do have options in there.
And Lynxworks, I mean, Lynxworks was an RTOS, but it was Unix-based, so everything looked like Unix.
They just had a real-time option in their scheduler.
That was what they, that was for their claim to fame.
So, I mean, yeah, you can have heavyweight RTOSes.
It's such an amorphous term.
Yeah.
So don't get stuck on that. So if you wanted to learn about threads and RTOSs and just to be able to put it on your resume and you'd only done bare metal, do you have any ideas for projects that would actually use threads?
You could do at home.
It might be fun.
Anything with networking.
So if you want to make a network attached blah.
You know, traffic indicator to LED.
Although LED is simple enough that you don't have to.
Or something you want to access and make something happen.
So something TCP IP-ish and user display or user input-ish.
Yeah, or something that goes to the internet and gets some statistic
and turns it into an indicator on your wall or something.
Oh, it's like my traffic display.
Oh, I thought you meant network traffic.
Oh, no, no, no.
I meant for people who don't work at home.
Sure, sure.
They have to do this thing called a commute.
I don't understand what that is.
Yeah, yeah, yeah, yeah.
Something like that,
or, you know, something where you're doing motion that needs to be kept up to date while doing something else.
Thinking of like a robot or some sort of balancing thing.
Ah, yes.
That also has some sort of display or plays a music or something like that.
Music is a good way to talk about race conditions.
Because if you, as a piano player, play an A and then a C and then a D,
you don't want those notes to come in in any other order.
And so just because you played a C last doesn't mean it should immediately play
that one. It should play all of the intervening notes.
There's a race condition there that it
might want to... When you hit the GPIO, it wants
to say, oh, I hit this note. But if there's
any delay, there's a tiny delay between you hit the note
and you finish playing the audio,
you have to play all the intervening ones.
You can't skip.
Right.
Sorry, I went back to race conditions.
It's fine.
Where were we?
We were talking about projects you could do, fun projects you can do at home with real-time operating systems if you're that kind of person.
Okay, so networking stuff, display stuff, graphics-heavy stuff.
Graphics-heavy stuff, graphics and sound.
Again, motion control, like if you've got a plotter.
Yeah. You're making a plotter or some sort of 3D motion control. Like if you've got a plotter, you're making a plotter
or some sort of 3D motion thing.
Simple things.
I'm trying to think of simple things.
Anything with Bluetooth,
which everybody's doing,
but they're all doing it with these easy things now,
like our Python.
Who cares about all this stuff
when it's all hidden from you?
It's when, instead of saying i want to blink my light when a button is pushed you have an ant yeah i want to blink my light when a button is pushed and I want to tell the internet. I would say while.
Okay.
And is easy.
While is because they do this and then do that colloquially.
Oh yeah.
Okay.
So while is I want to blink this light while I'm playing a song and not have
any hiccups in between them.
Or I want to drive this robot while I'm taking data.
And oftentimes having one thing be a higher priority than another is really
useful for music and a light music.
If you mess that up,
it's noticeable humans,
humans hate that sort of thing.
But if you are off by a 10 tenth of a second in the light thread, they won't notice.
It's less noticeable.
Yeah, exactly.
I don't know.
It's kind of hard to suggest home projects for art houses because I'm not sure I would suggest art houses for home projects that much.
Because, you know, most of the time people aren't doing stuff
with a bare microcontroller.
They're doing hobbyist things at home.
Oh, it's like an embed stuff.
Yeah.
Just to be able to get a little bit of familiarity with it,
to look at threads and communication between them
and just try it out.
Just think of Vartas as a work thing.
Well, yes, but if I say,
what kind of microcontroller projects
should people do at home?
You'll be like,
yeah, I'm going to go play Mactar.
Yeah.
Yeah, I know.
We've been working a lot,
so our after work stuff is not technical.
I don't use microcontrollers anymore.
I just had to buy 64 gigs of RAM.
Because I ran out of RAM.
I'm still not sure how you haven't bought a new GPU yet.
Because, well, the code we're currently using is not fully utilized the one we have.
Doesn't mean we shouldn't get a bigger one.
It does because it costs money.
It's wasteful.
Maybe when Flight Simulator 2020 comes out.
Okay, have we exhausted our tosses at least all that we can think of?
Everybody probably hates us now and has yelled at the car.
About all the things that got wrong.
Their iPhones or their Androids?
I mean, realistically, if you want to know a lot more about operating systems,
Tannenbaum's operating system book is great.
Pretty dated.
It's in the fifth edition, so it's updated.
I actually thought the first edition, when I looked at it recently,
was pretty good because that kind of is where Embedded is now.
Not that much changes, especially with things like ThreadX, NVXworks.
ThreadX has been the same for 20 years.
They've added some things, but the basics are all the same.
The concepts of message queues, semaphores, schedulers, New Texas, those things have not changed yeah they're not new what is
changing is stuff like async and uh stuff like that which is just starting to async yeah it's
where you just bundle up a function and say go do this and tell me when you're done
instead of having a bunch of threads that are well-defined and you say,
this thread has this function, this thread has this function,
and they're doing their thing.
This is the move towards callbacks?
Not exactly callbacks.
More like lambdas.
I meant to talk about callbacks when we were doing
the big loop and interrupts and how
callbacks can change how things happen,
but I forgot so more
like closures and lambdas with thread pools so instead of starting up your own thread it kind
of secretly starts a thread and does what you want it to do okay yes and then it kills the thread it
goes on yes okay and then you get the result back in some manner. Some magical manner. With a notification or something
you were waiting on or stuff like that.
I'm just going to think of it as
callbacks.
But that allows the
system to put them
wherever it wants.
If you have multiple processors, for example,
it dispatches
work to various places.
Anyway, don't worry about that.
I kind of miss the 8-bit processors.
Of course you do.
They were easy.
Yeah, they were.
I could put everything I needed in my head.
I didn't have to like...
But all I could do was blink a light.
Do a lot more.
I'll have you know.
All I could do is blink a light
and kick off a frog saying,
I love you.
Yeah,
no,
it could do a lot more,
man.
You know how hard audio is.
Yes,
I do.
I'm very familiar with it.
All right.
Are we,
uh,
did you have anything else?
I don't,
I mean, we have comments and emails we should talk about and say hello to people,
but,
um,
I didn't,
I didn't queue any of those up.
So I mostly want to talk about our tosses.
All right.
We did it.
Okay.
Then,
uh,
I'm hungry.
Okay.
So that's it for our tosses.
And,
uh,
as Christopher mentioned,
he's hungry so we will
have to go do something about that
and so thank you thank you for
listening patrons
thank you for supporting us
people who write show
reviews that have five stars
thank you as well
thank you to people who talk
to other people about us
thank you all thank you thank you Thank you to people who talk to other people about us.
Thank you all.
Thank you.
Thank you.
Thank you. Thank you.
Winnie the Pooh was also hungry.
He ate way too much.
And now he's stuck trying to get out of Rabbit's hole.
Christopher Robin nodded.
Then there's only one thing to be done, he said.
We shall have to wait for you to get thin again.
How long does getting thin take? said Pooh anxiously.
About a week, I should think.
But I can't stay here for a week.
You can stay here all right, silly bear.
It's getting out, which is so difficult.
We'll read to you, said Rabbit cheerfully. And I hope it won't snow, silly bear. It's getting out, which is so difficult. We'll read to you, said Rabbit
cheerfully. And I hope it won't snow, he added. And I say, old fellow, you're taking up a good
deal of the room in my house. Do you mind if I use your back legs as a towel horse? Because, I mean,
there they are, doing nothing, and it would be very convenient just to hang towels on them. A week, said Pooh
gloomily. What about meals? I'm afraid there are no meals, said Christopher Robin,
because of getting thin quicker, but we will read to you. Bear began to sigh, and then he found he
couldn't because he was so tightly stuck, and a tear rolled down his eye as he said,
Then would you read a sustaining book such as would help and comfort a wedged bear in great tightness?
So for a week, Christopher Robin read this sort of book at the north end of Pooh.
And Rabbit hung his washing on the south end.
And in between, Pooh felt himself getting slenderer and slenderer.
And at the end of the week, Christopher Robin said,
Now!
Embedded is an independently produced radio show that focuses on the many aspects of engineering.
It is a production of Logical Elegance, an embedded software consulting company in California.
If there are advertisements in the show, we did not put them there and do not receive money from
them. At this time, our sponsors are Logical Elegance and listeners like you.