Jump to content

    

FreeRTOS на AVR

Здравствуйте! Давно присматриваюсь к идее запуска на AVR какой-либо РТОС... В моем обзоре есть JacOS, scmRTOS и FreeRTOS. Решил остановится на последней, т.к. она портирована на большинство платформ и о ней достаточно много говорят на этом форуме) Вот хочу спросить, запускал ли кто эту ось на АВРке и какие траблы были? Стоит ли вообще этим заниматься? Может лучше чихнуть на порты для остальных платформ и остановится на менее ресурсоекой JacOS?

Цель моей задумки просто изучение... Хочется в живую пощупать, ощутить работу ОС на AVR...

Прошу прощения, что не очень четко и грамотно изложил вопрос, но я думаю основное направление понятно...

 

Технически подробности:

1. Предпочитаемый мною компилятор: GCC.

2. МК: ATmega16 либо (если не хватит ОЗУ, т.к. примеры с сайта для 32 меги) ATmega32.

Share this post


Link to post
Share on other sites
В моем обзоре есть JacOS, scmRTOS и FreeRTOS. Решил остановится на последней

Я плотно работаю с FreeRTOS, но не работаю с AVR, посему на объективность претендовать не могу :-(

Но FreeRTOS в полной сборке как-то мне кажется тяжеловатой для AVR. Впрочем, наверное следует просто собрать ядро и пару простейших задач, после чего Вы сможете сами решить утраивает Вас размер и тайминги шедулера.

Share this post


Link to post
Share on other sites

В моем обзоре есть JacOS, scmRTOS и FreeRTOS. Решил остановится на последней

Я плотно работаю с FreeRTOS, но не работаю с AVR, посему на объективность претендовать не могу :-(

Но FreeRTOS в полной сборке как-то мне кажется тяжеловатой для AVR. Впрочем, наверное следует просто собрать ядро и пару простейших задач, после чего Вы сможете сами решить утраивает Вас размер и тайминги шедулера.

Спасибо!

Видимо так и нужно будет сделать... В любом случая на FreeRTOS смотрю из за наличия портов для других платформ, так сказать закладываю фундамент для будущего, кто знает, с чем придется работать дальше...

Share this post


Link to post
Share on other sites
Здравствуйте! Давно присматриваюсь к идее запуска на AVR какой-либо РТОС... В моем обзоре есть JacOS, scmRTOS и FreeRTOS. Решил остановится на последней, т.к. она портирована на большинство платформ и о ней достаточно много говорят на этом форуме) Вот хочу спросить, запускал ли кто эту ось на АВРке и какие траблы были? Стоит ли вообще этим заниматься? Может лучше чихнуть на порты для остальных платформ и остановится на менее ресурсоекой JacOS?

+1 за scmRTOS:

- минимальная ресурсоемкость

- свободная и открытая (в отличии от JacOS)

- отличная документация

- существуе порт для ARM, не за горами для FR (MB91)

Share this post


Link to post
Share on other sites
+1 за scmRTOS:

- минимальная ресурсоемкость

- свободная и открытая (в отличии от JacOS)

- отличная документация

- существуе порт для ARM, не за горами для FR (MB91)

И -1 за то, что она требует С++ компилера -> WinAVR пролетает, что неправильно.

Share this post


Link to post
Share on other sites

Introduction

Any embedded system usually has three purposes: gathering input, processing, and providing output. The most efficient way to respond to input and present output is to make input and output event driven, such that the normal task execution is interrupted when new events occur: the system has event based multitasking. If this technique is used, the system has event based multitasking. It also can be said to have two priority levels: the event driven interrupt handler and the processing task or tasks. One design could be to have a main loop analyze all events that occur and respond. Another would be to separate events into independent concurrent processes and have a dedicated main task (known as a kernel) transferring control among them. The kernel, allocates and efficiently distributes the resource of the processor between competing tasks.

There are two major methods of sharing processor time. A system timer interval can determine when context switches occur and one process is preempted by another or the tasks themselves can decide when it is a good time to transfer control by using a system call. If timing is used, the system is preemptively scheduled. The other approach describes a cooperatively scheduled system. Of course there are tradeoffs between both designs.

As previously noted any event driven system already has two priority levels: interrupt handling code, and the tasks. Easily enough, different priorities can be given to different tasks, such that when two tasks have the opportunity to run, the higher priority task is chosen by the scheduler. Alternatively, all tasks can be given the same priority. This is known a round-robin kernel. Again, there are tradeoffs as always between these options.

It is obvious that having different priorities allow achieving more flexible control but the price to pay is a problem with priority scheduling - threads with low priority may rarely gain processor control. This is known as starvation. One of the solutions to this is to issue escalating priorities, such that the priority of a task will increase the longer a task waits to be run .

The requirements of your project should help you determine if you need an operating system, and if so, which one.

Requirements for Real Time Kernel

Brick is designed to

• Fit into 2048 bytes of internal SRAM including all application tasks and their separate stacks

• Support up to 15 user defined tasks

• Switch automatically between regular and power save mode

• Switch context in less than 1024 MCU clocks

• Use a very limited amount of inline assembly

What is BRICK?

BRICK stands for Basic Reduced Integrated Cooperative Kernel. It supports a real time, cooperatively scheduled operating system designed to meet very strict memory and the highest achievable speed requirements. It uses round-robin scheduling. It is written in Object Oriented C (C--) with very limited elements of inline assembly. It also supports an internal messaging system for inter-task communications, as well as semaphores, and timer operations. It features functions to handle automatic power saving. This feature requires additional 32 kHz external crystal oscillator. With it system timer frequency is 64 Hz. Otherwise system timer should be running with frequency close to 60 Hz.

This kernel offers only very basic functions. It is reduced to only one system call: sleep () used by the application tasks to transfer control to the kernel and therefore to each other. The internal messaging system has a queue only one message deep which means that any task can receive only one message at a time.

Any project based on BRICK may be interpreted as a proprietary, dedicated operating system which uses BRICK as its kernel. This OS can have memory management, command interpreter, file system, or many other traditional features, but they need to be added when required as application tasks. Most embedded systems do not need a big list of features, but instead require some unique combination. Excluding almost all features makes BRICK very light weight, flexible, and responsive. You can build your own RTOS to fit your needs from BRICK in the same way that many different buildings can be constructed from the same bricks...

BRICK uses only hardware integrated into the MCU circuitry and does not require any external hardware except crystal oscillator(s).

BRICK is a suitable kernel for a real time operating system, which is useful when stringent time deadlines for certain behaviors are necessary. BRICK meets the necessities for time critical computing through strong optimization for speed and a round robin priority cooperative task design.

Why Round Robin?

BRICK uses round robin scheduling instead of a priority based. There is more than one way to implement a prioritized tasks scheme, but there is no clear reason to choose any one for a general unknown model. Interpreting the round robin priority scheme as one level and interrupt handlers as another higher level, seems to be the most efficient design to meet the declared requirements.

Why Cooperative?

BRICK uses cooperative scheduling. This means tasks must cede processor control to each other in order to achieve multitasking. This contrasts the preemptive model, in which the timer may force context switches between tasks.

BRICK was designed to be cooperative due to memory and speed requirements. First, BRICK allows fitting up to 15 application task and itself into 2 kb of SRAM. Each task has its own stack which must be large enough to hold all of the registers needed for context switching as well as those needed for any interrupt: the interrupts use stack of the currently running task and may occur at any time! Because BRICK is cooperative, and therefore context switching is done only using a system call, the optimizing compiler can recognize what registers need to be saved. Only those registers are pushed, thus minimizing the amount of stacks size and time latency needed to allow for context switching. This contrasts a preemptive operating system which must push and pop all registers for each context switch, because the context switch may occur unexpectedly and can not be optimized. Also, in a preemptive system the scheduler has to be executed each system timer tick, but this behavior slows the performance of the tasks which actually need to run, and thus the overall system.

The cost of using cooperative scheduling is that writing a task is writing a part of the OS itself. Therefore it requires more effort from the software engineer. One failing task can cause the whole system to crash. Care must be taken when designing tasks to ensure that they cooperate well with the system.

Using Brick

Drivers

Device drivers are an interface between application software and hardware, allowing access sharing and control. Using BRICK it is often appropriate to divide device drivers into two halves, an interrupt handler and a task.

By default the interrupt is disabled when entering the interrupt service routine and BRICK does not support nested interrupts, so it is necessary that the amount of processing done in the interrupt service routine is minimal, otherwise we may lose other interrupts. Therefore usually all that is done in the interrupt handler is reading/writing input/output/status from/to the device or shared memory location, preparing for the next cycle if necessary and to communicate with another half of the device driver implemented as an application task. This can be done by writing the data to a shared memory location or by sending data or a signal in a message to the destination task. Interrupt handlers are allowed to send a message using the BRICK messaging system, but they can not receive any messages, other than via shared memory. ISRs run in the memory of the task that was running when the interrupt occurred, not only the task with which they are associated. Receiving a message uses the descriptor of the currently running task. This is why interrupt handlers can not receive messages.

Shared Memory Usage

If shared memory is used to communicate between the interrupt handler and the task, some mechanism must be developed to allow the task and ISR to follow all stages of the inter-communication process. Care must be taken to insure that the shared memory is not modified by the interrupt handler while it is being processed by the involved task. Otherwise unpredictable results may occur. This can be prevented by masking (disabling) the interrupt handler or by using a semaphore to obtain mutual exclusion between reading and writing halves to this memory.

Semaphore Operations

Access to resources can be protected through the BRICK supported semaphore operation. There are many ways to achieve a semaphore operation, but BRICK has only one simple built in semaphore used to limit access to a resource on a first come first served basis. It is usually used for communication between the interrupt handler and its corresponding task. The indicator has to be initialized to FREE before communication has begun and changed to BUSY while updating. Once at the end of the critical section, the indicator has to be set back to FREE.

Communication using BRICK Messaging System

As was mentioned above any task or interrupt handler can send a message or number of messages to other tasks. Interrupt handler can only send a message or messages using dedicated BRICK function. At the same time each task can receive one and only one message at a time using another devoted BRICK function. There is an exception. BRICK supports special a WAKEUP_TYPE message. This type does NOT have any data to transfer. When the task descriptor already has a WAKEUP_TYPE message and another type of message is sent it is allowed to replace the WAKEUP_TYPE with that one. The purpose of the WAKEUP_TYPE is to provide a signal of some event occurrence and replacement will not cause data loss but any type will transfer the signal.

When received data is processed a special BRICK function for clearing receive buffer has to be called.

Task Design

A system designed for a RTOS has to be structured so that functionality is divided into independent tasks. BRICK supports up to 15 user defined tasks. Because BRICK uses cooperative scheduling, tasks must be designed to work together. All tasks must use the only one system call sleep () to cede control, giving other tasks a chance to run.

Ceding Control: Sleep ()

This function allows for cooperative scheduling between tasks. It is important that all tasks sleep frequently, so that they may politely give other tasks a chance to run. Usually each task can be described as an initialization section followed by an infinite loop. In this loop some functionality occurs. Before the loop is closed the function should sleep, allowing other tasks to run. There should be no long loops without a call to sleep.

There are 3 modes supported. When calling sleep, a task declares a condition to become ready to run again. Tasks will become ready to run:

• after requested number of ticks (system timer counts);

• after any message has been received

• combined previous two events

Note that system call sleep must NEVER be called from an interrupt handler. It also re-enables global interrupts. Therefore it should not be used inside atomic blocks.

Power Control

To switch to the power save mode several conditions have to be met:

• power save option is turned on;

• kernel has run over all tasks descriptors and hasn’t found any one ready to run;

• minimal time left to wakeup at least one task is greater than some predefined constant;

• no power locks has been set.

 

Power locks are necessary when task expects some event i.e. wakeup message from the interrupt handler. At the same time it is not ready to run yet. While it is waiting the task should set a power lock.

Timing Operations

BRICK supports several functions to handle timing operations in system ticks. The system timer frequency is close to 60 Hz. Ticks are valued from 0 to 65535. Timing begins when BRICK is started. Overflow of ticks resets the value back to 0. That covers a time interval of approximately 15 minutes. If a greater time period is necessary it becomes responsibility of the application task.

Share this post


Link to post
Share on other sites
+1 за scmRTOS:

- минимальная ресурсоемкость

- свободная и открытая (в отличии от JacOS)

- отличная документация

- существуе порт для ARM, не за горами для FR (MB91)

И -1 за то, что она требует С++ компилера -> WinAVR пролетает, что неправильно.

Никуда WinAVR не пролетает - в нем С++ появился как бы не раньше, чем в IAR (по крайней мере поддержка шаблонов и прочего, чего нет в так называемом Embedded C++ в нем появилась сразу с появлением поддержки ++, в отличие от IAR'а). На scmRTOS есть порт для WinAVR, правда, он довольно старый, еще для версии 1.х.

Share this post


Link to post
Share on other sites
И -1 за то, что она требует С++ компилера -> WinAVR пролетает, что неправильно.

 

Давайте не будем опускаться до того что "все что не на Си-89 - неправильно" ;)

Share this post


Link to post
Share on other sites

Прошу прощения за ламерство!

 

http://winavr.sourceforge.net/

WinAVR (pronounced "whenever") is a suite of executable, open source software development tools for the Atmel AVR series of RISC microprocessors hosted on the Windows platform. It includes the GNU GCC compiler for C and C++.

 

Я предыдущий вывод сделал на основе данных сайта

http://klen.org/Projects/Embeded-gnu-tools...last_build.html

http://klen.org/Projects/Embeded-gnu-tools...gcc-cpp-how.txt

Share this post


Link to post
Share on other sites

Ещё один +1 в пользу scmRTOS и в поддержку тезиса "минимальная ресурсоёмкость" это отдельный стек прерываний, что для небогатых на ОЗУ AVR (особенно mega16) довольно существенно.

Использую эту RTOS давно и продуктивно (7 проектов).

Share this post


Link to post
Share on other sites
На scmRTOS есть порт для WinAVR, правда, он довольно старый, еще для версии 1.х.

Т.е. можно рискнуть пересобрать новую версию под gcc?

Share this post


Link to post
Share on other sites

Большое спасибо, всем ответившим! На основе всего сказанного, решил что действительно FreeRTOS тяжеловата для МК AVR, поэтому останавлюсь пока на выборе между scmRTOS и JacOS...

 

Немного подумал :) ... выбор падает на scmRTOS, потому что:

