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

 
 
18 страниц V  « < 2 3 4 5 6 > »   
Reply to this topicStart new topic
> Начало работы with scmRTOS, Несколько вопросиков
alux
сообщение Mar 18 2008, 07:50
Сообщение #46


Знающий
****

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



Как узнать точное использование стека процессами? А то я все делаю вслепую: выставил 100 - работает. Добавил ф-цию - зависает... Использую AVR (Mega324P). JTAG исключен из-за отсутствия свободных выводов. В симуляторе тоже проблематично (как получить ответ от перефирии I2C, SPI, ?..). Было бы совсем неплохо, если бы средствами ОС была возможность в отладочном режиме посмотреть размер неиспользуемого стека каждой задачи через терминал. Такую возможность я увидел в ОС нашего соотечественника uOS. Там для этой цели используется ф-ция task_stack_avail().

И второе. По поводу ф-ции Blink в режиме редактирования времени. Я это реализовал с использованием очереди сообщений, как в примере 3- Channel. Создал от базового класса TMsg объект Blink с методом InvertRect(...); Вопрос, собственно, заключается в следующем : Как обеспечить периодический MsgQueue.push(&Blink) ? Конечно, можно для этой цели использовать отдельный таймер, но хотелось бы обойтись системным таймером. Но не хочу использовать SystemTimerUserHook() по понятным причинам. Может воспользоваться OS::GetTickCount(); которая, на сколько я понял, возвращает общее количество тиков с момента запуска ОС ? Тогда при входе в п. меню "Редактирование" сохранить T = OS::GetTickCount(), а в низкоприоритетном процессе LCDProc отсчитывать от значения T 500 тиков (500*2=1сек) и тогда класть сообщение Blink в очередь. Также нужно учитывать переполнение счетчика. Что скажете?
Go to the top of the page
 
+Quote Post
dxp
сообщение Mar 18 2008, 09:02
Сообщение #47


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(alux @ Mar 18 2008, 13:50) *
Как узнать точное использование стека процессами?

Сергей Борщ советовал добавить в конструктор процесса memset, которая заполнит стековую память указанным значением. Стек для эксперимента надо взять с запасом. После этого делается прогон программы и анализируется глубина потребления стека.

Цитата(alux @ Mar 18 2008, 13:50) *
Вопрос, собственно, заключается в следующем : Как обеспечить периодический MsgQueue.push(&Blink) ? Конечно, можно для этой цели использовать отдельный таймер, но хотелось бы обойтись системным таймером. Но не хочу использовать SystemTimerUserHook() по понятным причинам. Может воспользоваться OS::GetTickCount(); которая, на сколько я понял, возвращает общее количество тиков с момента запуска ОС ? Тогда при входе в п. меню "Редактирование" сохранить T = OS::GetTickCount(), а в низкоприоритетном процессе LCDProc отсчитывать от значения T 500 тиков (500*2=1сек) и тогда класть сообщение Blink в очередь. Также нужно учитывать переполнение счетчика. Что скажете?

А что является инициатором (источником события) этого блинка? Вот оно и должно пихать в очередь сообщение. Если надо просто периодически мигать, то запуск по счетчику тиков, имхо, не самое плохое решение (если в отдельный процесс не выносить, а запускать из имеющегося, выполняющиегося с заданной периодичностью).


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
alux
сообщение Mar 18 2008, 09:38
Сообщение #48


Знающий
****

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



Цитата(dxp @ Mar 18 2008, 13:02) *
Сергей Борщ советовал добавить в конструктор процесса memset, которая заполнит стековую память указанным значением. Стек для эксперимента надо взять с запасом. После этого делается прогон программы и анализируется глубина потребления стека.
Что такое memset ? Можно поподробней?
Цитата(dxp @ Mar 18 2008, 13:02) *
А что является инициатором (источником события) этого блинка? Вот оно и должно пихать в очередь сообщение.
Инициатором Blink является вход в п. меню "Настройка", в котором меняется режим работы клавиатуры (вернее процесса ScanKey):
..............................
CurrentMode = &EditTime;
}
Цитата(dxp @ Mar 18 2008, 13:02) *
если в отдельный процесс не выносить, а запускать из имеющегося, выполняющееся с заданной периодичностью).
Т.е. есть необходимо, чтобы был отдельный процесс, который запускается с заданной периодичностью? Я думал для этой цели использовать низкоприоритетный процесс LCDProc, а заданную периодичность в нем же осуществлять проверкой OS::GetTickCount()? и каждые 500 тиков в этом же процессе делать MsgQueue.push(&Blink). Но почему-то это не сработало:
Код
OS_PROCESS void TProcLCD::Exec()    //TProc5
{
    for(;;)
    {
      CurrentTick = OS::GetTickCount();
      
      if(((CurrentTick-T) > 500)&&(CurrentMode == &EditTime))
      {
        MsgQueue.push(&Blink);
        T = CurrentTick;
      }
      
      TMsg* msg;
      
      MsgQueue.pop(msg);
      msg->run();
    }
}
Go to the top of the page
 
