#22 RTOS Part-1: What is a Real-Time Operating System?

แชร์
ฝัง
  • เผยแพร่เมื่อ 27 ม.ค. 2018
  • In this first lesson on RTOS you will see how to extend the foreground/background architecture from the previous lesson so that you can have multiple background loops running seemingly simultaneously.
    ------
    Resources:
    Companion web page for this video course:
    www.state-machine.com/quickstart
    GitHub repository for projects for this video course:
    github.com/QuantumLeaps/moder...
    Transcript of this lesson:
    www.state-machine.com/course/...
    Music credits:
    The background music comes from:
    www.bensound.com/royalty-free...
  • วิทยาศาสตร์และเทคโนโลยี

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

  • @StateMachineCOM
    @StateMachineCOM  ปีที่แล้ว +4

    NOTE: The source code, as presented in the video, might cause compilation errors with the newer MDK-ARM / uVision toolsets. This is because the underlying compiler in MDK-ARM has been changed to "Compiler-6", while the older "Compiler-5" is considered now obsolete. The updated code that compiles cleanly with "Compiler-6" is available from the companion website at:
    www.state-machine.com/video-course
    and from GitHub:
    github.com/QuantumLeaps/modern-embedded-programming-course

  • @shreeshavitthala
    @shreeshavitthala 4 ปีที่แล้ว +26

    This took me several iterations back and forth previous lessons to grasp what is going on! So each minute in the videos is so succinct. And of course this is the best embedded programming course I ever came across! Thanks for these fantastic lessons. I'm lucky to come across this right in my early searches.

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

    Notes:
    In the earlier example, we were changing the value of PC to switch to different led functions. That basically means when an entry into an exception such as Systick Handler is made, the stack frame (which comprises R0, R1, R2, R3, R12, LR, PC and xPSR) are saved on the stack. Then the address of the exception is fetched from the vector table by NVIC, and the processor starts executing the exception handler function.
    So when we changed the value of PC in the stack frame, we were able to switch to another function.
    However in the last example, we essentially created two stack frames for each LED function. And just when the exception handler was about to return, we changed the value of stack frame to one of our stack frame.
    Our personal stack frame had the context for our particular blinky function saved (i.e. R0-R3,R12,LR,PC,xPSR), so the processor was tricked into thinking that it saved this particular stack frame and popped the value of PC and LR from this stack frame. And thus we made the switch to another function lets say green led.
    After we executed it few times, we again put a breakpoint on the Systick handler, And this time we retrieve the value of stack frame of the green led function. However this time the top of green led stack frame is legitimate and has the correct value of return instruction.
    Now we put the value of blue led fabricated stack frame, and again trick the processor into thinking that this is the stack frame which was pushed on it, upon entry to the exception handler. And the blue led function runs now. If we break at systick handler now, we will have a legitimate stack frame for blue led as well.
    Thus we have two legitimate stack frames for context switch, and now upon context switching we would return to the original address, where the exception entry was made.

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

    if you need to monetize to create more content in less time, I would definitely pay for this quality of instruction. Better than any class I had at university by far.

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

      If you really wish to help, please spread the word about this video course! You could make posts or comments on: stackoverflow, reddit, quora, linkedin, facebook, or wherever you see fit. People constantly ask about specific subjects, about fundamental concepts, and about learning resources. This course is such a resource, but it is still relatively unknown. Please help others to find it and make this course more popular in the process. --Miro

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

      @@StateMachineCOM absolutely!

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

      There is nothing more to say than... i love you!

  • @mengnan24
    @mengnan24 5 ปีที่แล้ว +4

    I have been going back and forth in your all videos, especially RTOS ones. All of them are extremely valuable! I really appreciate your efforts in making these wonderful tutorials and hope see more of them in future!

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

    This series continues to get better and better. Keep up the good work!

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

    This is really insightful and easy to follow at the same time. Your lessons are awesome! As I'm self-taught at embedded programming these deeper-level topics are really interesting, because digging all of this up on my own would have taken loads of time. Thanks!

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

    Can't wait for next video. Thank you so much Miro for creating these videos.

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

    The best explanation I've watched, thanks!

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

    ONe of The MOST awaited videos RTOS!!! Great Thanks

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

    Fantastic video Miro. It's even helpful for experienced engineers to refresh the basics. Waiting for next one. Keep up the good work.

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

    Quality content! Thanks for your uploads. I watched your videos before taking a course at school and I am well ahead of the class!

  • @10e999
    @10e999 5 ปีที่แล้ว +2

    Excellent teacher and skilled firmware designer.
    Thanks for your video.

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

    so far the best video i have watched explaining rtos thank you so much

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

    Excellent lessons (this and others)! Absolute brilliance! Top quality!

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

    You are such a great teacher! Thanks for clarifying all these things

  • @Anuragsingh-ye6du
    @Anuragsingh-ye6du 4 ปีที่แล้ว +1

    Really a great representation of context switching with programming and highlighted details....Thanks it will be a part of my vdo library on YT

  • @PawanKumarYouTube
    @PawanKumarYouTube 6 ปีที่แล้ว +26

    the best 25 minutes of my day... :)

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

      Best lesson of my whole year!

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

    I will share your channel !!!! Good job like this should not go unnoticed!!!

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

    Welcome back Miro, I always waiting for you.

  • @baurnext
    @baurnext 6 ปีที่แล้ว +4

    I am on the edge of my seat for the next video :)

  • @augustinenishilraj
    @augustinenishilraj 6 ปีที่แล้ว

    Thanx for the videos.
    one of the best content on the web.
    thanx for all the videos.
    keep up the good work

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

    Thank you very much for excellent lesson. Can’t to see part 2.

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

    thank you for taking time in making these videos

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

    Very deep understanding to RTOS!

  • @alexXove
    @alexXove 5 ปีที่แล้ว

    great video! I think i will make some time to watch all your lessons!. Thank you!

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

    really under the hood RTOS operation :) keep up!

  • @7race725
    @7race725 3 ปีที่แล้ว +1

    Thank you sir. Your videos are great. You do not need to entertain the public by music. It interferes focusing on material.

  • @mengnan24
    @mengnan24 6 ปีที่แล้ว

    Great explanation! Thank you very much!

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

    fantastic classes...waiting for next video

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

    what a fabulous :) .. thank you very much Miro ,

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

    Truly very profound!!

  • @MrHoangvanloc
    @MrHoangvanloc 6 ปีที่แล้ว

    Waiting for the next video. These video of your is very helpful.

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

    Impresionante!! great Mr! thanks a lot!

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

    been waiting for so long for the rest of the videos :(

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

    Note-2:
    Also when we make entry to exception handler, register R0-R3,R12,LR,PC and xPSR are saved. But R4-R11 are not.
    Therefore if the ISR does use any of the registers R4-R11, it will restore the original value before returning to the original functions. Thus no harm done.
    However if we are returning to some other function, than this will create a problem. Since we would be returning the value of register meant for the previous function, and not to the function which we are jumping into.
    Thus we have two situtations, one is the automatic saving of registers (R0-R3,R12,LR,PC and xPSR) upon entry to the exception handler as guaranteed by ARM procedure call. But to ensure integrity we have to additionally save register R4-R11 as well. But the second thing needs to be done manually !! (or by coding, :-p) ,, --> we also have to decrement the stack pointer by 0x20 (32) --> so the 8 registers(R4-R11), each of 4 bytes could be accounted for in the stack frame.

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

    15:56 I was even holding my breath, with sweat on my forehead!

  • @minazulkhan8287
    @minazulkhan8287 3 ปีที่แล้ว

    one of best channel

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

    excellent video ..Thanking u

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

    macOS?
    manOS!
    -- this man just made manual OS entirely by hand.

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

    waiting for next video

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

    Thank you so much for the amazing video! One question though, at 21:11, the solution is to save the additional registers R4-R11 to the thread stack. The timing diagram shows they are saved after the ISR returns. Can we save them before the ISR preempts (i.e. save them at the same time as other registers like R0-R3, etc.)?

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

      In order to save registers before an ISR is not possible, because you don't know when the interrupt will occur. Once it occurs and your ISR starts running, the interrupt stack frame is already saved on the stack. --MMS

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

    Miro, here you mention that "an ISR must necessarily run to completion before returning to the preempted code". And I'm wondering what that means in terms of ISR preempted by an ISR of higher priority. If I were to use a while loop as the idle thread and have 2 or 3 ISRs running at different rates and each with a different priority level, also each one more computationally burdensome on the CPU than simple blinky ( I am thinking motor control applications) would it still be necessary to store registers R4-to-R11 for meeting hard and soft real time deadlines? Because it almost seems like a higher priority would preempt a low priority ISR, and all ISRs would eventually run to completion before returning to the idle thread.

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

    Great video Miro. Did you know that according to our very complex video scoring system (sounds fancy but we simply do (likes-dislikes)/views), this video has the highest score of all the videos posted over the course of the last 12 months (for all vendors we monitor). See: www.embeddedrelated.com/vendors#tabs1-popyt and click on the 'one year' button. Great job!

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

      I'm really glad to hear this. New video lessons are coming. The next lesson 27, RTOS part-6 will be about inter-thread synchronization with semaphores. Stay tuned! --Miro

  • @karthikramesh8489
    @karthikramesh8489 4 ปีที่แล้ว

    Hello Sir, thanks for the video. I have a problem with this. After changing my stack address in debugger with my created stack, the stacks on the debugger doesn't change values. But the functions are working. Hope you can help me solve.!!

  • @user-gd5jn8cb9u
    @user-gd5jn8cb9u 6 ปีที่แล้ว

    very good

  • @71GA
    @71GA 5 ปีที่แล้ว +1

    Can you do a video on interrupt latency and how to deal with it?

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

    Hello Miro,
    I've got a question, isnt global data(i.e the array) placed somewhere else other than the stack(.bss since this isnt initialized), how did we assume this to be a stack frame and poping worked on it?
    Thanks.

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

      Global or static data is not placed on the C stack, of course. But in this lesson, we *made* the stack out of a global array by forcing the CPU stack pointer register to point into that array.

  • @omarayman5318
    @omarayman5318 3 ปีที่แล้ว

    hello mr miro
    i just want to understand __just in brief definition__ what do we mean by word (kernel) in our course ....and thanks a lot .
    i ve already googled but i am little confused !

  • @ManishSharma-qs3sv
    @ManishSharma-qs3sv 4 ปีที่แล้ว +1

    Hi Sir,
    Thanks for the series of great videos.
    I have an query here as my newbie in the embedded world. Could you please tell me that why didn't you save R12 on the stack while you stored R11 down to R4 on the stack (Last of this video : 21:53 time line)? I am seeing that SP is set as 0x200000088 on the stack and above SP , we must have R12 then followed by R11-R4 while you showed a red block (R11-R4) copied just above 0x200000088 which i felt , it must be two addresses up from SP (R13) and R12 then it would be aligned.
    Regards,
    Manish

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

      The complete stack frame for a thread's context consists of two parts: (1) the registers saved in hardware upon the interrupt entry and (2) registers saved on top of that by the software. The choice of the software-saved registers is dictated by what the hardware already saved, because you don't want to repeatedly save the same registers and you don't want to miss any either. Also, you might want to watch lesson 9 about ARM Application Procedure Call Standard, which explains the registers saved during a function call. --MMS

  • @chrislu6053
    @chrislu6053 3 ปีที่แล้ว

    Wish I had this video 10 years ago

  • @connectme2karthik
    @connectme2karthik 2 ปีที่แล้ว

    Hi Miro, thanks a lot for the RTOS series of videos. I have a silly question, specifically on this example. Where is the interrupt used in this code, What is the ISR doing in this example? Is it used for the delay? Particularly from the plot /illustration of 10:53, why is ISR happening non-periodically and why are they of different duration?

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

      "Where is the interrupt used in this code?" -> This code uses the periodic SysTick interrupt, which is configured in BSP_init() inside bsp.c file.
      "What is the ISR doing in this example" -> The SysTick ISR is only incrementing a counter variable. But it is also used to manually simulate context switching, by setting a breakpoint inside the ISR and then changing things manually inside the CPU using the debugger.
      "Why is ISR happening non-periodically and why are they of different duration?" -> The ISR used for context switching does not need to be periodic and it does not need to have the same duration each time. These things simply don't matter, and therefore the timing diagram at 10:53 shows a general case. --MMS

  • @user-pc9hl8el5x
    @user-pc9hl8el5x 4 หลายเดือนก่อน

    Thank you very much for this wonderful course! BTW, the transcript for lesson 16 and 21 are missing on your official website. When click on the txt file it brings you to a page saying file is missing.

    • @StateMachineCOM
      @StateMachineCOM  4 หลายเดือนก่อน

      The companion website at www.state-machine.com/video-course has been corrected and the transcipts shouild be available. Thank you for reporting! --MMS

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

    Hello miro , hope your doin good .
    I recently noticed something when I debugged this lesson , when u switch context , say u want switch to blinkey1 , u put sp_blinky1 in sp CPU register , but before this u save the OLD sp CPU value in sp_blinkey2 .
    in the video , every time u do this the sp CPU must be less than the old sp_blinkey2 by 2 words
    sp_blinkey1 is either (0x20000090) or (0x20000088) ,
    sp_blinkey2 is either (0x20000130) or (0x20000128),
    , but with me there is no difference,
    sp_blinkey1 is always (0x20000090),
    sp_blinkey2 is always (0x20000130),
    as u notice : the sp CPU is exactly the same previous sp_blinky when i hit the breakpoint . is it normal ?

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

    Hi Miro, I did not understand the offset of 20 bytes regarding the stack pointer at 22:04

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

      It is to account for the 8 values that had to be manually copied from registers R4-R11 onto the top of the current ISR stack frame at 21:44 (8 values * 4 bytes each = 32 bytes = 0x20 bytes in hex).

  • @wassimdhokar731
    @wassimdhokar731 3 ปีที่แล้ว

    Check course online to learn embedded C programming on arm cortex-m processor: www.udemy.com/course/embedded-arm-cortex-m3-programming-guide/

  • @robbieschultz3559
    @robbieschultz3559 2 หลายเดือนก่อน

    Hello Doc,
    First of all thank you for your work on this. Its good stuff.I have a couple of questions for you. At around the 16:50 mark:
    You mention that we would have to save the current top of stack for the blink1 thread before attempting to preempt with with the blinky2 thread.
    Is this because points of preempting of at the blinky1 thread would generate the corresponding exception frame?
    And the reason we do this is so that we can save the context to return to where we left off , once blink2 has been preempted by blinky1?
    I think if didn't do that and go with initial values that we populated the stack frame for blink1 with, we would simply resume from the beginning which I suppose is okay for simple blinking examples but not so for more complex examples where more info is saved before a context switch. Is this understanding correct?
    Thank you for your time in advance!

    • @StateMachineCOM
      @StateMachineCOM  2 หลายเดือนก่อน +1

      I've read your comment carefully, but I don't understand yor question. However, the most important thing I want you to remember is that all of this context switching is really utilizing the *interrupt* handling mechanism of the ARM Cortex-M CPU (hardware mechanism). Everything that transpires during a context switch follows from the understanding of that mechanism. In particular, the preemption you see at 16:50 has already happened and was caused by the SysTick interrupt. At 16:50 you merely change the stack pointer (SP) to control the *return* from interrupt. So, I think your problem might be that you think incorrectly about the "preemption". The context switching code does not cause preemption, it merely uses it. The preemption has to happen in hardware, so in case you need to create it at will, you need to trigger an interrupt. You'll see in the later lessons how to do just that and utilize the special PendSV interrupt for it. --MMS

    • @robbieschultz3559
      @robbieschultz3559 2 หลายเดือนก่อน

      @@StateMachineCOM I'm sorry if I wasnt clear.
      I was referring to the fact that stack pointer value that you had to save manually. It is different from the one that was initial value that we set in order to begin execution.
      If we were to use this initial value, we would begin execution from the beginning of the theard, which is okay if we are doing it for the first time , so as it get things going.
      As I understand it, Context switching is to be done in such a way as to resume from the point of preemptiion, and not to start over at the beginning.
      That is to say if we are to supply the incorrect context, the thread may not resume from where it left off.
      In this particular example, after the thread is preempted, you save the new stackpointer value (to correctly record this context) such that when control is restored to this thread , it picks up from where it left off when it was preempted as opposed it starting from the beginning if we had supplied it the initial sp value.
      So when a thread is preempted at different stages of its execution, the corresponding exeption stack that is generated with with a sp value is to be used to get back and to the point from where it was preempted.
      I apologise if this sounded a bit repetitive. I just wanted to get my point access. and yes I did believe that I've misunderstood preemptiion and context switching . It is interrupt premeptuin that allows us to switch away from the normal sequential execution. It is during this premeptuin that were are able ti change the context by altering the values if the sp so that after premption the flow of execution is able to return to point from what the sp points to.
      I hope this is clear

    • @StateMachineCOM
      @StateMachineCOM  2 หลายเดือนก่อน +3

      @@robbieschultz3559 Yes, of course! Every preempted thread needs to continue from the point of preemption. Starting over from the beginning every time would make no sense, would it? In fact, you can think of the private stack of a thread as a "bookmark", which remembers precisely where a thread was preempted, so that it can be resumed from that exact point. The stack "bookmark" is very sophisticated because it can remember very complex patterns of thread execution. For example, a thread can call a function, that calls another function, which gets preempted. The stack "bookmark" remembers all this, so that it can resume from the nested function call and correctly continue by returning from the second function, then returning from the first function, etc. I hope you can see how complicated things can get and how powerful the concept of the stack is. --MMS

  • @mahphalke
    @mahphalke 5 ปีที่แล้ว

    Hello Dr Miro. Thanks for the wonderful tutorial. I am trying to create same application on NXP Kl25z freedom board, however when I try to switch stack entry from CPU stack to blinky1/2 stack, by loading SP register with value of blinky 1/2 stack pointer variable at sys tick interrupt exit (at BX lr instruction), the hard fault interrupt is triggered. When I try to swtch from main thred to blinky thread by changing PC address in main CPU stack (at sys tick interrupt exit) it works properly. I am using Keil uvision 5 IDE. I am facing similar issue in IAR but there hard fault interrupt occurs after running blinky thread for few msec. Appreciate your help on this!

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

      To use the code discussed in this video course directly, you really need the same board as used in this course (TivaC LaunchPad). Other boards, even if based on ARM Cortex-M CPU, differ just enough so that the code will NOT work without some changes. For example, your KL25Z Freedom board is based on Cortex-M0+, which is significantly different from the Cortex-M4 in the TivaC LaunchPad. Also, the GPIO structure (used to blink the LEDs) is very different in the NXP processors compared to the TI processors. But TivaC LauchPad costs only $12.99, so perhaps you could afford it to benefit from this course. I really hope this makes sense to you. --MMS

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

      Thanks for the reply. I could try this on Tiva board. Actually I have followed all of your earlier tutorials and created all applications on NXP KL 25z including led blinking and also found that the exception entries (stack frame) for Cortex M0 and Cortex M4 are also similar. Also, the code that I have written for Kl25z based on this tutorial is also same as that you have written for Tiva board, so I was hoping to have it working on kl25z. Is there any generic way that MIROS will work independent of arm architecture/board? Thank you again for the help!

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

      Looks like manually changing SP register in IDE causing change in the debug instructions and thus triggering hard fault interrupt. Finally I could able to run multiple threads on KL25Z freedom board with automatic thread switching as mentioned in your next tutorial with little modifications.
      Really helpful tutorials and lot to learn. Thanks!!

  • @nizarzaidan2643
    @nizarzaidan2643 6 ปีที่แล้ว

    question:
    could you please more clearly why the aligner stack entry is not necessary? ( my platforme is cc2640R2 Launchpad from Ti with CCS toolset) .. thanks in advanced

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

      Stack aligner is necessary only when the stack before the interrupt is misaligned. Misaligned stack means that the value in the SP register is not divisible by 8. Normally a stack misalignment should not happen, because the compiler avoids pushing an odd number of registers. But in case there is some assembly code (not generated by the compiler), a misalignment could happen. In the following lessons on RTOS, you will see some assembly code to perform context switch, but this assembly code will be careful to avoid stack misalignment. Regarding your CC2460R2 LaunchPad board, it is not appropriate for this course. To really follow along, you need the TivaC123 LaunchPad. --MMS

  • @omer12berar
    @omer12berar 5 หลายเดือนก่อน

    hey DR Miro
    when i breakpoint at the first time at the of systick_hnadler unlike your call stack , which contains both SysTick_Handler and main mine only contains SysTick_Handler at addreess 0x00000000 which seems weird . additionaly after having the right adresses of sp_blinky1\2 stack , i hit run and again unlike your call stack i have calls ti BSP_tickCtr twice and call to SysTick_hnadler . when i run free only blinky1 main loop executes .i think the two issues are connected and somehow the one of BSP_tickCtr (maybie belongs to the callstack of the blue led main loop) returns to blinky_1 instead to blinky2 (but again in your call stack it does not even appear). do u have any idea?

    • @StateMachineCOM
      @StateMachineCOM  5 หลายเดือนก่อน +1

      In situations like that, I highly recommend that you download the official project for this lesson (lesson-22.zip) from the companion web page ( www.state-machine.com/video-course ). Back up your current project, and unzip the official project. Try the official project, which should work. Then compare the original to your own (a good free tool is WinMerge). The problem must be in the difference. I hope this strategy makes sense to you. --MMS

    • @omer12berar
      @omer12berar 5 หลายเดือนก่อน

      hey Dr Miro @@StateMachineCOM
      thanks for the fast response , this is exactly what i did . should i have all the directories & files under the project ? i use keil ide but i did not quite undersood the readme file . my project builds sucssesfuly and run (besides the context ) , maybie i had to remove a file from the project ? do we use arm or gcc in this ide ? maybie its related somehow

  • @hungvo8330
    @hungvo8330 4 ปีที่แล้ว

    Dear Mr. Miro, if the main_blinky2 use a lot of stack memory, could it overwrite the private stack memory of main_blinky1's exception frame?

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

      Yes it could! The risk of stack overflow is multiplied by the number of threads in an RTOS, because each and every private stack of a thread can overflow. So, you need to be extremely careful and you need to size every stack properly. This is one of the biggest problems of using a traditional RTOS.

    • @hungvo8330
      @hungvo8330 4 ปีที่แล้ว

      @@StateMachineCOM Dear Mr. Miro, thank you very much for your conscientious answers and awesome videos.

  • @alexcipriani6003
    @alexcipriani6003 2 ปีที่แล้ว

    any guesses why my blue led doesn't go OFF when the green one comes ON ? The blue led turns off when I run the code without the breakpoint

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

      Why should the Blue-LED go off when a preemption happens? I mean, if the preemption happens while the Blue-LED is on, it *should* stay on as long as the thread main_blinky1 is not running. This is because only main_blinky1 turns the Blue-LED off. --MMS

  • @BinGanzLieb
    @BinGanzLieb 7 หลายเดือนก่อน

    If you are using a FPU, your stack for each Task has to be increased to 26 additional Bytes, right?

    • @StateMachineCOM
      @StateMachineCOM  7 หลายเดือนก่อน +1

      The interrupt stack frame is larger when the FPU is used. But there is more to it. An excellent description of the issues is published in the ARM Application Note 298 (just google for it) "Cortex-M4(F) Lazy Stacking and Context Switching". --MMS

  • @shradhas45
    @shradhas45 4 ปีที่แล้ว

    While debugging i got error driver DLL could not be found in specified path please help

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

      For all such problems, please visit the companion web-page to this video course advertised in every video and listed in the notes under every video: www.state-machine.com/quickstart/ . Specifically to driver issues, you might need to (re)install the Tiva/Stellaris USB Drivers on your Windows PC. The companion web-page provides a download link for these drivers as well as the USB drivers installation instructions (Tiva/Stellaris In-Circuit ICDI Manual). --MMS

  • @chandanbhatia3382
    @chandanbhatia3382 3 ปีที่แล้ว

    First thanks for great lessons, I am going through RTOS lesson again after a year. I have one doubt. At 12:50, you are explaining that we don't need extra aligned unit for task specific stack as its already 8 byte boundary aligned. I am not able to understand reason. I watched that portion multiple times. Can you please tell the reason in comment box ?

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

      Yes, you are right that the alignment of the arrays `stack_blink1[]` and `stack_blinky2[]` at 8-byte boundary is not guaranteed at this point. The ARM-KEIL compiler happens to align the arrays that way, but in principle, another, standard-compliant compiler (or the linker for that matter) could align them differently (only on 4-byte boundary.) To guarantee the 8-byte-boundary alignment, you could add `__attribute__ ((aligned (8)))` before or after the declarations of the stack arrays, but this is a non-portable extension to the C language. In the next lesson about the RTOS, you would see how this will be implemented in the "MiROS" RTOS, in the OSThread_start() function. Specifically, you'll see that the top of stack will be aligned explicitly. --MMS

    • @chandanbhatia3382
      @chandanbhatia3382 3 ปีที่แล้ว

      @@StateMachineCOM Thanks for reply. Yes in next lecture we are taking care of it.
      Also would like to put a thank you note for helping and motivating me & many other embedded engineers through your work.

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

    Hi sir, i knew how to create a RTOS, pls make a video how to create mutex, semaphore. Thank you.

  • @thucngoxuan9011
    @thucngoxuan9011 2 หลายเดือนก่อน

    hi Miro. Can you talk about firts setting with Debug in Keil-C. I do everything the same as you but the result is different. BX lr don't jump to main_blinky1 and display in Call Stack + Local also not the same you. Thank you so much about 2 previous response. Hope to receive your reply soon.

    • @StateMachineCOM
      @StateMachineCOM  2 หลายเดือนก่อน +1

      It's difficult for me to talk you through setting up the KEIL uVision debugger in this TH-cam comment. You just need to watch the video and try it on your host computer. But regarding the BX LR instruction that returns from the SysTick interrupt, it will NEVER go to main_blinky1 or main_blinky2 unless you manually change something in the CPU. For example, at 7:09 you change the stack entry corresponding to the PC register, and only after that change you execute the BX LR instruciton. This change causes the BX LR to return to your main_blinky1. Such "manual context switching" is the main point of this lesson. --MMS

    • @thucngoxuan9011
      @thucngoxuan9011 2 หลายเดือนก่อน

      @@StateMachineCOM i understand returns from the SysTick interrupt. I had change the value of SP same to main_blinky1 or main_blinky2 but it not go back what i want :

    • @StateMachineCOM
      @StateMachineCOM  2 หลายเดือนก่อน

      @@thucngoxuan9011 I think that you must be doing something else than what is shown in the video. Please note that the video progresses in a few steps and at each step you need to do something different. For example, at 7:09 you need to change a value in the stack memory. Later, at 15:55 you change the SP register in the CPU. So, please pay attention to what needs to happen at wich stage. Finally, if you cannot get your code to do what's shown in the video, you should download the project accompanying this lesson (from the companion web-page at www.state-machine.com/video-course ) and use that project. --MMS

  • @mehdirahman4127
    @mehdirahman4127 5 ปีที่แล้ว

    "But in your case, the ISR does NOT return to the preempted code, but
    rather to another thread: blinky2. This other thread can also use the R7 register and as any function is also obligated by the AAPCS to restore the R7 upon its return. But you are not executing the whole thread function but rather just a piece of it. This piece of code doesn't need to comply with the AAPCS and it can change the value in R7."
    What exactly is meant by not executing the whole thread function, but rather a piece of it?

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

      When you call a C function, you execute the whole function from the beginning to the end. This is important, because at the beginning of a function the compiler generates special code known as function prologue, which saves the required registers on the stack. Also, the right before returning from the function, the compiler generates special code known as function epilogue to restore the previously saved registers.
      However, when you return from an interrupt to a preempted thread function, you specifically DON'T execute the function from the beginning but rather only a piece of it from the point of preemption. This means that you generally don't execute the function prologue, so the registers required by the AAPCS are not saved. This is what is meant by saying the "the piece of code does not need to comply with AAPCS". --MMS

    • @mehdirahman4127
      @mehdirahman4127 5 ปีที่แล้ว

      @@StateMachineCOM Thanks for the detailed explanation

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

    Is it possible to apply this concept on an Arduino board or with an Atmel chip??

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

      Yes, this lesson should be applicable to Arduino boards based on the ARM Cortex-M CPU, such as Arduino DUE, Arduino Zero, or Arduino MKR, and perhaps others. (At the same time, the code presented here will NOT work on AVR-based Arduinos, such as Arduino UNO.) Also, if you are interested in Arduino, you might want to check out QP-arduino adaptation on GitHub github.com/QuantumLeaps/qp-arduino

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

      @@StateMachineCOM Thank you

  • @MultiNova100
    @MultiNova100 6 ปีที่แล้ว

    Hi Miro, why is this 'OS' called RTOS? What does 'real-time' refer to exactly here? Regular OSes do context switching too, what makes your RTOS different?

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

      You are right that in the initial stages the MiROS "RTOS" should not be even called that way. It will become an RTOS kernel only later, in future lesson-26 "RTOS part-4", where the priority-based preemptive scheduling will be implemented. You will also learn what "real-time" means and how RTOS differs from other OSes. --MMS

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

      RTOS is OS where correctness of task depends on logical correctness and temporal correctness. Saying simple, task(thread) in RTOS must do the right thing on right time

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

      The most stringent temporal demands for real-time systems have their origin in the requirements of the control loops, e.g., in the control of a fast mechanical process such as an automotive engine. The temporal requirements at the man-machineinterface are, in comparison, less stringent because the human perception delay, in the range of 50-100msec, is orders of magnitudes larger than the latency requirements of fast control loops.
      REAL-TIME SYSTEMS
      Design Principles for Distributed Embedded Applications

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

    I am very much disappointed, That I can give only one like for this Video 😅

  • @zhaoxiao2002
    @zhaoxiao2002 4 ปีที่แล้ว

    Excellent Explanation and course! But I used almost 2-3 hour to really understand this course. Content is really difficult.

    • @StateMachineCOM
      @StateMachineCOM  4 ปีที่แล้ว +6

      No pain, no gain! 2-3 hours is not long to learn, is it...

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

    Hello Dr. Miro, I feel so lucky to find your tutorial series. I follow your tutorial with an STM32-L432KC board and the STM Cube IDE software. I managed to get the context switching done, but I had to fabricate a different stack.
    The STM32-L432KC MCU also uses an ARM Cortex-M4 CPU so I'm not sure why I had to change the stack pattern for blinky sp's.
    Here is what I had to come up after a lot of trial and error.
    // Fabricate Cortex-M ISR stack frame for blinky1
    *(--sp_blinky1) = (1U

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

      Hi Amila. I assume that you're talking about the ISR stack frame discussed at 14:35. I don't understand why you had to add 2 extra registers to that stack frame because it should be the same for all Cortex-M CPUs. I would check your brake point at the end of SysTick in case you still have some code that changes the SP (such as popping two additional registers). The point where you manually change the SP is critical and the video assumes that there are no instructions that would mess up with the SP. I hope you see what I mean. --MMS

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

      I'm not sure why your second comment is not showing up here. But the GCC compiler apparently pops 2 registers at the end of SysTick_Handler (at the optimization level you chose). This is completely normal. To use the ISR stack frame shown in the video, you simply need to move your break point to the very last machine instruction of your SysTick_Handler in disassembly. --MMS

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

      @@StateMachineCOM Thank you so much Miro. I managed to figure out the issue with the help of your response. Earlier, I had a function inside SysTick_Handler() that made some changes to the disassembly, popping two registers as you mentioned. I removed that function and used the stack fabrication as in the video, and it worked!
      Although there are some additional assembly instructions before the "bx lr" instruction that I'm not aware of. Anyways, I copied the blinky1 sp to the sp register before executing the "bx lr" instruction and it worked as expected.
      Here are the assembly instructions:
      SysTick_Handler:
      push {r7}
      add r7, sp, #0
      }
      nop
      mov sp, r7
      ldr.w r7, [sp], #4
      bx lr
      Also, another interesting thing I found is that earlier, I didn't had the "bx lr" instruction. I'm not familiar with assembly, so debugging is a bit challenging for me. I will try to figure things out from here, thank you again Miro. You are a wonderful teacher!

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

      @@StateMachineCOM Sorry I deleted a comment. I actually did what you said just now and also made a comment. Many thanks Miro!

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

    sssssuuuuuppppppeeeer

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

    Why is there overly loud music playing whenever you pause on talking. I would recommend for future videos just keep it silent so its not distracting, over-wise great video and thank you!

  • @OlexiyTykhomyrovTiger
    @OlexiyTykhomyrovTiger 6 ปีที่แล้ว

    Very nice tutorial, but... I do not like when the word 'thread' is used as a synonym of the word 'task' or 'process'... These things are different.

    • @StateMachineCOM
      @StateMachineCOM  6 ปีที่แล้ว +5

      Actually, I was very careful NOT to use the term "process", because it has a different meaning than "task" or "thread. On the other hand, the terms "task" and "thread" seem to be synonymous in the RTOS community. Virtually all RTOS manuals/books (VxWorks, ThreadX, MicroC/OS, FreeRTOS, Wikipedia RTOS article, etc.) use predominantly the word "task", but note that "thread" is also an alternative term for the same thing. The clarification of the terms "thread"/"process"/"task" can be found on StackOverflow at: stackoverflow.com/questions/3042717/what-is-the-difference-between-a-thread-process-task

    • @OlexiyTykhomyrovTiger
      @OlexiyTykhomyrovTiger 6 ปีที่แล้ว

      I agree that _unfortunately_ 'task' and 'thread' uses simultaneously. I am quote old person and in my mind 'process', 'task' and 'thread' are different. With embedded systems these words are more 'synonymous' then it was with the big engines and this is why in my case I usually start lessons of RTOS with 'adjustment of therms'. From the classical point, the 'task' resources were created when a task was created with calls like 'task_create()', 'execv()', 'posix_spawn()', etc, derivate from general 'fork()'. From the other hand, 'fork()' has a strong correlation with a process. This is why in some OS there is also a 'task group'. In the link you've provided, from StackOverflow, task and thread are not the same as well.
      All these does not make your course bad! :)

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

    Dear Miro, why not to put a link for donation for this channel and for your effort? This level of information can not be achieved with courses of thousands of dollars. Therefore I want to donate for this effort.

    • @StateMachineCOM
      @StateMachineCOM  6 ปีที่แล้ว +13

      Thank you for the suggestion. It is very generous. But for anybody who would like to help, it would be actually more valuable if you could simply subscribe and spread the word about this video channel (share the links on forums, Reddit, Quora, LinkedIn, etc.). --MMS

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

      I agree as well.

  • @MohamedEnein
    @MohamedEnein 6 ปีที่แล้ว

    The music is a terrible idea :(

    • @StateMachineCOM
      @StateMachineCOM  6 ปีที่แล้ว +6

      Note that the music is completely suppressed during narration and is mostly used to fill out the silence. Also, you can always use the Closed Captions by pressing the CC button at the bottom-right of the video. --MMS

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

    Hi, just want to make sure I understand this correctly: why initialize the stack pointer variable for each thread to (length of stack + 1) instead of just the bottom of the stack ?
    Because in your code, you pre-decrement the stack pointer address before you start assigning values to the stack (so you're starting from the bottom of the stack regardless).

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

      @ClassyJohn: As explained at 13:00, the ARM stack is the so-called *full stack*, which means that the SP points to the last used slot (as opposed to the last empty slot). Therefore, in the video, the stack pointer variable has been initialized to simulate a situation right before adding a new interrupt stack frame. For each stack entry, the ARM hardware would first decrement the SP and then would fill the stack memory. Please note that code efficiency is not the objective here. It is more important to faithfully simulate the hardware. I hope that this makes more sense now. --MMS

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

      @ClassyJohn: The stack pointer variable is NOT initialized to (length-of-stack + 1). The initialization is sp = &stack_blinky1[40], which corresponds to the length-of-stack (without +1). But you need to remember that arrays in C start with the index 0, so &stack_blinky1[40] points one word beyond the end of stack_blinky1[40] array (see video at 11:45). This is an important aspect to understand about C arrays. Otherwise, you'll be making a lot of off-by-one errors in your code. --MMS

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

    could someone tell me where I can found out the 'qassert.h' file? I would be interested in looking up Q_* macros. Thanks

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

      The qassert.h file is located in the qpc/include directory. This is a very *useful* file that can be used standalone without the rest of the qpc framework. Also, the latest lesson #47 and #48 are precisely about assertions and Design by Contract in embedded systems. --MMS