Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Начало работы with scmRTOS
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > scmRTOS
Страницы: 1, 2, 3, 4, 5, 6
dxp
Цитата(alux @ Mar 18 2008, 21:19) *
Уж извините за назойливость. А каким образом проанализировать глубину потребления стека? Вернее, как просмотреть содержимое стека?

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

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

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

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

Предлагаете написать мне для вас функцию? smile.gif Там все это совсем не сложно - адрес объекта известен, размер его полей до стека тоже известен, отсюда можно вычислить адрес, где начинается стек. Размер стека тоже известен. По сути надо просто от начала стека пройти до первого значения, которое отличается от значения по умолчанию (того, которым заполнен стек сначала). Это и будет размер свободного пространства в стеке. Далее, можно это опять же эмулятором смотреть, а можно вываливать хоть на терминал или куда удобно.
alux
Обнаружил такую проблему. Если два процесса ждут один и тот же 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();  
}
Второй процесс вообще ничего не делает, только ждет и спит. В чем может быть проблема?
dxp
Цитата(alux @ Mar 19 2008, 19:15) *
Обнаружил такую проблему. Если два процесса ждут один и тот же Signal от третьего процесса, то почему-то программа виснет. Если ef.Wait() в одном из процессов убрать, то все работает.

Возможное решение есть тут. Файлы OS_Services.h и OS_Services.cpp.
alux
Цитата(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
.
dxp
Цитата(alux @ Mar 21 2008, 15:07) *
Заменил эти файлы. Проблема осталась. Плюс перестала работать очередь сообщений.

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

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

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

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

Т.е. отладкой вообще не пользуетесь. sad.gif Это не есть гуд. Почти всегда необходимо иметь какой-то канал для отладки - не JTAG, так вывод на терминал (а еще лучше их оба, т.е. они вполне комплементарны), не вывод на терминал, так вывод еще куда-нибудь, но так, чтобы этот канал был усточивым к траблам в программе. Да хоть ножкой МК помахать. Если у вас есть экран, то, может, на него попробовать выводить отладочную инфу, если это не сложно.

Цитата(alux @ Mar 21 2008, 20:46) *
А в чем же дело? Два процесса ждут Signal, каждый от своего EventFlag. В процессах после Wait() идет Sleep(). Когда из третьего процесса (из п. меню) даю ef1.Signal() и ef2.Signal() для процессов, то все виснет. В смысле остальные процессы не работают. Что я делаю не так ? 05.gif

Не могу сказать, "удаленно лечить не умею" smile.gif. Попробуйте на симуляторе прогнать, возможно, там можно будет увидеть проблему.

Про OS::EventFlag мы знаем только один баг, и он проявляется в ситуации, когда два процесса ждут одновременно одного и того же флага. Общего утвержденного решения пока нет - есть частные, но они имеют проблемы с совместимостью поведения. Наиболее близким к желаемому вариантом является bug_1878045_fix, но он пока как следует не оттестирован, ждет своей очереди. Но два отдельных непересекающихся флага - это не сюда.

В общем, попробуйте наладить какой-то канал отладки в железе и/или погонять в симуляторе - если ошибка логическая, то там ее несложно будет отловить.
alux
Вроде нашел еще один свой прокол : Скорость поступления данных из TMeasure в канал по крайней мере в 5 раз выше, чем скорость считывания из канала в TProcLCD. Возможно из-за этого были проблемы. Пока проверить не могу. Позже сообщу. По поводу симулятора. Как раз об этом думаю. Осталось разобраться с написанием макросов для симуляции прерываний и периферии. Заодно можно будет посмотреть использование стека каждым процессом.

PS. Перед отправкой в канал сделал проверку свободного места:
Код
          if(MsgQueue.get_count() < 3)
            MsgQueue.push(&ReDraw);

Проверил. Проблема осталась. Т.е. когда два процесса ждут каждый свой EventFlag , то при подаче Сигналов из третьего процесса, программа виснет. То же самое и для одного общего флага. Кроме этого не могу понять, почему максимально возможное значение АЦП 0xffffff , которое я отправляю через очередь сообщений для TProcLCD, на индикатор выводится 0x4b7fffff. В данным момент в канал больше никто ничего не посылает. Проверял printf действительное значение АЦП перед запуском ОС (0xffffff) ? sad.gif


PS2. Так, это уже слишком... При входе в пункт меню устанавливаю глобальный флаг (не EventFlag): Flags |= MEASURE; В процессе TMeasure в качестве отладки использую инвертирование знакоместа на ЖКИ и printf:
Код
OS_PROCESS void TMeasure::Exec()    //TProc1
{
    for(;;)
    {
      monitoring.Wait();
      
//      while(Flags & MEASURE)
      for(unsigned char i=0;i<20;i++)
      {      
        PCInt1.Wait();    // Ждем окончания преобразования АЦП (RDY => 0)
        //measure();  
        MsgQueue.push(&Blink);
        printf_P("\n\rFlags: %d\n", Flags);
        Sleep(500);
      }
    }
}
Выяснилось, что после нулевой итерации Flags = 1, а после первой Flags=0 ! При этом в других процессах нет обращений к Flags. Что за... 07.gif Почему обнуляется глобальный флаг?
alux
Прошу прощения за невнимательность. Проблема с обнулением глобального флага связана с использованием ф-ции printf.

PS. Кстати, этот маленький эксперимент с printf натолкнул меня на мысль, что возможная проблема с неправильным выводом данных на ЖКИ (0x4b7fffff вместо 0xffffff) связана с тем, что в реализации ReDraw используются функция-"пожиратель" стека: sprintf_P. А под процесс ProcLCD, в котором используется этот метод выделено 200 байт. Необходимо заменить sprintf на что-нибудь полегче. И к тому же это могло приводить к зависанию программы. Я прав?
sevstels
Хочу поинтересоваться, это только у меня не запускается симулятор IAR в проекте с scmRTOS, или так и должно быть?
IgorKossak
Цитата(alux @ Mar 23 2008, 17:25) *
... в реализации ReDraw используются функция-"пожиратель" стека: sprintf_P. А под процесс ProcLCD, в котором используется этот метод выделено 200 байт. Необходимо заменить sprintf на что-нибудь полегче. И к тому же это могло приводить к зависанию программы. Я прав?

Более чем правы.

Цитата(sevstels @ Mar 25 2008, 11:11) *
Хочу поинтересоваться, это только у меня не запускается симулятор IAR в проекте с scmRTOS, или так и должно быть?

У меня запускается и симулятор и эмулятор.
А без scmRTOS запускается? Или что Вы понимаете под фразой "не запускается"?
sevstels
Тестировал на примерах scmRTOS v3 AVR.
Изменил только настройки для работы с симулятором.
Компилируется идеально, без ошибок или предупреждений.
Но старт отладки не происходит. Стал искать наличие *.d90, его нигде нет .... хотя в окне workspace он присутствует. Открыл несколько своих старых проектов, там симулятор работает без проблем.

Подумал, что в EWL версии ввели ограничение на размер кода.
Установил полную версию IAR 5.10a
Результат тот же - ни в одном примере c scmRTOS симулятор не работает и *.d90 не создаётся... sad.gif
IgorKossak
sevstels, приложите к сообщению файл проекта (.ewp) и файл .ewd с настройками отладчика.
sevstels
Пока пытаюсь найти причину сам.
Вот нашёл вот тут:
http://scmrtos.sourceforge.net/releases/avr/

-DENABLE_BIT_DEFINITIONS
-I$TOOLKIT_PATH$\AVR\inc
-I$TOOLKIT_PATH$\AVR\inc\dlib

TOOLKIT_PATH - отсутствует такое определение в IAR5.10
Есть TOOLKIT_DIR, см EWAVR_UserGuide.pdf стр 263(303)

DENABLE_BIT_DEFINITIONS - тоже не нашёл такого нигде..
а вот ENABLE_BIT_DEFINITIONS есть
IgorKossak
Цитата(sevstels @ Mar 26 2008, 07:27) *
DENABLE_BIT_DEFINITIONS - тоже не нашёл такого нигде..
а вот ENABLE_BIT_DEFINITIONS есть

Это одно и то же (одно в xcl файле, другое в настройках).
Опцию линкера -D смотрите.
Ykidia
Здравствуйте! Есть небольшой проектик под scmRTOS, ранее созданный для IAR EWARM 4.41, микроконтроллер LPC2148. Поставил EWARM 5.11 для пробы, но как-то не удается сделать так, чтобы, как и раньше, в векторах по адресам #00-#3F мирно сосуществовали как части из стандартного cstartup, так и части из OS_Target_asm. Поменял сегменты на секции, ORG на LTORG и т.д., но при компиляции в векторах присутствует либо только код из cstartup (т.е. нет частей ОС для программного и аппаратных IRQ/FIQ прерываний), либо только из OS_Target_asm (т.е. по 0-му вектору например находится какой-то мусор). Пытался менять :ROOT(x) в строках объявлений секций, что и приводило к вытеснению либо содержимого cstartup.s, либо OS_Target_asm.s.
Что нужно сделать либо есть может у кого уже адаптированный OS_Target_asm.s для EWARM 5.11 ? Спасибо.
spf
Цитата(Ykidia @ Mar 26 2008, 15:33) *
Что нужно сделать либо есть может у кого уже адаптированный OS_Target_asm.s для EWARM 5.11 ? Спасибо.


Господа! Ну зачем все пихать в одну тему ?????

Почему нельзя создать новую, в которой и будет обсуждаться конкретный вопрос?

PS:
А еще лучше задать вопрос в рассылке scmRTOS.
Ykidia
Хорошо-хорошо, уже создал. Зачем кричать-то? smile.gif
sevstels
Игорь, в общем, ничего к сожалению не получается.
Файл *.d90 создаётся, но симулятор всё равно не работает.
IgorKossak
Цитата(sevstels @ Mar 27 2008, 05:48) *
Игорь, в общем, ничего к сожалению не получается.
Файл *.d90 создаётся, но симулятор всё равно не работает.

С Вашими настройками симулятор запустился и работает.
Попробуйте отключить опцию Debugger->Setup->Setup macros на случай если подхватываются левые макросы. Отключите плагины Debugger->Plugins если они криво встали. Если ничего не поможет, переустановите продукт.
sevstels
Цитата(IgorKossak @ Mar 27 2008, 15:45) *
Если ничего не поможет, переустановите продукт.


Ничего не помогло, переустановка тоже.
А спасло простое нажатие на кнопочку "Factory Settings" по пути: Project->Options->Simulator->Factory Settings. Странно конечно, нет там вроде никаких установок. Но заработало ... 07.gif
alux
Цитата(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() ?
Сергей Борщ
Цитата(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
alux
Цитата(Сергей Борщ @ 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)
}
Stas633
И снова "уровень оптимизации".. 05.gif / см.следующий пост /
Цитата(alux @ Mar 5 2008, 11:36) *
Дело в том, что у jacOS есть примечание для IAR C/EC++ for AVR 4.11A/W32 :
Цитата

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


Подтверждаю! / не верно! /
Условия:
- порт Сергея Борща (спасибо, Сергей! a14.gif );
- 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.gif
Stas633
Прошу прощения за предыдущий пост! (стыдно, но рука не "поднялась" его "пофиксить")
"Правды" в нем - только благодарность авторам! smile.gif
Я не стек увеличивал, а размер контекста.... lol.gif
Код
#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.
....
Попутно возник вопрос.. Как лучше поступать? Делать функции встраиваемыми, "экономя" ОЗУ, или использовать вложенные, увеличивая размер стека? Понимаю, что ответ, скорее всего будет, - "Все зависит от конкретной задачи.." Но все же.. Нужно ли, допустим, объявлять встраиваемыми функции, зависимые от платформы ("нижние", так сказать)?
Что подсказывает "опыт" и какой "стиль программирования" правильный?
Спасибо.
alux
Как определить размеры потребления 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)];
        };