1. Есть несколько портов на другие архитектуры.

2. Вытесняющая многозадачность мне больше нравится, чем кооперативная.

 

Скачал версию 1.10 для GCC, будем пробывать... уж не знаю, что получится.

Share this post


Link to post
Share on other sites
Скачал версию 1.10 для GCC, будем пробывать... уж не знаю, что получится.

При желании должно получиться :)

Скачай и остальные версии для AVR (объем то крохотный) , изучи (раз уж занялся ;) и объем то крохотный ) да и сделай порт последней версии OS для любимого тобой gcc. Там нет ничего сложного, а хорошее описание поможет разобраться во всех тонкостях.

Share this post


Link to post
Share on other sites
Скачал версию 1.10 для GCC, будем пробывать... уж не знаю, что получится.

При желании должно получиться :)

Скачай и остальные версии для AVR (объем то крохотный) , изучи (раз уж занялся ;) и объем то крохотный ) да и сделай порт последней версии OS для любимого тобой gcc. Там нет ничего сложного, а хорошее описание поможет разобраться во всех тонкостях.

К сожалению опыта в портировании у меня совсем нет :( Да и со знанием Си++ есть проблемы.... программирую в основном только на Си. В общем проблем будет много, но я думаю смогу их решить.

Share this post


Link to post
Share on other sites

Сдравствуйте! Объясните пожалуйста дураку целесообразность применения RTOS на AVR.

Заранее спасибо.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this