Hello Miro, I've got une question. If __WFI() stops CPU execution and it is called with interrupts disabled, why "enable_irq" is still executed afterwards? Is it because the CPU knows you have previously pressed the button when calling __WFI()?
@StateMachineCOM12 сағат бұрын
@jordibatlledelallave As you say, WFI is called with interrupts still disabled (with PRIMASK), and the interrupts remain *disabled* after the CPU wakes up. You can see this at 23:35. So, you must enable interrupts because nothing else will! This is precisely the special property of the PRIMASK register I referenced at 27:30 (Joseph Yiu's book). PRIMASK disables interrupts but still allows the CPU to be WOKEN UP by an interrupt (see the "Wake-up conditions" in Yiu). --MMS
@jordibatlledelallave19309 сағат бұрын
Oh, gotcha! Thanks for the clarification
@gamerboy6227Күн бұрын
Complex stuff in simpler way ....brilliant.
@jamesterpaul2 күн бұрын
Using Keil Microvision with the Nucleo C031C6, the main.o file doesn't start with "ELF" instead it starts with "ORC" any way to read this with a program like the one in the video?
@StateMachineCOM2 күн бұрын
@jamesterpaul My KEIL uVision project for the NUCLEO-C031C6 board produces object files that start with "ELF". Please try to download lesson-14.zip from the companion web-page: www.state-machine.com/quickstart . I also checked that the GNU objdump utility works for the main.o file produced by this project. --MMS
@alexg49744 күн бұрын
At ~9:30 I don't know where you get that at address 0x40025400 (GPIODIR Port F (APB) base + offset) bits 1 2 and 3 should be set to 1, why not bit 0, 4, 5, 6, or 7? I can't find in the datasheet that these 3 specific bits configure these LEDs to be outputs. Or why 0x4002551C are supposed to also be 1 2 and 3. Where does it say this? I am missing a puzzle piece somewhere, where is it?
@StateMachineCOM4 күн бұрын
This info is in the TM4C123GH6PM Datasheet (available on the companion web-page www.state-machine.com/video-course#Resources . You can search the PDF for "GPIODIR", which you find on page 663. On this page, you look for GPIO Port F and you find its address 0x4002.5000. Finally, you add the Offset 0x400 (provided in small print below the GPIO addresses). All this ends up as address 0x4002.5400, which you see at 9:50. Regarding the individual bits, they are explained on the same page. You need to know which LEDs are connected to which GPIOF bits, and this is described in the manual for the TivaC board (also provided on the companion web-page). --MMS
@spiralspree5 күн бұрын
anyone doing this in keil microvision and is being confused because the value that you typed into the memory address will change after you hit enter: try right click inside the memory window, then select unsigned long for datatype.
@Nikita-wh2vc5 күн бұрын
26:04 It should be noted that such explicit cast (unsigned integer to signed integer) is also dangerous, because it works incorrectly for unsigned integers greater than or equal to 0x80000000U. Obviously, the unsigned integer 0x80000000U is greater than -1 in common sense, but after explicit cast it becomes negative number -2,147,483,648. Maybe the better way is to make an explicit cast to int64_t
@StateMachineCOM5 күн бұрын
Mixing signed and unsigned representations is tricky, and its correctness depends on the context. Therefore, explicit casting is often necessary. Using a bigger integer (like your suggested int64_t) only kicks the can down the road, because precisely the same argument can be made at the end of the dynamic range of the bigger integer (0x8000000000000000). --MMS
@juanorlando97837 күн бұрын
This a great tool, thanks for the lesson Mr. Samek. What are your thought on SysML for Model Based System Engineering for Embedded Systems designs? I like the idea of MSBE with SysML due to the fact that it begins from the requirements the system and the multiple tools to represents these and the behaviour of the actors and use cases. State machines are part of this approach, as you mentioned QM allows the code generation and seems to be the easiest as far as SM modeling / code generator I've seen (so far only tried Sparx EA). I think I could use the QM for code generation in hand with SysML to develop Embedded Systems.
@StateMachineCOM7 күн бұрын
SysML is an example of a bigger modeling language aimed at the whole system, not just software. The QM modeling tool supports only the state diagrams, which are fully compatible with the state diagrams of SysML. In this sense, QM can be used to model the state behavior of various system components, not necessarily just software components. Of course, non-software components cannot take advantage of QM's code-generation capabilities. But for software, QM can be a lightweight, no-nonsense, "low ceremony" tool that will get the job done. --MMS
@juanorlando97833 күн бұрын
@@StateMachineCOM Is SysML a modeling language you would recommend for embedded system design or is there a simpler one?
@StateMachineCOM3 күн бұрын
@@juanorlando9783 SysML (similar to the whole UML) is complex, and only small parts are "constructive," meaning elements that can be used for final implementation. Big methodologies like that have been tried and failed because elements that are not useful in the final product are abandoned. Hierarchical state machines are one of the few exceptions because they are "constructive" and can be used to generate production code that otherwise would be error-prone to create by hand. But here again, the danger is that if this feature is not used, state diagrams will get abandoned just like the rest of it. In this sense, automatic code generation is essential for the success of modeling in software. --MMS
@jamesterpaul10 күн бұрын
Anyone using the STM Nucleo C031C6 can help me out? I downloaded all the project files for STM and STM cube, but when I try to build the file I get Error instantiating RTE components Error #545: Required input file from generator STM32CubeMX: 'C:/Users/James/Desktop/Modern_Embedded_Systems/lesson-01/simulator-keil/RTE/Device/STM32C031C6Tx/FrameworkCubeMX.gpdsc' is missing. I set up STMCube in the run time and downloaded the required packages but nothing seems to work.
@jamesterpaul10 күн бұрын
After some messing around and trying to get the original files to work I just decided to use STMCube code generator completely. When using the files from the Github instead just use the code generation from STMCube and copy the main.c function from the Github into the Cube folder and delete the source folder
@luispena574011 күн бұрын
Questions: when you wrote: 1) SYSCTL_GPIOHBCTL_R |= (1U << 5); /* enable AHB for GPIOF */ 2) SYSCTL_RCGCGPIO_R |= (1U << 5); /* enable clock for GPIOF */ I noticed that you didn't comment the 2) for the APB question (1): does that mean that both buses APB and AHB are active? Question (2): can I get away by just enabling AHB bus and not the APB since at the end when we optimized the code with the AHB we end up using AHB registers only? Or do I necessary have to enable both although I am only using one in this video? Question (3): Finally, in this case only one bit was modified at a time. How do you address modifying multiple bit at a time. (GPIO_PORTF_DATA_BITS_R + (LED_RED | LED_BLUE| LED_GREEN )) = (LED_RED | LED_BLUE| LED_GREEN ) will work?
@StateMachineCOM11 күн бұрын
It seems that the APB and AHB in TivaC are mutually exclusive, so you should use one or the other, but not both. The APB is provided for backward compatibility. The AHB is faster and should be preferred.
@luispena574013 күн бұрын
Hi, I have a question. I know you provided the header file "lm4f120h5qr.h". Where do you download this file from? I ask because I may be using a different board and would like to know where to get the header file for a Different processor.
@StateMachineCOM13 күн бұрын
Please google for lm4f120h5qr.h. --MMS
@yanhairen729317 күн бұрын
really really really excellent video. Thanks a lot
@Bharathiyan-g9x18 күн бұрын
This is the best embedded systems programming course I have taken. Thank you Miro Samek.
@peterpolidoro20 күн бұрын
Great video, thanks! Do you have any open source examples of real-world projects, not described in the book or QP documentation, that demonstrate the proper use of these tips? Some examples that show a nice way of organizing a director active object and multiple service active objects along with their state machines would be super helpful. Thanks!
@StateMachineCOM20 күн бұрын
Unfortunately, no. Even though QP is licensed under the GPL, and GPL requires all applications that use QP to be open source, no company has opened up their real-world projects. This widespread non-compliance with GPL is disconcerting.
@peterpolidoro20 күн бұрын
That is disconcerting. You are very generous to provide a GPL dual license for such a wonderful framework. Perhaps the FSF could help you if you know of companies that are non-compliant.
@ashrafkamel128723 күн бұрын
when i tried QP, I faced a little challenge which i hope you could help with First Question : How should I design my HSM when I want to do a different action to the same signal event ex: delay signal / time out the same delay signal I would like to use with different pieces of code in the same state machine wait for input or HW response or user selection etc with the same timeout signal but in a different condition Second Question: compinded events: How to design an Active object when It wait for two or more events to be published un synchronized
@StateMachineCOM23 күн бұрын
First question: a state machine needs different states to react differently to the same signal. For example, a "Blinky" state machine that blinks an LED reacts to the same TIMEOUT event signal differently. One reaction is to turn the LED on (e.g., in the entry action to the "on" state), and the other is to turn the LED off (e.g., in the entry action to the "off" state). Second question: to wait for a published event, an Active Object must subscribe to that event signal. Of course, a single Active Object can subscribe to multiple event signals. Then, whenever one of the subscribed events gets published, it will be "posted" to all subscribers. The events will then processed, starting with the highest-priority subscriber Active Object.
@ashrafkamel128722 күн бұрын
@@StateMachineCOM Thanks for your quick respond. I understood my misconception in the first question thanks Second question: I need to do an action when two evens or more happen ex: GPIO signal 1 is High and GPIO signal 2 is High and Timeout In a real example a state transion is needed when the timeout of the current state is fired and a motor is stopped and a clutch is released those are 3 different event generators that i am subscribed to each would notify alone but I want to servce there notifcations together previously I would use if(timeout && motorisStopped && clutchIsreleased) { //do something } how to make the same with qp?
@StateMachineCOM22 күн бұрын
@@ashrafkamel1287 The status of your GPIO pins are *guard conditions*, not events. So, when your TIMEOUT event arrives, you just check GPIO-signal-1 and GPIO-signal-2. There is a whole lesson dedicated to guard conditions: kzbin.info/www/bejne/iHi0g5-iq9eAr7ssi=62pfV211JxSvaZnq . Actually, you can all your questions by watching the whole playlist about state machines: kzbin.info/aero/PLPW8O6W-1chxym7TgIPV9k5E8YJtSBToI --MMS
@israelkoiku207626 күн бұрын
It's a great video to follow and understand; thank you Miro.
@chandu79826 күн бұрын
Since RAM starts from 0x20000000 and you are trying to push to stack and as the stack grows downwards and it is a illegal memory address so it causes HardFault. And again in HardFault there is one more push and it causes another HardFault and goes on in loop.
@StateMachineCOM26 күн бұрын
Yes, precisely, manually setting the stack pointer (SP) to the beginning of RAM at 0x20000000 is how the fault has been "injected" into the program to test the error handling. But this has an interesting application: it shows you how to *detect stack overflow*! Specifically, if you place the whole stack at the beginning of RAM, overflowing the stack means that the SP would drop below 0x20000000, and from this video, you know that this causes the HardFault exception! Traditionally, the stack is placed at the end of RAM, not the beginning of RAM. But this placement won't detect stack overflow. Instead, the overflowing stack would corrupt the RAM below it. For this reason, I recommend placing the stack at the beginning of RAM. --MMS
@chandu79825 күн бұрын
@@StateMachineCOM if __stackless is not available for other compilers like stm32, then we have to code the Hardfault handler in assembly to check whether the stack is valid or not. if not valid then call NVIC_reset. Am I right here ?
@govindthinks26 күн бұрын
Do i need both the boards for the course?
@StateMachineCOM26 күн бұрын
Yes and no, depending on how you learn and what you want to gain from this course. A few early lessons run in the simulator entirely on your host computer, so these lessons don't require a broad. However, later lessons run only on real hardware. You can still watch and learn from such lessons, but doing the exercises on your own board would reinforce the learning and would give you more confidence that you can actually do it on your own. I hope that this reasoning makes sense to you. --MMS
@bhavaysen28 күн бұрын
Hi @Quantum Leaps, LLC, Dr. Samik, In the example, where you demonstrated the comparison, there will be an issue. if ( (uint32_t) u32e > -1 ){ u8a = 1U; } else { u8a = 0U; } what will be the result when u32e = 0xFFFFFFFF ? This becomes a bug in the code, or there is some solution to this? please share and thanks for the lectures, these are too good and helpful.
@fredo51428 күн бұрын
About tip #2, does it really matter to reserve a range? I’m thinking that as long as the next group is keyed off the max of the previous one, you’ll be able to add and remove entries and just push around what comes after.
@mattheweshleman232327 күн бұрын
Either way will help the project avoid human error. One possible issue with "keying off the max of the previous" is that it means that private signals will be exposed too, since that final private signal would have to be exposed to allow the next AO starting value. If we define ranges only, then it is up to each active object to define the signals within that range, and other AOs can avoid any knowledge of the other AOs. Mixed with a sprinkling of static_assert(...), the build will help protect from overflowing assigned ranges too. These concerns probably mainly apply to large projects where I want to avoid human error and also want to avoid too many inter-dependent modules from a compile time point of view. To some extent, just defining all the signals in a single header would take care of this too. But I just like the idea of: printf("sig: %d ", event->sig); having some clarity/directly by just visually looking at the value of the signal.
@peterbuss790328 күн бұрын
I completed lesson #29 OOP Part 1. In your demo you used blinky1 process and the others but it's not in the available lesson code. I prepared your demo code and get a linker error assert_failed missing symbol by startup_tmc123gh6pm.o (Error L6218E). assert_failed is defined at the end of bsp.cpp. I was unable to find a solution for this up to now. I read several articles on missing symbols.
@StateMachineCOM28 күн бұрын
This lesson #29 about OOP only starts with the previous lesson #28 with some "blinkys", but it changes that code entirely to use "shapes" (the Shape base class and subclasses). Therefore, the project downloads for this lesson no longer have any "blinkys" and no longer run on real hardware; instead, they use the Simulator. Please download lesson-29.zip from the companion web page: www.state-machine.com/video-course . Actually, any time you run into problems like this, please just download the corresponding project. Then you can compare that known-good project with your own and see precisely where you differ. I hope this makes sense. --MMS
@theangelofspace15528 күн бұрын
It would be good to add QP definition to the title so people know what is the video about. I tuned because I love the channel's content, but I have not clue ehqt the video was about, or what you were talking about when you said "QP". If the video is aimed to a specific audience I guess it is ok.
@StateMachineCOM26 күн бұрын
The video description has been modified to contain a definition of QP Frameworks.
@jamebounes28 күн бұрын
Should the entire program be managed as a state machine or should the program be organized as a combination of multiple state machines?
@StateMachineCOM28 күн бұрын
It depends on what your program is supposed to do. Simpler programs can indeed be organized as a single state machine. However, a single-state machine can be in only one state at a time, which might not fit your problem. For example, communication software often must handle several communication channels, where each channel can be in a different state, so most naturally each channel should have its own state machine. Another limitation of a single state machine is the run-to-completion (RTC) processing. So, once it starts with an event, it must finish before processing another event. If this processing takes long, other events might not be serviced fast enough to meet your real-time constraints. The solution is to use different state machines running at different priority levels so the long-running RTC steps of low-priority state machines can be preempted by the high-priority state machines. All this means that in practice, you typically structure your programs as multiple state machines and have to deal with concurrency among those state machines. And here is precisely where the Active Object pattern and active object frameworks like QP come in.
@mattheweshleman232328 күн бұрын
I'll just re-iterate what @StateMachineCOM noted. Real world programs based on QP tend to involve dozens of active objects. Each active object has its own state machine. See the section Tip #3 - Define a Basic Software Architecture, where I discuss the top level executor and the N services. Each of those has its own state machine. Some of them might be very simple. Some complex. The drivers may (or may not) also consist of state machines.
@GiaBaoDuong-oz7ky29 күн бұрын
Hi Miro, sorry for my silly question, but I’m wondering-I’ve been looking for the post() function that posts TIMEOUT1_SIG signal in the sst_cpp/examples/blinky file, but I couldn’t find it. Is TIMEOUT1_SIG placed in the queue in some other special way? Thanks for the great video.
@StateMachineCOM29 күн бұрын
The post() function is declared inside the Task class in the sst.hpp header file (located in the Super-Simple-Tasker/include directory). The Task::post() is defined in the sst.cpp source file (in the Super-Simple-Tasker/sst_cpp/src directory). These are the most sensible places to put such a central functionality. --MMS
@bhavaysenАй бұрын
@Quantum Leaps, LLC - Error - Fatal Error : Selected core (Cortex - M0) is not same as the target core (Cortec-M4). Session Aborted! - Using the latest version of the IDE. I tried to do the same, compiled for M0 and trying to upload it in M4 (TM4C123) but getting the below error. Dr. MMS, Please check and suggest some solution
@StateMachineCOMАй бұрын
Indeed, the newer IAR EWARM seems to disallow loading code for Cortex-M0 onto a target reporting Cortex-M4. Unfortunately, I cannot change that. But, the project for the KEIL Vision IDE for this lesson has been updated to compile for the M0, but run on the M4. Please download from the companion page and try. --MMS
@bhavaysen28 күн бұрын
@@StateMachineCOM Thanks, I will try this. I get the hack to do it in IAR. First, I have selected the "core - M0" and build the project. then again selected the Device - "TM4C123GH6PM" now from Projects > Download > Download file. I have flashed the device with M0 compiled .out (bin). Later for debug, I run "Debug without download"
@bhavaysen28 күн бұрын
@@StateMachineCOM Thanks, I will try it. I also managed to do it in IAR. First, I have selected "M0" and build the project. then, again I have changed the "Device : tm4c123gh6pm". After that I downloaded the code into flash with Projects > Download > Download file. To debug the M0 code in M4, I run the "Debug without download option".
@brianmagana4478Ай бұрын
Hello, Mr. Samek. Thank you for your dedication to sharing your knowledge and insight into this field. I have a BS in Computer Science, but no work when searching for work in software development. I learned about embedded systems from some good folks online, so I decided to search for information on the subject. Consequently, I've come across your KZbin channel and I've watched this video, now. I've learned that in this field, one works with low-level concepts and the CPU and hardware directly, which fascinates me greatly. My assembly and CPU architecture classes were some of my favorites during my studies and I'm very excited to learn more and gain some hands-on experience in this field. You have my thanks for all your efforts and dedication to this field and for sharing this with the world.
@duongdavid6732Ай бұрын
Hi Miro, thanks for the great video! You mentioned 'just 2 MHz,' but is it possible to run it at higher frequencies? If so, it would be great if you could show me how to adjust it.
@StateMachineCOMАй бұрын
Absolutely, it *is* possible to run SST at much higher CPU frequencies, at which point the kernel performs even better. In fact, SST will be so fast that it would require a much faster logic analyzer, so the cheap 24MHz analyzer won't be adequate anymore. Now, adjusting the CPU clock is not trivial. It requires adjusting several registers in the clock-control section, waiting for the PLL (Phase-Lock Loop) to settle, etc. There are whole tools (e.g., STM32CubeMX), which allow you to set it up correctly. --MMS
@matthewszklany101Ай бұрын
Has anyone else gotten the error "Error 65: access violation at 0x400FE070 : no 'write' permission" when trying to run the code in the debugger? It seems to have something to do with line 587 in system_TM4C123.c which is: SYSCTL->RCC2 = 0x078027810 I don't think I observed this when I had the board connected, rather I think it may have something to do with the simulator?
@StateMachineCOMАй бұрын
Projects that involve real peripherals, such as the GPIO, generally don't run in the simulator. Perhaps the simulator could be configured to accept reads/writes to the address range starting at 0x40000000, but I haven't investigated it. For these lessons, please just use the real board. --MMS
@JoseLucasdАй бұрын
i didnt understand a shit🔥
@noobprogrammer2247Ай бұрын
Hi Dr.Miros, I am learning about your MiROS series and I want to start a challenge that is implementing the os in stm32f103c8t6 bluepill board, I have been doing the instructions in the video, there was some errors when using arm compiler v5 on my keilc v5.31.0.0 to execute asm code in function PenSV_handler and after searching on Google, reading the comments in the video, I changed the Arm compiler in keilc to v6.14 and change the syntax of asm code that is followed to the code on your Github but there is an error that I can't handle *** Using Compiler 'V6.14', folder: 'C:\Keil_v5\ARM\ARMCLANG\Bin' Build target 'mini-RTOS-STM32f103' linking... mini-RTOS-STM32f103\mini-RTOS-STM32f103.axf: Error: L6286E: Relocation #REL:0 in miros.o(.text.PendSV_Handler) with respect to OS_next_thread. Value(0x17fff3f0) out of range(0 - 0xfff) for (R_ARM_THM_PC12) mini-RTOS-STM32f103\mini-RTOS-STM32f103.axf: Error: L6286E: Relocation #REL:1 in miros.o(.text.PendSV_Handler) with respect to OS_current_thread. Value(0x17fff3e8) out of range(0 - 0xfff) for (R_ARM_THM_PC12) Not enough information to list load addresses in the image map. Finished: 1 information, 0 warning and 2 error messages. "mini-RTOS-STM32f103\mini-RTOS-STM32f103.axf" - 2 Error(s), 0 Warning(s). Target not created. I'm so glad if you know the issue and help me to fix it. Thank you.
@MSKY2113Ай бұрын
You still have a bug in the final code - you should put both lines withing CS as opposed each line separately! As the same race condition can still happen if right after enable inbetween the interrupt occurs!
@StateMachineCOMАй бұрын
Ho so? Please explain.
@artfathАй бұрын
very helpful
@taylorh140Ай бұрын
I feel like the word "blocking" is stretched a bit from its usual context here. Sometimes blocking means that the thing just runs without yielding. Other times it means that interrupts are disabled in that section of code. I almost thought here that by non-blocking a very short operation that runs to completion. But I think it's more blocking and non-blocking has to do with the priority of the operations. I need to look closer but it seems like the Systick holds the event loop and selects the hardware-preemption of possible events, pretty much perfect for RMS/RMA.
@StateMachineCOMАй бұрын
Indeed, the term "blocking" is extended here to mean any form of waiting in line until some external event happens. For example, busy waiting for a time delay is considered "blocking" in this context. Traditionally, "blocking" tends to mean only by a context switch in an RTOS. However, any form of "blocking" should be clearly distinguished from performing computations. For example, some complex floating-point computations on a CPU without the FPU might take considerable CPU time. This happens in line, but this is NOT waiting for an external event. --MMS
@RegularUserOfficialАй бұрын
If I use a cheaper board like Stm32f103c8t6 Arm + St-link V2, will it work for this course? (chatgpt's idea) The mentioned boards are really expensive where I live, and the "combo" I mentioned is like 4x cheaper than any of these boards you mentioned
@StateMachineCOMАй бұрын
STM32F10 won't work directly with the provided projects, which currently are for the TivaC LauchPad and the NUCLEO-C031C6 boards. Maybe the F10 could be added in the future, but it's not there yet. Regarding the cost, it has been always carefully considered in choosing the boards. For example, the C031C6 MCU is advertised as the most cost-effective and as a replacement for 8-bitters. The board is available for $10.97, which is a fraction of any book or paid-for course. I really don't know how to make it any cheaper than that. --MMS
@ArjunPoudel-q3hАй бұрын
Lovely way of explaining sir.
@mattheweshleman2323Ай бұрын
BTW, my HUGE thanks to Miro Samek for enabling this guest video on cpputest-for-qpc. Thank you!
@CanCaglar-r6c2 ай бұрын
Awesome video Matthew! May I ask, in your view, how does QSPY/QUTEST compare to CPPUTEST when testing QPC? I find it difficult to do TDD with the former, as I feel I need to write the code first and not the test just so I can get the qspy output to copy paste it back in for the tests. Would love to hear your thoughts.
@mattheweshleman2323Ай бұрын
Thank you for the question. It has been about 5+ years since I last tried to use QUTEST for a real-world firmware project. Myself and that team at the time decided QUTEST was best for driver level testing OR integration testing, where you might want to test just a subset of active objects at the same time on the target hardware (think IoT network testing). Otherwise, we preferred the approach described in the video. In fact, that same team, on the next project, drove the firmware development almost entirely with this approach. QUTEST was still used some, but more niche/driver oriented tests. From a TDD point of view, where we generally desire fast test execution and fast test cycles, I prefer the approach described in this video.
@larrypage66352 ай бұрын
Hi Miro! Please provide some clarification on the point that "counter variables lives in R0" (what happens if there are more local variables than the cpu registers ). Let me clarify what I understood here, the program runs in privileged mode thus it uses the main stack right? If so the counter with local scope must be in the stack, by making it global moves the variable out of the stack but within RAM (may be in Flash). So how does the variable in stack is mapped to CPU register ?
@StateMachineCOM2 ай бұрын
There is NO requirement that a local variable is in RAM, and the C-compiler is allowed to allocate such variables the way it sees fit. It turns out that keeping the 'counter' variable inside a CPU register is optimal because it avoids memory access. (Every memory access costs at least 2 CPU cycles, and you need LDR instruction to read and STR instruction to write back, which adds up to at least 4 additional cycles for incrementing 'counter'). If there are more variables than registers, the compiler must start using the RAM, but again, there is no strict requirement that the local variables be in certain memory locations. The main point here is that allocation and management of local variables is left to the compiler and you that's precisely why some compilers generate faster code than others. --MMS
@Vish-i7c2 ай бұрын
Hello, is there a new/refresh embedded systems course video series in the pipeline? If so do you recommend to wait for it or go ahead and start on these current videos snd projects?
@StateMachineCOM2 ай бұрын
This course is going to continue with new material, but there is NO NEED to update the first 20-30 lessons. The fundamentals presented in those lessons don't change and remain as relevant today as ever. But even the choice of the hardware (ARM Cortex-M4F CPU) remains absolutely spot on. So, don't wait and waste your time. Just dive in and learn! --MMS
@mr.ayush1412 ай бұрын
Dear Miro Sir, I have a doubt regarding the scheduler, Requesting your guidance for the same. In the designed priority scheduler, if we assume an hypothetical situation where we design tasks such that no task ever goes to blocked and sleeping state, will this case produce starvation for a lower priority task ? since now only the highest priority task runs as it never goes to blocked/sleeping state. For a RTOS is it mandatory for the task to have a OS_delay() like function, to implement priority based scheduling ? Are there any other scheduling based algorithms which will work in this hypothetical case ?
@StateMachineCOM2 ай бұрын
Very good observation! Under the priority-based scheduler higher-priority task *must* necessarily block for any lower-priority tasks to ever run. And yes, there are other scheduling algorithms, where blocking would not be mandatory. For example, many RTOSes allow you to assign the *same* priority to multiple tasks. In that case (and if no higher-priority task is ready-to-run), the RTOS will execute all tasks with the same priority in the round-robin fashion. Such round-robin scheduling based on time slices has been discussed in this course in lesson #24 RTOS Part-3: Automating the scheduling with round-robin policy ( kzbin.info/www/bejne/honCfXevnr2ma7ssi=-4aJeLXt6K5ip2Ij ). --MMS
@mr.ayush1412 ай бұрын
@@StateMachineCOM Thanks a lot for the answer Sir You have very good teaching skills.
@larrypage66352 ай бұрын
Hi Miro! I'm currently using uvision 5 for this course. I could understand that the generated assembly code differs with respect to the compiler used. Here my doubt is IAR shows single MOVS and multiple ADDS on R0 as per the increment but KEIL uses LDR ADDS STR (r1, [sp, #0x00] ) instructions each time the counter increments. Is there any difference here?
@StateMachineCOM2 ай бұрын
That's true that KEIL Compiler-6 at optimization level -O0 generates LDR/ADDS/STR instructions for every increment of the counter variable. If you remove the 'volatile' keyword from the counter variable definition, all optimizations above -O0 (O1/O2/etc) will completely skip the incrementing of the counter. So in the end it seems impossible to generate code like IAR did. This actually shows the power of the 'volatile' specification and that without it compilers are free to optimize that any way they like (including skipping the whole incrementing altogether). --MMS
@larrypage66352 ай бұрын
@@StateMachineCOMThanks! tried that, usual signed integer and optimization at O0 and the generated assembly is same as previous.
@hamzaaslam19992 ай бұрын
One of the toughest video in the series
@StateMachineCOM2 ай бұрын
This video might require a bit more effort to fully understand, but the reward is also higher. Understanding the automatic context switch is your gateway to understanding the RTOS at a much deeper level than is usual in the industry. --MMS
@kimani_michael2 ай бұрын
My blue and green LED blink at a slower interval(at the end of the video when the red LED is switched ON and OFF in the idle thread). I wonder where the bug could be coming from. Both seem to miss a beat with a very low intensity and short blink between the now longer intervals.
@StateMachineCOM2 ай бұрын
In all cases like "my project works differently than yours..." the only sane advice is to compare and see for yourself what's different. Specifically, you should: (1) download the project for this lesson from the companion web-page to this course at www.state-machine.com/video-course , (2) build and run that project on your board and verify that it behaves as in the video, and (3) compare *your* project to the official one. A good free differencing tool is WinMerge (please google for it). The tool can compare whole directories. --MMS
@kimani_michaelАй бұрын
It seems like a hardware problem with my board. This issue does not occur when I switch a different pin in the idle thread i.e instead of switching the red LED(PB14 in my case), I switch PA12 in the idle thread instead.
@ericmarvel1002 ай бұрын
When switching to Keil and STM DK for lesson 3, I found I could no longer step through lines of code in main using debug. No mater which step button I used it would run to the end of program to return 0; line even with breakpoints set. The solution was to lower the optimization like this- go to Options for Target => C/C++ tab => Optimization level.
@StateMachineCOM2 ай бұрын
In all cases like "my project works differently than yours..." the only sane advice is to compare and see for yourself what's different. Specifically, you should: (1) download the project for this lesson from the companion web-page to this course at www.state-machine.com/video-course , (2) build and run that project on your computer and verify that it behaves as in the video, and (3) compare your project to the official one. A good free differencing tool is WinMerge (please google for it). The tool can compare whole directories. --MMS
@hoa.yev.2192 ай бұрын
Have a good day Mr. Samek!
@madhavpatel48742 ай бұрын
I'll try my hand at going through this course on a linux machine. Seems like the tools are there. And if it doesn't work out, that's what dual booting is for
@danielfagbohunlu56262 ай бұрын
Will there be any difficulty installing the usb drivers on a linux machine? I've heard that linux already suppots most drivers
@StateMachineCOM2 ай бұрын
Frankly, I don't know where to find the correct USB drivers for Linux and whether they would work. This course uses Windows as the development host machine because for better or worse, Windows has been historically chosen by the embedded community. Admittedly, this is changing now, but still most embedded tools are designed primarily for Windows.
@PyJu802 ай бұрын
Can I use either my Pi 4b, Arduino UNO or Node MCU, this I also have an ESP whatever its called...
@StateMachineCOM2 ай бұрын
The question "Can I use XYZ board for this course?" is by far the most frequently asked in this course. The answer is NO. To follow along and benefit the most, you need to use one of the supported boards. This strong hardware dependence is precisely the very nature of embedded systems. Embedded software runs on a specific CPU and controls a specific set of peripherals (input/output pins, timers, communication, etc.) Please just watch a few lessons of this course to get a feel of what's all about. --MMS
@PyJu802 ай бұрын
@@StateMachineCOM no problem, I will buy one anyway. Do you need the red one or white or both, sorry I was confused. Also, I get this sometimes, when speak say 'coding language' we use certain terminologies which we personally take for granted. However when talking to a total noob, its best to try to not use those terms, and simplify it a little. Like buy the red one, plug it it, then follow..... Sorry, its just I want to continue the course and get a cert, just the terms are overwhelming in the beginning. Love your content though and will stick with it till the end.
@StateMachineCOM2 ай бұрын
@@PyJu80 The primary embedded board for this course is the TivaC LauchPad (EK-TM4C123GXL). The board is oldish now, but still in production and available from suppliers like DigiKey, Mouser, and directly from TI. If you wish to follow this course most closely, get TivaC LaunchPad. It is based on ARM Cortex-M4F CPU, which continues to be the workhorse of the industry. The other board is the STM32 NUCLEO-C031, which is newer and based on ARM Cortex-M0+ CPU. That board is actually less powerful than TivaC, but has a more modern on-board debugger (ST-Link) and is expected to have a longer lifespan. Project files for the NUCLEO-C031 are provided, but they are slightly different than the projects for TivaC presented in the videos. If you wish to get the NUCLEO-C031 board, please do, but this is not necessary to benefit from the course. I hope this clarifies the situation. --MMS
@premislelewis3947Ай бұрын
@@StateMachineCOM I'm sorry to ask this. Tiva C launchpad and NUCLEO-C031 is hard to find here in my country, only some series from NUCLEO that are available in here ( NUCLEO-F446RE STM32 Nucleo-64 development board with STM32F446RE MCU , STM32 Nucleo G474RE Development Board Microcontroller , and STM32 Nucleo-64 G0B1RE Development Board MCU ) is it okay for me to use one of these boards I mentioned above ? Or should I buy this Raspberry Pi Pico RP2040 ARM Cortex M0+ instead ? I'm very new about MCU ( barely made the LED's blink with Arduino Uno R3 ) so should I really be super duper precise with the board especially with Nucleo or any Nucleo Series is alright to follow this course smoothly ? If i have to be precise ( ARM Cortex M0+) my only choice is to buy the cheap Raspberry Pi Pico RP2040, so is that okay too ? Thank you so much, sorry to bother you on this question, I do really want to use your course as a big step to be an Embedded Systems Engineer.
@gc76552 ай бұрын
Thanks for your exceptional work on this. I have a question that I don't know what is the right way to make a proper transition to the non-blocking paradigm or event-driven programming. If I have three active objects created and each one is linked to a hardware resource for example AO1-Battery Monitor IC, AO2-Actuators, AO3-Battery Charger IC. Of course no active object can access the hardware resource of another active object directly the only way is through events between one active object and another. But it turns out that the hardware resources of each active object are connected to the same I2C bus despite being seen independently in the end they share the same resource which is the I2C bus traditionally a mechanism like the mutex would be used to prevent access but this would cause a temporary block How should this problem be addressed from your experience?
@StateMachineCOM2 ай бұрын
Indeed, the traditional RTOS solution for a shared resource like the I2C bus would be to protect it with a mutex. Unfortunately, this sweeps a lot of problems under the rug. Among others, the behavior of all contending threads (BatteryMonitor, Actuators, BatteryCharger) is no longer "real-time" in the sense that it is impossible to analyze (e.g., with RMS/RMA method). I2C is not particularly fast, so the mutex might be blocking for a very long time. The non-blocking event-driven approach forces you to confront such implicit coupling directly. One option would be to create a dedicated I2C_Broker AO, which would encapsulate the I2C bus so that all other AOs would post events to the I2C_Broker. The I2C_Broker then can resolve any potential conflicts around the shared resource but must be careful to process the incoming events quickly so that its event queue and event pools don't overflow. Here, the "Deferred Event pattern" is quite useful (please google for it). Another option would be to create only one AO that would encapsulate the I2C bus and contain other functionality (BatteryMonitor, Actuators, BatteryCharger) as the "Orthogonal Component pattern" (again, please google for it). With this design, you acknowledge that an AO is really a real-time priority level. Since all the components are only as "real-time" as the I2C bus allows, they all should run at the same priority as assigning different priorities doesn't help in "real-time".
@hamzaaslam19992 ай бұрын
The background music was cool why you have removed that ? :(