Безрезультатно. После этого программа даже не запускается sad.gif
dxp
Цитата(alux @ Apr 14 2009, 10:03) *
Как определить размеры потребления RSTACK процессами? Вариант Сергея Борща (сообщение #77) определения CSTACK работает, если функции-члены StackFree() и StackUsed() определить НЕ static, т.к. в них используется нестатические переменные Stack, RStack.

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

Можно посоветовать внимательно посмотреть на количество циклов при заполнении памяти - правильное ли количество ячеек заполняется (т.е. правильно ли вычислен Size). Иначе (если больше), то там Memory Overwrite со всеми вытекающими.
alux
Цитата(dxp @ Apr 14 2009, 09:04) *
Иначе (если больше), то там Memory Overwrite со всеми вытекающими.

Не работает, даже если уменьшить Size :
Size = GetReturnSP() - RStack - 2;

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

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

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

При этом программа работает. Так и должно быть или это ошибка? Объясните пожалуста.
IgorKossak
Цитата(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.
Как при этом контролировать переполнения стеков - не спрашивайте, тема избитая и на форуме много раз обсуждалась.
Embedder74
Начал разбираться с scmRTOS.3.10. Ответьте, плз. на несколько вопросов.
1) смотрю пример 1-EventFlag, описание процесса:
typedef OS::process<OS::pr0, 120, 32> TProc1;
Что означает 32? В доке на V2.0 такого параметра нет.

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

http://electronix.ru/forum/index.php?showt...st&p=734676
dxp
Цитата(Embedder74 @ Mar 24 2010, 16:09) *
Начал разбираться с scmRTOS.3.10. Ответьте, плз. на несколько вопросов.
1) смотрю пример 1-EventFlag, описание процесса:
typedef OS::process<OS::pr0, 120, 32> TProc1;
Что означает 32? В доке на V2.0 такого параметра нет.

