Dr.NoA 0 7 сентября, 2006 Опубликовано 7 сентября, 2006 · Жалоба Использую операционную систему 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. Я, конечно, понимаю, что проблема несколько надуманная, но все таки хочется хоть что-то использовать без нарушения лицензии. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 34 7 сентября, 2006 Опубликовано 7 сентября, 2006 · Жалоба Использую операционную систему scmRTOS на микроконтроллерах MSP430 (в основном F169 и F1611), все замечательно, но есть одна проблема. Хотелось бы переводить МК в режим пониженного энергопотребления (например, LPM3), когда ему нечем заняться. Насколько я понимаю, для этого достаточно в теле функции void OS::IdleProcessUserHook() выполнить команду _BIS_SR(LPM3_bits). В результате МК "заснет" до следующего прерывания от сторожевого таймера, от которого тактируется планировчик задач ОС. В обработчике прерывания нужно выполнить _BIC_SR_IRQ(LPM3_bits), чтобы МК нормально вернулся в активный режим. Но проблема в том, что код обработчика прерывания от сторожевого таймера является частью scmRTOS, а добавление одной строчки "_BIC_SR_IRQ(LPM3_bits)" приведет к нарушению условий лицензии на scmRTOS. В общем вопрос в следующем. Решал ли кто-нибудь эту задачу без внесения изменений в исходники операционки? Если да, то поделитесь рецептом. Там для системного таймера есть тоже соответсвующий хук. Его нужно разрешить в конфигурации и определить его потроха. Я, конечно, понимаю, что проблема несколько надуманная, но все таки хочется хоть что-то использовать без нарушения лицензии. Вы как будто не в России. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dr.NoA 0 7 сентября, 2006 Опубликовано 7 сентября, 2006 · Жалоба Там для системного таймера есть тоже соответсвующий хук. Его нужно разрешить в конфигурации и определить его потроха. Это я знаю, но как-то не подумал его использовать для сброса флагов LPM-режима. Надо будет попробовать. Спасибо. Вы как будто не в России. :) В России, но я же говорю, что хочу хотя бы что-то честно использовать:) Тем более что автор scmRTOS денег за нее не хочет, а просит просто не курочить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 34 7 сентября, 2006 Опубликовано 7 сентября, 2006 · Жалоба Вы как будто не в России. :) Тем более что автор scmRTOS денег за нее не хочет, а просит просто не курочить. Ну, думается, что сломать Вы там ничего не сломаете так, чтоб нанести ущерб автору. :) И потом, я знаю, что народ рихтует под себя, не боится. Никто еще не пострадал от гнева автора. Самым негативным моментом (для Вас опять же, не для автора) того, что залезете руками, будет то, что когда (если вдруг) выйдет новая версия, и Вы захотите ее использовать, то придется опять лезть руками и править. Не лучше ли обратиться к автору с предложением внести ту или иную фичу - если в ней есть рациональное зерно, то оно наверняка будет принято к рассмотрению. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dr.NoA 0 7 сентября, 2006 Опубликовано 7 сентября, 2006 · Жалоба Вы как будто не в России. :) Тем более что автор scmRTOS денег за нее не хочет, а просит просто не курочить. Ну, думается, что сломать Вы там ничего не сломаете так, чтоб нанести ущерб автору. :) И потом, я знаю, что народ рихтует под себя, не боится. Никто еще не пострадал от гнева автора. Самым негативным моментом (для Вас опять же, не для автора) того, что залезете руками, будет то, что когда (если вдруг) выйдет новая версия, и Вы захотите ее использовать, то придется опять лезть руками и править. Не лучше ли обратиться к автору с предложением внести ту или иную фичу - если в ней есть рациональное зерно, то оно наверняка будет принято к рассмотрению. Да, проблема с совместимостью тоже является одной из причин нежелания делать "тюнинг" операционки. Но думаю, что в данном случае можно обойдись штатными средствами, воспользовавшись вашим советом. Правда пока не проверял. Кстати, по поводу "рихтования". Вы случайно не встречали порта scmRTOS на 51-семейство? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 34 8 сентября, 2006 Опубликовано 8 сентября, 2006 · Жалоба Но думаю, что в данном случае можно обойдись штатными средствами, воспользовавшись вашим советом. Правда пока не проверял. Должно работать - этот хук там для того и предназначен, чтобы пользователь мог выполнить какие-то действия внутри обработчика прерывания от системного таймера, не модифицируя исходный код. Кстати, по поводу "рихтования". Вы случайно не встречали порта scmRTOS на 51-семейство? Нет, все порты лежат вместе. Для 51-го оно врядли появится по причине того, что на оный МК даже С ложится плохо, а уж С++... К тому же, не помню, чтобы для 51-го вообще был С++, может быть ошибаюсь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yornik 0 8 сентября, 2006 Опубликовано 8 сентября, 2006 · Жалоба Поправьте меня, если ошибаюсь: в изначальном виде порт scmRTOS для MSP430 заточен под использование сторожевого таймера в режиме источника периодических прерываний => точности по времени в вызовах типа OS::Sleep( MY_FAVORITE_PROTOCOL_TIMEOUT ) - никакой => править надо по-любому? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dr.NoA 0 8 сентября, 2006 Опубликовано 8 сентября, 2006 · Жалоба Поправьте меня, если ошибаюсь: в изначальном виде порт scmRTOS для MSP430 заточен под использование сторожевого таймера в режиме источника периодических прерываний => точности по времени в вызовах типа OS::Sleep( MY_FAVORITE_PROTOCOL_TIMEOUT ) - никакой => править надо по-любому? А что вы хотите править? Просто по умолчанию сторожевой таймер тактируется внутренним генератором DCO, у которого действительно частота "гуляет". Если вам нужно точнее, то можете при загрузке ОС перенастроить сторожевой таймер на внешний тактовый сигнал, например, часовой кварц. Сделать это можно в функции OS::SystemStartUserHook(). То есть штатные средства вам позволяют это сделать и править исходники нет необходимости. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Hamster1979 0 15 января, 2010 Опубликовано 15 января, 2010 · Жалоба Должно работать - этот хук там для того и предназначен, чтобы пользователь мог выполнить какие-то действия внутри обработчика прерывания от системного таймера, не модифицируя исходный код. Задача переходит в режим пониженного потребления функцией _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? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 34 16 января, 2010 Опубликовано 16 января, 2010 · Жалоба Задача переходит в режим пониженного потребления функцией _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 функцию, из которой звать означенный интринсик, а вызов самой этой функции поместить в хук? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Hamster1979 0 16 января, 2010 Опубликовано 16 января, 2010 (изменено) · Жалоба А если написать свою __inline __monitor функцию, из которой звать означенный интринсик, а вызов самой этой функции поместить в хук? Пробовал. Не помагает. Восстанавливается контекс задачи и вместе с ним состояние бита CPUOFF.... Дело в том что насколько я понимаю BIC_SR_IRQ функция меняет состояние битов не в самом теле функции а на выходе из нее ... Если не использовать операционную систему то применяют BIC_SR_IRQ в обработчике прерывания ... вызываемого при необходимости выхода из режима power down. Если использовать функцию BIC_SR_IRQ во вложенной в вызываемой из прерывания функции пусть даже __inerrupt и __monitor, модификация бита CPUOFF произойдет не на выходе из прерывания а внутри него..поправьте если я не прав. Изменено 16 января, 2010 пользователем Hamster1979 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 34 16 января, 2010 Опубликовано 16 января, 2010 · Жалоба Пробовал. Не помагает. Восстанавливается контекс задачи и вместе с ним состояние бита CPUOFF.... Дело в том что насколько я понимаю BIC_SR_IRQ функция меняет состояние битов не в самом теле функции а на выходе из нее ... Если не использовать операционную систему то применяют BIC_SR_IRQ в обработчике прерывания ... вызываемого при необходимости выхода из режима power down. Если использовать функцию BIC_SR_IRQ во вложенной в вызываемой из прерывания функции пусть даже __inerrupt и __monitor, модификация бита CPUOFF произойдет не на выходе из прерывания а внутри него..поправьте если я не прав. Стоп, стоп. Тогда, как я понимаю, дело совсем не в этом. Этот интринсик сбрасывает бит не в реальном SR, а в его копии, находящейся в стеке, куда эта копия попадает при сохранении SR во время входа в прерывание (или при вызове __monitor функций). Смысл этого в том, чтобы нужный бит в SR был сброшен после выхода из прерывания - менять бит в SR, находясь в прерывании смысла имеет мало - при выходе процессор аппаратно восстанавливает сохраненное при входе значение SR, поэтому значение SR, когда процессор находится в прерывании, при выходе из прерывания теряется. Исходя из вышесказанного, применять этот интринсик всегда нужно только в прерывании безотносительно к тому, используется ОС или нет. ОС - это обычная программа, на логику применения обсуждаемого интринсика это влияния оказывать не должно. И к хуку IdleProcess'а все это отношения не имеет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Hamster1979 0 16 января, 2010 Опубликовано 16 января, 2010 (изменено) · Жалоба Даже не так. При применении _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 и работу от литиевой батареии. при этом отсаются рабочими только прерывания... гарантированным включенным прерыванием на этот момент может только системный таймер ОС . Вот я его хук и пользую. Изменено 16 января, 2010 пользователем Hamster1979 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 34 17 января, 2010 Опубликовано 17 января, 2010 · Жалоба Даже не так. При применении _Pragma ("inline = forced") выдало warning что не может встроить мою функцию (которая с модификатором __monitor, внтури содержит _BIC_SR_IRQ(LPM3bits)). :) Стало еще понятнее. А зачем вам в прерывании фукнция __monitor? Только если разрешены вложенные прерывания. И, имхо, в при использовании ОС логично применять для этого критические секции (и без ОС тоже лучше не использовать эти непереносимые расширения конкретного компилятора, а лучше написать что-нибудь свое вроде критической секции). Без нее со встроенной _BIC_SR_IRQ должно работать. Насколько понимаю, этот интринсик важно вызывать с уровня самого прерывания, чтобы компилятор правильно нашел копию SR в стеке. Поэтому если интринсик "обернут" другой функцией, то эта функция должна быть встраиваемой. Таким образом, у вас и хук таймера должен быть встроенным, и wakeUp тоже. Попробуйте без __monitor. Не вижу тут никаких противоречий, связанных с использованием ОС. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Hamster1979 0 17 января, 2010 Опубликовано 17 января, 2010 (изменено) · Жалоба А зачем вам в прерывании фукнция __monitor? ... Попробуйте без __monitor. Не вижу тут никаких противоречий, связанных с использованием ОС. ну мы так опять покругу пойдем. __monitor - потому что просто вставить _BIC_SR_IRQ компилятор в хук системного таймера не даст (см мои посты выше), в том то и проблема что хук не ВСТРОЕННАЯ функция! Ладно я пошел дальше вкорячил этот интринсик, вызываемый тупо по глобальному флагу, непосредственно в обработчик прерывания системного таймера (это уже не хук а исходы ОС, чтобы не городить встраивание inline и _monitor)- не помогло. Потом сделал голое (без всяких оберток и т.п.)аппаратное прерывание вызываемое только когда нужно выйти из режима спячки, в обработчике - интринсик - - не работает!!! бит CPUoff всегда в еденице при возврате из прерывания .. у меня впечатление что интринсик некорректно находит копию регистра в стеке либо регистр восстанавливается для задачи из другого места(не там где интринсик правит). Причем без ОС все работает как должно. Вобщем буду рад примеру работаещему с low power и scmRTOS (в любом виде хоть с правками исходов ОС, хоть с вставками на асме) ))) оч надо! Изменено 17 января, 2010 пользователем rezident Излишнее цитирование. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться