Adding Preemptive Multitasking to Piccolo OS for the Raspberry Pi Pico

แชร์
ฝัง
  • เผยแพร่เมื่อ 25 ส.ค. 2022
  • Piccolo OS is a small multitasking OS for the Raspberry Pi Pico. It is designed primarily as a teaching tool. I have released a new version that demonstrates the fundamentals of a preemptive multitasking on the Arm Cortex-M0+.
    ---
    GitHub repo: github.com/garyexplains/picco...
    Piccolo OS: What is Context Switching? • Piccolo OS: What is Co...
    Piccolo OS: Write Your Own Multitasking OS: • Piccolo OS: Write Your...
    Let Me Explain T-shirt: teespring.com/gary-explains-l...
    Twitter: / garyexplains
    Instagram: / garyexplains
    #garyexplains

ความคิดเห็น • 51

  • @walterpark8824
    @walterpark8824 ปีที่แล้ว +7

    This is why I wanted Berners-Lee to invent the www. Being able to share CERN docs is great, but the new level to serious, popular teaching/ learning is just fantastic. And Gary is one of its best practitioners. Thanks so much!

    • @wayland7150
      @wayland7150 ปีที่แล้ว +2

      I don't think Tim had this in mind.

  • @TheEulerID
    @TheEulerID ปีที่แล้ว +3

    When I wrote what amounted to the kernel of an RTOS as part of a car race timing system back in the 1980s (this ran on a Z80), then my task scheduling system was rather different. I took a tip from a large scale OLTP system I worked on, and used an adaptive priority system. Basically it would give a higher CPU priority to tasks that voluntarily waited, which was normally because they were waiting on some sort of event, typically I/O related. it used something called mean time between waits (MTBW), and the shorter the interval, the higher the CPU priority. That meant I/O-intensive tasks which used very little CPU got the highest priority, which made them very responsive. The more cpu intensive jobs would drift down the priority queue and be pre-empted by the ones handling events. In general, I find these adaptive scheduling systems work very well with real time systems that have to be responsive. I did have a few tweaks in place to make sure that even the lowest priority task got some CPU time. Fortunately the way the application was designed essentially all the tasks were event driven (even if it was a software event, such as processing the output from the FIFO buffers I used for inter-task communication, or waiting for space in a FIFO buffer for sending output to another task or a device). There was one, and only one task that was not event driven (and an event would include timer wake-ups), and that just issued the Z80 halt instruction (which drove an LED - which gave a visual indication of how busy the system was).
    I should say there were only 7 tasks in this system (which ran in just 64 KB), but it ran extremely well and was very tolerant to being loaded up to 100% cpu. I was always a great fan of MTBW scheduling on real time systems.

  • @Abhi00111
    @Abhi00111 ปีที่แล้ว

    Just learnt the course on OS and this video is like a bridge between academics and reality

  • @josephfngosa6416
    @josephfngosa6416 ปีที่แล้ว +1

    I love how you explain things

  • @wayland7150
    @wayland7150 ปีที่แล้ว +1

    Good work Gary. I think I'll still use Yield but this is excellent.

  • @wayland7150
    @wayland7150 ปีที่แล้ว +2

    I think in embedded applications then the Yield function is the best method. It ensures the task is complete or at a good place to switch before switching. Obviously you have to write the code very very well.

    • @dirkreisig4465
      @dirkreisig4465 ปีที่แล้ว +1

      Yes, and put the tasks in a circular list.

  • @EricWAtchesVideos
    @EricWAtchesVideos ปีที่แล้ว

    I'd like to see your review of the Mi band 7.

  • @oskarelmgren
    @oskarelmgren ปีที่แล้ว +3

    Nice work! Would be interesting if you did a follow up video with the performance impact of task switching. Which seems to be a typical trade-off with rtos's. Shorter time between preempts -> quicker response, but overall performance impact.
    But how bad is it really? How short can the preempt cycles be before you're loosing a meaningful amount of cpu power?

    • @bjornbeishline6619
      @bjornbeishline6619 ปีที่แล้ว +2

      This is a very interesting point, I was wondering this myself, I’ll make a repo to test it and add data.

    • @keithstandiford3761
      @keithstandiford3761 ปีที่แล้ว +1

      @oskar @bjorntheprogrammer I just timed a loop with only yield() and up to three tasks doing it. Context switching takes about 1.45 microseconds on a production build. So given the number of tasks and how long they compute, you can calculate how long it will be until your compute bound one gets another time slice. So for a few trivial tasks along with the compute bound one, at 1 mSec time slices the losses are still way under 1%!

    • @oskarelmgren
      @oskarelmgren ปีที่แล้ว

      @@keithstandiford3761 Very interesting! So if I understand that correctly, would the equivalent test with about 6 tasks run with a 10kHz "response rate" result in ~10% overhead? And 100kHz closer to 100%?
      RTOS have a hard life!

    • @keithstandiford3761
      @keithstandiford3761 ปีที่แล้ว +1

      ​ @Oskar I think I agree, depending on definition of overhead. 6 tasks gives about 10 usec of context switching. Assuming 100kHz means 10 usec time slices, the compute bound task gets 10 usec, and then waits about 10 usec for another turn. So "overhead" (in my mind) is 50% of time to compute a result. But if you only have one compute task, the perfect solution is to use both cores like I did.

    • @bjornbeishline6619
      @bjornbeishline6619 ปีที่แล้ว +1

      Yeah, I did some testing, the different is extremely negligible, at least using the default piccolo_os_v1.1 framework. I was just timing the difference in prime number calculation by changing the PICCOLO_OS_TIME_SLICE, and I could not get any statistically significant result, despite how low or high I set it. Personally, I would not be worried about it whatsoever.

  • @captaindunsell8568
    @captaindunsell8568 10 หลายเดือนก่อน

    Now we need a fair share schedule and dispatcher and a swap area

  • @gurrag79
    @gurrag79 ปีที่แล้ว +1

    Love your Mickey Mouse Jr cap Gary! 😀

  • @DwinTechnologyOfficial
    @DwinTechnologyOfficial ปีที่แล้ว

    If some day you can test our DWIN OS that would be great!

  • @Ratteler
    @Ratteler ปีที่แล้ว

    Amiga OS did preemptive multitasking with as little as 256, although 264kB is a little tight these days, The 2MB of flash is a little more than we we had with 2 floppies. 133Mhz is 19 times faster than our old 68000 Motorola.

  • @grantwoodside4071
    @grantwoodside4071 9 หลายเดือนก่อน

    @GaryExplains I have a version of Piccolo OS V1.1 running on RP2040 using multi-core. If you are interested in making a video about that, I can discuss the changes.

    • @GaryExplains
      @GaryExplains  9 หลายเดือนก่อน

      That sounds great. Is there a GitHub repo?

    • @grantwoodside4071
      @grantwoodside4071 9 หลายเดือนก่อน +1

      @@GaryExplains I'll make one. I'll let you know.

    • @grantwoodside4071
      @grantwoodside4071 9 หลายเดือนก่อน +1

      @@GaryExplains I created a private repo and gave you access. You should get an invite.

  • @markderlo212
    @markderlo212 ปีที่แล้ว

    Can you Point to the video you mentioned about multitasking with RP Pico ? Thanks

    • @GaryExplains
      @GaryExplains  ปีที่แล้ว

      Typing "Piccolo OS" into TH-cam search should give you want you need. But here are the links anyway.
      Piccolo OS: What is Context Switching? th-cam.com/video/eSkdn342hIQ/w-d-xo.html
      Piccolo OS: Write Your Own Multitasking OS: th-cam.com/video/G_3uvEFSDuA/w-d-xo.html

  • @nigelgunn322
    @nigelgunn322 ปีที่แล้ว

    The more I watch of Gary's vids, the more I realise that he's a really switched on old boy.

  • @garyreinsch510
    @garyreinsch510 ปีที่แล้ว

    Did you ever work on RSX-11M at Digital?

    • @GaryExplains
      @GaryExplains  ปีที่แล้ว

      No, that was quite a bit before my time!

    • @garyreinsch510
      @garyreinsch510 ปีที่แล้ว

      @@GaryExplains Well, I'm almost 75 so that explains it.

  • @esra_erimez
    @esra_erimez ปีที่แล้ว +2

    The "Like" button is simply not enough for this splendid video!!! Absolutely amazing. Thank you.

  • @peterschets1380
    @peterschets1380 ปีที่แล้ว +1

    Hi Gary. If this is true, then it is awesome. But i do not understand where the drawbacks are. Maybe make a video without the technical detail and history. Simply, this can be done and this can't be done. Btw, also link your github page in the description. Keep up the good work!

    • @GaryExplains
      @GaryExplains  ปีที่แล้ว +2

      I have added the repo to the description. It is github.com/garyexplains/piccolo_os_v1.1

  • @etmax1
    @etmax1 ปีที่แล้ว

    A bit of info on the side, while SysTick() may count down from a number to zero, it needn't do so, it could count up from zero to a particular number. It really depends on the HW used to generate the tick and how it was programmed.
    Also if you're worried about eg. malloc() or some other lib function call from getting knackered then just use int enable/disable around the bits that would be affected. Just remember that this has to be used extremely sparingly lest you end up doing something as bad as not yielding.

    • @GaryExplains
      @GaryExplains  ปีที่แล้ว

      Well here we are talking about the Cortex-M0+ and SysTick only works by counting down to zero.

    • @keithstandiford3761
      @keithstandiford3761 ปีที่แล้ว

      If you want to use preemption, disabling interrupts for critical section will of course work. However malloc() and free() might get a bit lengthy if memory gets seriously fragmented. The methods used here have big additional benefits. C++ compatibility for one (You hardly know when it calls malloc())! The other plus is that ALL the Pico SDK synchronization, protection and communication methods will ALSO work (mutexes, semaphores, critical sections, queues, etc). -Keith

    • @etmax1
      @etmax1 ปีที่แล้ว +1

      @@keithstandiford3761 Yeah I know what you mean, but the embedded systems I work with I like to have a good idea of how long something will take to run. At the cost of a bit of extra memory use I try and avoid using memory allocation because any function(s) that use(s) it can be so variable over time.

    • @keithstandiford3761
      @keithstandiford3761 ปีที่แล้ว

      No argument. BTDT. I find KISS to be the Golden Rule, mostly because of the overwhelming evidence that the last ‘S’ means me!

    • @etmax1
      @etmax1 ปีที่แล้ว

      @@keithstandiford3761 Exactly, the simplest (or cheapest) solution that works (ie. meets all the requirements) is the best.

  • @esra_erimez
    @esra_erimez ปีที่แล้ว +1

    Mi band 7 please

  • @lohikarhu734
    @lohikarhu734 ปีที่แล้ว +1

    Time sliced doesn't quite seem "preemptive" to me...is preemptive not actually an rtos that responds to typically hardware-initiated 'interrupts' that take the next available cpu time, based on priority... One level of preemptive above time-sliced. Or?

    • @GaryExplains
      @GaryExplains  ปีที่แล้ว +3

      Here is quote from Wikipedia, which is meant to be from Tanenbaum's Modern operating systems. "In computing, preemption is the act of temporarily interrupting an executing task, with the intention of resuming it at a later time. This interrupt is done by an external scheduler with no assistance or cooperation from the task."

    • @rene0
      @rene0 ปีที่แล้ว +1

      Pre-emptive just means a task can be forcefully interrupted (to, for example, a context switch). The challenge being restoring the context after such uncontrolled interrupt. which may vary by hardware design. However, by my understanding, it (pre-emptive multitasking) was possible even on something as basic as a Z80 cpu, it just costs (quite) some overhead pushing and popping all those registers to stack and you assume certain memory regions to be safe.

    • @John.0z
      @John.0z ปีที่แล้ว +4

      Hi Lohi. A non-preemptive system will allow a task to run until some sort of natural break in the application processing occurs. This might be access to a data file, or sending some data to an output device. Ie a task switch will happen when control is passed to the device driver. When the device driver completes that task, control is then passed to the job scheduler. When we established "in memory" tasks hooked off the software interrupts in DOS, that created a crude form of non-preemptive multitasking - on completion, the in-memory task returned control to the DOS interrupt we had hooked onto. You did not do much processing with such tasks. Obviously a very CPU-intensive application might run for some time before those natural system calls happen. This can have all sorts of difficulties in a general-purpose OS. But it can be ideal if that CPU-intensive task is the primary objective of the computer, and there are no time-limited "housekeeping tasks".
      As Gary said, preemptive systems have some form of clock that triggers a hardware interrupt regularly - each time allocation being a time slice. That form of interrupt returns control to the scheduler, and it allocates the next task according the priority you mentioned. That does not necessarily mean that each time slice of a program runs until the timer creates the interrupt. If you look at all the processes running in a modern computer (there are 476 running in my computer as I type) you can see that many barely register CPU time - but they have to be regularly swapped into action to ensure that there is nothing waiting on them. In other cases the application might call a device driver part way through a time slice. Most general purpose OS use this system.
      But time slicing alone does meet the needs of an RTOS - those specialist operating systems *must* perform allocated tasks within time limits.
      Have you ever played around with the priority of tasks? I don't any more, but I used to carefully fiddle around with Windows 2000, as that OS made it so easy to do so. You could even set tasks to run in what Redmond called "Real Time". But nobody would call Win2K a real time OS. Horses for courses. 🙂

    • @toby9999
      @toby9999 ปีที่แล้ว

      I don't fully understand the picilo but in general, preemptive is when the OS manages the switching. Perhaps an over simplification, but this differentiates cooperative wherein an application can hog the system. Even Amigas were preemptive in the 80's, long before macs and PCs. I can remember our whole Mac lab going down whenever a developer caused his power mac to hang.

  • @endoflevelboss
    @endoflevelboss ปีที่แล้ว

    Are you still here? Go, it's the end of the video.... OK Ferris!

  • @markderlo212
    @markderlo212 ปีที่แล้ว

    Correction : re context switching , not multitasking, thanks

  • @yaghiyahbrenner8902
    @yaghiyahbrenner8902 ปีที่แล้ว +1

    Piccolo OS - Question why not just contribute to Zephyr OS?