Как это нет? Раздел 6.3 (порт для AVR), стр 85.
Embedder74
Цитата(dxp @ Mar 24 2010, 18:04) *
Как это нет? Раздел 6.3 (порт для AVR), стр 85.

Извиняюсь, виноват, до порта еще не дочитал... laughing.gif
Embedder74
Пользуясь случаем, хочу спросить у DXP. Когда примерно вы планируете выпуск мануала ОСи V3.1?
dxp
Цитата(Embedder74 @ Mar 25 2010, 15:03) *
Пользуясь случаем, хочу спросить у DXP. Когда примерно вы планируете выпуск мануала ОСи V3.1?

Определенно сказать не могу. Тот функционал, который существует сейчас, на 90% (если не больше) закрыт мануалом версии 2. Есть планы относительно новых возможностей, когда они будет реализованы, тогда и будет смысл выпускать новую документацию. По срокам ничего обещать не могу, планировал еще года полтора все это сделать, но текущая работа съедает все время. Удается только выкраивать какие-то куски на решение текущих вопросов по проекту.
jorikdima
Ну и я что ли спрошу.
Почему в проекте, написанном на С++ вы используете модификаторы доступа private а не protected, например в классах описывающих сервисы? Я вот захотел малость дополнить/изменить функционал кольцевого буфера TCbuf, унаследовавшись от него, и не получил доступа к полям
Код
private:
        byte* buf;
         byte  size;
         volatile byte count;
         byte  first;
         byte  last;

без изменения исходника ОС.
dxp
Цитата(jorikdima @ Mar 26 2010, 14:46) *
Почему в проекте, написанном на С++ вы используете модификаторы доступа private а не protected, например в классах описывающих сервисы? Я вот захотел малость дополнить/изменить функционал кольцевого буфера TCbuf, унаследовавшись от него, и не получил доступа к полям

Потому, что этот класс не предназначался для того, чтобы его расширять наследованием, а только лишь как основа для сервиса TChannel. И оба класса уже давно obsolete, вместо них лучше использовать шаблоны ring_buffer и channel соответственно, которые универсальнее и функциональнее.
jorikdima
Цитата(dxp @ Mar 26 2010, 15:54) *
Потому, что этот класс не предназначался для того, чтобы его расширять наследованием, а только лишь как основа для сервиса TChannel. И оба класса уже давно obsolete, вместо них лучше использовать шаблоны ring_buffer и channel соответственно, которые универсальнее и функциональнее.

Сорри, я как раз ring_buffer и использовал, перепутал. Но это не имеет значение, я говорил вообще про все классы. TEventFlag например, или тот же channel. У всех есть поля private. Почему бы не предназначить эти классы в том числе для расширения наследованием? Ведь всего-то надо сделать поля не private, а protected smile.gif
Сергей Борщ
Цитата(jorikdima @ Mar 26 2010, 15:24) *
Почему бы не предназначить эти классы в том числе для расширения наследованием? Ведь всего-то надо сделать поля не private, а protected smile.gif
Это цель новой версии, которая уже почти 2 года зреет в ветке TService репозитория - унаследовать все сервисы от одного базового класса с механизмом доступа к ядру и дать пользователю возможность самостоятельно создавать новые сервисы.
dxp
Цитата(jorikdima @ Mar 26 2010, 19:24) *
Сорри, я как раз ring_buffer и использовал, перепутал. Но это не имеет значение, я говорил вообще про все классы. TEventFlag например, или тот же channel. У всех есть поля private. Почему бы не предназначить эти классы в том числе для расширения наследованием? Ведь всего-то надо сделать поля не private, а protected smile.gif

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

