Do you need a real-time operating system? Real-time operating systems for beginners Micro operating systems on avr controllers

This article focuses on the real-time operating system (RTOS) called SYS/BIOS (formerly known as DSP/BIOS) from Texas Instruments and its use on the ultra-low power 16-bit MSP430 microcontrollers. The article provides general recommendations on the use of an RTOS, and also indicates in which cases the use of an RTOS is wasteful or simply impractical.

Are you planning to use less than 1KB SRAM and 2KB Flash? Will your application perform only one task without communicating with the outside world, and at the same time you do not plan to increase its functionality? Then perhaps you should stop reading the article here and continue working on the project. The advice in this article is unlikely to be useful to you and will only take up some of your precious time before launching the product on the market.

For some reason in the world of embedded software Over and over again you can see a situation where the creation of appropriate software for a new project starts from scratch. But we should have known for decades that the key to increasing efficiency is reuse. And while code formatting standards in object-oriented programming can provide reuse benefits, let's face it: how much C++ code have you seen on, say, 16-bit microcontroller platforms? Most of the code is written in C and is still available a whole series low-level assemblers, but only a minority are truly expressed in C++.

There's one more thing I want to point out before we get into the technical details. Do you agree with the idea that new project represents a good opportunity to get rid of this old, huge, error-ridden spaghetti code due to historical reasons? Code that researchers and developers spent years copying and fixing. recent years a lot of effort, and yet only a few of them know (but cannot explain) how this monster is even able to perform its functions? You're probably right that a new project is a great opportunity to start over, but have you ever asked yourself how the code managed to last so long in the first place? With changing requirements at the stage of software creation, the need for new intermediate elements, without following uniform guidelines for code design and standardized interface definitions, without debugging and analysis infrastructure to increase test coverage. So, if your target application will run at least 3-4 various tasks including possibly real-time operation, and also involving communication with some external part of the system, you should seriously consider using an RTOS.

There are many RTOS solutions on the market, both in the commercial sector and from non-commercial free and open source software developers. Alas, it is quite difficult to tell a software development specialist that one RTOS is better than another or that one system is good and another is not so good. However, there are a number of basic general requirements to RTOS, which can help software developers determine the functions and capabilities of a particular RTOS. Finally, the necessary evaluation of functions can only be carried out taking into account the actual end application. So, again, successful software development largely depends on how well you know and understand the target application; object-oriented programming and real-time operating systems are no substitute for sound requirements engineering and system design.

Commercial aspect of the SYS/BIOS system

In general, there are two criteria for choosing an RTOS. On the one hand this technical specifications RTOS, on the other hand, the commercial aspect of implementation. In the case of a SYS/BIOS system, the commercial issue is not an issue. There is no additional cost for the SYS/BIOS system as it is provided free and open source by Texas Instruments under the BSD open source license and thus does not require any permission fees.

SYS/BIOS System Specifications

The Texas Instruments Wikipedia web page states the following: technical description SYS/BIOS systems: “SYS/BIOS is a scalable real-time kernel. It is designed for use by applications that require scheduling and synchronization or real-time instrumentation. The SYS/BIOS provides preemptive multithreading, hardware abstraction, real-time analysis, and configuration tools. The SYS/BIOS is designed to minimize memory and CPU requirements in the target application" ()


Rice. 1 Graphical configuration

These proposals cover all the key factors: scalability, portability, operational tools, real-time operation, and provision of development and analysis tools. An important aspect is the size or amount of memory occupied. Thanks to optimized configuration technologies, the SYS/BIOS system is able to reduce its flash memory requirements on MSP430 microcontrollers to less than 4 KB. Depending on the configuration (equal to the specified elements used), only the SYS/BIOS kernel code is compiled necessary functions. SYS/BIOS is provided as part of the Code Composer Studio (CCS) version 4 and 5 integrated development environment. Static configuration of the SYS/BIOS system can be done within the CCS environment using a convenient graphical configuration tool. You can choose which software modules to enable, change default parameter values ​​to customize the behavior of the target application, and create RTOS operational features such as threads and semaphores. For larger, more dynamic systems, all of these functions can be performed using live C APIs. Dynamic SYS/BIOS configuration provides application flexibility, while static configuration can improve performance and reduce memory footprint.

However, systems that work well on 32-bit platforms will also be compatible with a select range of 16-bit microcontrollers. The overlap of platforms is quite large, and both of them can successfully use an RTOS as a software foundation. New functional nodes make it possible to increase the number of elements, increase complexity, and also place more memory on a silicon chip of the same format. At the same time, the speed characteristics of the processors also increase, and all this can be successfully abstracted using a suitable RTOS solution. By providing a certain level of hardware abstraction, the SYS/BIOS system makes it possible, for example, to write all interrupt handling routines in C, which makes it easy to transfer code between microcontrollers, ARM microprocessors and digital signal processors from Texas Instruments. In terms of operating capabilities, the SYS/BIOS provides a wide variety of thread types to suit a variety of application situations. By selecting appropriate thread types, you can control execution priorities and blocking characteristics. In addition, the SYS/BIOS system offers various structures to support communication and synchronization between threads, such as semaphores, mailboxes, events, gates, and variable-length message exchange. The execution time in a particular RTOS, as a rule, depends on the interrupt latency, context switch time, and some other kernel performance indicators. Thus, to ensure that applications reliably meet deadlines in real time, virtually all SYS/BIOS kernel issues provide deterministic operation. Last but not least, the Code Composer Studio IDE comes with a set of tools that help the user find and fix problems while working. Dynamic Object Viewer (ROV) and Real-Time Analysis (RTA) are Eclipse-based data visualization tools that collect native instrumentation data recorded by the SYS/BIOS, for example to display execution sequence graphs. However, debugging instrumentation can be tuned or removed entirely from the final product code to maximize performance and minimize memory footprint.

