aliko 0 20 июня, 2011 Опубликовано 20 июня, 2011 · Жалоба Добрый день. Вопрос собственно в заголовке. Надо чтобы контроллер MSP430F149 все свободное время спал. Достаточно ли будет написать так: void OS::IdleProcessUserHook() { LPM0; } PS использую IAR Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aliko 0 21 июня, 2011 Опубликовано 21 июня, 2011 · Жалоба Наверное вопрос сочли слишком глупым чтобы на него отвечать... :05: Все же господа хорошие, объясните пожалуйста новичку премудрости вытесняющего планирования. :) Я постараюсь более подробно изложить свои вопросы: 1) Я так понимаю IdleProcess такой же процесс как и все остальные. Разве что не надо его оборачивать в бесконечный цикл, так как это уже сделано в коде ОС. Значит если я усыплю МК в этом процессе то всякий раз возвращаясь в него планировщик будет восстанавливать SR, а значит впадать в спячку. Так ли это? 2) Если IdleProcess нужен лишь для усыпления контроллера, не слишком ли жирным будет выделять для таких целей отдельный процесс со своим стеком? Можно ли вообще отказаться от этого процесса? Как в таком случае реализовать спящий режим при простое МК? 3) Этот вопрос наверное уже больше завязан на конкретную среду IAR. В настройках проекта в среде IAR указывается величина выделяемого стека и кучи. Кто будет пользоваться этим стеком? Какие значения лучше указывать? Заранее большое спасибо за помощь! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SSerge 4 21 июня, 2011 Опубликовано 21 июня, 2011 · Жалоба 1) Я так понимаю IdleProcess такой же процесс как и все остальные. Разве что не надо его оборачивать в бесконечный цикл, так как это уже сделано в коде ОС. Значит если я усыплю МК в этом процессе то всякий раз возвращаясь в него планировщик будет восстанавливать SR, а значит впадать в спячку. Так ли это? Тут уже было обсуждение похожей темы: http://electronix.ru/forum/index.php?showt...=20811&st=0 пришли к такому же выводу. 2) Если IdleProcess нужен лишь для усыпления контроллера, не слишком ли жирным будет выделять для таких целей отдельный процесс со своим стеком? Можно ли вообще отказаться от этого процесса? Как в таком случае реализовать спящий режим при простое МК? Ну надо же что-то делать когда совсем нечего делать :) В принципе можно что-то и там делать, но далеко не что угодно, так как усыплять этот процесс нельзя. С другой стороны, накладные расходы на ещё один процесс минимальны. 3) Этот вопрос наверное уже больше завязан на конкретную среду IAR. В настройках проекта в среде IAR указывается величина выделяемого стека и кучи. Кто будет пользоваться этим стеком? Какие значения лучше указывать? А это зависит от дефайна scmRTOS_ISRW_TYPE Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aliko 0 22 июня, 2011 Опубликовано 22 июня, 2011 · Жалоба Тут уже было обсуждение похожей темы: http://electronix.ru/forum/index.php?showt...=20811&st=0 пришли к такому же выводу. Большое спасибо за эту ссылку, я рад что оказался не одинок в своих поисках решения) Ну надо же что-то делать когда совсем нечего делать :) В принципе можно что-то и там делать, но далеко не что угодно, так как усыплять этот процесс нельзя. С другой стороны, накладные расходы на ещё один процесс минимальны. Ну вобщем-то делать мне там совершенно нечего и хотелось бы сэкономить побольше оперативки так что держать отдельный IdleProcess со своим стеком и постоянно переключать на него контекст лишь для того чтобы в нем спать несколько накладно... А это зависит от дефайна scmRTOS_ISRW_TYPE значение этого дефайна выставил в TISRW. Правильно ли я понимаю что теперь стек выделяемый IAR (тот что задается в конфигурации проекта) будет использоваться прерываниями? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 32 22 июня, 2011 Опубликовано 22 июня, 2011 · Жалоба Ну вобщем-то делать мне там совершенно нечего и хотелось бы сэкономить побольше оперативки так что держать отдельный IdleProcess со своим стеком и постоянно переключать на него контекст лишь для того чтобы в нем спать несколько накладно... Что вы предлагаете делать, когда все ваши процессы упали в ожидание и отдали управление? Куда оно должно пойти? значение этого дефайна выставил в TISRW. Правильно ли я понимаю что теперь стек выделяемый IAR (тот что задается в конфигурации проекта) будет использоваться прерываниями? Нет. Этот стек используется для стека прерываний только при схеме с включенным отдельным стеком прерываний (TISRW_SS), но использовать его на MSP430 очень не рекомендуется. Т.ч. оставьте как есть. P.S. У вас проблемы с объёмом памяти, что вы так упорно хотите её сэкономить? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aliko 0 22 июня, 2011 Опубликовано 22 июня, 2011 · Жалоба Что вы предлагаете делать, когда все ваши процессы упали в ожидание и отдали управление? Куда оно должно пойти? Ну в общем-то когда ресурсы МК никому не нужны, МК должен спать. Сейчас это реализовано вызовом LPM0 в IdleProcess. Однако что-то мне говорит что должно быть более красивое решение чем тратить отдельный процесс со своим стеком и регулярным переключением контекста на него для того чтобы в нем просто спать. Нет. Этот стек используется для стека прерываний только при схеме с включенным отдельным стеком прерываний (TISRW_SS), но использовать его на MSP430 очень не рекомендуется. Т.ч. оставьте как есть. Не совсем понятно... Каждый процесс имеет свой стек, IdleProcess также имеет свой стек. В какой стек кладут данные тогда прерывания? В стек IdleProcess-a? И кто пользуется тогда стеком по-умолчанию размер которого задается в настройках ИАР? Я наверное задаю не самые умные вопросы, так что сильно не пинайте, хочу понять как че же это все работает... P.S. У вас проблемы с объёмом памяти, что вы так упорно хотите её сэкономить? Если уложусь в 1 Кб смогу использовать более дешевый и доступный МК. Более того всегда есть куда с пользой потратить свободную память - на буферы для более быстрого обмена по UART и на структуры данных с диагностикой... Да и вообще надо же во всем до конца разобраться иначе как же выпускать продукт не понимая во всех деталях как он работает.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 22 июня, 2011 Опубликовано 22 июня, 2011 · Жалоба IdleProcess со своим стеком и постоянно переключать на него контекст лишь для того чтобы в нем спать несколько накладно... Ну зачем это только для... Считайте, что это самый низкоприоритетный процесс, который по завершению того, что ему положено переводит не процесс а контроллер в спячку. Единственно, что время спячки Вы для него задать не сможете. Ну и если вдруг, будут нужны какие-то системные вызовы, то придется сделать их варианты для Idle. Вот примерчик более утилитарного использования Idle (операционка похожая на FreeRTOS и ARM, но не суть важно): / void idle_system( void ) { ......... if( xQueueReceiveFromIdle( idle_queue, &imsg ) ) { ....... } else { // CPU Idle PCON |= PCON_IDL; } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 16 22 июня, 2011 Опубликовано 22 июня, 2011 · Жалоба Если уложусь в 1 Кб смогу использовать более дешевый и доступный МК. Более дешёвый и доступный, чем 149, трудно найти. Разве что 135, но там памяти всего 512. И упихивать под завязку - в корне неправильно. Всегда надо иметь хотя бы 30% запас на будущее. Чтобы не было мучительно больно © Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 32 22 июня, 2011 Опубликовано 22 июня, 2011 · Жалоба Ну в общем-то когда ресурсы МК никому не нужны, МК должен спать. Сейчас это реализовано вызовом LPM0 в IdleProcess. Однако что-то мне говорит что должно быть более красивое решение чем тратить отдельный процесс со своим стеком и регулярным переключением контекста на него для того чтобы в нем просто спать. Мне было бы тоже очень интересно узнать про такую реализацию. Предлагайте? Не совсем понятно... Каждый процесс имеет свой стек, IdleProcess также имеет свой стек. В какой стек кладут данные тогда прерывания? В стек IdleProcess-a? И кто пользуется тогда стеком по-умолчанию размер которого задается в настройках ИАР? Я наверное задаю не самые умные вопросы, так что сильно не пинайте, хочу понять как че же это все работает... Прерывания работают в стеке прерванного процесса, если при переходе к обработчику прерываний не происходит переключения на специальный стек прерываний, это очевидно. Вообще-то, этот момент достаточно подробно рассмотрен в документации. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aliko 0 22 июня, 2011 Опубликовано 22 июня, 2011 · Жалоба Мне было бы тоже очень интересно узнать про такую реализацию. Предлагайте? Пока что придумал лишь такой вариант: Перенести функционал одного из процессов (самого низкоприоритетного) в IdleProcess. Но тут возникают сложности с отсутствием всех плюшек которые есть у обычного процесса - это возможность вызывать sleep() а также прочие варианты передачи управления и работы с разделяемыми ресурсами. Я так понимаю это все не будет работать в Idle. Также опять же вопрос спячки контроллера еще более усложняется. Представим что я выполнил цикл подпрограмм в IdleProcess после которого надо уснуть на какое-то время. Я вызываю LPM0 и засыпаю. Кто же меня теперь разбудит??? Планировщик восстанавливая контекст IdleProcess всякий раз будет восстанавливать SR и сразу засыпать. Получается кто-то извне должен залезть в стек процесса IdleProcess и в его стеке исправить значение SR. Как-то все слишком сложно выходит...( Прерывания работают в стеке прерванного процесса, если при переходе к обработчику прерываний не происходит переключения на специальный стек прерываний, это очевидно. Вообще-то, этот момент достаточно подробно рассмотрен в документации. В том-то и дело. У каждого процесса свой стек и у IdleProcess тоже свой. Кто же пользуется стеком по-умолчанию (тот размер которого задается в настройках проекта ИАР в General Options). Получается им пользуется только все то что идет до вызова os_start? Выходит если я все правильно понимаю его можно сделать минимальным, так как из os_start мы никогда уже не выйдем? Более дешёвый и доступный, чем 149, трудно найти. Разве что 135, но там памяти всего 512. И упихивать под завязку - в корне неправильно. Всегда надо иметь хотя бы 30% запас на будущее. Чтобы не было мучительно больно © Прошу прощения, я хотел сказать уложиться в 2 Кб. Да и вообще неприятно когда несколько десятков байт, а то и сотни тратятся впустую. Ведь если даже спать в Idle всеравно нужно выделить ему стек для всех регистров + под прерывания оставить не забыть... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 32 22 июня, 2011 Опубликовано 22 июня, 2011 · Жалоба Как-то все слишком сложно выходит...( В том-то и дело, что не всё там так просто и за всё надо платить. В том-то и дело. У каждого процесса свой стек и у IdleProcess тоже свой. Кто же пользуется стеком по-умолчанию (тот размер которого задается в настройках проекта ИАР в General Options). Получается им пользуется только все то что идет до вызова os_start? Выходит если я все правильно понимаю его можно сделать минимальным, так как из os_start мы никогда уже не выйдем? Когда-то был вариант (ещё в версиях 2.хх), когда системный стек использовался в качестве стека IdleProcess, но потом от этого отказались по какой-то причине, уже не помню. Вроде, гемора много, а толку мало. Если вам так надо эту память, но и юзайте её под свои нужды - размещайте в ней переменные, буфера или что хотите. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 16 22 июня, 2011 Опубликовано 22 июня, 2011 · Жалоба Ещё вопрос на засыпку: а оно обязательно, вытесняющее планирование? Как-то у меня в голове энергосбережение и постоянный запуск планировщика вместе не вяжутся... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aliko 0 22 июня, 2011 Опубликовано 22 июня, 2011 · Жалоба Ещё вопрос на засыпку: а оно обязательно, вытесняющее планирование? Как-то у меня в голове энергосбережение и постоянный запуск планировщика вместе не вяжутся... Наверное вы правы для случая работы от батарейки. В моем же случае есть хоть и очень маленькое но постоянное питание, так что вполне можно себе позволить переключение контекста, тем более занимает оно < 50 мкс... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 32 22 июня, 2011 Опубликовано 22 июня, 2011 · Жалоба Ещё вопрос на засыпку: а оно обязательно, вытесняющее планирование? Как-то у меня в голове энергосбережение и постоянный запуск планировщика вместе не вяжутся... Как раз-таки очень вяжется - когда все процессы работу сделали и ждут своих событий, то процессор спокойно падает в спячку, из которой будет поднят по событию (внешнему или внутреннему). Работает только полезный код (т.е. тот, кому реально есть, что делать). Ну, не без накладных, конечно, на передачу управления, но это мизер, имхо. А без этого придётся заниматься поллингом тех или иных событий с каким-то периодом - это и есть непроизводительный расход энергии. Можно и без оси делать всё по событиям, но тут придётся всю обработку городить в обработчиках прерываний, а это не очень-то красиво и функционально, и всё равно похоже на работу ос с event-driven управлением, особенно, если контроллер прерываний многоуровневый приоритетный. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 22 июня, 2011 Опубликовано 22 июня, 2011 · Жалоба Как раз-таки очень вяжется - когда все процессы работу сделали и ждут своих событий, то процессор спокойно падает в спячку, из.... Я думаю, что тут народ волнуется о том, что системный таймер будет периодически будить и система будет считать время, даже если кто-то захочет поспать интервал времени много превышающий тик системного таймера. Можно и без оси делать всё по событиям, но тут придётся всю обработку городить в обработчиках прерываний... Однажды, выжимая все и вся пришлось :) написать такой вот: __noreturn void main(void) { for(;; ) __sleep(); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться