|
|
  |
Начало работы with scmRTOS, Несколько вопросиков |
|
|
|
Jun 28 2008, 08:38
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Цитата(dxp @ Mar 19 2008, 12:42)  Там все это совсем не сложно - адрес объекта известен, размер его полей до стека тоже известен, отсюда можно вычислить адрес, где начинается стек. Размер стека тоже известен. По сути надо просто от начала стека пройти до первого значения, которое отличается от значения по умолчанию (того, которым заполнен стек сначала). Это и будет размер свободного пространства в стеке. Далее, можно это опять же эмулятором смотреть, а можно вываливать хоть на терминал или куда удобно. Хочу вернуться к актуальному для меня сегодня вопросу определения размеров потребления стека процессами. scmRTOS порт IAR, AVR. Можно хотя бы пару строк кода примера привести? Допустим, создан объект Код TKeyScan KeyScan; // Процесс обработки клавиатуры с параметрами Код typedef OS::process<OS::pr0, 250, 32> TKeyScan; // Proc1; Задача: вычислить реальные CSTACK, RSTACK , использованные этим процессом в runtime. Ну, а вывести эти значения на ЖКИ в виде числа - это не проблема. И второй вопрос. Размер CSTACK, RSTACK в опциях компилятора имеет отношение только к функциям, которые вызываются до запуска OS::Run() ?
|
|
|
|
|
Jun 28 2008, 12:29
|

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

|
Цитата(alux @ Jun 28 2008, 11:38)  Можно хотя бы пару строк кода примера привести?
Задача: вычислить реальные 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 они совпадают). Не проверял, но думаю идея понятна. Посмотрите также еще один вариант реализации. Цитата(alux @ Jun 28 2008, 11:38)  И второй вопрос. Размер CSTACK, RSTACK в опциях компилятора имеет отношение только к функциям, которые вызываются до запуска OS::Run() ? Да. Эти же стеки используются для прерываний, если вы выбрали #define scmRTOS_ISRW_TYPE TISRW_SS
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jun 28 2008, 18:11
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Цитата(Сергей Борщ @ Jun 28 2008, 15:29)  добавляем в конструктор процесса заполнение стека каким-то числом А разве стек в конструкторе (порт 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) }
|
|
|
|
|
Jul 30 2008, 18:42
|

Частый гость
 
Группа: Свой
Сообщений: 105
Регистрация: 6-01-06
Пользователь №: 12 901

|
И снова "уровень оптимизации".. / см.следующий пост /Цитата(alux @ Mar 5 2008, 11:36)  Дело в том, что у jacOS есть примечание для IAR C/EC++ for AVR 4.11A/W32 : Цитата Вероятны проблемы при установке опций оптимизации Code motion (?) Cross Call (?)
Подтверждаю! / не верно! /Условия: - порт Сергея Борща (спасибо, Сергей!  ); - 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" - это, увы, скорее программатор, чем отладчик. Ни память "посмотреть", ни "останов" задать, ни "вообще"...
|
|
|
|
|
Jul 30 2008, 20:30
|

Частый гость
 
Группа: Свой
Сообщений: 105
Регистрация: 6-01-06
Пользователь №: 12 901

|
Прошу прощения за предыдущий пост! (стыдно, но рука не "поднялась" его "пофиксить") "Правды" в нем - только благодарность авторам! Я не стек увеличивал, а размер контекста.... Код #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. .... Попутно возник вопрос.. Как лучше поступать? Делать функции встраиваемыми, "экономя" ОЗУ, или использовать вложенные, увеличивая размер стека? Понимаю, что ответ, скорее всего будет, - "Все зависит от конкретной задачи.." Но все же.. Нужно ли, допустим, объявлять встраиваемыми функции, зависимые от платформы ("нижние", так сказать)? Что подсказывает "опыт" и какой "стиль программирования" правильный? Спасибо.
|
|
|
|
|
Apr 14 2009, 03:03
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Как определить размеры потребления 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)]; }; Безрезультатно. После этого программа даже не запускается
|
|
|
|
|
Apr 14 2009, 11:09
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Цитата(dxp @ Apr 14 2009, 09:04)  Иначе (если больше), то там Memory Overwrite со всеми вытекающими. Не работает, даже если уменьшить Size : Size = GetReturnSP() - RStack - 2; Странно, ведь при вычислении реального CSTACK эти функции работают...
|
|
|
|
|
Apr 15 2009, 06:41
|

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

|
Цитата(alux @ Apr 14 2009, 18:09)  Не работает, даже если уменьшить Size : Size = GetReturnSP() - RStack - 2;
Странно, ведь при вычислении реального CSTACK эти функции работают... Тут нужно не пытаться угадать, а просто посмотреть отладчиком (хотя бы на симуляторе) структуру stack frame и убедиться, что все делается правильно: заполнение, инициализация полей. Просто по шагам пройти спокойно и посмотреть. И заодно посмотреть, как происходит передача управления первому процессу (в OS_Start). Там будет видно, куда переход осуществляется, и видно причину, почему (если) не туда - значения в стеке.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Jul 28 2009, 11:16
|
Группа: Участник
Сообщений: 14
Регистрация: 14-04-09
Пользователь №: 47 644

|
При отладке демо-приложения в 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)
При этом программа работает. Так и должно быть или это ошибка? Объясните пожалуста.
|
|
|
|
|
Jul 28 2009, 12:36
|

Шаман
     
Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221

|
Цитата(Copypaster @ Jul 28 2009, 14:16)  При отладке демо-приложения в 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. Как при этом контролировать переполнения стеков - не спрашивайте, тема избитая и на форуме много раз обсуждалась.
|
|
|
|
|
Mar 24 2010, 10:09
|
Группа: Участник
Сообщений: 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? Чего-то я недопонимаю.
|
|
|
|
|
Mar 25 2010, 06:50
|
Группа: Участник
Сообщений: 10
Регистрация: 8-02-10
Пользователь №: 55 367

|
Цитата(dxp @ Mar 24 2010, 18:04)  Как это нет? Раздел 6.3 (порт для AVR), стр 85. Извиняюсь, виноват, до порта еще не дочитал...
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|