#44 Active Objects in Real-Time Part-2: Mutable Events

Поделиться
HTML-код
  • Опубликовано: 4 окт 2024
  • This lesson continues the subject of Active Objects for Real-Time. Specifically, today you'll see how the use of asynchronous, mutable events makes Active Objects even more suitable for hard real-time than traditional with a Real-Time Operating System (RTOS).
    Contents with Timestamps:
    -------------------------
    1:40 Adding interactions among Active Objects, first with sharing
    4:30 Race condition caused by sharing
    6:05 Observing consequences of the race condition
    8:00 Applying mutual exclusion for protection
    9:20 Timing problems caused by mutual exclusion
    10:40 Switching over to interactions via events
    12:00 Naive approach with the static mutable event with parameters
    13:30 Receiving event with parameters
    15:50 Why static mutable events aren't safe?
    16:45 Framework-based, management of mutable events
    18:50 Summary of "Zero-copy" event management
    19:32 "The Law of Leaky Abstractions"
    19:50 Ownership rules for mutable events
    -------
    Resources:
    Companion web page for this video course:
    www.state-mach...
    GitHub repository for projects for this video course:
    github.com/Qua...
    Transcript of this lesson:
    www.state-mach...
    Recommended Reading:
    Book: "Practical UML Statecharts in C/C++, 2nd Edition":
    www.state-mach...
    Article: "The Law of Leaky Abstractions" by Joel Spolsky
    www.joelonsoft...
    Music credits:
    The background music comes from:
    www.bensound.c...

