Real Time Operating System
The problem with RTOS’s is they always get complicated.
At least that is how they are presented when put out there for everyone to use. To give you easier access to an RTOS, I have taken a different approach for the PSOC 5.
FreeRTOS has been ported to the Arm Processor, and then to the PSOC, and someone bundled the entire demo project and presented it for your consumption on GitHub. The work that was done is masterful, and a credit to the engineer. There is nothing wrong with it, it was just too much to swallow for me on a part time basis. This full fledged, complicated demo is available at https://github.com/idelsink/cypress_psoc_freertos_demo.
That project kept me away from FreeRTOS for a long time. Too Complicated! Especially since the side work is part time. Every time I looked at it, my eyes glazed over.
Finally, I had some “round tuits” available to me, and I spent a week or so on it, full time. I was able to reduce the project down to a minimal size (in terms of bytes in memory and number of files in the project.)
The FreeRTOS project was purchased by Amazon and released under a permissive license by them. The main website is https://www.freertos.org. Please go there to download their PDF manual and find answers to questions as you use the FreeRTOS in your projects.
The project I created to give easier access to FreeRTOS on PSOC 5 is on GitHub at https://github.com/wmaxfield/FreeRTOS-Minimal/tree/master. That project, when zipped, is large (about 6 megabytes) but only because I kept the original demo files in case you need them. If you wish to reduce the number of files in this PSOC implementation when making your own projects, you can remove almost all of the directories in the Common folder, except for the “include” directory (keep all files there), and the “Minimal” directory (which has one file (LEDflash.c) that you need to keep). All other files can be deleted.
The easiest way to get the project from GitHub is to download it as a “zip” file and unzip it wherever you want. Rename the FreeRTOS-Minimal-master folder as you wish (i.e. MyProject), and rename the project inside the folder using the PSoC Creator rename functions. The project was saved with PSoC Creator 4.2.
Please note that PSoC Creator 4.3 has issues with USB when being used in a virtual machine, along with the fact the KitProg driver for PSoC Creator 4.3 fails to recognize the KitProg on Windows 7 quite often. The unrecognized KitProg is listed as one of the issues in the update Readme file. If you use this project on Creator 4.3, you may have to downgrade the PSoC programmer to the previous version, as indicated in a previous blog post.
Brief Tour of the FreeRTOS Port, and RTOS in general
An RTOS layout consists of many “main loop” functions which are called tasks. These functions have a “forever loop” (in C, it is usually a for(;;) { } construct). Once the forever loop begins execution, the code flow never leaves the loop. At least that is how it looks to the untrained eye.
The heart of an RTOS is a timer. In my years of doing real time software, I always have used a millisecond interrupt. This interrupt allows me to know how long the processor has been running, and allows me to time events, or cause events to occur at regular times. (See the posts from the beginning of this blog.)
An RTOS uses the timer, which can be faster than 1000 times per second, to yank control away from one forever loop (aka task) and give it to another forever loop (task). Years ago, I wrote a very simple RTOS which called each task as a function, so each task had control of when it stopped execution. This is known as a cooperative OS. (Think Windows 95, 98, original Mac Finder.) But the overall ideas are the same.
Each task’s duty in that RTOS was to get its work done as quickly as possible and return to the operating system main loop. You should also follow this pattern with your task design, executing as quickly as possible and returning to the RTOS to allow it to “switch” to your task when an event occurs. If you do this, your RTOS design will usually work well, without having to tweak it very much. You generally do this waiting by calling a Semaphore Wait function or Queue Wait function.
The RTOS that I created (in a few hours) had a main loop that was the task switching mechanism. It sent messages between tasks, skipped tasks that did not need to run, and arbitrarily ran tasks upon events or messages. It is still in use, running on sensor gathering equipment for the last 30 years. It currently runs on a 10 mhz 386 processor, which is much, much, slower than a 25 mhz Arm processor, for most everything, even taking the clock speeds into consideration.
In an interrupt driven RTOS design methodology, the task usually does not control when it stops executing. It can override the RTOS, preventing it from stopping the task, but it should only do so under specific circumstances, which you as the designer fully understand. However, for most situations, the design of the system prevents unexpected stopping of execution.
This design methodology is controlled using Priorities. In general a Higher Priority Task (designated by a larger number) can and does interrupt a Lower Priority Task (designated by a smaller number) and the high priority execution will not stop until it is finished with its job.
So, what can cause a High Priority Task interrupt a Low Priority Task? Events! These events can be things like a button press which give an interrupt which causes the RTOS to execute the higher priority task (also known as a task switch). These events can be posts from other tasks which were decided by software. The controlling mechanism for these task switches is grouped into several categories.
The first category is a semaphore (also known as a flag). If a high priority task is waiting for a flag to be set, its execution is halted by the RTOS until the flag is set (usually by code in an interrupt), and then is resumed. An important rule to follow for semaphores is only one place in the code sets a semaphore and only one place in the code resets the semaphore.
Another is queues. A queue can be thought of as an array of integers that can contain the addresses of memory locations, and thus can “point” to any type of value. Queues can be “first in, first out” (FIFO), or “last in first out” (LIFO). Your task will wait (sleep) on a queue or semaphore and be “woken up” (execute) when a post is made to the queue or semaphore.
There are other control mechanisms available to RTOS system designers that I will not cover. However the two I have mentioned are sufficient for everything I have done in the last 50 years or so. At one time many thousands of land line phone calls were handled each year on equipment running software designed with queue and semaphore mechanisms, using message based system design.
RTOS Design Paradigm
Queues also allow the transition to a methodology of design that allows Real Time Operating Systems to be easily designed and debugged. This methodology is called message based system design. This design methodology uses structures to pass messages from task to task, from interrupt to task, and from the outside world to tasks via communication channels. These messages can also be considered events, and are acted upon the system to get work accomplished.
In the FreeRTOS-Minimal project, one or more characters from the micro-USB connected USBUART port are packaged into an individual structure (which becomes the format for a message) and sent to the Terminal Debug Task. This task takes these message structures and pieces the characters together until a complete command is gathered, and then acts upon it. (See TerminalDebug.c, along with USBSerial.c)
The mechanism for passing messages around is using a queue. The sending task pushes a message pointer onto a queue. The receiving task is waiting upon that queue. The RTOS hands the pointer to the message to the receiving task at the time is wakes it up to execute.
As you have probably deduced by now, the message can come from inside the CPU, or from outside the CPU. It can be sent over RS232, radio, the Internet, or even decoded voice. This allows you to add more processors to get work done if your CPU is overloaded. Or it allows a hacker a way into the system. Everything comes at a price.
FreeRTOS-Minimal
The project you download from my link has two tasks included. Both are communication tasks, one with the USB port (based, in part, on the USBUart shown in the previous blog posts) and one with the RS232 UART which links to the USB Uart on the USB Finger Debugger on the CY8CKit-059. If you break the debugger off of the board, you can use the pins P12[6], P12[7] to communicate to another processor.
This FreeRTOS-Minimal project is the seed project for my attempt to get an old 3D printer working; back from the dead so to speak. I will start laying out this project over the next months. I cannot guarantee that I can get it to work, but the project will be entertaining, and hopefully usable by some. That project will be under GPLV3, but will contain only MIT/Apache code from others, and my own code, so a commercial license will also be available. (I still need to eat.)
Posts and Future
Recently, a tremendous amount of spam has hit this blog. Evidently it is being referenced by at least someone. So, if you post a question, please be patient, I will approve it and answer it after a day or two.
Enjoy!