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

Начало работы с scmRTOS

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

Хочу вернуться к актуальному для меня сегодня вопросу определения размеров потребления стека процессами. scmRTOS порт IAR, AVR. Можно хотя бы пару строк кода примера привести? Допустим, создан объект

TKeyScan  KeyScan;          // Процесс обработки клавиатуры

с параметрами

typedef OS::process<OS::pr0, 250, 32> TKeyScan;   // Proc1;

Задача: вычислить реальные CSTACK, RSTACK , использованные этим процессом в runtime.

 

Ну, а вывести эти значения на ЖКИ в виде числа - это не проблема.

 

И второй вопрос. Размер CSTACK, RSTACK в опциях компилятора имеет отношение только к функциям, которые вызываются до запуска OS::Run() ?

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


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

Можно хотя бы пару строк кода примера привести?

 

Задача: вычислить реальные CSTACK, RSTACK , использованные этим процессом в runtime.

Примерно так: добавляем в конструктор процесса заполнение стека каким-то числом и добавляем функции сканирования стека:
        template<TPriority pr, word stack_size>
        class process : public TBaseProcess
        {
        public:
            INLINE process() : TBaseProcess(&Stack[stack_size/sizeof(TStackItem)]
                                      , pr
                                      , (void (*)())Exec)
            {
                TStackItem *pDst = Stack;
                word Size = StackPointer - Stack;
                while(Size)
                {
                    *pDst++ = 0xAB;
                    --Size;
                }
            }
            static int StackFree() 
            { 
                word Free = 0;
                for(;;)   // stack always has non-0xAB items.
                {
                    if( Stack[Free] != 0xAB )
                        return Free;
                    ++Free;
                }
            }
            static int StackUsed() { return stack_size - StackFree(); }
            ................

Для двухстекового варианта переделайте сами. Для простоты функции возвращают результат в количестве элементов стека (а не байтах, но для AVR они совпадают). Не проверял, но думаю идея понятна. Посмотрите также еще один вариант реализации.

И второй вопрос. Размер CSTACK, RSTACK в опциях компилятора имеет отношение только к функциям, которые вызываются до запуска OS::Run() ?
Да. Эти же стеки используются для прерываний, если вы выбрали #define scmRTOS_ISRW_TYPE TISRW_SS

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


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

добавляем в конструктор процесса заполнение стека каким-то числом
А разве стек в конструкторе (порт AVR) не инициализирован нулями?

 

Прошу прощения за ламерский вопрос. В этом конструкторе просто добавить функции static int StackFree() и static int StackUsed(), в которой вычислять Stack[Free] == 0 или еще что-то нужно еще менять?

OS::TBaseProcess::TBaseProcess(TStackItem* Stack, TStackItem* RStack, TPriority pr, void (*exec)())
    : StackPointer(Stack)
    , Priority(pr)
    , Timeout(0)
{
    Kernel.RegisterProcess(this);

    //---------------------------------------------------------------
    //
    //  Prepare Process Stack Frame
    //
    *(--RStack) = reinterpret_cast<word>(exec);                // return from interrupt address (low  byte)
    *(--RStack) = reinterpret_cast<word>(exec) >> 8;           // return from interrupt address (high byte)

    --StackPointer;                                            // emulate saving r31
    *(--StackPointer) =   0x80;                                // SREG value: I-bit set, enable interrupts
    *(--StackPointer) = reinterpret_cast<word>(RStack-1) >> 8; // SP (high byte)
    *(--StackPointer) = reinterpret_cast<word>(RStack-1);      // SP (low  byte)
    StackPointer     -= REGS_COUNT;                            // emulate saving regs (except r31)
}

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


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

И снова "уровень оптимизации".. :05: / см.следующий пост /

Дело в том, что у jacOS есть примечание для IAR C/EC++ for AVR 4.11A/W32 :

Вероятны проблемы при установке опций оптимизации Code motion (?) Cross Call (?)

Подтверждаю! / не верно! /

Условия:

- порт Сергея Борща (спасибо, Сергей! :a14: );

- SAM7S (256, опции "проекта" и xcl соответственно "подправлены");

- IAR AR C/C++ for ARM 4.40A;

- optimization - speed (high)

 

, если флаг Code motion не снят, то "сложные" (имеющие вложенные) ф-ции, вызванные из Процесса НЕ выполняются: / причина в малом размере стека!!!! /

OS_PROCESS void TProc2::Exec()
{
....
  for(;;)
    {
      Timer_Ovf.Wait();
....
         StDisp.Draw_Line(0,0,110,59,n);// А в "ней" вызыв."одноклассница" (TDisp) - Put_Pixel(x,x,x);
...
    }
}

Не знаю "чего и куда" компиллятор при оптимизации "motion" (видимо цикл обработки точек линии "выворачивает"), но только ОСь падает.. Интуитивно - что-то со стеком, НО его увеличение /не проводилось!!!/, даже "неразумное", ситуацию не меняет... (попытаюсь разобраться "через" Simulator)

...

И еще "побочный" вывод:

"Wiggleg + H-JTAG" - это, увы, скорее программатор, чем отладчик. Ни память "посмотреть", ни "останов" задать, ни "вообще"... :05:

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


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

Прошу прощения за предыдущий пост! (стыдно, но рука не "поднялась" его "пофиксить")

"Правды" в нем - только благодарность авторам! :)

Я не стек увеличивал, а размер контекста.... :lol:

#define scmRTOS_IDLE_PROCESS_STACK_SIZE     17 * sizeof(TStackItem)

А как только увеличил размер стека

typedef OS::process<OS::pr0, 200> TProc1;
typedef OS::process<OS::pr1, 400> TProc2;
typedef OS::process<OS::pr2, 200> TProc3;

, так сразу Code motion перестал оказывать "влияние".

....

Дизассембленый код, все же, посмотрел, разницы не увидел (опция Code motion ). Код функций неизмЕнен, функции на "своих" (одних и тех же) местах (две "верхние", во всяком случае). Глубина вложения "оказалась" - 4-ре уровня: линия->точка->формирование байта для записи->передача байта в LCD.

....

Попутно возник вопрос.. Как лучше поступать? Делать функции встраиваемыми, "экономя" ОЗУ, или использовать вложенные, увеличивая размер стека? Понимаю, что ответ, скорее всего будет, - "Все зависит от конкретной задачи.." Но все же.. Нужно ли, допустим, объявлять встраиваемыми функции, зависимые от платформы ("нижние", так сказать)?

Что подсказывает "опыт" и какой "стиль программирования" правильный?

Спасибо.

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


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

Как определить размеры потребления RSTACK процессами? Вариант Сергея Борща (сообщение #77) определения CSTACK работает, если функции-члены StackFree() и StackUsed() определить НЕ static, т.к. в них используется нестатические переменные Stack, RStack.

 

Пробовал вставить в конструктор процесса:

        template<TPriority pr, word stack_size, word rstack_size>
        class process : public TBaseProcess
        {
        public:
            INLINE process() : TBaseProcess( &Stack[stack_size/sizeof(TStackItem)] 
                                    , &RStack[rstack_size/sizeof(TStackItem)]
                                    , pr
                                    , (void (*)())Exec)
            {
             // Заполнить RSTACK процесса значением 0xAB
             TStackItem *pDst = RStack;
             word Size = GetReturnSP() - RStack;
             while(Size)
             {
                 *pDst++ = 0xAB;
                 --Size;
             }
             }  

            OS_PROCESS int RStackFree()
            {
                word Free = 0;
                for(;;)   // stack always has non-0xAB items.
                {
                    if( RStack[Free] != 0xAB )
                        return Free;
                    ++Free;
                }
            }
                      OS_PROCESS static void Exec();
        private:
            TStackItem Stack [stack_size/sizeof(TStackItem)];
            TStackItem RStack[rstack_size/sizeof(TStackItem)];
        };

Безрезультатно. После этого программа даже не запускается :(

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


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

Как определить размеры потребления RSTACK процессами? Вариант Сергея Борща (сообщение #77) определения CSTACK работает, если функции-члены StackFree() и StackUsed() определить НЕ static, т.к. в них используется нестатические переменные Stack, RStack.

 

Пробовал вставить в конструктор процесса:

Можно посоветовать внимательно посмотреть на количество циклов при заполнении памяти - правильное ли количество ячеек заполняется (т.е. правильно ли вычислен Size). Иначе (если больше), то там Memory Overwrite со всеми вытекающими.

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


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

Иначе (если больше), то там Memory Overwrite со всеми вытекающими.

Не работает, даже если уменьшить Size :

Size = GetReturnSP() - RStack - 2;

 

Странно, ведь при вычислении реального CSTACK эти функции работают...

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


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

Не работает, даже если уменьшить Size :

Size = GetReturnSP() - RStack - 2;

 

Странно, ведь при вычислении реального CSTACK эти функции работают...

Тут нужно не пытаться угадать, а просто посмотреть отладчиком (хотя бы на симуляторе) структуру stack frame и убедиться, что все делается правильно: заполнение, инициализация полей. Просто по шагам пройти спокойно и посмотреть. И заодно посмотреть, как происходит передача управления первому процессу (в OS_Start). Там будет видно, куда переход осуществляется, и видно причину, почему (если) не туда - значения в стеке.

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


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

При отладке демо-приложения в IAREW v 4.11b для MSP430 на точке останова вылетает следующее сообщение:

 

Tue Jul 28 15:06:49 2009: Breakpoint hit: Code @ main.cpp:123.9

Tue Jul 28 15:06:49 2009: The stack pointer for stack 'Stack' (currently Memory:0x402) is outside the stack range (Memory:0x9B0

to Memory:0xA00)

 

При этом программа работает. Так и должно быть или это ошибка? Объясните пожалуста.

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


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

При отладке демо-приложения в IAREW v 4.11b для MSP430 на точке останова вылетает следующее сообщение:

 

Tue Jul 28 15:06:49 2009: Breakpoint hit: Code @ main.cpp:123.9

Tue Jul 28 15:06:49 2009: The stack pointer for stack 'Stack' (currently Memory:0x402) is outside the stack range (Memory:0x9B0

to Memory:0xA00)

 

При этом программа работает. Так и должно быть или это ошибка? Объясните пожалуста.

Такое сообщение выскакивает когда stack plugin обнаруживает, что указатель стека указывает за пределы стека, обьявленного в среде по умолчанию.

Но в контексте применения данной ОС (как и многих других) указатель стека указывают на стеки процессов, которые находятся вне стека по умолчанию.

Единственный выход - отключить плагин stack.

Как при этом контролировать переполнения стеков - не спрашивайте, тема избитая и на форуме много раз обсуждалась.

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


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

Начал разбираться с scmRTOS.3.10. Ответьте, плз. на несколько вопросов.

1) смотрю пример 1-EventFlag, описание процесса:

typedef OS::process<OS::pr0, 120, 32> TProc1;

Что означает 32? В доке на V2.0 такого параметра нет.

 

2) Существует ли проблема локальных переменных, объявленных в разных процессах?

Когда происходит прерывание текущего процесса более приоритетным, тогда есть опасность порчи локальных переменных, ведь они формируются компилятором из кучи. Как быть? Объявлять их static? Чего-то я недопонимаю.

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


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

Начал разбираться с scmRTOS.3.10. Ответьте, плз. на несколько вопросов.

http://electronix.ru/forum/index.php?showt...st&p=734676

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


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

Начал разбираться с scmRTOS.3.10. Ответьте, плз. на несколько вопросов.

1) смотрю пример 1-EventFlag, описание процесса:

typedef OS::process<OS::pr0, 120, 32> TProc1;

Что означает 32? В доке на V2.0 такого параметра нет.

Как это нет? Раздел 6.3 (порт для AVR), стр 85.

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


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

Как это нет? Раздел 6.3 (порт для AVR), стр 85.

Извиняюсь, виноват, до порта еще не дочитал... :laughing:

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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