Author Topic: Converting cooperative OS to preemptive OS  (Read 4204 times)

0 Members and 1 Guest are viewing this topic.

Offline blueskullTopic starter

  • Supporter
  • ****
  • !
  • Posts: 367
  • Country: cn
  • BA7LKP
Converting cooperative OS to preemptive OS
« on: March 07, 2020, 04:21:33 pm »
Is it possible to convert a cooperative OS to a preemptive OS? If so, what is the general procedure?

I'm working on a project with AllWinner Tina (F1C series), and I'd like to get an OS to run on it.

Since it is a relatively less popular chip from China, there's no FreeRTOS or other Western RTOS ports for it, and I'm not interested in porting everything from scratch.

There are three OSes that I can use right now, XBoot, RT-Thread and Linux.

Linux has the advantage of supporting all peripherals, but that's a feature that I don't need, besides I want as fast as possible boot time, so I'll just skip that part. Booting XBoot takes shorter than u-boot itself, rest alone Linux.

RT-Thread had a good port on this chip, but it was removed from official GIT and no future support will be given as RTT received funding from a VC, and part of the deal is RTT team must generate revenue, so their Tina port has been dumb down since then so they can sell proprietary products based on it.

Besides, I'm really not fond of scons. I prefer Makefile, and I hate Python. I'm a religiously firm C user for the past 15 years.

That leaves me with XBoot, an OS I had read inside out, and stripped it all the way down from 3.4MB to 230kB. I've got all drivers I needed to work, and I did quite some deep customization to it.

I'd be very prefer if I can modify XBoot from cooperative to preemptive, but I don't know how.

It has a scheduler already, and the libcpu part has context switching code already. I've also got the timer part done, so I can now generate ticks and call functions periodically. I think all I need is to call the scheduler periodically (which was called only upon yield(), as it was cooperative).

What do you think? If I add a tracer in scheduler structure to indicate the current task, and call yield() with that current task as its current task parameter, in a timer callback (and use some locking mechanism to make sure the timer doesn't switch a task during a task is yielding), should it work?
 

Offline PlainName

  • Super Contributor
  • ***
  • Posts: 8927
  • Country: 00
Re: Converting cooperative OS to preemptive OS
« Reply #1 on: March 07, 2020, 06:57:59 pm »
The big issue with going that way is access to shared stuff. With co-operative you only worry about that when you call yield (or some OS function that might  achieve the same).  So, for instance, you might have a callable function to post a task event, and that function would be callable by any other task. With cooperative multitasking, once you're in that function you know nothing else is going to get in the way. As a trivial example, you could call asctime() without undue hassle.

The same function in a pre-emptive multitasker would be very different because you could get a second task entering in just as you hit asctime(). The second task would also end up calling that and screw up the shared output string - asctime is not a reentrant-capable function. It's fixable by having, say, and access mutex so only one task can hit the dodgy bits at a time. If you were writing for a pre-emptive multitasker from the start then you'd put that stuff in as you write the function (or not use things like asctime()). The issue you have here is that you need to identify those dodgy things and deal with them having forgotten what the code does (or even that it exists).

Other than that... :)

So it's doable. How practical depends on the specific project.
 

Offline PlainName

  • Super Contributor
  • ***
  • Posts: 8927
  • Country: 00
Re: Converting cooperative OS to preemptive OS
« Reply #2 on: March 08, 2020, 06:01:57 pm »
Quote
context switching function called in ISR changed PC

Easy mistake to make :)
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 17830
  • Country: fr
Re: Converting cooperative OS to preemptive OS
« Reply #3 on: March 08, 2020, 07:09:22 pm »
Good luck. I don't know XBoot, but converting a cooperative OS to fully preemptive, even if the base functions are all there, is going to give you many headaches IMO. I'm sure many of the base blocks are not designed to accomodate being preempted. You will probably need to modify all drivers as well. A lot of work. I don't know if it's worth it, but keep us posted.

 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 10091
  • Country: us
Re: Converting cooperative OS to preemptive OS
« Reply #4 on: June 09, 2020, 06:16:15 pm »
What's an OS?  To you... 