И всегда остается возможность строить свои типы на основе включения штатных сервисов.

Кстати, ring_buffer - это не сервис, а просто реализация кольцевого буфера. Что вам не хватает в его реализации, что вы хотите отнаследоваться и написать свой вариант?
jorikdima
Цитата(dxp @ Mar 26 2010, 17:48) *
Кстати, ring_buffer - это не сервис, а просто реализация кольцевого буфера. Что вам не хватает в его реализации, что вы хотите отнаследоваться и написать свой вариант?

Приведу конкретный пример, удачный, неудачный - неважно.
Я использую кольцевой буфер для хранения данных, которые я выдаю наружу через UART, используя DMA. Для зарядки DMA нужно знать адрес, по которому хранится первый элемент и размер. Можно сделать, например так: вычитываем все что есть в буфере в переменную (массив, лучше глобальный) и даем DMA адрес этого массива. Тут всего текущего функционала достаточно. Но это требует удвоенного RAM и постоянного перекладывания "из одного кармана в другой". Я бы предпочел указывать DMA адрес, где уже хранятся даные в ring_buffer, создав наследника и добавив функцию возвращения адреса. Для этого мне нужен доступ к его private полям, который я получил бы, будь они protected, наследованием. В данном примере мне доступ к ядру не нужен.
Быть может это редкий случай, когда можно применять наследование?
dxp
Цитата(jorikdima @ Mar 27 2010, 12:51) *
Приведу конкретный пример, удачный, неудачный - неважно.
Я использую кольцевой буфер для хранения данных, которые я выдаю наружу через UART, используя DMA.

А что, у вас DMA контроллер умеет читать по кольцу с произвольного адреса (делать wrap around при достижении границы пула памяти, выделенной под кольцевой буфер)? И кто будет модифицировать состояние объекта-буфера - head/tail указатели, count и т.д.? Просто так вычитать с "черного хода" данные недостаточно для корректной работы кольцевого буфера. Может я чего-то не понял, но такой вариант выглядит как грязный хак.
jorikdima
Цитата(dxp @ Mar 27 2010, 16:31) *
А что, у вас DMA контроллер умеет читать по кольцу с произвольного адреса (делать wrap around при достижении границы пула памяти, выделенной под кольцевой буфер)? И кто будет модифицировать состояние объекта-буфера - head/tail указатели, count и т.д.? Просто так вычитать с "черного хода" данные недостаточно для корректной работы кольцевого буфера. Может я чего-то не понял, но такой вариант выглядит как грязный хак.

Нет, DMA по кольцу не читает (про MSP430 речь). О wrap around забочусь я, если вижу, что не вычитанные данные "разрываются", то на вход DMA даю только те данные, которые идут от текущего места до конца линейного буфера, а остальное в следующий раз. Модифицирую состояние объекта-буфера - head/tail указатели, count и т.д я при таком вот чтении. Тут конечно кроется момент, связынный с тем, что сообщив на вход DMA адрес начала данных, запустив его на передачу и модифицировав count и head указатель, я по настоящему то буфер еще не освободил (пока DMA не отработал до конца). Но я сам гарантирую в своем софте, что не затру ту часть данных, которая с точки зрения кольцевого буфера свободна (а по факту еще не вычитана), новыми данными. Гарантирую это знанием о частоте прихода новых данных и размером кольцевого буфера, взятого с запасом.
Собственно это конечно не есть пример грамотного программирования, быть может smile.gif, но пример наследования, где private модификатор мне пришлось поменять на protected.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.