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

Использую операционную систему scmRTOS на микроконтроллерах MSP430 (в основном F169 и F1611), все замечательно, но есть одна проблема.

Хотелось бы переводить МК в режим пониженного энергопотребления (например, LPM3), когда ему нечем заняться. Насколько я понимаю, для этого достаточно в теле функции void OS::IdleProcessUserHook() выполнить команду _BIS_SR(LPM3_bits). В результате МК "заснет" до следующего прерывания от сторожевого таймера, от которого тактируется планировчик задач ОС. В обработчике прерывания нужно выполнить _BIC_SR_IRQ(LPM3_bits), чтобы МК нормально вернулся в активный режим. Но проблема в том, что код обработчика прерывания от сторожевого таймера является частью scmRTOS, а добавление одной строчки "_BIC_SR_IRQ(LPM3_bits)" приведет к нарушению условий лицензии на scmRTOS.

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

 

P.S.

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

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


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

Использую операционную систему scmRTOS на микроконтроллерах MSP430 (в основном F169 и F1611), все замечательно, но есть одна проблема.

Хотелось бы переводить МК в режим пониженного энергопотребления (например, LPM3), когда ему нечем заняться. Насколько я понимаю, для этого достаточно в теле функции void OS::IdleProcessUserHook() выполнить команду _BIS_SR(LPM3_bits). В результате МК "заснет" до следующего прерывания от сторожевого таймера, от которого тактируется планировчик задач ОС. В обработчике прерывания нужно выполнить _BIC_SR_IRQ(LPM3_bits), чтобы МК нормально вернулся в активный режим. Но проблема в том, что код обработчика прерывания от сторожевого таймера является частью scmRTOS, а добавление одной строчки "_BIC_SR_IRQ(LPM3_bits)" приведет к нарушению условий лицензии на scmRTOS.

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

Там для системного таймера есть тоже соответсвующий хук. Его нужно разрешить в конфигурации и определить его потроха.

 

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

Вы как будто не в России. :)

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


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

Там для системного таймера есть тоже соответсвующий хук. Его нужно разрешить в конфигурации и определить его потроха.

Это я знаю, но как-то не подумал его использовать для сброса флагов LPM-режима. Надо будет попробовать. Спасибо.

Вы как будто не в России. :)

В России, но я же говорю, что хочу хотя бы что-то честно использовать:) Тем более что автор scmRTOS денег за нее не хочет, а просит просто не курочить.

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


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

Вы как будто не в России. :)

Тем более что автор scmRTOS денег за нее не хочет, а просит просто не курочить.

Ну, думается, что сломать Вы там ничего не сломаете так, чтоб нанести ущерб автору. :) И потом, я знаю, что народ рихтует под себя, не боится. Никто еще не пострадал от гнева автора. :biggrin:

 

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

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


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

Вы как будто не в России. :)

Тем более что автор scmRTOS денег за нее не хочет, а просит просто не курочить.

Ну, думается, что сломать Вы там ничего не сломаете так, чтоб нанести ущерб автору. :) И потом, я знаю, что народ рихтует под себя, не боится. Никто еще не пострадал от гнева автора. :biggrin:

 

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

Да, проблема с совместимостью тоже является одной из причин нежелания делать "тюнинг" операционки.

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

 

Кстати, по поводу "рихтования". Вы случайно не встречали порта scmRTOS на 51-семейство?

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


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

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

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

 

Кстати, по поводу "рихтования". Вы случайно не встречали порта scmRTOS на 51-семейство?

Нет, все порты лежат вместе. Для 51-го оно врядли появится по причине того, что на оный МК даже С ложится плохо, а уж С++... К тому же, не помню, чтобы для 51-го вообще был С++, может быть ошибаюсь.

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


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

Поправьте меня, если ошибаюсь: в изначальном виде порт scmRTOS для MSP430 заточен под использование сторожевого таймера в режиме источника периодических прерываний => точности по времени в вызовах типа OS::Sleep( MY_FAVORITE_PROTOCOL_TIMEOUT ) - никакой => править надо по-любому?

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


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

