реклама на сайте
подробности

 
 
10 страниц V  « < 5 6 7 8 9 > »   
Reply to this topicStart new topic
> Вопросы по scmRTOS
kurtis
сообщение Feb 26 2010, 19:20
Сообщение #91


Местный
***

Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205



Спасибо!))
Теперь получилось.
Go to the top of the page
 
+Quote Post
Embedder74
сообщение Mar 24 2010, 10:18
Сообщение #92





Группа: Участник
Сообщений: 10
Регистрация: 8-02-10
Пользователь №: 55 367



Начал разбираться с scmRTOS.3.10. Ответьте, плз. на несколько вопросов.
1) смотрю пример 1-EventFlag, описание процесса:
typedef OS::process<OS::pr0, 120, 32> TProc1;
Что означает 32? В доке на V2.0 такого параметра нет.

2) Существует ли проблема локальных переменных, объявленных в разных процессах?
Когда происходит прерывание текущего процесса более приоритетным, тогда есть опасность порчи локальных переменных, ведь они формируются компилятором из кучи. Как быть? Объявлять их static? Чего-то я недопонимаю. Сильно не пинайте.
Go to the top of the page
 
+Quote Post
jorikdima
сообщение Mar 24 2010, 11:14
Сообщение #93


тут может быть ваша реклама
*****

Группа: Свой
Сообщений: 1 164
Регистрация: 15-03-06
Из: Санкт-Петербург/CA
Пользователь №: 15 280



Цитата(Embedder74 @ Mar 24 2010, 13:18) *
2) Существует ли проблема локальных переменных, объявленных в разных процессах?
Когда происходит прерывание текущего процесса более приоритетным, тогда есть опасность порчи локальных переменных, ведь они формируются компилятором из кучи. Как быть? Объявлять их static? Чего-то я недопонимаю. Сильно не пинайте.

из стека, если вы не пользуетесь динамическим выделением. А стек у каждой задачи свой, следовательно проблемы нет.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Mar 24 2010, 11:42
Сообщение #94


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Embedder74 @ Mar 24 2010, 15:18) *
1) смотрю пример 1-EventFlag, описание процесса:
typedef OS::process<OS::pr0, 120, 32> TProc1;
Что означает 32?


Это размер стека возвратов. IAR для AVR использует два стека.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Embedder74
сообщение Mar 25 2010, 08:37
Сообщение #95





Группа: Участник
Сообщений: 10
Регистрация: 8-02-10
Пользователь №: 55 367



Цитата(jorikdima @ Mar 24 2010, 14:14) *
из стека, если вы не пользуетесь динамическим выделением. А стек у каждой задачи свой, следовательно проблемы нет.

В стеке задачи сохраняются только регистры, при этом не факт, что компилятор назначит регистр какой-либо локальной переменной. Например, если в подпрограмме определяются несколько float - локальных переменных, то скорее всего они создадутся из кучи, т.е из ОЗУ. Вы никогда не пробовали (в программе без ОСи) в прерываниях определить несколько локальных переменных (не static)? И что из этого вышло?

Цитата(jorikdima @ Mar 24 2010, 14:14) *
из стека, если вы не пользуетесь динамическим выделением.

А что, разве существует какой-то другой тип распределения памяти компилятором? Как в IARe я могу изменить этот тип?
Научите меня, плз.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 25 2010, 09:01
Сообщение #96


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Embedder74 @ Mar 25 2010, 10:37) *
Например, если в подпрограмме определяются несколько float - локальных переменных, то скорее всего они создадутся из кучи, т.е из ОЗУ.
Локальные переменные выделяются на стеке. Всегда. Память из кучи выделяется функцией malloc() и подобными. В плюсах - оператором new. И никак иначе. Куча находится в ОЗУ точно так же, как и стек находится в ОЗУ. ОЗУ (RAM) != куча (heap).
Цитата(Embedder74 @ Mar 25 2010, 10:37) *
Вы никогда не пробовали (в программе без ОСи) в прерываниях определить несколько локальных переменных (не static)? И что из этого вышло?
Пробовали. Вышло именно то, что и должно было.


Цитата(Embedder74 @ Mar 25 2010, 10:37) *
А что, разве существует какой-то другой тип распределения памяти компилятором? Как в IARe я могу изменить этот тип?
Сначала опишите, что вы понимаете под "этим" способом. Это поможет определить, какие способы являются "другими".


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
jorikdima
сообщение Mar 25 2010, 10:02
Сообщение #97


тут может быть ваша реклама
*****

Группа: Свой
Сообщений: 1 164
Регистрация: 15-03-06
Из: Санкт-Петербург/CA
Пользователь №: 15 280



Цитата(Embedder74 @ Mar 25 2010, 11:37) *
А что, разве существует какой-то другой тип распределения памяти компилятором? Как в IARe я могу изменить этот тип?
Научите меня, плз.

На самом деле, тут эффективнее всего вам какую-нибудь книжку прочитать про С/С++. К компилятору это отношение далекое имеет, это стандарт С. Почитайте в книжках про локальные, глобальные, статические переменные, судя по всему у вас пробел тут в знаниях.
Go to the top of the page
 
+Quote Post
a9d
сообщение Apr 9 2010, 17:34
Сообщение #98


Местный
***

Группа: Участник
Сообщений: 312
Регистрация: 9-04-10
Пользователь №: 56 532



atmega8
scmRTOS_SYSTIMER_NEST_INTS_ENABLE 1
scmRTOS_PROCESS_COUNT 2