To me, Windows or Linux is an OS, some embedded chip running FreeRTOS as a real-time scheduler might be viewed differently.

Does the OS include higher level code like a network stack?  Are the tasks static (like an embedded system) or is there some kind of shell for command line stuff?  Is there a user accessible file system?

I think you need to list the features the system is to provide.

I don't see much commonality between a preemptive OS and a cooperative OS.

As to FreeRTOS, don't build what you can buy!  There are people who specialize in porting FreeRTOS and they can probably do in a week what it would take a newcomer an entire year to get working.  It would be cheaper to buy the port than to build it in-house.

See "Getting Help" here:
https://www.freertos.org/FreeRTOS-porting-guide.html
 

Offline wizard69

  • Super Contributor
  • ***
  • Posts: 1187
  • Country: us
Re: Converting cooperative OS to preemptive OS
« Reply #5 on: June 11, 2020, 04:37:13 am »


Since it is a relatively less popular chip from China, there's no FreeRTOS or other Western RTOS ports for it, and I'm not interested in porting everything from scratch.


Porting is far easier than converting.    You might even get help with porting as an open source project.   Converting an cooperative OS is a massive headache.
 

Offline coppice

  • Super Contributor
  • ***
  • Posts: 10289
  • Country: gb
Re: Converting cooperative OS to preemptive OS
« Reply #6 on: June 11, 2020, 05:10:10 am »
Since it is a relatively less popular chip from China, there's no FreeRTOS or other Western RTOS ports for it, and I'm not interested in porting everything from scratch.
Porting is far easier than converting.    You might even get help with porting as an open source project.   Converting an cooperative OS is a massive headache.
There is a simple test that demonstrates this to be true. If it were a modest task to turn a cooperative multi-tasker into a pre-emptive multi-tasker there would be no cooperative multi-taskers around, as they are far less flexible. The reason both types exists is there is a gulf between them.
« Last Edit: June 11, 2020, 05:11:47 am by coppice »
 

Offline coppice

  • Super Contributor
  • ***
  • Posts: 10289
  • Country: gb
Re: Converting cooperative OS to preemptive OS
« Reply #7 on: June 11, 2020, 06:04:02 am »
There is a simple test that demonstrates this to be true. If it were a modest task to turn a cooperative multi-tasker into a pre-emptive multi-tasker there would be no cooperative multi-taskers around, as they are far less flexible. The reason both types exists is there is a gulf between them.

Actually, this turned to be not that hard. I did give up, but not without some working preliminary results. It's not that hard at all.

XBoot is actually built around a preemptive thread model and scheduler, just the scheduler is dumbed down to be called from switch() function instead of a timer interrupt, and a cooperative context switcher.

All I had to do was to patch the context switcher to be ISR friendly and to call the scheduler from a timer ISR, which is easier said than done considering the f*ed up ARM9 architecture (compared to Cortex).

The true reason I gave up XBoot is its lack of modularity. It is a behemoth that comes with an LUA virtual machine, a GUI and lots of other bits so that it can be used to quickly prototype embedded systems.

It took me a few days just to strip it down, and what's worse is I need to repeat it every time when they update their code base, or I have to freeze the version and patch up bugs in the future all by myself.

It's so messy that its GUI is literally intertwined with its kernel, just like early Win32, and all its APIs are officially exposed and documented only in LUA form, the native C APIs are 100% undocumented.

RTT, OTOH, is modular, and it can be configured down to a few kB without manually touching a single line of code, and it is commercially maintained, unlike XBoot which is a personal project.

The fact that XBoot has a bodged scheduler says it all -- it's bodged to just work, for fun, not for production, and they never cared to make it preemptive as as suggested by its name, it's a glorified bootloader, not a full OS.
It wasn't that hard to get some preliminary results because you started with something built, at its lowest levels, to be pre-emptive. However, getting from "some preliminary working results" to a polished platform is a long long road. It the road most travelled in software development, which is why software projects are notorious for delivering late.  :)
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf

 

- - -
-->