Комментарии • 30

  • @StateMachineCOM
    @StateMachineCOM  2 года назад +1

    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

    • @damiengates7581
      @damiengates7581 Год назад

      Do you think QF/C and QEP/C can be ported to an "RTOS" that implements the Immediate Priority Ceiling Protocol, but only allows application tasks to be scheduled periodically (1ms too fast, 100ms too slow.. because fixed periodicity..) or non-periodically in the lowest priority background loop in which case even if the priority is temporarily raised while the application runs - it can't be guaranteed to start again fast enough because of the processes that are between the periodic application task priority and the background task priority??
      Specifically do you think it can be ported to that without having to manually manage the scheduling by yourself using the given periodic task options?

    • @damiengates7581
      @damiengates7581 Год назад

      It also doesn't provide queues, but I guess that's not a problem.

    • @StateMachineCOM
      @StateMachineCOM  Год назад +1

      @@damiengates7581 I'm not quite sure that I understand the "RTOS" scheduler you are proposing. But the event-driven Active Objects can execute under a wide range of schedulers. For example, the QP/C/C++ active object frameworks include the following kernels: cooperative QV kernel, preemptive but non-blocking QK kernel, and dual-mode QXK kernel. Additionally, active objects can run on top of any traditional RTOS (inside threads organized as event loops). Your proposed "RTOS" seems like a periodic Time-Triggered" scheduler, and this should also work for active objects. I plan to talk about the various schedulers for active objects in the future videos in this course. --MMS

    • @damiengates7581
      @damiengates7581 Год назад

      ​​@@StateMachineCOM
      Thanks for response. I don't know what's the correct term for it, but the vendor calls it a sort of "RTOS" anyway. There's no main-loop, you have to define the periodic task times and their relative priorities, and all the application code goes either in those or in the lowest priority background loop. I don't think there's any other way to use it without breaking it, and I do need the other functionalities it provides.
      I will have a quick look if I could manage porting to it. It's called "OpenECU RTOS" if you care to have a quick look for yourself. It compiles with Wind River Diab to MPC5746C processor.

    • @damiengates7581
      @damiengates7581 Год назад

      Just to be clear about what I think is problematic with it.. It's that if I set the whole framework to run in the 1ms (fastest allowed) task, it will allow it to run as long as it takes and it will start again within every ~1ms if it loops through, but I think it will show CPU use as 100% all the time and it could cause problems.. It could also miss the watchdog, although that is probably configurable.
      I think I will try putting all the AOs in the tasks that correspond with their fastest subcomponents and time their slower subcomponents with the system timer, and put the dispatcher or whatever controls the events to a 5ms task that should be faster than any of the AOs.

  • @hsierc3307
    @hsierc3307 2 года назад

    Great tutorial!!!😘

  • @bipulsarkar3910
    @bipulsarkar3910 2 года назад +1

    Great tutorial

  • @Bits32
    @Bits32 6 месяцев назад

    Thank you very much, Miro. I found this very helpful! Do you have any ideas for publish/subscribe mechanism videos anytime?

  • @ManikantaRaju
    @ManikantaRaju 2 года назад +1

    Hi Miro. I would like to a know a bit about taking control from the framework to go bare metal. For example we have an application where we have 4 active object threads. No we have a special use case where we want the mcu to go to deep sleep and periodically wakeup. Here can we actually take control from the framework and stop all the active objects and go to deep sleep. We are using a pic32 mcu.

    • @StateMachineCOM
      @StateMachineCOM  2 года назад +2

      The QP framework provides the "idle callback", which is called when the system becomes "idle" (meaning that no events are to be processed by any AOs). This callback gives control to the application, where you can put the system to sleep. There is also a whole "Low-Power Example", described in the online manual: www.state-machine.com/qpc/tut_low.html . --MMS

  • @imk8729
    @imk8729 2 года назад

    Great job, 👍

  • @ashrafkamel1287
    @ashrafkamel1287 2 года назад +1

    but the mutable events are immutable to the receiver AO.
    the Event dispatch function receives it as a const * const
    .....
    I just realized how unsafe C is
    you can just recast the pointer or assign it to another non-const pointer.
    Mmmmmm
    but if the pointer sent was a variable declared as a const, it should be located in Flash,
    it should give a linker or a run time error.
    why is C like this
    but as you said in the OOP videos.
    although you can access the OBJ's parameters directly, you shouldn't do such a thing.
    we can also ensure such a thing by trusting the programmer to not recast.
    thanks for the great topic!
    really great content.

    • @StateMachineCOM
      @StateMachineCOM  2 года назад +3

      Yes, that's right. The producer of mutable events can change them, but the consumer cannot. This corresponds to the "zero-copy" abstraction, where you would receive a copy and changing that copy does not change the original. Here, you get the original event, so you are not allowed to change it. Now, regarding the "const" keyword, it does NOT mean that the variable must be in ROM. It only means that *you* are not allowed to change it. --MMS

    • @Karujin277
      @Karujin277 2 года назад

      Miro is right in the sense that const means read only not constant. It is a misnomer sadly that they got wrong 50 years ago :D

    • @StateMachineCOM
      @StateMachineCOM  2 года назад

      Yes, that's right. And additioanlly, 'const' has different meaning when allocating objects and different for function parameters. --MMS

    • @technics6215
      @technics6215 2 года назад

      @@Karujin277 Also "static" keyword for function is a bit missleading. They probably had no idea how programming languages evolve 50 years ago.

  • @ramadhanafif
    @ramadhanafif 2 года назад

    Thank you for your work, it really made me think deeply about my design patterns. Just wondering, will there be another lesson? What kind of topics are you going to cover next?

    • @StateMachineCOM
      @StateMachineCOM  2 года назад +1

      I apologize for the long pause in releasing new lessons, but yes, I still have a lot of subjects to cover in this video course. The next few lessons will be about *software tracing*, starting with the most primitive "debugging with printf". After this, I will go back to active objects and talk about different modes of execution. It turns out that the traditional blocking event loop with an RTOS is just one of many options. The fact that active objects run to completion and don't need to block opens up possibilities of applying different, non-blocking types of kernels. This is a fascinating subject that not many embedded developers are even familiar with. Stay tuned!

  • @Karujin277
    @Karujin277 2 года назад +1

    Hello Miro, thank you for another great video.
    I wanted to talk about the usage of (semi)dynamically allocated events. Since your possible values cannot change at runtime (lookup table ) wouldn't it make more sense to create const events for each possible value pair and publish those? This method would avoid the event pool so it is better in terms of size and effort.
    If your values are determined at runtime ( hardware reading, uart input etc.) It would make sense to create the messages from a pool with your method.
    I assume you just wanted to highlight object borrowing and being careful with pointers to non-const data with this example so you went with this approach. Was this the case?

    • @StateMachineCOM
      @StateMachineCOM  2 года назад +4

      Yes, this is a very good observation. If the situation allows, immutable (static) events are always more efficient to use. In this particular toy example, immutable events will be feasible, and actually better. But here I wanted to demonstrate mutable events... In real-life often it's impractical to pre-allocate all event combinations. For example, event conveying a position on an LCD screen has coordinates (x,y). It would be impractical to pre-allocate all possible combinations of (x,y). In such cases mutable events are the way to go. --MMS

  • @BerthaProt
    @BerthaProt Год назад

    One question (maybe stupid and sorry about that) about this global approch, where and when, if possible, we can set task priorities ?

    • @StateMachineCOM
      @StateMachineCOM  Год назад +1

      Task priorities are set in the main() function (file main.c) when you start the "active objects" (tasks). Specifically, the second parameter of the QACTIVE_START() call denotes the priority. In the QP environment priorities are numbered in the most straightforward way starting from 1 for the lowest priority and higher priorities corresponding to higher numbers. The priority 0 is reserved for the "idle task". --MMS

  • @prasanthcp3097
    @prasanthcp3097 2 года назад

    Hi..... Is there any learning resources for GTM (generic timer module). Please kindly let me know!

  • @persupersulast2506
    @persupersulast2506 2 года назад

    Is your book psicc outdated?

  • @technics6215
    @technics6215 2 года назад

    EDIT: comment deleted, I have to clarify my question :)

  • @toddmoore112
    @toddmoore112 2 года назад

    Hi

  • @MahmoudAli-sv7fj
    @MahmoudAli-sv7fj 2 года назад

    I have tried to use Qpc with FreeRTOS (in lesson 43 instead of QXK Kernal )but i got the fellowing error.
    ../qpc/3rd_party/ek-tm4c123gxl/ti/startup_TM4C123GH6PM.c(361):
    error: invalid instruction
    " .global SystemInit

    "
    so what should i do?

    • @StateMachineCOM
      @StateMachineCOM  2 года назад +1

      I'm not sure what you're doing, but moving an active object framework (like QP) from one real-time kernel to another is *NOT* trivial. Just think about it: Posting an event to an active object, for example, must call some primitive in the kernel to make the internal thread of the active object ready to run. So, if you wish to use QP on top of a different kernel, you need to adapt it for that kernel. This adaptation is called *porting* and the good news is that the QP to FreeRTOS port already exists. If you are interested, you can try the provided examples, which are located in the directory: qpc\examples\freertos\arm-cm\dpp_ek-tm4c123gxl. --MMS