Начал изучать эту ОС. Документацию прочитал.
Но не пойму. Почему в моем коде никогда не выполняется TProc2?

TProc1 ждет байт. Если пришел то отправить.
TProc2 постоянно шлет 'b'.
SystemTimerUserHook. постоянно отсылает 'v'.

На выводе постоянно фижу 'v' но никогда 'b'. Если отсылаю байт то он тут же возвращается.
Вывод TProc2 никогда не передается управление.

Код
int main()
{
    MyUart.init();
    // Start System Timer
    TCCR0 = (1 << CS01) | (1 << CS00);    // clk/64
    TIMSK |= (1 << TOIE0);

    //Запускаем ОС
    OS::Run();

    return 0;
}

//---------------------------------------------------------------------------
namespace OS {

template<> OS_PROCESS void TProc1::Exec()
{
    unsigned char c;

    for(;;)
    {
        c=MyUart.receiveByte();
                    MyUart.sendByte(c);
    }
} // TProc1::Exec()


template<> OS_PROCESS void TProc2::Exec()
{
    for(;;)
    {
        MyUart.sendByte('b');
        Sleep(50);
    }
} // TProc2::Exec()


} // namespace OS

void OS::SystemTimerUserHook()
{
#if  scmRTOS_SYSTIMER_NEST_INTS_ENABLE  &&  !PORT_TOGGLE_BY_PIN_WRITE
    TCritSect cs;
#endif
    MyUart.sendByte('v');
}
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 9 2010, 18:26
Сообщение #99


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



А всё потому, что TProc1 имеет наивысший приоритет, и не отдаёт никому управление.
Вставьте в TProc1
Код
        MyUart.sendByte('b');
        Sleep(10);

и всё заработает.
А если всё делать по уму, то надо чтобы функция MyUart.receiveByte(); сама вгоняла вызвавший её процесс в спячку до прихода символа.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
a9d
сообщение Apr 9 2010, 18:51
Сообщение #100


Местный
***

Группа: Участник
Сообщений: 312
Регистрация: 9-04-10
Пользователь №: 56 532



Т.е. я должен должен явно указывать какой процесс может отдать управление?

Если вставить в первый процесс Sleep(10) то ничего не изменится. Второй процесс не получит управления пока первый не уснет(т.е. пока не прийдет байт). По приходу байта, второй процесс получит управление отошлет байт и снова уснет, до тех пор пока снова не прийдет байт.

Сообщение отредактировал a9d - Apr 9 2010, 18:55
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 9 2010, 19:04
Сообщение #101


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(a9d @ Apr 10 2010, 01:06) *
Т.е. я должен должен явно указывать какой процесс может отдать управление?


Конечно. Это не виндоуз, где все процессы получают время, только более приоритетные побольше. Здесь, пока более приоритетный процесс не отдаст управление, менее приоритетный его не получит. А вот наоборот - запросто.

Цитата
Если вставить в первый процесс Sleep(10) то ничего не изменится.


Ну значит надо вызывать какую-то другую, неблокирующую функцию, типа MyUart.rx_count(). Тут уж вам виднее.
И кстати, если вы работаете с MyUart из разных потоков, то надо обернуть обращения к нему блокировками. Например, завести мьютекс MyUartMutex, и при начале работы его захватывать, а по окончании - отдавать.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 9 2010, 19:08
Сообщение #102


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(a9d @ Apr 9 2010, 21:06) *
Второй процесс не получит управления пока первый не уснет(т.е. пока не прийдет байт).
А покажите код MyUart.receiveByte(). Пока он ожидает прихода байта он должен отдать управление.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
a9d
сообщение Apr 9 2010, 19:13
Сообщение #103


Местный
***

Группа: Участник
Сообщений: 312
Регистрация: 9-04-10
Пользователь №: 56 532



Мда. Не удобно.

Модифицировал
Код
void OS::SystemTimerUserHook()
{
#if  scmRTOS_SYSTIMER_NEST_INTS_ENABLE  &&  !PORT_TOGGLE_BY_PIN_WRITE
    TCritSect cs;
#endif
    //MyUart.sendByte('v');
    OS::Sleep(1);
}


И все заработало. Но походу это очень плохая идея.

Вот код получения байта.
Код
    unsigned char CUart::receiveByte()
    {
        while((UCSRA&(1<<RXC))==0);
        return UDR;
    }


Сообщение отредактировал a9d - Apr 9 2010, 19:15
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Apr 9 2010, 21:26
Сообщение #104


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Вы четко должны понять, в RTOS реализуется "псевдопараллельное" выполнение задач, ведь процессор то один. Если вы в своей функции, которая вызывается из самого приоритетного процесса, висите в while(), то никогда этот процесс не передаст управление другим процессам. Вставлять Sleep в функцию, вызываемую по прерыванию, на мой взгляд, тоже не лучший вариант. Не очень понятно, как оно у вас заработало
Go to the top of the page
 
+Quote Post
a9d
сообщение Apr 9 2010, 21:43
Сообщение #105


Местный
***

Группа: Участник
Сообщений: 312
Регистрация: 9-04-10
Пользователь №: 56 532



Заработало он из за того, что в Sleep вызывается Kernel.Scheduler().

Но ведь почему бы не создать прерывание по таймеру. В котором бы вызывался планировщик процессов. Который бы и определял на основе приоритетов кому вернуть управление.
Go to the top of the page
 
+Quote Post

10 страниц V  « < 5 6 7 8 9 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 25th June 2025 - 18:49
Рейтинг@Mail.ru


Страница сгенерированна за 0.01497 секунд с 7
ELECTRONIX ©2004-2016