Adapts to MSP430's ultra-low power intelligent programming techniques

A typical MSP430-based application where power consumption is important follows a standard code flowchart. The MSP430 Programming Techniques application report (SLAA294) from Texas Instruments details how to take advantage of the power-saving capabilities of MSP430 microcontrollers by applying appropriate programming techniques. Figure 2 generally shows a typical code block diagram. top level for ultra-low power MSP430 based applications.


Rice. 2 High level code block diagram

The code structure is interrupt driven because this provides the greatest opportunity to power down the device. Until an interrupt is received, the device remains idle, thus maximizing power efficiency. In order to understand how the interrupt service routines (ISRs) shown are implemented, it makes sense to recall the way the MSP430 microcontroller operates in low power modes. Power modes are controlled by bits inside the CPU's Status Register (SR). The advantage of this is that the power mode activated before the ISR is executed is saved onto the stack as part of the initial interrupt handling. When the ISR procedure resets this value upon completion of execution, program flow returns to this stored power mode. By operating the stored SR value on the stack from within the ISR procedure, it is possible to redirect program execution after the ISR to another power mode. This mechanism is integral to the low power operation of the MSP430 as it enables the device to turn on quickly in response to an interrupt. The MSP430 SYS/BIOS makes it easy to use this standard programming method and also provides a power module that can be used to automatically idle the CPU when there are no threads ready to run. When the power module is enabled for this operation, it automatically inserts a function into the SYS/BIOS idle cycle that activates the specified low power mode. The CPU will remain in this mode until a hardware interrupt is triggered, which will bring the CPU into the active state.


Rice. 3 Suppressing interrupt ticks

Speaking of energy savings for the MSP430, it is worth mentioning another advanced RTOS technology. Like many other RTOSs, the SYS/BIOS system provides various timing services to trigger certain events at specific points in time. For this purpose, on MSP430 microcontrollers, the SYS/BIOS system uses available peripheral timers. Using ultra-low power built-in timer functions, the SYS/BIOS automatically eliminates unnecessary interrupts in the form of timer ticks to maximize idle time and therefore reduce CPU power consumption. The ability to suppress each interrupt that is executed using this technology directly saves operating power consumption. Figure 3 shows a typical RTOS implementation compared to the SYS/BIOS intelligent tick suppression technology. In the standard implementation, interrupt routines are sent even when there is no need to trigger an event, while the SYS/BIOS intelligently configures the MSP430 peripheral timer to trigger interrupts only when action is required for further processing.

With that said, now may be the time to consider using a SYS/BIOS system for your next MSP430-based project - or any other TI processor that suits your application requirements.

About the author

Wolfgang Luch is a tool engineer for the MSP430 microcontrollers for a company in Freising, Germany. He holds a Master's degree in electrical engineering from the University of Applied Sciences in Leipzig, Germany. During his eight years at Texas Instruments, he contributed to the design of numerous MSP430 ICs and worked on MSP430 tools such as the eZ430 low-cost development tools. Specializes in JTAG programming of MSP430 microcontrollers, flash memory programming, and embedded emulation architectures and principles.

What comes to mind when you hear operating system? Probably windows, Linux, MacOS... or something similar. That’s right, and when asked why it is needed, everyone will confidently answer: listen to music, play a game (on the Internet!), while talking with a friend on Skype. At the same time, contemplating how the LED blinks, having received a byte from the computer =).

And if you dig deeper, listening to music, sending data over the Internet are all single processes, and since we have one processor, it can only perform one task at a time. Therefore, tasks are performed one by one in small “portions”, the essence of the OS is to do this unnoticed by the user: so that the sound does not wheeze and the bytes are sent and everything works at the same time. At the same time, if one of the tasks “hangs,” then everything else continues to work.

If we discard all the extra goodies and leave the bare essence, then first of all the OS is just a timer that counts equal periods of time, and also switches between tasks without user intervention, performs some part and switches again. You also need to take into account that most tasks may not be completed in one time slice, so you need to save the state of the task at the time of switching to another, and restore the state of the variables the next time. All this is managed by the task scheduler.

There are two main types of OS: preemptive and cooperative. In the first case, switching between tasks will be “hard”, i.e. if the time slice is 1ms, then first the first task will be executed for exactly 1ms, then the second for exactly 1ms, etc. Such axes are called real-time axes (RTOS). Cooperative ones are a little simpler; the process itself must say that “I have completed it,” so they cannot be classified as an RTOS.

It will not be possible to transfer the preemptive one to small AVRs due to the small amount of RAM. Of the available cooperative options, I liked mRTOS; you can read the details of this system on the author’s website (easy to Google). Main reason its use - simplicity, availability of a ready-made version for CAVR, for easy understanding general principles that's it.

So, the main questions remain: why and when to use the axis. Theoretically, everything is the same as what you do with the axis, you can screw up without it, because the resources are the same. Just because you adapt it to the project, megahertz will not fly into space, the hardware will remain the same, therefore the resources are the same.

So it's worth asking yourself a few questions:
1.Can you manage resources wisely?
2. Is it possible to reinvent the same wheel, similar to a scheduler, in the process of writing firmware?
3. How readable is your code? Are you able to open it in six months or a year and figure it out right away?
4. Do you write alone or in a group?

It’s difficult to answer the first question, because everything depends on the developer’s cunning. With the second, everything is more clear: if there are many independent tasks and they are planned to be executed at certain intervals, then it is better to look towards the OS. The third one is also clear; it’s much easier to understand a separate task than to pick dependencies in the main loop. If you are not writing alone, then there are also advantages, because everyone can write their task separately, without interfering with others.

Combining the above, the scope of application is quite specific, for a certain range of tasks. You shouldn't shove it into every project. For most amateur radio projects, the axis is unnecessary, but having known about it before, I would probably have stuck it into a couple of projects.

Now let's look under the hood. To run mRTOS, you need to connect mrtos.c to the project and include mrtos.h. The code structure is slightly different from usual

#include #include "mrtos.h" //here is the body of the function where we write our super code void task1() ( while (1) //tasks in any OS are built on the basis of an infinite loop { //here is the code of your task DISPATCH; //function of transferring control to the scheduler } ; } //timer 0 interrupt handler interrupt [ TIM0_OVF] void timer0_ovf_isr(void ) ( char ii; #asm("cli") TCNT0= 0x9C ; inc_systime() ; for (ii = 0 ; ii< init_tasks; ii++ ) if (tasks[ ii] .delay ) -- tasks[ ii] .delay ; #asm("sei") } void main(void ) { //initialize peripherals Init_mRTOS() ; //OS initialization //here we create tasks (tasks) 3 tasks have been created here create_task(task1, 1 , Active) ; //create a task (task name, priority, status) create_task(task2, 1 , Active) ; create_task(task3, 1 , Active) ; Scheduler() ; //start the scheduler while(1); )

#include #include "mrtos.h" //here is the body of the function where we write our super code void task1() ( while(1)//tasks in any OS are built on the basis of an infinite loop ( //here is the code of your task DISPATCH; //function transfer control to the scheduler); ) //timer interrupt handler 0 interrupt void timer0_ovf_isr(void) ( char ii; #asm("cli") TCNT0=0x9C; inc_systime(); for(ii = 0; ii

Now more details. the number of tasks is indicated in mrtos.h by default APPTASKS N. The task is declared inside task1()(), task2()() and the like, inside while(1) you don’t need to write anything, there’s no need to call functions either, it’ll do it all in you planner. As you can see, the task consists of an infinite loop, this is normal and should be, but inside the task it is necessary to give control to the scheduler. Either with the WAIT or DISPATCH function. If this is not done, the task will run endlessly.

How does this work? Let's create a task for blinking an LED.

void task1() ( while (1 ) ( PORTB.0 = ! PORTB.0; WAIT(100 ) ; ) ; )

void task1() ( while(1) ( PORTB.0 = !PORTB.0; WAIT(100); ); )

WAIT is a kind of analogue of delay(), only during division the microcontroller does nothing and runs empty cycles. During WAIT, control is transferred to other tasks. Those. you can create a bunch of tasks by blinking different LEDs, with different WAITs, and they will all blink at different frequencies. If delays are not needed, then use DISPATCH at the end.

When using WAIT, it is important to understand that the entire system has a minimum tick (time slice), so we are not waiting for WAIT(50) 50 milliseconds, but for 50 system ticks. The tick setting depends on how often the timer0 interrupt is called, i.e. if we set the interrupt to 1ms, then we can assume that our action will complete within 1ms. Experiments have shown that the system tick can be reduced to ~20 µs at a clock speed of 16 MHz.

Setting the timer is no different from what we studied earlier, since timer0 only has an overflow interrupt, then all settings are tied to this. The latest versions of CAVR make it very convenient to write time requirements, the settings will be automatically generated.

create_task(task1, 1 , Active) ;

create_task(task1,1,Active);

With priorities, everything is quite not simple. If there are two tasks with different priorities and the task with a higher priority is constantly running, then we will never enter the task with a low priority. Therefore, you need to organize work so that all tasks have access. We won’t focus on this, we’ll save it for next time. Task status, Active - running, stopped StopTask.

So, for those who want to just blink the LED:

#include #include "mRTOS.h" void task1() ( while (1 ) ( WAIT(1000 ) ; PORTB.0=! PORTB.0; ) ) // Timer 0 overflow interrupt service routine interrupt [ TIM0_OVF] void timer0_ovf_isr(void ) ( char ii; #asm("cli") TCNT0= 0xb2 ; inc_systime() ; for (ii = 0 ; ii< init_tasks; ii++ ) if (tasks[ ii] .delay ) -- tasks[ ii] .delay ; #asm("sei") } void main(void ) { DDRB= (1 << DDB7) | (1 << DDB6) | (1 << DDB5) | (1 << DDB4) | (1 << DDB3) | (1 << DDB2) | (1 << DDB1) | (1 << DDB0) ; PORTB= (0 << PORTB7) | (0 << PORTB6) | (0 << PORTB5) | (0 << PORTB4) | (0 << PORTB3) | (0 << PORTB2) | (0 << PORTB1) | (0 << PORTB0) ; // Timer/Counter 0 initialization// Clock source: System Clock // Clock value: 7.813 kHz TCCR0= (0<< CS02) | (1 << CS01) | (1 << CS00) ; TCNT0= 0x83 ; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK= (0<< OCIE2) | (0 << TOIE2) | (0 << TICIE1) | (0 << OCIE1A) | (0 << OCIE1B) | (0 << TOIE1) | (1 << TOIE0) ; Init_mRTOS() ; create_task(task1, 1 , Active) ; Sheduler() ; while (1 ) ; }

