#34 Event-Driven Programming Part-2: Best practices for concurrency & Active Object pattern

  Рет қаралды 26,108

Quantum Leaps, LLC

Quantum Leaps, LLC

Күн бұрын

Пікірлер: 84
@anthonyrocha8075
@anthonyrocha8075 2 жыл бұрын
This collection of lectures is the best one I've found so far. Thanks for sharing this. Active objects are the first pillar of concurrency.
@StateMachineCOM
@StateMachineCOM 2 жыл бұрын
Yes, that's the main message of this lesson. But this is not the mainstream approach yet. Most concurrent systems still use the "free threading" with multiple blocking mechanisms. Unfortunately, most developers vastly underestimate the true risks, costs, and skills required to use these blocking mechanisms correctly and safely. The active object model of computation restricts the "free threading" approach and avoids a lot of the problems (not all, but the most tricky ones). --MMS
@ethiopia-prevails498
@ethiopia-prevails498 Жыл бұрын
Wow wow wow!!!!!!!! After several ups and downs in ur tutorials: This tutorial made it clear to me that all the threads should be developed around the EVENT LOOP!! Great tnx!!!!
@StateMachineCOM
@StateMachineCOM Жыл бұрын
Yes, this is the right conclusion. *All* threads should have the event loop structure. Here again, I'd like to recommend the article "Managing Concurrency in Complex Embedded Systems" by David Cummings ( www.state-machine.com/doc/Cummings2006.pdf ). By now, this is perhaps the most frequently recommended article in all my presentations and videos. It uses simple terminology that should be familiar to users of traditional RTOSes. The "Active Object" pattern is not even mentioned (but this is what is being advocated, actually). Please read. --MMS
@nolimangulabnan6101
@nolimangulabnan6101 4 жыл бұрын
Wow thanks so much Miro. The greatest ARM lessons ever
@Vexown
@Vexown 4 жыл бұрын
Thank you for making these videos through all those years. The first video in this course was made in 2013!
@CrisMadla
@CrisMadla 4 жыл бұрын
Whew took me 9 days but I watched everything for a brief overview of embedded programming! Now to google everything later lol
@muhammedmucahit7335
@muhammedmucahit7335 4 жыл бұрын
Never clicked​ a video so fast like this one *_* Thank you for sharing.
@rupantaradhikary6580
@rupantaradhikary6580 11 ай бұрын
anybody new to embedded system can't justify the value of this technique but in my 1.5 years of fulltime embedded carrier I understand. Great work sir ,Thank You.
@ykc702
@ykc702 4 жыл бұрын
This works well if worst case time of your event loop processing is less than hard realtime deadline. Otherwise it will be a mix of RTOS and event driven. I have used event driven approach to implement usbpd/typec fw stack. But you presented a more generic and secure implementation of event driven approach. Awesome work.
@StateMachineCOM
@StateMachineCOM 4 жыл бұрын
Yes, indeed, the active-object (AO) model can execute on top of many types of real-time kernels. In the presentation I had only time to outline the execution model based on a traditional RTOS. But I've also mentioned that a traditional RTOS is overkill to execute non-blocking AOs. There are simpler non-blocking, but fully *preemptive* hard real-time kernels that can be used instead (e.g., in OSEK/VDX RTOS specification such kernels execute only so called basic threads). But in any case, the run-to-completion (RTC) event processing within each AO should *not* be confused with preemption. RTC does *not* mean that a running AO must monopolize the CPU. To the contrary, different AOs running at different priorities *can* preempt each other, but as long as they don't share resources there are no concurrency hazards. --MMS
@eddiemhako9350
@eddiemhako9350 4 жыл бұрын
Thank you very much Miro for your hard work. I also really enjoyed your presentation on the embedded online conference very informative.
@StateMachineCOM
@StateMachineCOM 4 жыл бұрын
Yes, this lesson covers similar material as the Embedded Online Conference presentation. The following lessons will also state machines and other related things, but in more detail. Stay tuned!
@andpe161
@andpe161 4 жыл бұрын
Thanks a lot Miro! Very pedagogical.
@stephanmorgenstern5611
@stephanmorgenstern5611 4 жыл бұрын
thanks a lot for this video. This really helps to make better design decisions. Very well explained.
@lazarchervenkov6635
@lazarchervenkov6635 4 жыл бұрын
Great tutorials! I follow them since the beginning. I do mainly hardware, with a little bit firmware. Watching them makes me want to start writing more firmware. Can you share what future lessons are coming to this channel? Are you planning more GUI tutorials, also with real display? Thank you!
@dan5607
@dan5607 Жыл бұрын
Excellent explanation! Clear and succinct.
@goranjosipovic353
@goranjosipovic353 3 жыл бұрын
Thank you Miro once again.
@borisnimcevic7424
@borisnimcevic7424 4 жыл бұрын
Awesome! Thank you so much for the new video!
@tuhoang6609
@tuhoang6609 2 жыл бұрын
What a great tutorial !!!
@hassaanshah9819
@hassaanshah9819 4 жыл бұрын
Amazing Tutorial! Keep it up Sir. Thank you
@jankeshchakravarthy9389
@jankeshchakravarthy9389 11 ай бұрын
Hi - Thanks for the very insightful video. If I understand correctly, active object = its own thread + private data + private queue. My question is, why is active object has tied to own RTOS based thread? It could be non-RTOS based task handler, which touches only its own private data and has its won queue. Can we call such pattern as Active Object?? thanks
@StateMachineCOM
@StateMachineCOM 11 ай бұрын
This is an excellent insight. Active Objects are not limited to using threads of traditional RTOS kernel. I started with a traditional RTOS only because it is so widely known. But Active Objects can also use a different kernel, including much simpler kernels. I made a video about one example of such a simpler and more efficient kernel ( kzbin.info/www/bejne/hoXGkqiPoZ5saqMsi=V-AdnSug-hmRDql9 ). But even this can be simplified further and Active Objects can be also executed cooperatively without any preemptive kernel. I plan to make some lessons about the various options for executing Active Objects. --MMS
@benravin6547
@benravin6547 4 жыл бұрын
Good Video. Please add a video on comparison of RTOS like Zephyr, uCOSII, FreeRTOS, Azure
@jugnu361
@jugnu361 2 жыл бұрын
Best On Internet
@Bits32
@Bits32 2 жыл бұрын
Excellent content. Please keep it up.
@carlogrisafi5512
@carlogrisafi5512 4 жыл бұрын
Amazing comeback!!!!
@MahmoudAli-sv7fj
@MahmoudAli-sv7fj 2 жыл бұрын
Great, Awesome, I love you man
@ofirfedida252
@ofirfedida252 3 жыл бұрын
Hi Miro, Combining the "Blinky" AO and the "Button" makes the AO thread priority at the same level. (I guess that the scheduler sets the AO thread priority) So how can you ensure and calculate the real rime requirements? when there were separated threads the real time requirements could be calculated. Which leads me to the question, should i always consider to design according to the new methodology (AO and object oriented wise)? or elsewhere? Really enjoying your course, thanks a lot
@StateMachineCOM
@StateMachineCOM 3 жыл бұрын
Yes, absolutely, the combined AO runs both activities at the same priority. This might be undesirable if these activities have different real-time requirements. But this is not the case here. In fact, most of the time activities are put into separate threads because of blocking in the traditional approach. -MMS
@coderlangthang4110
@coderlangthang4110 2 жыл бұрын
Watching your tutorial video makes me excited to learn embedded more, even though it is still difficult. And I have a concern that: Event-driven programming will include Active Object pattern, is that correct ?
@wondererasl
@wondererasl Жыл бұрын
Before the message has been handled by the target AO, it May still use the obsolete data, in case we have two or more AOs that need to notify each other with the updated data. There is a time gap between message sent and message processed.
@StateMachineCOM
@StateMachineCOM Жыл бұрын
Any computation takes time, so we fundamentally cannot process data "instantaneously". That means that we always deal with some "obsolete data", as you say. This is independent if you use event-driven programming, traditional blocking RTOS, "superloop" or little gnomes to process your data. But we can deal with this by introducing the concept of real-time deadlines, which characterize how long specific data is still good and when it becomes "bad". (Please watch the video "What is real-time?" kzbin.info/www/bejne/oX3bqYuEeNeMbJI ). The issue is really different here. The real problem would be if the data was somehow corrupted or inconsistent. This can happen quite easily when you *share* data between ISRs and the background loop, or between tasks in an RTOS. In contrast, event-driven programming solves this problem rather elegantly. The data carried inside events could be a little "obsolete", but is always *consistent* . This is huge! I hope you see the point. --MMS
@wondererasl
@wondererasl Жыл бұрын
@@StateMachineCOM Thank you Dr Miros! Yes, I agree with you that event driven programming is the best architecture for concurrence processes Just wondering if quantum computing can use entanglement phenomenon to realize absolute real time concurrence, as now they can use entanglement to flip qbits to get the computing result immediately. You got a PhD in nuclei physics, maybe can share some thoughts on it. Sorry for asking so many questions but you are the best.
@StateMachineCOM
@StateMachineCOM Жыл бұрын
@@wondererasl Quantum computing and quantum entanglement have really nothing to do with the real-time embedded programming discussed here. There is no way to compare the two. --MMS
@bonadio60
@bonadio60 4 жыл бұрын
This is great, thank you.
@matthenry7342
@matthenry7342 3 жыл бұрын
Hello Miro, Im curious if you have any videos in your repository that would help someone whose using SPI to communicate with a sensor of somekind? Im specifically using a fingerprint scanner, but anything with detail about sending data from one device to another would sure be helpful!
@bouazizihsan5777
@bouazizihsan5777 3 жыл бұрын
Thank you so much. please can you tell me why you didn't use the virtual table to declare the virtual function dispatch in the Active class?
@jankeshchakravarthy9389
@jankeshchakravarthy9389 10 ай бұрын
Hi - I would like to thank you again for amazing video. I do have three more comments or questions. 1. In the original implementation(at the beginning of this video) of the code where bink_time is shared between threads. Since the resource is shared between threads, it is protected by mutex. My question is, do we really need to protect the resource as one thread updates and other thread only reads? There is never going to be data corruption. 2. What is the reason for declaring the dispatch routine as virtual function? Is it really virtual as in case of desktop version? 3. Why timeEvent object is created which is attached to one particular active object and that too, mapped to one particular event in that AO? Why can;t timeEvent be generic/global object and when any object wants to arm a time_tick, it will provide queue and sig value. Once the event triggers(after the tick expires), the TimeEvent_tick will post an event to the particular queue. That also means, the timeEvent has to maintain a table like array of armed timer event data structure, which mainly contains the queue object, event, timeout, interval, state etc. and running_bitmap of active timeEvents. Let me know, if I am missing anything.
@StateMachineCOM
@StateMachineCOM 10 ай бұрын
Regarding your question #1 about sharing the "shared_blink_time" variable. In this case of just one 32-bit variable, a 32-bit CPU, and only reading on one end, you might get away without the mutual exclusion protection. But this is a *slippery slope* . The code will not work reliably on 16- or 8-bit CPUs, and will be fragile for any future modifications. For example, if you also added the possibility of changing the color of the LED, you will have two variables (blink_time and led_color). Due to preemption, the thread reading the variables might end up using the new "blink_time", but the old "led_color", so it will display an inconsistent state. Regarding your question #2 about the virtual dispatch() function. Such a design allows you to provide different state machine implementation strategies in different subclasses. For example, one implementation could be based on the "state table", another on the "nested switch" and yet another on the "event processor". Finally, regarding your question #3 about the time-events. The presented design is obviously just one of many possibilities. But your suggestion of global and shared time events is potentially hazardous. For example, one hazard is that a time event triggers and gets posted to an event queue, but before it is consumed, another thread arms it again and changes the signal. I hope you can see the problem. And there are many more corner cases like that. Ultimately, it all goes back to the fundamental "sin" of sharing resources. So, one needs to be very careful because it's awfully easy to create something unsafe. (Unfortunately, I see a *lot* of such ad hoc solutions when people improvise with traditional RTOS kernels.) The design presented here avoids such hazards by making time events private to active objects (not shared) with fixed signals. This may be a bit limiting, but it's *safe* . --MMS
@jankeshchakravarthy9389
@jankeshchakravarthy9389 10 ай бұрын
@@StateMachineCOM - #1: Yes, if someone wants to overlap two variables in same word, then of course there will collision. If the variable is word size and word aligned then read by one thread and write by other thread then the expensive blocking can be avoided. I guess, you wanted to show the issue of blocking in a thread and that is the reason for use of mutex. #3: I did not get this. The functionality of OS-Delay in RTOS video series was also global; except that scope of delay function starts from the point it is triggered to till it expires. In timeEvent object, the scope extends till the event is processed in dispatch routine. For example, array of tick_events and every entry of tick_event will have state, which can be enumerated to IDLE, ARMED, and POSTED. Yes, one can protect the operation that is combines the update of state and l_tevtNum. Why can't tick_event be generic and used as service by any object? Thanks
@StateMachineCOM
@StateMachineCOM 10 ай бұрын
@@jankeshchakravarthy9389 Regarding issue #3, as I said there are many ways to implement time events and event passing in general. You probably are used to passing messages by copy, which does not involve sharing and therefore is safe, but also slow, memory-hungry, and potentially non-deterministic. Therefore, the option presented here passes only *pointers* to events into the queues, so that event passing is fast and deterministic. However, the consequences are that the event objects (including time events) remain *shared*. So far in this course, all events were immutable (const), so sharing them wasn't a problem. (And I still need to discuss mutable events in future lessons!) However, time events are mutable, so this issue of sharing such events came up here. So, the time event objects are only protected momentarily during posting, but are NOT protected thereafter and definitely not till dispatch. I hope this clarifies the issue, and my earlier comment makes more sense now. --MMS
@alaouchicheabdellah4986
@alaouchicheabdellah4986 3 жыл бұрын
Thank you very much.
@saisushanth2459
@saisushanth2459 4 жыл бұрын
sir please update videos regularly or weakly
@kenanparacik316
@kenanparacik316 4 жыл бұрын
Hey Miro, I wanted to ask you what could I do if I have a blackout reset situation. Is there any register that reserves any kind of data about why this reset occurs...
@cernejr
@cernejr 5 ай бұрын
Is there some emulator which would allow me to learn and practice these concepts on a Windows or Linux computer?
@StateMachineCOM
@StateMachineCOM 5 ай бұрын
Sure. For example, the event-driven QP frameworks implement the Active Object design pattern and the best practices of concurrent programming. You can also build and run QP on the host computers (Windows, Linux, macOS). To learn and practice the presented concepts, you can download and install QP-bundle ( www.state-machine.com/#Downloads ). On the download web-page, you can also find a "Getting Started" video that shows how to build and run QP on Windows. --MMS
@cernejr
@cernejr 5 ай бұрын
@@StateMachineCOM Thank you. I will have a look.
@ramadhanafif
@ramadhanafif 2 жыл бұрын
Active objects seems like a powerful paradigm. Is most of the sequential code can be converted this way? I expect there would be some exceptions, so what are they? I asked this because I have tried to convert some of my naked thread into active objects. I soon found that making dispatch function was either hard to be efficient or spaghetti..
@StateMachineCOM
@StateMachineCOM 2 жыл бұрын
As you found out by yourself, converting sequential code to event-driven code is NOT trivial at all. For example, consider a piece of sequential code that consists of a while loop that calls a function, that calls another function, that... blocks (or polls). How do you unravel something like that? I mean you need to eliminate the blocking (or polling) and instead return to the event loop, right? I remember spending a whole year in a company doing exactly such a conversion from the existing sequential code to event-driven code. That's why it is important to understand the difference in paradigms and to create event-driven code to begin with. Here, I would like to recommend an article strongly advocating to avoid blocking: "Managing Concurrency in Complex Embedded Systems", see www.state-machine.com/doc/Cummings2006.pdf
@EngMazen
@EngMazen 4 жыл бұрын
Welcome back :)
@technics6215
@technics6215 2 жыл бұрын
What about two-way communication with Active Object pattern? Is this covered in this course? I'm not using strictly AO pattern yet, but I have something very similar based on (unfortunately) single Event Bus in my case and I wonder what I can improve (after I split my event bus into AO queues). Lets say I have ModbusActiveObject, SchedulerActiveObject and WebInterfaceActiveObject. ModbusAO has a queue with ModbusReadRequests. SchedulerAO and WebInterfaceAO can send messages to ModbusAO. When ModbusAO reads data from bus (or there is an error) ModbusAO posts response to the caller AO as another message. I have few other objects (like datalogger, display etc.).
@StateMachineCOM
@StateMachineCOM 2 жыл бұрын
I'm not sure what you mean by "two-way" communication and what's special about it. In the active object model, AO1 can post events to AO2 and also AO2 can post events back to AO1. Does that count as "two-way" communication? Regarding you partitioning of the system, please remember that one AO can typically have more functionality than a traditional thread, because an AO remains *responsive* to events (while a thread blocks and is thus unresponsive). This means that a "ModbusAO" can have also some functionality, besides also encapsulating the Modbus. I'm not sure what the SchedulerAO does. --MMS
@technics6215
@technics6215 2 жыл бұрын
@@StateMachineCOM Regarding SchedulerAO - this is just one of two event producers for ModbusAO. It is part of data logger feature. Regarding "what's special about two-way" - I have problem because my "data request" events must be related with "data response" events. AO1 (tcp interface that processed 10 tcp requests) wants data from AO2 (modbus) and it produces multiple events with "ModbusReadRequest". AO2 consumes these events, does it's job and then it must "respond" to AO1. So it should produce multiple events with "ModbusReadResult". But these ModbusReadRequest events must be linked with ModbusReadResult events (to know which response belongs to which request, or at least to which TCP client data should go). But ModbusReadRequest does not exist (in queue), because it was consumed by AO2. So I have to keep "ModbusReadRequest" copies in AO1. At this moment I have implemented weird kind of queue with two heads and tails to handle this, now I'm thinking about something else.
@StateMachineCOM
@StateMachineCOM 2 жыл бұрын
@@technics6215 The request-response pattern is very common, and typically people like to send a request and *block* until the response is received. This, of course, sweeps the whole slew of problems under the rug, because the question is what do you do with all the events that *might* be produced during the several milliseconds between the request and the response(?) Here, I would highly recommend that you read the article "Managing Concurrency in Complex Embedded Systems": www.state-machine.com/doc/Cummings2006.pdf But with active objects, you don't block, but instead, use the *state machine* to "remember" your specific situation. Specifically, you can send the request and then transition to the special state "wait4response". In this state, you can process the RESPONSE event, obviously, but you can also process all other events. Some of them you might ignore (as is the case with blocking), some of them you might simply handle (because they have nothing to do with waiting for the response), and some others you might need to defer, for which you can use the "Deferred Event" state pattern (just google for it). The point is that you face the problems head-on and *you* remain in control of what exactly happens.
@technics6215
@technics6215 2 жыл бұрын
@@StateMachineCOM Thank you for your comprehensive answer and interesting article. I already tried "waiting4response" state, and as you noticed - there is little problem with multiple events that could be produced while waiting for first modbus response. It is quite simple approach and actually waiting for an answer is inevitable anyway. I'm wondering if going beyond this kind of implementation (keeping many deferred/pending requests in memory) can be useful with interface like slow Modbus. I want to try to experimentally solve this whole problem without keeping all/multiple sent request states and their contexts inside SchedulerAO (by contexts I mean information like tcp session that should receive result etc.). Maybe I can move around whole modbus transaction state including context in AO1->AO2 event, and then send that information back with result AO2->AO1 event. Maybe such "wandering state and context" that changes owner will simplify my Active Objects and reduce "fragmentation" of information related with whole system-wide operation. That would be also "stateless functional programming manner" implementation inside Active Object instead of "state machine manner" implementation. Functional programming approach is also "run to completion" friendly...
@StateMachineCOM
@StateMachineCOM 2 жыл бұрын
@@technics6215 Sure, you can improve the design of your events and they can carry parameters (like the TCP session, etc.) From my experience events have the biggest impact on the complexity of the state machine(s) that need to process them. In other words, to simplify your state machines you should start with your events. (As they say: "garbage in, garbage out"). I'm not sure if you can go all the way to completely "stateless programming" with this, though. I suppose what will happen is that you will see increasing number of IF-ELSE statements in your code based on testing the parameters of your events. This is a slippery slope to "spaghetti", which you tried to avoid in the first place. --MMS
@BinGanzLieb
@BinGanzLieb Жыл бұрын
So in Event Driven Design, you have only one Task (the Active Object)? Is it possible to have more active objects for different purposes? You are saying, that in the Dispatch-Handler we should never block. What if I use for instance an I2C Dispatch Handler, and for some actions I have to wait through a while loop if an action is performed like "Wait until startbit is sent". Edit: I have another question. Can you speak/read german, because you studied in germany?
@StateMachineCOM
@StateMachineCOM Жыл бұрын
I'm terribly failing as a teacher if you conclude that event-driven design means only one Active Object. This is absolutely *not* the case. You *can* have multiple Active Objects, as demonstrated at 20:40, where the second Active Object "Button" is created. (Later on, Blinky and Button AOs are merged, but this is independent of the possibility of having multiple AOs.) I hope this makes sense. --MMS
@BinGanzLieb
@BinGanzLieb Жыл бұрын
@@StateMachineCOM No you are not failing as a teacher. I was wondering why you merged blinky and button. It seems to me that I need a "god" function and implement all my application there. Thank you for your help. Regardless, can you maybe answer my question about the I2C topic?
@StateMachineCOM
@StateMachineCOM Жыл бұрын
Regarding the I/O (such as I2C, SPI, UART), sometimes you need to wait for microsecond-level periods, for example when you "bit-bang" the data through a low-level hardware interface. Such delays are too short to use time events, so your only option is to wait in a busy polling loop. This would then make long-lasting RTC steps, which might be tolerable if the AO has low priority. However, this should be clearly distinguished from long waiting periods like in the request-reply scenario. Specifically, after sending a request (through I2C, SPI, or UART) you should generally *not* wait in-line for the response. The response should arrive as a separate asynchronous event. Please read the recommended article "Managing Concurrency in Complex Embedded Systems" ( www.state-machine.com/doc/Cummings2006.pdf ). --MMS
@StateMachineCOM
@StateMachineCOM Жыл бұрын
Yes, I used to speak German and can still read it, but I prefer English. --MMS
@MahmoudAli-sv7fj
@MahmoudAli-sv7fj 2 жыл бұрын
i have one question you always emphasize that we shouldn't use blocking with event driven programming but you have to use mutex (blocking) to protect the shared resource (blinky time) is it correct ?
@StateMachineCOM
@StateMachineCOM 2 жыл бұрын
Thank you for the question because it pertains to the most important point of this video. And that point is spelled out in the very first best practice of concurrent programming (at 6:30), which is NO SHARING of anything among concurrent threads. With no sharing there is no need for mutual exclusion, so no need for mutual exclusion such as mutexes. Instead of sharing, event-driven programs use EVENTS. This lesson showed how to eliminate sharing by merging the separate active objects (Blinky and Button) into one (BlinkyButton). But you could also eliminate sharing by putting the "blink_time" data into an event and sending it over whenever it changes, instead of sharing a variable. Either way, you can ELIMINATE the sharing and the mutex. --MMS
@MahmoudAli-sv7fj
@MahmoudAli-sv7fj 2 жыл бұрын
@@StateMachineCOM excellent as always thanks a lot.
@bouazizihsan5777
@bouazizihsan5777 4 жыл бұрын
really hat off
@bgrad1
@bgrad1 3 жыл бұрын
Great course! Is there a way to get the source code you started the lesson with? lesson34.zip is from the end of the lecture. Thank you!
@StateMachineCOM
@StateMachineCOM 3 жыл бұрын
The project download for this lesson (www.state-machine.com/course/lesson34.zip ) has been augmented with the original code. The starting versions, before any changes were made in the course of the lesson, are provided as bsp0.h, bsp0.c, and main0.c. --MMS
@bgrad1
@bgrad1 3 жыл бұрын
@@StateMachineCOM Awesome, thank you very much. Benjamin
@panagiotismarkopoulos6649
@panagiotismarkopoulos6649 3 жыл бұрын
@@StateMachineCOM Great transformation example from OS tasks to AOs! The starting files however still do not seem to be included in the zip file. Can you please check?
@bgrad1
@bgrad1 3 жыл бұрын
@@panagiotismarkopoulos6649 Files are in the git repository, but perhaps not yet on the website.
@ducnguyentuan8778
@ducnguyentuan8778 2 жыл бұрын
the link to get source code of this lesson have changes . can you give me the original ?
@StateMachineCOM
@StateMachineCOM 2 жыл бұрын
The code for all lessons should be still available from the advertised link at www.state-machine.com/quickstart (there is now a redirection to www.state-machine.com/video-course , but this should be transparent.) Additionally, all the companion code for the course is available on GitHub at: github.com/QuantumLeaps/modern-embedded-programming-course . --MMS
@ducnguyentuan8778
@ducnguyentuan8778 2 жыл бұрын
@@StateMachineCOM Thank you.
@ducnguyentuan8778
@ducnguyentuan8778 2 жыл бұрын
./bsp.h(26): error: use of undeclared identifier 'USER_SIG' BUTTON_PRESSED_SIG = USER_SIG ./bsp.h(33): error: unknown type name 'Active' extern Active *AO_BlinkyButton; I got 2 Error, how can I solve this problems ?
@StateMachineCOM
@StateMachineCOM 2 жыл бұрын
The missing elements in your build are defined in the "uc_ao.h" header file (part of the uC/AO "framework" that is being built in this lesson.) You should have both "uc_ao.h" and "uc_ao.c" files in your directory and in your uVision project. If you don't please download the project for this lesson #34 from the usual place: www.state-machine.com/video-course or from GitHub: github.com/QuantumLeaps/modern-embedded-programming-course . Then you can compare *your* files with the originals. For such comparisons, I recommend the free code-differencing tool called WinMerge (you can google for it). --MMS
@ducnguyentuan8778
@ducnguyentuan8778 2 жыл бұрын
@@StateMachineCOM I downloaded lesson 34 from githup and project have "uc_ao.h" and "uc_ao.c" . sometimes i can run it on my board in first time, but after that it have error (i have extract from RAR again). the main.c run fine. but when i change main0.c to main.c. it get errors. ./bsp.h(26): error: use of undeclared identifier 'USER_SIG' ./bsp.h(33): error: unknown type name 'Active' extern Active *AO_BlinkyButton; main.c(45): error: use of undeclared identifier 'BSP_semaPress' OSSemPend(BSP_semaPress, 0, &err); /* BLOCKING! */ main.c(59): error: use of undeclared identifier 'BSP_semaRelease' OSSemPend(BSP_semaRelease, 0, &err); /* BLOCKING! */ I just tested again, first run oke, second times get errors.
@StateMachineCOM
@StateMachineCOM 2 жыл бұрын
@@ducnguyentuan8778 If you change main0.c -> main.c, you must also change bsp0.c -> bsp.c. That's because the main0.c and bsp0.c correspond to the earlier example, where only uC/OS-II RTOS was used, but without the active-object framework ("uC/AO"). --MMS
@ducnguyentuan8778
@ducnguyentuan8778 2 жыл бұрын
@@StateMachineCOM cannot believe, now it is working.
@scravengerx
@scravengerx 4 жыл бұрын
👍👍👍
@ClassyJohn
@ClassyJohn 3 жыл бұрын
What are "naked" threads?
@StateMachineCOM
@StateMachineCOM 3 жыл бұрын
"Naked" threads, as referenced by Herb Sutter in his article "Prefer Using Active Objects Instead of Naked Threads", are threads that you, as the application designer, write yourself. In that case, the thread routine can be structured any which way and can include any number of *blocking* primitives. In contrast, thread routines in the Active Object pattern are all structured as the event-loop, which contains exactly one blocking point on the event-queue. The tread inside each active object is no longer "naked", because it is pre-defined in the active object and is no longer exposed to the application. In other words, you don't write the body of the thread. You only write the event-handling code that is *not allowed* to block anywhere. --MMS
@fatty-it-man
@fatty-it-man 10 ай бұрын
extremely good!!
#35 State Machines Part-1: What is a state machine?
24:16
Quantum Leaps, LLC
Рет қаралды 48 М.
#29 OOP Part-1: Encapsulation (classes) in C and C++
31:29
Quantum Leaps, LLC
Рет қаралды 37 М.
This mother's baby is too unreliable.
00:13
FUNNY XIAOTING 666
Рет қаралды 30 МЛН
когда не обедаешь в школе // EVA mash
00:51
EVA mash
Рет қаралды 4,2 МЛН
Microcontroller Interrupts | Embedded System Project Series #17
54:40
Beyond the RTOS - Part 3: Active Objects implemented on top of FreeRTOS
26:47
Dependency Injection, The Best Pattern
13:16
CodeAesthetic
Рет қаралды 840 М.
#23 RTOS Part-2: Automating the context switch
37:37
Quantum Leaps, LLC
Рет қаралды 51 М.
Embedded C Programming Design Patterns: Callback
22:55
Martin K. Schröder
Рет қаралды 7 М.
Cross Platform Graphical User Interfaces in C++
44:49
javidx9
Рет қаралды 869 М.
Why Isn't Functional Programming the Norm? - Richard Feldman
46:09