Перейти к содержанию
    

а) расход процессорного времени по процессам

В чем измерять? В тиках системного таймера?

 

Канал вообще не нужен, имхо. Нужны функции для получения требуемых данных, типа

TBaseProcess.GetFreeStack(), TBaseProcess.GetTimes()... етц. А уж как их вызовет пользователь - его дело.

Да, пожалуй надо только сами внутренние средства приделать и интерфейс к ним, а там уж видно будет, как лучше. Можно хоть по отдельности юзать, хоть какой-нить класс монитора написать и подключать к любому доступному каналу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В чем измерять? В тиках системного таймера?
Возможно. Как вариант - что-то поточнее. Вплоть до тиков таймера, на прерывании которого висит системный таймер. Ибо частенько процесс работает меньше тика системного таймера. Пользователя чаще интересует отношение загрузки между процессами, поэтому размерность не важна.

Самый простой вариант (применялся на моей предыдущей работе в другой операционке) - в прерывании системного таймера инкрементируется счетчик в активном процессе. Раз в несколько сотен прерываний накопленные значения переносятся в результат, счетчики обнуляются. Такой подход не учитывает время, потраченное на прерывания. Для его учета надо вклиниваться в точку переключения процессов и обертку прерываний.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Самый простой вариант (применялся на моей предыдущей работе в другой операционке) - в прерывании системного таймера инкрементируется счетчик в активном процессе.

Если какой-то процесс работает малое количество времени, то он вообще может не пересекаться с прерыванием системного таймера, и тогда он будет вообще казаться полностью неактивным. Наверное правильнее всего делать отсечки при переключении контекста - прямо в тактах, которыми тактируется системный таймер (реализация должна быть простой - через считывание значения таймера. Хотя тут есть трудности на некоторых платформах - например, у MSP430 системным таймером удобно взять сторожевого барбоса, а из него значения взять, насколько помню, нельзя :( ). Для каждой платформы тут должна быть своя функция (в порте), которая возвращает количество тактов (не тиков) частоты, тактирующей системный таймер. Иначе, имхо, смысла мало в таком сервисе.

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если какой-то процесс работает малое количество времени, то он вообще может не пересекаться с прерыванием системного таймера, и тогда он будет вообще казаться полностью неактивным.

Ну и пусть себе кажется неактивным, счётчик переключений контекста процесса покажет, что это не так. Тут, имхо, важно не переборщить. Размер стека нужно вычислять точно. А количество процессорного времени - всё равно получится приблизительным. Хотя, если в порте доставать тики таймера не накладно, то можно и их конечно:)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А можно как нибудь код процессов разнести по разным файлам?

У меня файл main.cpp на APM раздулся нешуточно. Уже надоедает его по полчаса листать в поисках процесса.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А что мешает? :)

Например, выносим процесс TProc1:

Создаём файл proc1.h:

#ifndef PROC1_H_INCLUDED
#define PROC1_H_INCLUDED
#include <scmRTOS.h>

typedef OS::process<OS::pr3, 1200> TProc1;

extern TProc1 Proc1;

#endif // PROC1_H_INCLUDED

 

И затем proc1.cpp:

#include "proc1.h"

namespace OS
{
    template <>
    OS_PROCESS void TProc1::Exec()
    {
        for (;;)
        {
            Sleep(100)
        }
    }
}
TProc1 Proc1;

Везде, где надо обращаться к Proc1 - пишем сначала

#include "proc1.h"

 

Или же, чтобы не запутаться в приоритетах, вынести все объявления процессов в один файл, типа procs.h:

#ifndef PROCS_H_INCLUDED
#define PROCS_H_INCLUDED
#include <scmRTOS.h>

typedef OS::process<OS::pr0, 1200> TProc0;
typedef OS::process<OS::pr1, 1200> TProc1;
typedef OS::process<OS::pr2, 1200> TProc2;

extern TProc0 Proc0;
extern TProc1 Proc1;
extern TProc2 Proc2;

#endif // PROCS_H_INCLUDED

 

Как-то так.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо. То, что доктор прописал.

 

Я пробовал разнести по разным файлам, но у меня компилятор вечно матерился.

 

ЗЫ: Закоментил в main.cpp namespace OS и все процессы. Вместо этого вставил инклуд #include "process/process.h".

 

В #include "process/process.h" описания процессов. И дальше в каждом отдельном файле код процесса.

Все компилится но компилятор никак не реагирует на ошибки в коде процесса и не включает этот код в прошивку. Т.е он собирает прошивку без процессов.

Изменено пользователем a9d

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну, эта проблема уже не связана scmRTOS. Нужно добавить новые *.cpp файлы к проекту, то есть указать компилятору, что их надо тоже компилировать. Способ зависит от компилятора (и IDE).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Подскажите пожалуйста:

 

Исходные данные. Ядро CortexM3.

scmRTOS_CONTEXT_SWITCH_SCHEME 1

 

Как передать управление другому процессу без использования SetSleep ?

Получается что процесс с высоким приоритетом не отдает управление

процессу с низким приоритетом.

 

Вставка SchedISR() в обработчик сис. таймера не помогает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Получается что процесс с высоким приоритетом не отдает управление

процессу с низким приоритетом.

И правильно. На то у него и более высокий приоритет.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ну я в принципе разобрался.

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

высокоприоритетные заберут сами. только в них надо ставить время ожидание не меньше 2 тиков.

а то не перепадет низкоприоритетному ничего.

 

жалко что нельзя два и более процесса сделать с одинаковым приоритетом.

Хотелось бы писать допустим чисто интерфейсные процессы, не думая где отдавать управление

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

жалко что нельзя два и более процесса сделать с одинаковым приоритетом.

Хотелось бы писать допустим чисто интерфейсные процессы, не думая где отдавать управление

При использовании вытесняющей ОС нужно программу строить как управляемую по событиям (event-driven). И интерфейсные процессы отлично ложатся под эту идеологию.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

... не думая где отдавать управление

В привычке думать, где отдавать управление, чувствуется опыт работы с кооперативными ОС.

Ломайте привычки, меняйте идеологию.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня состоит задача в том, чтобы по запросу возвращать самые актуальные данные. У меня два процесса один постоянно опрашивает датчики, обрабатывает показания записывает их в структуру и отсылает меседж. Второй процесс опрашивает трансивер и если пришел запрос, то проверяет is_non_empty() меседжа, и если там что-то есть, то отправляет данные.

 

1) Это нормально многократно перезаписывать сообщение не получая его?

2) Процесс может отправить сам себе сообщение? Иногда такое, тоже требуется.

3) Используя is_non_empty(), нужно ли потом вручную вызывать reset()?

4) При использовании wait() флаг наличия сообщения сбрасывается сам?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1) Это нормально многократно перезаписывать сообщение не получая его?

Можно, только прежние тела сообщения будут затёрты. Насколько это вас устраивает, я не знаю.

 

2) Процесс может отправить сам себе сообщение? Иногда такое, тоже требуется.

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

 

3) Используя is_non_empty(), нужно ли потом вручную вызывать reset()?

Можно. Почему нельзя?

 

4) При использовании wait() флаг наличия сообщения сбрасывается сам?

А в исходник посмотреть? :)

Если на момент посылки уже были ожидающие процессы, то флаг наличия и не будет установлен, ибо незачем.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...