Поправьте меня, если ошибаюсь: в изначальном виде порт scmRTOS для MSP430 заточен под использование сторожевого таймера в режиме источника периодических прерываний => точности по времени в вызовах типа OS::Sleep( MY_FAVORITE_PROTOCOL_TIMEOUT ) - никакой => править надо по-любому?

А что вы хотите править?

Просто по умолчанию сторожевой таймер тактируется внутренним генератором DCO, у которого действительно частота "гуляет". Если вам нужно точнее, то можете при загрузке ОС перенастроить сторожевой таймер на внешний тактовый сигнал, например, часовой кварц. Сделать это можно в функции OS::SystemStartUserHook(). То есть штатные средства вам позволяют это сделать и править исходники нет необходимости.

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


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

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

Задача переходит в режим пониженного потребления функцией _BIS_SR (LPM3_bits+GIE).

Попробовал выйти из пониженного режима энергопотребления, используя вызов функции _BIC_SR_IRQ (LPM3_bits) в хуке системного таймера ОС. При компиляции выдает ошибку This intrinsic function can only be used in interrupt or monitor function. Посмотрел в исходники операционки - действительно хук не имеет модификатора __inline или __monitor. Как тогда выйти из режима power down?

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


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

Задача переходит в режим пониженного потребления функцией _BIS_SR (LPM3_bits+GIE).

Попробовал выйти из пониженного режима энергопотребления, используя вызов функции _BIC_SR_IRQ (LPM3_bits) в хуке системного таймера ОС. При компиляции выдает ошибку This intrinsic function can only be used in interrupt or monitor function. Посмотрел в исходники операционки - действительно хук не имеет модификатора __inline или __monitor. Как тогда выйти из режима power down?

А если написать свою __inline __monitor функцию, из которой звать означенный интринсик, а вызов самой этой функции поместить в хук?

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


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

А если написать свою __inline __monitor функцию, из которой звать означенный интринсик, а вызов самой этой функции поместить в хук?

Пробовал. Не помагает. Восстанавливается контекс задачи и вместе с ним состояние бита CPUOFF....

 

Дело в том что насколько я понимаю BIC_SR_IRQ функция меняет состояние битов не в самом теле функции а на выходе из нее ... Если не использовать операционную систему то применяют BIC_SR_IRQ в обработчике прерывания ... вызываемого при необходимости выхода из режима power down. Если использовать функцию BIC_SR_IRQ во вложенной в вызываемой из прерывания функции пусть даже __inerrupt и __monitor, модификация бита CPUOFF произойдет не на выходе из прерывания а внутри него..поправьте если я не прав.

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

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


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

Пробовал. Не помагает. Восстанавливается контекс задачи и вместе с ним состояние бита CPUOFF....

 

Дело в том что насколько я понимаю BIC_SR_IRQ функция меняет состояние битов не в самом теле функции а на выходе из нее ... Если не использовать операционную систему то применяют BIC_SR_IRQ в обработчике прерывания ... вызываемого при необходимости выхода из режима power down. Если использовать функцию BIC_SR_IRQ во вложенной в вызываемой из прерывания функции пусть даже __inerrupt и __monitor, модификация бита CPUOFF произойдет не на выходе из прерывания а внутри него..поправьте если я не прав.

Стоп, стоп. Тогда, как я понимаю, дело совсем не в этом. Этот интринсик сбрасывает бит не в реальном SR, а в его копии, находящейся в стеке, куда эта копия попадает при сохранении SR во время входа в прерывание (или при вызове __monitor функций). Смысл этого в том, чтобы нужный бит в SR был сброшен после выхода из прерывания - менять бит в SR, находясь в прерывании смысла имеет мало - при выходе процессор аппаратно восстанавливает сохраненное при входе значение SR, поэтому значение SR, когда процессор находится в прерывании, при выходе из прерывания теряется.

 

Исходя из вышесказанного, применять этот интринсик всегда нужно только в прерывании безотносительно к тому, используется ОС или нет. ОС - это обычная программа, на логику применения обсуждаемого интринсика это влияния оказывать не должно.

 

И к хуку IdleProcess'а все это отношения не имеет.

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


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

Даже не так. При применении _Pragma ("inline = forced") выдало warning что не может встроить мою функцию (которая с модификатором __monitor, внтури содержит _BIC_SR_IRQ(LPM3bits)).

Вот отрывок заголовочного файла power.h:

#define INLINE _Pragma("inline = forced")
. . .
class PWR
{
    public:
        static void init(void);
        static void off(void);
. . .
        INLINE static inline __monitor void wakeUp(void)
        {
               _BIC_SR_IRQ(LPM3bits);
        };
};

 

отрывок main.cpp:

 

void OS::SystemTimerUserHook(void)
{
       adc.read();
       adc.start();
       if(adc.reault[2] < 900)
       {
              PwrOffFlag.SignalISR();
       }
       else
       {
              wakeUp();
       }
}

 

OS_PROCESS void TPWRProc(void)
{
       for(;;)
       {
             pwr.off();
       }
}

 

//-------------------------------------------
// Реакция на пропадание уровня питания
//-------------------------------------------
void PWR::off(void)
{
    PowerOffFlag.Wait();
    ...
    //Выключение переферии
    ...
    BIS_SR(LPM3_bits +GIE);
}

Warning:[G004]: Could not inline function "PWR::wakeUp"

... на всякий случай, чтобы понятно было - у меня проект написан на С под msp430f449 без опреционной системы...я его переписываю с применением ОС(так как его очень трудно стало сопровождать, необходимы стали средства межпроцессоного взаимодействия, оптимизировать ресурсы и логику работы)..scmRTOS очень понравилась, перерписал почти все драйвера на ней,демку для проверки наваял все работает.. кроме power down.

 

Исходя из вышесказанного, применять этот интринсик всегда нужно только в прерывании безотносительно к тому, используется ОС или нет. ОС - это обычная программа, на логику применения обсуждаемого интринсика это влияния оказывать не должно.

 

И к хуку IdleProcess'а все это отношения не имеет.

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

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

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


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

Даже не так. При применении _Pragma ("inline = forced") выдало warning что не может встроить мою функцию (которая с модификатором __monitor, внтури содержит _BIC_SR_IRQ(LPM3bits)).

:) Стало еще понятнее.

 

А зачем вам в прерывании фукнция __monitor? Только если разрешены вложенные прерывания. И, имхо, в при использовании ОС логично применять для этого критические секции (и без ОС тоже лучше не использовать эти непереносимые расширения конкретного компилятора, а лучше написать что-нибудь свое вроде критической секции). Без нее со встроенной _BIC_SR_IRQ должно работать. Насколько понимаю, этот интринсик важно вызывать с уровня самого прерывания, чтобы компилятор правильно нашел копию SR в стеке. Поэтому если интринсик "обернут" другой функцией, то эта функция должна быть встраиваемой. Таким образом, у вас и хук таймера должен быть встроенным, и wakeUp тоже. Попробуйте без __monitor. Не вижу тут никаких противоречий, связанных с использованием ОС.

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


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

А зачем вам в прерывании фукнция __monitor?

...

Попробуйте без __monitor. Не вижу тут никаких противоречий, связанных с использованием ОС.

:biggrin: ну мы так опять покругу пойдем. __monitor - потому что просто вставить _BIC_SR_IRQ компилятор в хук системного таймера не даст (см мои посты выше), в том то и проблема что хук не ВСТРОЕННАЯ функция! Ладно я пошел дальше вкорячил этот интринсик, вызываемый тупо по глобальному флагу, непосредственно в обработчик прерывания системного таймера (это уже не хук а исходы ОС, чтобы не городить встраивание inline и _monitor)- не помогло. Потом сделал голое (без всяких оберток и т.п.)аппаратное прерывание вызываемое только когда нужно выйти из режима спячки, в обработчике - интринсик - - не работает!!! бит CPUoff всегда в еденице при возврате из прерывания .. у меня впечатление что интринсик некорректно находит копию регистра в стеке либо регистр восстанавливается для задачи из другого места(не там где интринсик правит). Причем без ОС все работает как должно.

Вобщем буду рад примеру работаещему с low power и scmRTOS (в любом виде хоть с правками исходов ОС, хоть с вставками на асме) ))) оч надо!

Изменено пользователем rezident
Излишнее цитирование.

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


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

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

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

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

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

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

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

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

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

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