#include #include "mRTOS.h" void task1() ( while(1) ( WAIT(1000); PORTB.0=!PORTB.0; ) ) // Timer 0 overflow interrupt service routine interrupt void timer0_ovf_isr(void) ( char ii ; #asm("cli") TCNT0=0xb2; for(ii = 0;ii

As a bonus, I tried to make a polyphonic (two-voice) melody “Dr.Mario chill”. The idea is that each controller pin is constantly inverted in a separate task, thereby generating a frequency. By changing the delay you can change the pitch of the note.

void task2(void) ( while (1) ( if (mute == 0) //if allowed to play( if (note_ch2[ n_n] == 0 ) //if there is a pause, then we wait, we don’t play anything( PORTB.4 = 0 ; WAIT(5 ) ; ) else ( PORTB.4 = ! PORTB.4; //if there is no pause, then we kick our legs with the required frequency WAIT(note_ch2[ n_n] ) ; ) ) ) )

void task2(void) ( while(1) ( if(mute == 0) //if it is allowed to play ( if(note_ch2 == 0) //if there is a pause, then we wait, we do not play anything ( PORTB.4 = 0; WAIT( 5); ) else ( PORTB.4 = !PORTB.4; //if there is no pause, then we kick our legs with the required frequency WAIT(note_ch2); ) ) ) )

I didn’t bother with the idea, in 1 task a meander is generated with the frequency of the note for the solo part, in the second for the bass. The pitch of each note is taken from arrays. Duration, switching and termination in a task3.

void task3(void) ( while (1) ( WAIT(1500) ; //play the minimum note duration for (mute = 0 ; mute< 500 ; mute++ ) //cut off the note so they don't merge(PORTB.3 = 0; PORTB.4 = 0;) ; mute = 0 ; //set the flag that sound can be played n_n++; //move to the next note if (n_n == n_max) //if everyone has played, then we go in a circle( n_n = 0 ; ) ) )

void task3(void) ( while(1) ( WAIT(1500); //play the minimum note duration for(mute = 0; mute< 500; mute++) //обрываем ноту, чтобы не сливались { PORTB.3 = 0; PORTB.4 = 0; }; mute = 0; //выставляем флаг, что можно воспроизводить звук n_n++; //переходим на следующую ноту if(n_n == n_max) //если сыграли все то идем по кругу { n_n = 0; } } }

To mix the two channels I used a simple circuit.

Total small piece

For those interested, firmware

I've developed a little over 10 electronic devices and have gotten by quite well on their low-level work without an operating system. The situation changed when the functionality of the next device expanded dramatically. In addition, there was a need for a task that is called at specified intervals, and the accuracy of the call affects the result. It also became clear that it would not be possible to write all the software in the allotted time, and it would be created later. After some thought, I realized that the project needed to include a real-time operating system (RTOS).

Unlike a PC, where the OS is more of a layer for working with system resources, for a microcontroller an RTOS is primarily a task scheduler; in fact, it plays the main role in “real time”. At the moment, it is important for me to ensure the so-called “pseudo-parallel” execution of tasks. That is, there are several tasks with the same priority and it is important to call them in a given order at given time intervals.

The following example is clear: in the Eurobot 2011 project, there were 18 peripheral devices in the system. 2 electronic boards could be functionally combined into one. Their cost would decrease, reliability would increase (the number of components in the system would be reduced), and the amount of free space in the case would increase. The situation is complicated by the fact that the number of tasks is growing proportionally and it is no longer possible to do without the OS. RTOS also helps to avoid possible processor downtime; for example, during ADC conversion, you can block this task and perform others, thereby correctly distributing the work of the device. It is also important that now the device will not fall due to a failure in the task; instead, it is possible to maintain partial functionality (although this can lead to unpredictable results). How do we ensure the growth of these indicators? In essence, we squeeze everything possible out of the MK, effectively using its computing capabilities.

After some searching, the choice fell on freeRTOS. This RTOS is distributed in C source code and ported to 27 architectures. The last circumstance is decisive for me. It will reduce labor costs when working with MK from other manufacturers. Now I'm more interested in the AVR port.

The presence of the freeRTOS RTOS in the project eats up about 9.8 KB of program memory and 1.8 KB of RAM. For example, for ATmega32 and the WinAVR compiler it is 60% and 85%, respectively. It’s already difficult to create a device with more functionality for this model - there won’t be enough memory. But this problem disappears when using new AVR models. This is absolutely nothing for the Mega2560 with its 256 KB of program memory and 8 KB of RAM. The trend of future MCs only accompanies the success of RTOS.

Having quickly browsed the RuNet, I was surprised to find that there is no documentation for the OS in Russian. Yes, what is it here! Original documentation is available at an additional cost. The situation was simplified by an article by Andrei Kurnits ( [email protected]) from the magazine "Components and Technologies". By agreement with the author, I will use the article’s materials in a revised version. His article may well serve as documentation in Russian. But the original is not available in printed form, the magazine’s website is no longer available, so the material will have to be slightly reworked. Overall, the author made an excellent article and there is no point in going through the theory again; it will be published in full here. The original article will be attached at the end of the publication. I also noticed that users were having difficulty compiling the RTOS. This is due to the fact that an external makefile is used, which contains the paths to the folders. Therefore, I will attach the finished project as a template for AVR Studio and AVR Eclipse. Unfortunately, the native makefile does not output debugging information, such as the occupancy rate of RAM and program memory; this had to be fixed by adding the appropriate standard call.

So, briefly about the need, it is advisable to use an RTOS in your project if necessary:

Organize multitasking and take turns performing tasks

Ensure that the task runs at strictly defined time intervals

Transfer information from one task to another

Add new tasks as needed

Advantages of RTOS over M TO:

  1. Multitasking. RTOS provides the programmer with a ready-made, well-functioning multitasking mechanism. In a simple case, each task can be programmed separately, and all the work can be divided among several team members. You don't need to worry about switching between tasks, the scheduler will do it.
  2. Temporary base. It is necessary to measure time intervals. The RTOS must have this tool. It will allow you to perform actions at strictly designated time intervals.
  3. Exchange data between tasks. For this purpose, the RTOS uses a queue.
  4. Synchronization. If different tasks use the same resource, such as a serial port, then mutexes and critical sections can be used. If you need to perform tasks in a strict sequence or when a specific event occurs, you can use semaphores or signals to synchronize tasks.

Disadvantages of RTOS:

1. A sharp increase in the required memory of programs for implementing the kernel

2. Increasing the required RAM to store the stack of each task, semaphores, queues, mutexes and other system kernel objects.

3. Delays when switching between tasks to preserve context.

DescriptionfreeRTOS:

FreeRTOS is a free and open source hard real-time operating system. Mostly written in C, but there are assembly inserts. It was developed by Real Time Engineers ltd specifically for embedded systems. Recently, the “SafeRTOS” project began to develop - a modified, documented, tested and certified version of FreeRTOS for compliance with the IEC 61508 safety standard. This project was carried out by a German company and now safeRTOS is used in the aerospace industry and medical technology. There is also an openRTOS project - a commercial version with a manufacturer's warranty.

Key Features of freeRTOS:

1. The scheduler supports 3 types of multitasking:

Displacing

Cooperative

Hybrid

2. The kernel size is 9.8 KB when compiled for AVR. (WINAVR)

3. The basis of the kernel is 4 files in C.

4. Supports tasks and coroutines. Coroutines are specially created for microcontrollers with a small amount of RAM.

5. Rich tracing capabilities.

6. It is possible to monitor stack overflow.

7. There are no software restrictions on the number of simultaneously performed tasks.

8. There is no limit on the number of task priorities.

9. Multiple tasks can be assigned the same priority

10. Developed “task-task” and “task-interrupt” synchronization tools:

Queues

Binary semaphores

Counting semaphores

Recursive semaphores

Mutexes

11. Mutexes with priority inheritance.

12. Support memory protection module for Cortex-M3

13. Delivered in a debugged form with demo projects for various platforms and compilers.

14. Free. Can be used in projects without disclosing the source code under the extended GPL license.

15. Documentation is paid, but is available online here.

16. The context switching time for an AVR with 16 MHz quartz will be only 20.8 µs. This is exactly how much is needed to save data onto the task stack and call the next one. (An interesting note, if you compare this with the PIC18xxx, the controller from AVR does it 4 times faster!!!, most likely this is due to the quality of the compiler)

Preemptive multitasking means that a running task with a low priority overlaps a ready task with a higher priority. Switching between tasks occurs in equal time slices. Therefore, before the high-priority task begins execution, the current time slice in which the low-priority task is executing must end.

Thus, the FreeRTOS response time to external events in preemptive multitasking mode is no more than one scheduler time quantum, which can be set in the settings. By default it is 1 ms.

If several tasks with the same priority are ready to be executed, then the scheduler allocates one time slice to each of them, after which the next task with the same priority receives control, and so on in a circle.

Cooperative multitasking differs from preemptive multitasking in that the scheduler cannot independently interrupt the execution of the current task, even a task with a high priority that is ready to execute. Each task must independently transfer control to the scheduler. Thus, the high-priority task will wait until the low-priority task completes its work and returns control to the scheduler. The system's response time to an external event becomes uncertain and depends on how long the current task will be running before control is transferred. Cooperative multitasking was used in the Windows 3.x family of operating systems.

Preemptive and cooperative multitasking concepts come together in hybrid multitasking, where a call to the scheduler occurs every slice of time, but unlike preemptive multitasking, the programmer has the ability to force it within the body of the task. This mode is especially useful when it is necessary to reduce the system response time to an interrupt. Let's say a low-priority task is currently running, and a high-priority task is waiting for some interruption to occur. Next, an interrupt occurs, but after the interrupt handler finishes, execution returns to the current low-priority task, and the high-priority task waits until the current time slice ends. However, if you transfer control to the scheduler after executing the interrupt handler, it will transfer control to a high-priority task, which reduces the system response time associated with an external event.

Whyonchatb?

You can start developing a microcontroller device running FreeRTOS by downloading its latest version.

The FreeRTOS distribution is available as a regular or self-extracting ZIP archive. Distribution Contains the kernel code itself (in the form of several header files and source code files) and demo projects (one project for each development environment for each port). Next, you should unpack the archive to any suitable location on the development station.

Despite the fairly large number of files in the archive, the directory structure is actually simple. If you plan to design devices on 2-3 architectures in 1-2 development environments, then most of the files related to demo projects and various development environments will not be needed.

The detailed directory structure is shown in the figure.

All kernel source code is located in the /Source directory.

Content:

1.tasks.c- implementation of the task mechanism, scheduler

2. queue.c- implementation of queues

3. list.c- internal needs of the scheduler, but the functions can also be used in application programs.

4. croutine.c- implementation of coroutines (may be absent if coroutines are not used).

Header files that are located in the directory source/include

1. tasks.h, queue.h, tist.h, croutine.h- header files, respectively, for code files of the same name.

2. FreeRTOS.h-contains preprocessor directives for configuring compilation.

3.mpu_wrappers.h- Contains FreeRTOS API function overrides to support the Memory Protection Unit (MPU).

4. portable.h-platform-dependent settings.

5.projdefs.h-some system definitions

6.semphr.h- defines API functions for working with semaphores, which are implemented based on queues.

7. StackMacros.h- contains macros to control stack overflow. Each hardware platform requires a small piece of kernel code that implements FreeRTOS interaction with that platform. All platform-specific code is located in the subdirectory /Source/Portable, where it is systematized by development environments (IAR, GCC, etc.) and hardware platforms (for example, AtmelSAM7S64, MSP430F449). For example, a subdirectory /Source/Portable/GCC/ATMega323 contains the files port.c and portmacro.h, which implement saving/restoring the task context, initializing the timer to create a time base, initializing the stack of each task and other hardware-dependent functions for microcontrollers of the mega AVR family and the WinAVR compiler (GCC).

A separate subdirectory should be highlighted /Source/Portable/MemMang, which contains files heap_l.c, heap_2.c, heap_3.c, implementing 3 different memory allocation mechanisms for FreeRTOS needs, which will be described in detail later.

The /Demo directory contains demo projects ready for compilation and assembly. The common part of the code for all demo projects is allocated to a subdirectory /Demo/Commo n.

To use FreeRTOS in your project, you must include the kernel source files and accompanying header files. There is no need to modify them or understand their implementation.

For example, if you plan to use a port for MSP430 microcontrollers and a GCC compiler, then subdirectories will be needed to create a project from scratch /Source/Portable/GCC/MSP430_GCC And / Source/Portable/ MemMang. All other subdirectories from the /Source/Portable directory are not needed and can be deleted.

If you plan to modify an existing demo project (which, in fact, is recommended to do at the beginning of learning FreeRTOS), then you will also need subdirectories /Demo/msp430_GCC And /Demo/Common. The remaining subdirectories located in /Demo are not needed and can be deleted.

When creating an application, it is recommended to use makefile(or development environment project file) from the corresponding demo project as a starting point. It is advisable to exclude files from the /Demo directory from the build, replacing them with your own, and the files from the /Source directory - untouched. Also worth mentioning is the header file FreeRTOSConfig.h, which is included in every demo project. FreeRTOSConfig.h contains definitions (#defines) that allow you to configure the FreeRTOS kernel:

1. A set of system functions.

2. Using coroutines.

3. Number of task priorities and coroutines

4. Memory sizes (stack and heap).

5. MK clock frequency.

6. The time scheduler period allocated to each execution task, which is usually 1 ms. Disabling some system functions and reducing the number of priorities (reduces memory consumption).

The FreeRTOS distribution also includes tools for converting trace information received from the scheduler into text form (directory /TraceCon) and license text (directory /License).

Conclusions

With the help of the first article in the series, the reader became acquainted with the operating system for FreeRTOS microcontrollers. Features of the work are shown. Describes the contents of the FreeRTOS distribution. Here are the basic steps to start developing a device running FreeRTOS.

In future publications, attention will be paid to the mechanism of multitasking, namely tasks and coroutines. A sample of the scheduler's operation will be given using the example of Atmel AVR microcontrollers and the WinAVR compiler (GCC).

RTOS MAX- a free Russian real-time operating system for multi-agent coherent systems.

MAX embodies the classic functionality of operating systems of this type and has a number of advantages that can significantly speed up the development of embedded software when creating new devices based on microcontrollers. The advantages of the new OS are especially evident in matters of organizing the interaction of multiple devices.


RTOS MAX includes:
  • Fully functional RTOS core.
  • Complete set of source codes.
  • Documentation.
  • Demo applications.
Check out the project on github: https://github.com/AstroSoft-MIR/macs-rtos

Or download the stable version as part of the MACS Master development environment based on Eclipse


Manufactured by STMicroelectronics (including ready-made projects for the STM32F429I-DISCO development kit).

Development tool support


Eclipse + GCC.

RTOS MAX is:

Scheduler:

  • dynamic creation and deletion of tasks,
  • support for preemptive and cooperative multitasking modes,
  • selecting the task execution mode - privileged or non-privileged.
Synchronization objects:
  • binary and counting semaphores,
  • recursive and non-recursive mutexes with support for priority inheritance,
  • events,
  • message queues.
Using hardware memory protection:
  • to protect the process stack from overflow,
  • to protect memory at address zero,
  • to protect peripheral ports from unprivileged access.
Handling interrupts in user tasks:
  • activating custom task handlers from a predefined universal interrupt handler that does not require additional configuration,
  • the ability to assign several handler tasks for one interrupt,
  • control of the processing sequence through the priorities of processor tasks.
Profiling:
  • measuring the execution time of code sections from point to point or in the scope of an automatic variable,
  • possibility of automatic adjustment (increasing measurement accuracy by calculating delays of one’s own work),
  • generating measurement statistics with grouping sections into sections (total execution time of all sections with and without nesting, minimum/average/maximum section execution time, standard deviation).
Device-level shared memory mechanism (Shared Memory):
  • task context synchronization between devices,
  • messaging within a group of devices.

Devices controlled by microcontrollers are used to solve a wide range of problems. RTOS MAX is a universal platform for developing embedded applications, and its scope of application is related to the advisability of using microcontrollers in a particular task.


Robotics, UAV
  • Control system

    The control electronics are installed directly on the robot itself and implement algorithms that allow it to solve the task.

  • Telemetry system

    Provides communication between the robot and a remote terminal, allowing the operator to receive information about the robot’s state and send commands.


  • Positioning system

    Additional external devices allow robots to navigate indoors and outdoors, find their way to their destinations and to base stations.

Smart home systems
  • Power and lighting management

    Ensuring uninterrupted power supply to the building, monitoring electricity consumption, automatically turning on/off lighting depending on the presence of people in the room and controlling the level of illumination (adjusting the brightness of light at different times of the day).


  • Climate control

    Maintaining a comfortable indoor microclimate (temperature and humidity regulation, ventilation and air purification) is carried out depending on the user’s preferences, the presence of people in the room, as well as external factors (weather, time of day).


  • Monitoring and security systems

    Video surveillance and control of access to premises, monitoring of events that threaten the safety of the home (burglary, fire, water leakage) and automatic notification of owners and relevant services (security, fire service).

Consumer Electronics and Home Appliances


With the development of technology, household appliances are becoming more functional and convenient to use. For example, currently, consumers already have access to equipment that is centrally controlled from a smartphone or tablet instead of separate remote controls. “Smart” equipment requires less and less attention from a person, which allows the user to significantly save time and money (robot vacuum cleaners do their own cleaning, delayed start and auto-shutdown functions control the operating time of the device and thereby optimize energy consumption). The rapidly developing technologies of the Internet of things (IoT) imply complete autonomy of devices, which creates high demands on their software, and on the part of the developers of these devices there is growing interest in the OS, which already provides services and interaction protocols “out of the box”, allowing for this autonomy.


Internet of Things technologies assume complete autonomy of devices. This creates high demands on their software. On the part of the developers of these devices, there is growing interest in OSes that provide services and interaction protocols out of the box that make it possible to ensure this autonomy.


Mesh network support
  • Reliability and fault tolerance of the network

    Network nodes connect to each other, forming a large number of connections. Several traffic routes can be formed between nodes. If there are redundant routes, the failure of one of the intermediate nodes will not disrupt the functioning of the entire network. The information will be dynamically rerouted along a different route.


  • Self-organization

    The network structure is formed automatically as nodes are connected/disconnected. If necessary, each node can independently obtain information about the availability of the destination node and build an optimal route for data exchange.


  • Increased communication range

    Each device may have a short communication range. However, the geographical distribution of many interconnected devices allows for much greater coverage.

Internet of Things technology support
  • Optimal configuration of a distributed system

    The hardware resources of each system device are selected based on its functional purpose. There is no need for powerful computers to solve simple problems, such as identifying objects or measuring environmental parameters. These functions can be performed in small, self-contained modules, reducing the cost of a distributed system.


  • Autonomous operation of the system

    By interacting with each other, devices are able to make decisions and perform tasks without human intervention, which reduces system maintenance costs.


  • Scalability

      Adding and removing devices from the network is painless and automatic. The network will “figure itself out” what device appeared in it and how to use it.

Areas of application
  • Sensors, sensors, converters
  • “Smart home”, “smart city” systems
  • Internet of things (IoT)
  • Industrial automation, control
  • Robotics
  • Medical equipment
  • Railway transport
  • Consumer Electronics
  • Communication systems
I constantly ask myself this question while pursuing my hobby - developing a home automatic control system (smart home) based on a 16-bit microcontroller - is this really the right approach? A month and a half ago, I already wrote in my blog on the topic “Microcontrollers versus systems-on-a-chip”. So, I'm going to write about this again.

Part of what prompted me to do this was the appearance of Stellaris Launchpad and Arduino Due on sale. They are both based on 32-bit microcontrollers, and are very similar in many ways. I looked at the datasheets for both, and although they are quite different in price, they are designed for the same target audience. I was thinking that maybe I should switch from MSP430 to Stellaris, or maybe even switch to a completely different system, use something like a Raspberry Pi instead of microcontrollers.

Both Stellaris Launchpad and Arduino Due are very powerful, but are not designed to run Linux. They run either on executable code written directly for them, or under the control of a real-time operating system (RTOS), a minimalistic OS with a very short response time to external events. They are also both significantly more complex than the MSP430 or 8-bit AVRs.

On the other hand, in real life (outside the Internet), most people I know use Raspberry Pi or other embedded systems on Linux. The use of microcontrollers is quite a rare case among those I have met. Even Arduino is much less popular in my environment than embedded Linux. The way I see it, why would anyone buy an Arduino when they can buy a Raspberry Pi, which can do so much more and cost the same or less? There is a huge amount of ready-made software for Linux, and you can program on it using simple scripting languages.

For me personally, the reason I don't want to use Linux is because I use it every day at work, and when I get home I don't enjoy having to work on Linux-like systems again. I have no problem using Linux, but there is too much of it everywhere and it's overwhelming me. I'm much more interested in working with simple electronic devices on 8/16-bit microchips.

However, I do not turn away from reality. If I want to stay in tune with the real world, I have to use the tools that the real world uses. Otherwise, it's like wanting to drive a car with a steam engine, just because the internal combustion engine is too common, I use it all the time anyway. If the world around us switches to more advanced technology, I need to master it, whether I like it or not. Especially if I want my blog to be interesting to people and remain relevant.

In my smart home project, I actually encountered this problem. I have already made a LAN driver for the monitoring system on the MSP430, and everything looks very good. Basically, I can do everything I need for an automation system on the MSP430. However, I wonder if the way I'm doing this is right? Am I trying to eat soup with a fork when there is a spoon? Maybe Linux is a better system? Let me explain.

If we stop and look at the current situation, in terms of technological advances as of November 2012. I'm asking myself, are microcontrollers good and relevant enough compared to system-on-a-chip systems using Linux?

If I list the projects on embedded systems that come to my mind, these are: drones, robots, home automation, motor controllers, sensors, watches, 3D printers, etc. In which of these cases is embedded Linux better suited than microcontrollers? And why?

I believe that there are three situations when a microcontroller is the best choice: where instant (realtime) reaction to events is important; where extremely low energy consumption is required; and where it is necessary to use microcircuits of the lowest possible cost.

To begin with, the use of cheap microcircuits is not such an important point for me. I do my hobby for myself and have no intention of ever releasing competitive products. I don't have to think about moving production to a factory that uses slave labor in order to be competitively priced for the small projects I develop. I would be happy if I could solder more than one board a day, thanks to my abilities!

For example, for a smart home project, I can develop a remote controlled switch. It can turn on/off the light or something else. At the same time, I can go to the local electrical store and buy the same thing for $20, made in China. Will I ever be able to beat that price by trying to sell my own switch? I don't think this is possible.

If you think about it, this applies to a lot of other things needed for home automation as well. Temperature, smoke, motion sensors, etc., I am quite capable of making the same ones myself, but it is unlikely that I can derive financial benefit from this. Who's interested in buying these things from me for $75 when they can find them for $20 at Household Supplies?

If you are thinking about getting some benefit from your hobby, it is better to pay attention to more expensive and complex products. For example, a home automation controller or thermostat usually costs over $100, and leaves more freedom for individual creativity, you can build one, sell it to your neighbors and even make something from it.

But the desire to achieve a better price for the final device does not mean that you need to use the cheapest microcontroller on Earth. In fact, this is a bad idea, because... development time has its own cost, as do the parts used. Perhaps a microcontroller is cheap, but requires more time to write control code. Time is money, and if you work faster, you will achieve more.

All these thoughts lead me to the conclusion that it is more profitable to develop a smart home system on Linux than on microcontrollers, despite my personal preferences, not to use Linux (I like low-level programming more than scripts, Linux makes me bored).

If we return to the topic of the topic, the price of microcontrollers, this may be an important factor for large corporations planning to release a new product, but at the individual level, if you are trying to run a business in the Kickstarter style, this factor is no longer so significant, in fact, fast development time, more important than the cost of the components.

On the other hand, microcontrollers may be a better choice than SoCs when low power consumption is needed. There are two points in such systems: low consumption of the circuit itself during operation, and short start time. A typical way to save battery for small devices is to shut off. When you turn off your Linux computer, it takes a fair amount of time for it to get back to work, sometimes up to several minutes. This time is not acceptable for embedded systems.

If you take a microcontroller like the MSP430, it can run for years on a single battery. Stellaris Launchpad and Arduino Due, in principle, are capable of the same thing, they consume more energy than the MSP430, but still very little compared to the Raspberry Pi. Also, MSP430 can start instantly after turning off.

So, I am absolutely confident that in all situations where low voltage operations are needed, it makes sense to use microcontrollers. There are a wide variety of battery-powered devices where the need arises.

In the third case, as I already said, using a microcontroller makes more sense than Linux in operations requiring instant response (realtime response). I'm talking about devices like 3D printers and CNC machines, I know what I'm talking about because I've spent a lot of time studying them. By their nature, they require high precision in operation, which is slightly less than entirely dependent on response time to commands.

For example, if you have a circular saw running that is currently cutting a piece of wood or metal, you cannot stop the process because the computer that controls it needed a pause to dump the data from memory to disk or something something else in the same spirit. Anyone who has used a PC is familiar with the occasional stuttering that occurs periodically during most normal work. Now imagine that you have a large drilling machine, controlled by a PC, which suddenly starts checking for updates for Windows while working, and the drill drills right through the table on which it stands, because... the computer lost control of her.

PCs and systems-on-a-chip are not designed to work in real time, even with Windows or Linux, but of course they are trying to get closer to this. As an example, there is a real-time patch for the Linux kernel, and special CNC software created to do this kind of work. I'm not familiar enough with this Linux patch, and I don't know how flexible it is to fully control real-time events. But I think that this is only a possible alternative, because... Linux, no matter what patches are put on it, will never beat microcontrollers in this area, thanks to the presence of their interrupt system.
In conclusion, I have spent a lot of time trying to find areas where using microcontrollers in my projects has an advantage. And it looks like the era of world dominance by Raspberry Pi and Beaglebones has arrived. This is the current situation in the DIY community. In most cases, it is faster and easier to develop on these systems, so they are often the best choice for most projects.

The only areas left for microcontrollers are low-voltage, real-time, and low-cost devices.

This is regardless of the fact that microcontrollers may seem "more fun" than PCs. This is something you have to come to terms with.

Translation from English of the original post

Did you like the article? Share with friends: