#27 RTOS Part-6: Synchronization and communication among concurrent threads
HTML-код
- Опубликовано: 19 янв 2019
- This sixth lesson on RTOS talks about the RTOS mechanisms for synchronization and communication among concurrent threads. Such mechanisms are the most complex elements of any RTOS, and are generally really tricky to develop by yourself. For that reason, this lesson replaces the toy MiROS RTOS with the professional-grade QXK RTOS included in the QP/C framework, parts of which have been used since lesson 21. The lesson demonstrates the process of porting an existing application to a different RTOS, and once this is done, explains semaphores and shows how they work in practice.
Articles mentioned in the lesson + recommended reading:
-------------------------------------------------------
Edsger W. Dijkstra "Cooperating sequential processes", Lecture Notes EWD123, 1963
www.cs.utexas.edu/~EWD/transc...
Jack Ganssle "A Guide to Debouncing, or, How to Debounce a Contact in Two Easy Pages"
www.ganssle.com/debouncing.htm
------
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...
Preemptive Dual-Mode QXK Kernel:
www.state-machine.com/qpc/arm...
Transcript of this lesson:
www.state-machine.com/course/...
Music credits:
The background music comes from:
www.bensound.com/royalty-free... Наука
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
Just in case anybody else is having problems with compiling:
Make sure the compiler is version-6
When adding ports : use armclang instead of arm.
In the path add the following --> ;..\qpc\ports\arm-cm\qxk\armclang
Also in the main.c file , just after include directives add the following --> Q_DEFINE_THIS_FILE
If you are getting 100s of errors, which are inline function --> change the c language standard to c99.
After that all good !! , and another brilliant lesson!!
Hope this comment gets to the top, it was super helpful
Some viewers have reported that the KEIL uVision debugger stopped working and now mysteriously quits every time they try to open it. This is a known problem with an easy fix, which is described in the Application Note "Troubleshooting Problems with TivaC LaunchPad Board", available for download from the companion web-page to this course at www.state-machine.com/quickstart/ --MMS
your explanation is crystal clear..please upload videos asap sir. following this series from years
This serie of videos is great information. Thank you for sharing your knowledge.
Thanks you. Can't wait for next lesson.
Best ever! Really appreciate your effort!
Priceless! Many thanks 🙏🏽
it is the Best Embedded Programming Article in the World
RTOS master class!
Oh my god. Where was your channel?
Such a great usefull resource you are.❤️
Great video sir. Very well explained and easy to understand. Please upload sooner :-)
thanks for sharing all this knowledge with us we appreciate your efforts. and we will more thankful for you if you can explain for us how to code that semaphores or the logic behind it
Thanks a lot Mr Miro
Thank you!
Thanks from China
Please make a video on bootloader
Hello. I'm a beginner to programming microcontrollers and embedded systems. (although I do have background in C). I'm considering this series as a starting point. Does it cover (or will it cover in the future) the circuitry aspects and actually interfacing to things?
No, the main focus of this video course is embedded software, not hardware. The aspects of interfacing to the hardware will be discussed only if this is necessary to understand a bigger point in the code. But to learn more about the hardware, you probably need to look elsewhere. --MMS
So the kernal aware interrupt means that when the critical tasks are still ongoing, then the interrupt prep (loading context to stack) would be delayed but no longer than the maximum delay time.
Yes. "Kernel aware" interrupts are those that cannot preempt critical sections of an RTOS. This means that servicing of such "kernel aware" interrupts might be delayed by the duration of the critical sections. The maximum such delay is the longest critical section in the system. Therefore, it is important to keep *all* critical sections as short as possible. --MMS
where can I find the QPC file? I don't see it available in the lesson 26 section on the companion page anymore
The lesson-27 project has been updated according to the new project structure explained lin lesson-0. The project is now self-contained and already contains the qpc framework (inside the lesson-27.zip archive). In fact, it contains also FreeRTOS and other things. Please just download, unzip, and open the selected project in KEIL uVision. It should compile cleanly. --MMS
Hello, I've been following your RTOS lesson on my STM32F407G Discovery Board and I'm running into an issue with qpc. In particular, I get an error for each QXTHREAD_START that says "identifier 'Q_this_module_' is undefined". I have tried re-downloading qpc and have double-checked that I added the necessary files to the project but this issue persists. Any help would be appreciated.
First, if you see any problems like this, please compare your code to the official download from the companion web-page to this video course at: www.state-machine.com/quickstart/ . The highly recommended, free utility for code differencing is WinMerge (you can google for it). But anyway, you will notice that the official code contains the line "Q_DEFINE_THIS_FILE" right after the #include directives. Again, you can just google for "Q_DEFINE_THIS_FILE" to see the documentation, but this macro defines the `Q_this_module_` string constant. This constant is then used in all assertions to report the name of the module (and "QXTHREAD_START()" uses an assertion internally). Also, for more information about assertions in embedded systems, you might want to read my article: barrgroup.com/embedded-systems/how-to/design-by-contract-for-embedded-software --MMS
@@StateMachineCOM Thank you for the quick reply! This did end up working, and I appreciate the added resources. Your guides have been immensely helpful and I look forward to completing the rest of this lesson now.
Hey Miro,
I am curious about the write to the ICR register. You write all ones to clear all the bits in RIS, and it makes sense to me that that works if you have just one interrupt source.
However, intuitively it seems to make more sense to me that just write 1 ICR = 0xFFU; ? Is GPIOF_AHB->ICR = (1
I haven't used the interrupt aspect of the TivaC GPIO design enough to answer your detailed questions. All I needed for this lesson was a user-triggered interrupt that was intentionally "bouncy" with potential glitches. The raw GPIO interrupt for the user-button filled the bill. But frankly, I would *never* use such a GPIO interrupt in any real project to determine the presses and releases of a button. For that, I use (and demonstrate in the future lessons) switch "debouncing", which is a form or digital filtering of the raw GPIO line, in the periodic SysTick interrupt. I hope this makes sense to you. --MMS
@@StateMachineCOM Thanks for your reply!
Hello there,is there any way that i could follow along in IAR workbench?i've been spend so much time on just running error-free,i've followed along all the way from lesson-1,it worked perfectly fine until this lesson,it would be really helpful if you could give us some help,thanks in advance.
Yes, you can now use IAR (as well as Makefiles for GNU-ARM) to build the projects for the whole RTOS segment (lessons 22-27). Specifically, all the projects for lessons 22-27 have been augmented by adding the project files for IAR EWARM (as well as Makefiles for GNU-ARM). Also, some files (like miros.c) have now versions for IAR (miros_iar.c) and GNU (miros_gnu.c). The projects for lessons 22-27 have been updated on the companion web-page to this course (www.state-machine.com/quickstart/ ) as well as in the GitHub repository: github.com/QuantumLeaps/modern-embedded-programming-course . You should be able to download from any of these sources and directly build the projects with IAR (and GNU-ARM). --MMS
@@StateMachineCOM Hi Miro,problem solved,thanks for the help.I have one last ask though if i may,i am wondering if you could point out to some learning directions,how should i go further from here?I'm a guy who will only go further when i think i grasped the essence of things at least in learning part,i spent accumulatively 70 hours in the past week on your RTOS series,now i could draw the flow diagram directly on the paper of how threads switchover and write the same code like "Miros",so like when you say they actually exist in different part of memory address areas with the trick of having their own "SP pointer",it totally spots on.
I wish you could point to me something,but it's fine if nothing on your mind at this moment,i'm genuinely super grateful for your sharing.
Thank you for these videos. They are very clear and helpful. I have ported the code for this lesson to an NXP part, LPC1343. When I tried to run the code QXThread_delay blocked forever! I changed the tickRate parameter in QXThread_ctor to 1 and found that it worked. However your code has the tickRate set to 0. Why is there a difference?
QXThread_delay(...,tickRate) blocked forever is typically indicative that the matching QF_TICK_X(tickRate) is not called periodically. Specifically, if you associate an extended thread with tickRate==0, you need to periodically call the QF_TICK_X(0). From your description, it seems that you're periodically calling QF_TICK_X(1). Please check in your code! --MMS
@@StateMachineCOM Thank you, that was a very quick response! I just checked my code and you were right. My SysTick handler was calling QF_TICK_X(1) instad of QF_TICK_X(0). I have changed it and the code is running nicely.
Hi. Thank you for hi quality lessons. Can you ansver one question. With RTOS i need to compile my application code with this OS. But i try to create system where some core is already on chip and i just compile and download only my application. For now i compile my app code with "fPIC " key that creates relocatable byte code. And if i need call some core function from my app ( like SYSCALL) i put pointer to that function in defined place/adress and than i can call it. But can i use linker ( LD ) for automatic address replacement in byte code or some other way to create downlodable byte code that i can run on chip? Something like big OS where you don't need to compile OS with your app code to run it, OS/core is always on machine.
RTOS code typically links right with the application, and the combined binary is programmed into the flash ROM of the MCU. Loading the application separately and independently, as you do this in "big" operating systems such as Linux, is rather unusual in deeply embedded applications. But, it is theoretically possible. The ARM processor provides even a mechanism that could be used for this in the form of the SWI (Software Interrupt) instruction. The SWI instruction is specifically designed for "system calls". It works similarly like the INT-21h mechanism in Microsoft DOS, if you are old enough to remember. An example RTOS for ARM Cortex-M that makes extensive use of the SWI mechanism is the RTX RTOS from Keil-ARM. But even RTX links directly with the application code. --MMS
@@StateMachineCOM Yes i remember about software interruption it's useful for switching to superuser mode(don't know how it's called) for isolation application code exactly like in OS. Actually i was able to compile download and run relocatable code. My main problem that i can not solve is how to explain what i did and where i load this relocatable code in memory to GNU Debugger. I want to debug this 'user application' that i compiled separately in chip.
In order to partition your code into operating system image and a separate application image you need to prepare two different linker scripts (.ld files) for the GNU-ARM compiler. These two linker scripts must ensure that both the operating system and the application would have non-overlapping ROM and RAM regions. --MMS
If I got you right I think ESP has some kind of linker scripts to solve your problem, check them. You need to provide symbols to your application linker script to get correct function calls. I hope I got you right. github.com/espressif/ESP8266_RTOS_SDK/tree/master/components/esp8266/ld
EDIT: Is it really worth it for your application to have different flash regions for core application. Does this core code is big or why it can not be linked each time you build your app?
@@kesmik Yes, thank you. I will look in to it. When i tryed to make it work, i looked into ld scripts, but for that time it was far beyond my comprehention. But for user code to know where to look up core SYSCALL functions addresses it doesn't matter if linker put correct address to byte code while linking or it will be hardcoded in to code while compiling. Of couse it matters if you change addresses of this functions. Actually from safety reason ( if user code can be malicious) it's better to make SYSCALL thrue software interruption, as Miro Samek(if i spelled it correctly) / Quantum Leaps supposed, but if you have a lot of syscalls it's quite costly. But anyway i still have problem with debugging. I was not able to connect linker (that knows where it puts code and different functions /DWARF info) and debbuger that needs this info for work. I think i just need to work deeper on this.
And about reason. I was thinking about system where external user can compile code for device but don't have source code for core/"OS". Someting like industrial programmable controller. I can create simple byte code machine but i dont want to create another language and it can be much slower. Why just don't use "C" language and compile it.
Hello,
Thank you for these nice videos.
Do you recommend a book which explains these concepts??
To my knowledge, the particular, low-level approach to explaining the RTOS is unique for these videos. But once you understand the basic concepts here, you might be better prepared for the generally available literature. If I were to recommend one book on RTOS, this would be "Micro-C/OS" by Jean Labrosse. Various editions of this book are available for free download in PDF from www.weston-embedded.com/micrium-books . --MMS
At around time 24.00 while explaining the semaphore objects waiting semaphores are saved in bitmap. Does it mean that the signaling of currently acquired semaphore will let the highest priority waiting thread to unblock and not the least recently blocked thread? In other words, the order of unblock is based on the priority of thread and not FIFO? Please clarify. On separate topic, can counter value in semaphore object become negative as more threads wait on semaphore? That also means, the absolute value of negative count value tells the number of threads that are currently waiting to acquire the semaphore.
First question: In case multiple threads block on a given semaphore, once the semaphore gets signaled, it will unblock the *highest-priority* thread. So, the order of releasing the threads is based on thread priorities and NOT the most recently blocked thread. Second question: the semaphore counter cannot become negative. If a semaphore count is zero and a thread calls wait() operation, the thread is *blocked* and the counter is NOT decremented below zero. That's the whole point of a semaphore. --MMS
@@StateMachineCOM Thanks a lot for clarifying the doubt.
Hey, In one of my assignments I have been asked to implement the following:
A virtual COM power using a 115200 baud, 8N1 protocol with no hardware handshaking.
For this design, you must set the ASP bit in the CONTROL register so that the thread code uses the PSP
(the handler mode will always use the MSP).
Can you please help me how can I set it, in C code.
Can you explain how to digital image processing in a RTOS, which processor may using?
Can you explain what you mean by "digital image processing"?
Working a finger base controlling small vehicle, with the help of digital camera. each finger represents speed and direction of the vehicle.finger is pose the camera then chenge the direction of the vehicle
In this project can use RTOS?
many thanks, but when i try to build the example i can't find the arm qxk_port.c file for arm toolchain to build it on keil so what should i do??
The ARM/KEIL Compiler 5 is now obsolete and the newer versions of KEIL uVision no longer install that compiler. Instead, they come with the new Compiler 6 (a.k.a. armclang). To match these changes, the qpc framework also switched to armclang, and therefore the QXK port to the obsolete ARM compiler 5 has been removed. I will update the projects for all affected lessons and will put them on the state-machine.com/video-course website as well as on GitHub (github.com/QuantumLeaps/modern-embedded-programming-course ). I'm sorry for the problems with the current versions, but this is the cost of progress. --MMS
@@StateMachineCOM I love you man, I just love you because you so so so smart.
Excellent videos Miro! I was able to get a clean build by modifying three things 1) Change the include folder entry from "..\qpc\ports\arm-cm\qxk\arm" to "..\qpc\ports\arm-cm\qxk\armclang". 2) import the qxk_port.c file from the changed directory in step 1. 3) Made sure my ARM Compiler was set to 'Use default compiler version 6'.
All ARM/KEIL uVision projects have been updated for the new Compiler-6. You can download them either from the companion webpage (as the lessonXX.zip files) or from GitHub (github.com/QuantumLeaps/modern-embedded-programming-course ). --MMS
What configurations would you need to use with the Logic Analyzer for the STM32?
The project download for lesson #27 has been updated to include project stm32c031-qxk-keil (STM32 NUCLEO-C031, QXK kernel, KEIL IDE). The download is located in the usual place: www.state-machine.com/course/lesson-27.zip --MMS
@@StateMachineCOM Thank you
Using other's creation will loss the opportunity to perform your own creativity. Is QP/C the best for its claimed purpose? Is there any peer competitor or better one available for free ?
QP/C is an example of modern embedded software architecture. It could well be the best software for the claimed purpose. And also QP/C is free software licensed under the open-source GPL license. To my knowledge, QP/C (and QP/C++) are the only truly open-source frameworks of this kind. All other frameworks of this kind (e.g., the OXF or RXF for IBM Rhapsody) are proprietary. --MMS
@@StateMachineCOM Thank you so much for your great work! I’ve got so much to learn, got a long way to go. But luckily to have you as my first Embedded teacher. BTW, I will receive my launchpad and usb logic analyzer in 2 days. Excited 😃
1st floor!
Hi Miro