+Quote Post
dxp
сообщение Mar 18 2008, 13:13
Сообщение #49


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(alux @ Mar 18 2008, 15:38) *
Что такое memset ? Можно поподробней?

Функция такая. smile.gif

Цитата(alux @ Mar 18 2008, 15:38) *
Инициатором Blink является вход в п. меню "Настройка", в котором меняется режим работы клавиатуры (вернее процесса ScanKey):

Ну, вот из этого места и надо метать сообщение в очередь.

Я имел в виду нечто иное. Когда запускается Blink, то это самостоятельный процесс (просто запускаемый в качестве job), который сам отмеряет все времена и управляет требуемой периферией. Т.е. метнули сообщение в очередь, на том конце очереди сообщение извлекается и вызывается соответствующая функция, которая весь процесс мигания и осуществляет. Отработала, закончилась. Обработчик очереди готов к обработке следующего сообщения. Т.е. вся низкоуровневая работа по формированию времен возложена на виртуальную функцию объекта Blink. А код входа в меню только лишь мечет команду сделать это (путем помещения указателя на объект: &Blink).

Удобнее всего формировать времянки с помощью системных средств - той же функции Sleep(), например. Но для этого надо выделить целый процесс, что жалко, т.к. само по себе действие нечастое. Так вот делегирование выполнения операции позволяет совместить приятное с полезным - выполнять код в отдельном процессе (с использованием слипов и прочего) и в то же время не выделять индивидуально процесс под одну операцию, а зашарить его между всеми "желающими" - естественно, все их "желания" будут выполняться по очереди. Если все успевает, то все хорошо. Т.е. если, скажем, во время блинка срочно надо еще что-то сделать, то тогда ой. А если нет, то и пусть себе мигает отведенное ему время. Т.е. насколько этот вариант подходит под ваши требования, вам виднее.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
alux
сообщение Mar 18 2008, 15:19
Сообщение #50


Знающий
****

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



Цитата(dxp @ Mar 18 2008, 13:02) *
После этого делается прогон программы и анализируется глубина потребления стека.
Уж извините за назойливость. А каким образом проанализировать глубину потребления стека? Вернее, как просмотреть содержимое стека?
Go to the top of the page
 
+Quote Post
dxp
сообщение Mar 19 2008, 04:32
Сообщение #51


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(alux @ Mar 18 2008, 21:19) *
Уж извините за назойливость. А каким образом проанализировать глубину потребления стека? Вернее, как просмотреть содержимое стека?

В данном случае руками либо написав функцию, которая будет анализировать область памяти, занятую под стек - адреса-то все известны.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
alux
сообщение Mar 19 2008, 07:26
Сообщение #52


Знающий
****

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



Цитата(dxp @ Mar 19 2008, 08:32) *
В данном случае руками либо написав функцию, которая будет анализировать область памяти, занятую под стек - адреса-то все известны.

Что значит "руками" ? Или приведите, пожалуйста, пример функции.
Go to the top of the page
 
+Quote Post
dxp
сообщение Mar 19 2008, 09:42
Сообщение #53


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(alux @ Mar 19 2008, 13:26) *
Что значит "руками" ?

Руками - значит, остановить эмулятором прогон программы и посмотреть до куда стек заполнился.

Цитата(alux @ Mar 19 2008, 13:26) *
Или приведите, пожалуйста, пример функции.

Предлагаете написать мне для вас функцию? smile.gif Там все это совсем не сложно - адрес объекта известен, размер его полей до стека тоже известен, отсюда можно вычислить адрес, где начинается стек. Размер стека тоже известен. По сути надо просто от начала стека пройти до первого значения, которое отличается от значения по умолчанию (того, которым заполнен стек сначала). Это и будет размер свободного пространства в стеке. Далее, можно это опять же эмулятором смотреть, а можно вываливать хоть на терминал или куда удобно.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
alux
сообщение Mar 19 2008, 13:15
Сообщение #54


Знающий
****

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



Обнаружил такую проблему. Если два процесса ждут один и тот же Signal от третьего процесса, то почему-то программа виснет. Если ef.Wait() в одном из процессов убрать, то все работает. Размеры стеков увеличивал. Не помогло.
Код
OS_PROCESS void TMeasure::Exec()    //TProc1
{
    for(;;)
    {
      monitoring.Wait();
      
      while(Flags & MEASURE)
      {      
        PCInt1.Wait();    // Ждем окончания преобразования АЦП (RDY => 0)
        measure();  
      }
    }
}

OS_PROCESS void TProcFOSP::Exec()    //TProc2
{
    for(;;)
    {
      monitoring.Wait();  // <<<<<<< Если этот убрать, то работает
      Sleep();
    }
}
...........
При входе в п. меню:
  Flags |= MEASURE;
  ENABLE_PCINT1;      // Разрешить прерывание от RDY
  monitoring.Signal();  
}
Второй процесс вообще ничего не делает, только ждет и спит. В чем может быть проблема?
Go to the top of the page
 
+Quote Post
dxp
сообщение Mar 20 2008, 07:17
Сообщение #55


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(alux @ Mar 19 2008, 19:15) *
Обнаружил такую проблему. Если два процесса ждут один и тот же Signal от третьего процесса, то почему-то программа виснет. Если ef.Wait() в одном из процессов убрать, то все работает.

Возможное решение есть тут. Файлы OS_Services.h и OS_Services.cpp.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
alux
сообщение Mar 21 2008, 09:07
Сообщение #56


Знающий
****

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



Цитата(dxp @ Mar 20 2008, 11:17) *
Возможное решение есть тут. Файлы OS_Services.h и OS_Services.cpp.

Заменил эти файлы. Проблема осталась. Плюс перестала работать очередь сообщений. А есть ли смысл пробовать /branches/b1/Common_b2 Rev138 ?

PS. Прпробовал заменить файлы из /branches/b1/Common_b2 Rev138 . Обнаружил, что в файле scmRTOS_def.h отсутствует #include "scmRTOS_config.h" со всеми вытекающими ошибками. При подключении scmRTOS_config.h компилятор выдает ошибку:

Error[Pe144]: a value of type "byte" cannot be used to initialize an entity of type "OS::TPriority" D:\...\device\scmRTOS\Common\OS_Kernel.h 355
.
Go to the top of the page
 
+Quote Post
dxp
сообщение Mar 21 2008, 09:27
Сообщение #57


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(alux @ Mar 21 2008, 15:07) *
Заменил эти файлы. Проблема осталась. Плюс перестала работать очередь сообщений.

На данный момент ничего сказать не могу. У меня тоже есть проблемы с этим вариантом реализации в текущем проекте, поэтому я пока использую штатный вариант из trunk. Скоро доберусь до этого. Автор варианта правки бага в этой ветке Сергей Борщ, возможно, он сможет прокомментировать.

Цитата(alux @ Mar 21 2008, 15:07) *
А есть ли смысл пробовать /branches/b1/Common_b2 Rev138 ?

Это тоже Сергей тренировался (Common_b2), но вся эта ветка (b1) - это полигон для отработки других вещей, никак не связанных с фиксом bug_1878045_fix. Т.ч. тут не ищите.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
alux
сообщение Mar 21 2008, 10:39
Сообщение #58


Знающий
****

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



Попробовал создать отдельный ef2 для TProc2 и
Код
...........
при входе в п. меню:
  Flags |= MEASURE;
  ENABLE_PCINT1;      // Разрешить прерывание от RDY
  monitoring.Signal();
  ef2.Signal();
Не помогло. Программа виснет и все тут... sad.gif
Go to the top of the page
 
+Quote Post
dxp
сообщение Mar 21 2008, 13:58
Сообщение #59


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(alux @ Mar 21 2008, 16:39) *
Попробовал создать отдельный ef2 для TProc2 и
Код
...........
при входе в п. меню:
  Flags |= MEASURE;
  ENABLE_PCINT1;      // Разрешить прерывание от RDY
  monitoring.Signal();
  ef2.Signal();
Не помогло. Программа виснет и все тут... sad.gif

Т.е. два разных флага для разных процессов? Ну, тогда не в них дело. А чем смотрите? В смысле, какие отладочные средства есть?


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
alux
сообщение Mar 21 2008, 14:46
Сообщение #60


Знающий
****

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



Отладчиком (JTAG) не пользуюсь по причине отсутствия свободных выводов. Наблюдаю визуально по программе: перестает реагировать на кнопки и не выводит результат на экран через очередь сообщений.
Цитата(dxp @ Mar 21 2008, 17:58) *
Ну, тогда не в них дело.
А в чем же дело? Два процесса ждут Signal, каждый от своего EventFlag. В процессах после Wait() идет Sleep(). Когда из третьего процесса (из п. меню) даю ef1.Signal() и ef2.Signal() для процессов, то все виснет. В смысле остальные процессы не работают. Что я делаю не так ? 05.gif
Go to the top of the page
 
+Quote Post

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

 


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


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