|
Вопросы по scmRTOS |
|
|
10 страниц
1 2 3 > »
|
 |
Ответов
(1 - 99)
|
May 15 2009, 13:42
|

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

|
Цитата(n_bogoyavlensky @ May 15 2009, 19:59)  1. В примерах T0 - системный таймер. Почему инициализация и запуск системного таймера производится не средствами ОС (допустим, в Run), а пользователем ОС вручную? Потому что системным таймером может быть не только Т0, но и любой другой таймер - это отдано на откуп пользователю, он может сам выбрать и настроить. Поэтому и вынесено с уровня ОС на уровень прикладного проекта. Цитата(n_bogoyavlensky @ May 15 2009, 19:59)  2. Почему при использовании передачи управления на основе программного прерывания инициализация компаратора производится не средствами ОС, а пользователем ОС вручную? Ровно по той же причине, что и п.1. Поскольку нет у процессора отдельного прерывания, предназначенного для этих дел, то приходится использовать какое-либо из свободных. А это тоже дело такое - в одном случае одно лучше подходит, в другом это занято. Вот чтобы ось не привязывать к выбору источника прерываний для переключения контекстов, это тоже вынесено но уровень проекта. В предыдущих версиях, кстати, оба прерывания были описаны внутри ОС, но это, как показала практика, оказалось негибко. Поэтому они сейчас и вынесены. Цитата(n_bogoyavlensky @ May 15 2009, 19:59)  3. Один тик системного таймера - одно его переполнение? Это одно его прерывание.  А уж по переполнению оно сделано или по Compare Match - это особенности конкретного проекта. Все в руках юзера.  Цитата(n_bogoyavlensky @ May 15 2009, 19:59)  4. Рекомендуемое значение системного тика 1-10 мс. Т. е., мы должны настраивать системный таймер, на переполнение его в пределах этого времени? Да, вы можете выбрать таймер, настроить его так, чтобы получить нужное вам значение системного тика. Оно может быть любым - какое сделаете, такое и будет. Цитата(n_bogoyavlensky @ May 15 2009, 19:59)  5. Каковы будут дополнительные опции компилятора для моей связки ОС + компилятор + IDE? Не понял вопроса. ОС требует только чтобы для компилятора была включена поддержка С++ и (если надо) расширения языка. Если для целей проекта надо еще что-то, ну добавьте. Если ответ не удовлетворил, уточните, что конкретно нужно. Либо дождемся ответа от автора порта.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
May 15 2009, 14:23
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
По вопросам 1 и 2 понятно. Т. е., для того, чтобы ОС работала, выбираем, настраиваем, запускаем системный таймер в main. Если используем конфигурацию ОС с передачей управления по программному прерыванию, то "настраиваем" соответствующее прерывание в main. По вопросу 3. Compare Match - для более точного подбора длительности тика? А нужно ли это?  Цитата(dxp @ May 15 2009, 17:42)  Не понял вопроса. ОС требует только чтобы для компилятора была включена поддержка С++ и (если надо) расширения языка. Если для целей проекта надо еще что-то, ну добавьте. Если ответ не удовлетворил, уточните, что конкретно нужно. Либо дождемся ответа от автора порта.  Понятно  6. При описании типа процесса размер двух стеков указывать или одного? 7. Как "прикинуть" размер требуемых стеков таким образом, чтобы взять его с запасом?
--------------------
Благодарю заранее!
|
|
|
|
|
May 15 2009, 14:47
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Там есть makefile с ключами компилятора. Если Code::Blocks позволяет создать проект "на всём готовом" (у NetBeans это называется С/С++ project from existing code - он тогда только подхватывает исходники в среду, а для компиляции в свой makefile подставляет вызов make с готовым makefile из проекта), то можно воспользоваться этим управляющим файлом. Если нет - то просто придётся посмотреть опции в makefile проекта и перенести их в IDE. Собственно, там каких-то специфических опций именно для scmRTOS действительно и не нужно. Цитата(n_bogoyavlensky @ May 15 2009, 17:23)  По вопросу 3. Compare Match - для более точного подбора длительности тика? А нужно ли это?  А это вопрос вкусовой. Если речь именно о точности. А так - частота тактирования процессора и прескалер могут дать, к примеру, переполнение в 2,2мс, а хочется иметь тик в 1мс. Или таймер 0 занят чем-то другим, а есть свободный канал сравнения на таймере 3. Цитата(n_bogoyavlensky @ May 15 2009, 17:23)  6. При описании типа процесса размер двух стеков указывать или одного? 7. Как "прикинуть" размер требуемых стеков таким образом, чтобы взять его с запасом? Для avr-gcc, как оно видно в примерах, стек один. Размер стека зависит от того, в какую глубину идут вызовы функций (в том числе сервисов ОС) и могут ли накладываться прерывания. Сколь-нибудь серьёзного исследования я не проводил, но так навскидку - висящему в Код for (;;) { Sleep(500); TOGGLE(LED_R); } достаточно 45-50 байт стека (без наложения прерываний) Вызывающему пару-тройку функций (без использования стека для локальных переменных), которые где-то там обращаются к Mutex да Event - уже нужно, скажем, 75-80. Для спокойствия можно начать где-то со 120 плюс ожидаемые размеры локальных переменных на стеке (обычно бывает когда есть массивчики или переменные, адрес которых передаётся куда-то).
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
May 15 2009, 18:37
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Вот и ещё вопросы подоспели  8. Для чего функция процесса Exec() - статическая? 9. Почему функции WakeUpProcess() и ForceWakeUpProcess() следует использовать с осторожностью? В каких случаях? 10. Какую оптимизацию задавать при компиляции? Цитата(sergeeff @ May 15 2009, 22:29)  У нас на форуме уже рассказывалось, как можно ввести контроль за объемом стека в scmRTOS. Методика простая. Выделяем поболее, смотрим за реальной работой процессора, анализируем сколько было использовано. Есть возможность - ужимаем, оставив еще немного про запас. Я читал  Но мне как новичку пока сложновато это... Цитата(ReAl @ May 15 2009, 18:47)  TOGGLE(LED_R); Что это?
--------------------
Благодарю заранее!
|
|
|
|
|
May 15 2009, 21:00
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(n_bogoyavlensky @ May 15 2009, 21:37)  10. Какую оптимизацию задавать при компиляции? По вкусу. Я ставлю -Os и выбрасывание неиспользуемого кода/данных (-ffunction-sections -fdata-sections для компилятора и --gc-sections для линкера) а также --relax линкеру для замен длинных вызовов/переходов на короткие там, где это возможно и замен комбинаций call+ret на jump. В общем, те же, что и для С-шных проектов. Цитата(n_bogoyavlensky @ May 15 2009, 21:37)  Что это? Макрос инверсии вывода (в данном случае - выхода светодиода), развитие "классики от Аскольда Волкова" http://electronix.ru/forum/index.php?showt...mp;#entry199555Включено в примеры к порту scmRTOS для avr-gcc - файл pin_macros.h
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
May 16 2009, 05:54
|

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

|
Цитата(n_bogoyavlensky @ May 16 2009, 01:37)  8. Для чего функция процесса Exec() - статическая? А как иначе? Эта функция должна быть в единственном экземпляре всегда. Кроме того, хотя эта функция и объявлена, как функция процесса, на самом деле к ресурсам процесса она отношения не имеет и служит исключительно для нужд пользовательского кода. Поэтому делать ее нестатической - это передача ненужного this, а учитывая, что эта фукнция нормально не вызывается, то и this нее передать невозможно. Вот такие логические и технические посылы. Цитата(n_bogoyavlensky @ May 16 2009, 01:37)  9. Почему функции WakeUpProcess() и ForceWakeUpProcess() следует использовать с осторожностью? В каких случаях? Потому, что их использование нарушает обычную логику работы программы. Например, какой-то процесс ожидает события, а тут его в другом месте выдергивают - это как бы нештатная ситуация. Поэтому тут надо действовать внимательно. К слову сказать, функции эти сделаны там скорее на всякий случай, лично я уже и не помню, когда их применял (и применял ли вообще). При правильно организованной программе необходимость в их использовании стемится к нулю. Это как с оператором goto.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
May 16 2009, 09:35
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Цитата(dxp @ May 16 2009, 09:54)  А как иначе? Эта функция должна быть в единственном экземпляре всегда. Каждый процесс - объект типа полученного с помощью шаблона process, наследник TBaseProcess. Каждый процесс существует в единственном экземпляре. Значит функция будет и так в единственном экземпляре... Или я не понимаю что такое статическая функция  Цитата Потому, что их использование нарушает обычную логику работы программы. Например, какой-то процесс ожидает события, а тут его в другом месте выдергивают - это как бы нештатная ситуация. Поэтому тут надо действовать внимательно. К слову сказать, функции эти сделаны там скорее на всякий случай, лично я уже и не помню, когда их применял (и применял ли вообще). При правильно организованной программе необходимость в их использовании стемится к нулю. Это как с оператором goto. А что может произойти? Система "упадёт"?
--------------------
Благодарю заранее!
|
|
|
|
|
May 16 2009, 10:57
|

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

|
Цитата(n_bogoyavlensky @ May 16 2009, 16:35)  Каждый процесс - объект типа полученного с помощью шаблона process, наследник TBaseProcess. Каждый процесс существует в единственном экземпляре. Значит функция будет и так в единственном экземпляре... Или я не понимаю что такое статическая функция  Никто не мешает завести больше одного объекта-процесса. Хотя это, конечно, неправильно. Я же ясно, вроде, пояснил, что: - хотя эта функция и объявлена, как функция процесса, на самом деле к ресурсам процесса она отношения не имеет и служит исключительно для нужд пользовательского кода. Это логический довод.
- делать ее нестатической - это передача ненужного this, а учитывая, что эта фукнция нормально не вызывается, то и this нее передать невозможно. Это технический довод.
Как бы вы передали в нее указатель this? А без этого она может работать некорректно, и там можно получить очень хорошие грабли. Цитата(n_bogoyavlensky @ May 16 2009, 16:35)  А что может произойти? Система "упадёт"? Можно получить неожиданное поведение. И удивляться.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
May 16 2009, 12:17
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(dxp @ May 16 2009, 13:57)  Как бы вы передали в нее указатель this? Если постараться - можно. В конструкторе TBaseProcess после Kernel.RegisterProcess(this), там, где формируется начальный стековый кадр, затолкать этот же this в такое место, чтобы после восстановления контекста он оказался в нужных регистрах. Только, насколько я понимаю, тип параметра exec у конструктора для этого должен быть другой - указатель на функцию-член. Топикстартеру: Таким же образом можно было бы передать в функцию процесса указатель на некую структуру/класс, с которыми процесс должен работать, но для этого надо конструктору добавить соответствующий аргумент. Но это имело бы смысл при одновремённом переводе Exec() в нестатическую - чтобы создавать два экземпляра процесса (с разными приоритетами, но это в конечном счёте не важно), работающие одинаковым образом с разными однотипными сущностями и разделяющими код. Но это же делается просто созданием двух процессов, из Exec() которых вызывается одна и та же функция с разными указателями на рабочий объект. Несколько накладнее, пожалуй. И не так красиво. Но у меня пока такие желания не возникали - ну пусть два UART - ну всё равно у них разное назначение в системе и они обрабатываются по разному. А ради просто красоты до/пере-делывать структуру ОС особого смысла не вижу. Цитата(sergeeff @ May 16 2009, 14:39)  Очень хотелось бы сделать так, чтобы первый объявленный процесс получал высший приоритет, следующий процесс - приоритет на 1 ниже и т.д. Тогда, объявив в самой ОС число возможных процессов по максимуму всю ОС оформить в виде отдельной библиотеки и пользователям в своей организации раздать, чтобы они "грязными ногами" в ее "чистом теле" не натоптали. Сколько не думал, пока ничего не придумалось. Может есть какие соображения на сей счет? Чтобы процессов было "по максимуму" их и задать бы надо. Ну там размер таблиц вырастет, это ладно, но между низшим по приоритету из созданных и Idle заполнено всё должно быть, она же их вызывать попытается. Можно наоборот - с низшего начинать. Ну, если выйдет, так как я тоже чисто языковыми средствами не могу придумать как это сделать - в разных файлах, независимо. Но тогда начинаться непонятно с чего выполнение будет - до наивысшего таблицы пусты. Главное - "а зачем"? Удобство "объектных", а не "исходниковых" библиотек в embeded обсуждалось неоднократно и практически для всего, кроме стандартной библиотеки языка оно для меня сомнительно. А уж scmRTOS, в которой ещё некоторые вещи конфигурируются попроектно - не только число процессов, и компилируется потом с inline-подстановками оптимально под проект - так и подавно. Так то, что должно решаться административными методами, ими и решайте. Пусть проверка результата работы производится компиляцией со свежевыдернутыми из недоступного по правам записи хранилища, а кто в рабочей копии наменял что-то - сам себе враг. Или ещё что-то придумайте.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
May 16 2009, 12:30
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Вопросы далее  11. Как лучше поступить с исходниками scmRTOS? Отвести для них отдельную папку и использовать для всех проектов сразу, как-то прописал пути в каждом проекте, или копировать в папку с каждым проектом? Скопировал исходники в отдельную папку, прописал пути. Но компилятор жалуется на отсутствие файлов scmRTOS_CONFIG.h и scmRTOS_TARGET_CFG.h - лежат в папке с проектом (это ведь файлы конфигурации ОС для конкретного проекта и по идее должны храниться в папке проекта). Переместил эти файлы в папку AVR ОС - компилятор перестал ругаться... 12. Сейчас при компиляции имею 5 ошибок. Скриншоты ниже (выбрана каждая из ошибок). http://file.qip.ru/file/87782953/9829dcad/e1_online.htmlhttp://file.qip.ru/file/87782958/ffb0525/e2_online.htmlhttp://file.qip.ru/file/87782964/2d601acd/e3_online.htmlhttp://file.qip.ru/file/87782966/c36e7be1/e4_online.htmlhttp://file.qip.ru/file/87782969/53d16670/e5_online.htmlКод main.cpp: Код #include <avr/io.h> #include "scmRTOS.h"
typedef OS::process<OS::pr0, 120> TProc1; typedef OS::process<OS::pr1, 160> TProc2;
TProc1 Proc1; TProc2 Proc2;
int main(void) { TCCR0B = (1 << CS01) | (1 << CS00); TIMSK0 |= (1 << TOIE0);
OS::Run();
return 0; };
namespace OS {
template<> OS_PROCESS void TProc1::Exec() { for(;;) { } }
}
namespace OS {
template<> OS_PROCESS void TProc2::Exec() { for(;;) { } }
}
Сообщение отредактировал n_bogoyavlensky - May 16 2009, 13:28
--------------------
Благодарю заранее!
|
|
|
|
|
May 16 2009, 13:40
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Вообще непонятны следующие конструкции в примерах, я запутался... Код namespace OS {
template<> OS_PROCESS void TProc1::Exec() { ... В руководстве этого нет... Цитата(ReAl @ May 16 2009, 17:31)  Текущая папка проекта должна быть прописана в ключах компилятора в -I иначе файлы из другой папки (из ОС) не видят .h из текущей. Получилось. Спасибо
--------------------
Благодарю заранее!
|
|
|
|
|
May 16 2009, 18:06
|
Профессионал
    
Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007

|
Цитата(ReAl @ May 16 2009, 15:17)  Если постараться - можно. В конструкторе TBaseProcess после Kernel.RegisterProcess(this), там, где формируется начальный стековый кадр, затолкать этот же this в такое место, чтобы после восстановления контекста он оказался в нужных регистрах. Только, насколько я понимаю, тип параметра exec у конструктора для этого должен быть другой - указатель на функцию-член. Вы понимаете, надеюсь, что на место параметра exec в дальнейшем при переключении процессов будет писаться адрес возврата в прерванный процесс? Соответственно, this->(адрес чего-то там) никак не укладывается в размерность "чего-то там". А exec за счет своего static - укладывается, да еще и существует в единственном виде. Про автоматическое присвоение приоритетам по мере объявления. Это могло бы автоматически решить проблему "бездырности" приоритетов в переменной, где устанавливаются/сбрасываются единички активных процессов. Одна из видимых проблем - pridle - намертво зашитый в enum. Понятно, что можно все тексты scmRTOS таскать вместе с проектом, но вы же исходники Windows/Linus и прочего в таком виде не используете? Вот и мне также хотелось бы иметь только библиотеки от scmRTOS, ну за вычетом inline и template, которые ну просто никак по-другому (пока, по крайней мере).
|
|
|
|
|
May 17 2009, 10:04
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(sergeeff @ May 16 2009, 21:06)  Вы понимаете, надеюсь, что на место параметра exec в дальнейшем при переключении процессов будет писаться адрес возврата в прерванный процесс? На место параметра писаться не будет ничего. Писаться будет на то место в стеке процесса, куда конструктор значение параметра - начальное значение счётчика команд для процесса, как якобы он в этот момент был прерван - будет записано. При статическом exec происходит то же - при первом же вызове любой подпрограммы, первом же вхождении в любое прерывание - стековый кадр процесса будет перезаписан, от инициализирующих значений там ничего не останется. Цитата(sergeeff @ May 16 2009, 21:06)  Соответственно, this->(адрес чего-то там) никак не укладывается в размерность "чего-то там". А exec за счет своего static - укладывается, да еще и существует в единственном виде. Это другое дело, тут я не прав (::*)() имеет более сложную структуру, чем (*)(), там наворочено на случай наследования/виртуальных и эта гадость не приводится ни к void* и к чему другому и просто так вызвать не получится. Так что если хочется сделать реальную функцию процесса нестатической, то нужно просто статический exec сделать принимающим указатель на объект класса (записывать в стековый кадр на нужное место this) и в самом exec() так Код bla_bla_bla::Exec(void *p) { bla_bla_bla * myprocess = reinterpret_cast<bla_bla_bla*>(p); myprocess->execute(); } Если сделать execute() ещё в TBaseProcess и сделать её виртуальной, то тогда можно прямо TBaseProcess* сделать аргументом Exec. Но это лишние расходы. А вот сделать Exec принимающим void*, добавить аргумент void *pросdata=0 в конструктор TBaseProcess и в шаблон процесса - практически ничего не требует дополнительного и, пожалуй, будет совместимо с уже написанным кодом. И иногда может быть удобным, по крайней мере если захочется из TBaseProcess вывести свой тип процесса и создать два экземпляра процесса. Но то же самое и со столь же небольшими расходами (хотя по ОЗУ вопрос - надо смотреть) можно сделать, создав два разных процесса "как оно сейчас" и сделав Код bla_bla_bla_1::Exec() { process1.execute(); }
bla_bla_bla_2::Exec() { process2.execute(); } Так что при желании сделать реальную функцию процесса нестатической можно разными способами, хоть и не выйдет через указатель на функцию-член. Цитата(sergeeff @ May 16 2009, 21:06)  вы же исходники Windows/Linus и прочего в таком виде не используете? Со сравнением с тасканием исходников "больших" ОС не согласен - эти ОС запускают отдельно скомпилированные процессы, долинковывая их к себе при запуске. И такая универсальность тянет за собой дополнительные расходы. От scmRTOS пока такого (к примеру, загрузки процесса по каналу связи или из воткнутой флешки) никто не требует, а если потребует, то она станет гораздо менее "scm-ной". Она в существенной мере инлайнится в пользовательское приложений - ну положите Вы объектные модули, по .cpp и .S от scmRTOS уже "никто не потопчется" ценой роста размера таблиц. Но существенная часть кода ОС всё равно находистя в .h-файлах и с "нетоптанием" по ним всё равно придётся работать "административно" а не "языково". "За что боролись?" Конечно, любая автоматизация даёт удобства. И можно даже что-то попробовать наворотить. Все ключевые места, где используется число процессов - или разогнать по максимуму (таблицы), или считывать из внешних по отношению к коду ОС переменных (начальные/конечные значения счётчиков/масок при переборе процессов), так как пустые места в таблицах надо будет обходить. Стоят ли эти расходы полученного частичного удобства, отличающегося не качественно, а только количественно (ограничен доступ грязных ножек и шаловливых ручек к половине файлов)? Ну не знаю.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
May 17 2009, 11:17
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Цитата(ReAl @ May 17 2009, 15:13)  Что-то мне казалось, что с включением текущей папки проекта в пути поиска все эти undefined reference должны были уйти. Но не ушли... А чтобы ушли, надо было в мой проект Code::Blocks добавить файлы ОС OS_Target_cpp.cpp, OS_Target_asm.S, OS_Kernel.cpp, OS_Services.cpp, usrlib.cpp. Я их не включил в проект, наивно полагая, что C::B или компилятор их сами включат...
--------------------
Благодарю заранее!
|
|
|
|
|
May 17 2009, 11:42
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Вот по поводу этого объясните, ещё пожалуйста: Код namespace OS {
template<> OS_PROCESS void TProc1::Exec() { ... Зачем namespace, template? На страницах 21, 27, 103-104 руководства процесс оформлен более просто... почему?
Сообщение отредактировал n_bogoyavlensky - May 17 2009, 11:57
--------------------
Благодарю заранее!
|
|
|
|
|
May 17 2009, 12:10
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Цитата(sergeeff @ May 17 2009, 15:53)  На 21 стр. - "скелет" функции. Собственно вызов (имя) и иллюстрация того, что процесс, как минимум, бесконечный цикл.
На 103-104 стр. - реальный пример. Да я это-то понял давно! Я не понял почему в этом примере (стр. 103-104) "namespace OS" и "template<>" перед функциями процессов не поставлены, а в примерах из дистрибутива ОС - поставлены. Почему?
--------------------
Благодарю заранее!
|
|
|
|
|
May 17 2009, 13:56
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(n_bogoyavlensky @ May 17 2009, 15:10)  Я не понял почему в этом примере (стр. 103-104) "namespace OS" и "template<>" перед функциями процессов не поставлены, а в примерах из дистрибутива ОС - поставлены. Почему?  Потому что gcc 4.x несколько строже к этому всему относится и требует, чтобы Exec() определялся в том же namespace, в котором он был объявлен (в файлах ОС). С template<> аналогичная петрушка - все параметры шаблона уже "специализированы", свободных не осталось, но Exec() - часть шаблона, поэтому gcc просит template<> IAR обходится без этого, а документация писалась автором оси по итогам IAR-вского варианта. Не вникал дотошно в стандарт - толи IAR даёт тут некоторое послабление относительно стандарта, толи gcc относится несколько прямолинейнее, чем нужно, но это в конечном итоге и неважно. А в стандарте в примерах такие же template<> с пустыми уголками.По поводу включения осевых .cpp в проект - ни среда ни компилятор действительно от себя ничего не включают. Так или иначе это нужно указать, в примерах к варианту avr-gcc просто в makefile сделаны правила "включать всё, что есть в указанных каталогах - проекта (текущий) и scmRTOS/Common scmRTOS/AVR". И make находит нужное и включает в команды для компилятора.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
May 18 2009, 05:44
|

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

|
Цитата(sergeeff @ May 16 2009, 18:39)  Очень хотелось бы сделать так, чтобы первый объявленный процесс получал высший приоритет, следующий процесс - приоритет на 1 ниже и т.д. Тогда, объявив в самой ОС число возможных процессов по максимуму всю ОС оформить в виде отдельной библиотеки и пользователям в своей организации раздать, чтобы они "грязными ногами" в ее "чистом теле" не натоптали. Сколько не думал, пока ничего не придумалось. Может есть какие соображения на сей счет? Собственно, про хранение в скомпилированном варианте уже обсудили - тоже придерживаюсь мнения, что на таких размерах и при требованиях к эффективности проще и реальнее компилировать сорцы оси с сорцами проекта. Ну, а про автоматическое присваивание приоритетов - а если процессы объявлены в разных файлах? Тут зависимость от порядка объявления возникнет. А для борьбы с ошибками конфигурации штатные средства (компилятор, линкер, препроцессор) не подходят (из-за раздельной компиляции), и лучше использовать утилитку, которую пускать в процессе сборки (до или после линкера). Я так и делаю. И проблем нет. Всем рекомендую.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
May 18 2009, 05:54
|

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

|
Цитата(ReAl @ May 16 2009, 19:17)  Если постараться - можно. В конструкторе TBaseProcess после Kernel.RegisterProcess(this), там, где формируется начальный стековый кадр, затолкать этот же this в такое место, чтобы после восстановления контекста он оказался в нужных регистрах. Только, насколько я понимаю, тип параметра exec у конструктора для этого должен быть другой - указатель на функцию-член. Да, согласен, если постараться, то можно. Раз уж готовим сами стековый кадр, то и внедрить туда this тоже можно. Только зачем? Я ни одной приличной причины не знаю. По своей сути функция exec - это функция пользователя. Ей от самого объекта-процесса ничего не надо. Т.е. это отдельная фукнция, просто помещенная в пространство имен процесса. С таким же успехом можно было бы создавать произвольные глобальные функции и подсовывать их в конструктор процесса. Ну, как сделано, так сделано.  В духе ++.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
May 18 2009, 11:37
|

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

|
Цитата(n_bogoyavlensky @ May 18 2009, 12:31)  13. Что такое системный процесс Idle и для чего он нужен? Процессор выполняет его, когда все пользовательские процессы находятся в состоянии ожидания. В нем может быть, например, команда перевода процессора в спячку. Цитата(n_bogoyavlensky @ May 18 2009, 12:31)  14. Как "сообщить" scmRTOS о том, что я в качестве системного таймера выбрал таймер Т0? Хороший. вопрос. Учитывая, что в примерах именно T0 уже выбран в качестве системного таймера. Цитата(n_bogoyavlensky @ May 18 2009, 12:31)  Зачем разрешать вложенные прерывания в обработчике прерывания от системного таймера? Для какой-нибудь очень важной и срочной задачи (если она есть)? Да. Для других прерываний, которые могут не использовать сервисы ОС.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 18 2009, 12:24
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Ну вот, запустил  Только вот код много места занимает. С опцией компилятора -Os, rtos.elf.hex - 8 кб, бинарный - около 3 кб. Это нормально? Или для сокращения размера надо ещё что-нибудь в опции компилятора добавить? Код #include <avr/io.h> #include <scmRTOS.h>
typedef OS::process<OS::pr0, 150> TProc1; typedef OS::process<OS::pr1, 150> TProc2;
TProc1 Proc1; TProc2 Proc2;
int main(void) { DDRB |= _BV(PB0); DDRC |= _BV(PC5);
TCCR0B = (1 << CS01) | (1 << CS00); // clk/64 TIMSK0 |= (1 << TOIE0);
OS::Run();
return 0; };
namespace OS { template<> OS_PROCESS void TProc1::Exec() { for(;;) { if ((PORTB & _BV(PB0))) {PORTB &= ~_BV(PB0);} else {PORTB |= _BV(PB0);}; Sleep(10); }; }; };
namespace OS { template<> OS_PROCESS void TProc2::Exec() { for(;;) { if ((PORTC & _BV(PC5))) {PORTC &= ~_BV(PC5);} else {PORTC |= _BV(PC5);}; Sleep(10); }; }; }; Цитата(Сергей Борщ @ May 18 2009, 15:37)  Процессор выполняет его, когда все пользовательские процессы находятся в состоянии ожидания. В нем может быть, например, команда перевода процессора в спячку. А ещё что там может быть? Что угодно с учётом того, что этот процесс самый низкоприоритетный? Цитата Хороший. вопрос. Учитывая, что в примерах именно T0 уже выбран в качестве системного таймера. Примеры смотрел. Но не так подробно все исходники. Времени пока нет. Пока нигде не "сообщал" и всё работает с Т0. Но ответ хотелось бы знать  Как я понял, если следовать логике авторов ОС, то для Idle код надо вставлять в IdleProcessUserHook()? А где её определять? В своём модуле или в OS_Target_cpp.cpp? Наверное, в своём лучше...
--------------------
Благодарю заранее!
|
|
|
|
|
May 18 2009, 12:27
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(n_bogoyavlensky @ May 18 2009, 15:12)  Ну вот, запустил  Только вот код много места занимает. С опцией компилятора -Os, rtos.elf.hex - 8 кб, бинарный - около 3 кб. Это нормально? Или для сокращения размера надо ещё что-нибудь в опции компилятора добавить? http://electronix.ru/forum/index.php?s=&am...st&p=593569Цитата(n_bogoyavlensky @ May 18 2009, 15:12)  А ещё что там может быть? Что угодно с учётом того, что этот процесс самый низкоприоритетный? И что он не может пользоваться "ожидающими" сервисами. Т.е. послать сигнал может, ждать его - нет. Код start = OS::GetTickCount(); while( (OS::GetTickCount() - start) < 10 ); может Код Sleep(10); не может. Хук, естественно, лучше в своём. Цитата(n_bogoyavlensky @ May 18 2009, 15:12)  Примеры смотрел. Но не так подробно все исходники. Времени пока нет. А у нас, значит, валом...
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
May 18 2009, 12:59
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Нашёл: В OS_Target_cpp.cpp определена функция: Код // System timer ISR // OS_INTERRUPT void SYSTEM_TIMER_VECTOR(void) { scmRTOS_ISRW_TYPE ISR; Kernel.SystemTimer();
#if scmRTOS_SYSTIMER_HOOK_ENABLE == 1
// enable nested interrupts ONLY if user hook enabled #if scmRTOS_SYSTIMER_NEST_INTS_ENABLE == 1 ENABLE_NESTED_INTERRUPTS(); #endif
SystemTimerUserHook(); #endif } А выбор вектора прерывания системного таймера осуществлён в scmRTOS_TARGET_CFG.h. Здесь и выбираем нужный системный таймер. А в main его инициализируем... Код // System Timer stuff // // #if defined(TIMER0_OVF0_vect) # define SYSTEM_TIMER_VECTOR TIMER0_OVF0_vect #elif defined(TIMER0_OVF_vect) # define SYSTEM_TIMER_VECTOR TIMER0_OVF_vect #else # error "Timer0 overflow vector not defined" #endif
#if defined(TIMSK0) # define TIMSK0_REG TIMSK0 #elif defined(TIMSK) # define TIMSK0_REG TIMSK #else # error "Timer0 interrupt mask register not defined" #endif
#define LOCK_SYSTEM_TIMER() ( TIMSK0_REG &= ~(1 << TOIE0) ) #define UNLOCK_SYSTEM_TIMER() ( TIMSK0_REG |= (1 << TOIE0) ) Цитата(ReAl @ May 18 2009, 16:27)  Пробовал, разницы нет...
--------------------
Благодарю заранее!
|
|
|
|
|
May 18 2009, 13:46
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(n_bogoyavlensky @ May 18 2009, 15:59)  Пробовал, разницы нет... Странно. Пример 1-EventFlag из порта - явно сложнее Вашего кода. CFLAGS = -Os -ffunction-sections -fdata-sections LDFLAGS = -Wl,--gc-sections -Wl,--relax Код ======== Beginning of project event_flag processing avr-gcc.exe (GCC) 4.2.2 (WinAVR 20071221) ... ==== Compiling ./src/main.cpp ==== Compiling ../scmRTOS/Common/OS_Kernel.cpp ==== Compiling ../scmRTOS/Common/OS_Services.cpp ==== Compiling ../scmRTOS/Common/usrlib.cpp ==== Compiling ../scmRTOS/AVR/OS_Target_cpp.cpp ==== Compiling ../scmRTOS/AVR/OS_Target_asm.S ==== Link to event_flag.elf ==== extract event_flag.hex ======== All OK, project size: AVR Memory Usage ---------------- Device: atmega168 Program: 1792 bytes (10.9% Full) (.text + .data + .bootloader) Data: 444 bytes (43.4% Full) (.data + .bss + .noinit) Код ======== Beginning of project event_flag processing avr-gcc.exe (GCC) 3.4.6 ... ======== All OK, project size: AVR Memory Usage ---------------- Device: atmega168 Program: 2084 bytes (12.7% Full) (.text + .data + .bootloader) Data: 444 bytes (43.4% Full) (.data + .bss + .noinit) Код ======== Beginning of project event_flag processing avr-gcc.exe (WinAVR 20081205) 4.3.2 ... ======== All OK, project size: AVR Memory Usage ---------------- Device: atmega168 Program: 1686 bytes (10.3% Full) (.text + .data + .bootloader) Data: 444 bytes (43.4% Full) (.data + .bss + .noinit) Код ======== Beginning of project event_flag processing avr-gcc.exe (WinAVR 20090313) 4.3.2 ... ======== All OK, project size: AVR Memory Usage ---------------- Device: atmega168 Program: 1664 bytes (10.2% Full) (.text + .data + .bootloader) Data: 444 bytes (43.4% Full) (.data + .bss + .noinit) -funsigned-bitfields -fshort-enums компилятору ещё немного уменьшает код, байт на тридцать в зависимости от версии компилятора (собственно, в примерах в makefile эти опции стоят, но я не упоминал их в том посте и сейчас для соответствия ему убрал)
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
May 18 2009, 17:14
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Цитата(ReAl @ May 18 2009, 20:42)  Попробуйте разобраться - какие опции реально получает компилятор. Я-то всем управляю руками через самописній makefile, а сто там среда куда подставляет... Я пока не знаю как это сделать  Вроде, прописал всё куда нужно... Надо как-то попробовать включить полный вывод того, что делает среда... Цитата p.s. если у меня на уровне makefile отключить линкеру --gc-sections --relax, то віходит 3400-3500 байт в зависимости от версии компилятора Кстати, вот ещё что... Добавил в проект старый модуль на Си (xxx.c). Получил на все функции в нём сообщения о том, что они не определены... Переименовал файл в "xxx.cpp" - всё сразу нашлось. Почему? Добавлял-то я файл с расширением...
Сообщение отредактировал n_bogoyavlensky - May 18 2009, 17:19
--------------------
Благодарю заранее!
|
|
|
|
|
May 18 2009, 17:25
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(n_bogoyavlensky @ May 18 2009, 20:14)  Добавил в проект старый модуль на Си (xxx.c). Получил на все функции в нём сообщения о том, что они не определены... Переименовал файл в "xxx.cpp" - всё сразу нашлось. Почему? Добавлял-то я файл с расширением... В .h они были объявлены "как обычно" и при компиляции С++ файлов (других в проекте) компилятор, грубо говоря, пытался на них сослаться как на С++ - функции. Надо внутренности этого h-файла охватить таким Код #ifdef __cplusplus extern "C" { #endif
// тут объявления всех функций из С-файла
#ifdef __cplusplus } #endif
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
May 18 2009, 17:28
|
Профессионал
    
Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007

|
Уважаемый коллега! Неужели вам в google трудно поискать ответы на тысячу раз расписанные вопросы совместной работы .с и .сpp модулей? Вы своим пытливым взглядом не разглядивали устройство .h файлов в библиотеках? Так вот там есть такая кострукция: Код #ifdef __cplusplus
extern "C" { #endif /* __cplusplus */
int ааа(int j); int bbb(const char *s);
.....
#ifdef __cplusplus } #endif /* __cplusplus */ Это заставляет С++ -ный компилятор генерить С-совместимые (nonmangled) имена. Что и вам надо сделать с вашими .h файлами (если вы ими в своими проектами пользуетесь, надеюсь).
|
|
|
|
|
May 25 2009, 06:06
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Здравствуйте! Ещё один вопрос  Корректным ли с точки зрения ОС будет использование объекта TEventFlag как поля данных внутри динамически создаваемого экземпляра класса (экземпляр класса, точнее указатель на него, при этом глобальный)? Или объект TEventFlag должен быть обязательно статическим?
--------------------
Благодарю заранее!
|
|
|
|
|
Jun 10 2009, 11:25
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Цитата(ReAl @ Jun 10 2009, 13:45)  Вход компаратора переключается на внутреннюю опору Это понятно. Не было понятно что же твориться с самим выводом в этом случае... Теперь понятно. Спасибо за разъяснения  Цитата(Сергей Борщ @ Jun 10 2009, 13:41)  Да, можно. А вам обязательно, чтобы это было прерывание компаратора? Используйте прерывание SPM. Посмотрим! Спасибо!
--------------------
Благодарю заранее!
|
|
|
|
|
Jun 22 2009, 11:56
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Цитата(Сергей Борщ @ Jun 10 2009, 14:41)  Да, можно. А вам обязательно, чтобы это было прерывание компаратора? Используйте прерывание SPM. Можно будет и AIN1 использовать под свои нужды. В одном из примеров была реализация. Здравствуйте! Скажите, пожалуйста, для организации передачи управления по прерыванию SPM какие действия надо предпринять? Смотрю примеры: 1-ый и 3-ий - то, что нужно. Но до конца пока не разобрался. 1. Использовать файл scmRTOS_TARGET_CFG.h из 1-го или 3-го примера. 2. В файле scmRTOS_CONFIG.h: #define scmRTOS_CONTEXT_SWITCH_SCHEME 1. Ещё что-нибудь надо написать, чтобы заработало?
--------------------
Благодарю заранее!
|
|
|
|
|
Jun 22 2009, 18:12
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Не работает!  Прямая передача управления работает, а передача управления по программному прерыванию не работает  Смотрел осциллографом. Такое ощущение, что первый поток начинает выполняться и... зависает... В чём может быть дело? Может быть я что-то не дописал?  Уточняю. Система работает до первого вызова Sleep из первого потока.
Сообщение отредактировал n_bogoyavlensky - Jun 22 2009, 18:44
--------------------
Благодарю заранее!
|
|
|
|
|
Jun 23 2009, 03:36
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Цитата(ReAl @ Jun 22 2009, 23:38)  Странно. В порте avr-gcc все примеры проверялись в железе c осциллографом с разными сочетаниями разрешения вложенных прерываний и методом переключения контекстов, но с WinAVR-20071221, 20070525. Я пробую с WinAVR 20080610. Исходники прилагаю (main.cpp, scmRTOS_CONFIG.h, scmRTOS_TARGET_CFG.h). Посмотрите, пожалуйста, а то я уже голову сломал
Прикрепленные файлы
Prob.rar ( 4.45 килобайт )
Кол-во скачиваний: 25
--------------------
Благодарю заранее!
|
|
|
|
|
Jun 23 2009, 08:42
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(n_bogoyavlensky @ Jun 23 2009, 06:36)  Я пробую с WinAVR 20080610. Исходники прилагаю (main.cpp, scmRTOS_CONFIG.h, scmRTOS_TARGET_CFG.h). Посмотрите, пожалуйста, а то я уже голову сломал  Хм. В коде всё нормально. Версия avr-gcc - значение опции MAKE_SMALLEST_HEX в makefile - размер кода/данных - работа в макете с atmega168@intRC8MHz (опция MAKE_SMALLEST_HEX для 20060421 работает, так как у себя я заменил этой версии ldscripts на более новые с KEEP() для нужных секций). Именно 20080610 у меня на компьютере нет и лень ставить. Цитата // 20060421-N - 3574/402 - OK // 20071221-N - 3164/402 - OK // 20081205-N - 3078/402 - OK // 20090313-N - 3056/402 - OK
// 20060421-Y - 1218/402 - OK // 20071221-Y - 1138/402 - OK // 20081205-Y - 1052/402 - OK // 20090313-Y - 1030/402 - OK Прикладываю всё кучей аж с листингами, архив всё равно небольшой. Попробуйте сверить ключи компилятора, хотя у меня ничего такого особого не прописано.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Jun 23 2009, 10:19
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Цитата(ReAl @ Jun 23 2009, 12:42)  Хм. В коде всё нормально. Версия avr-gcc - значение опции MAKE_SMALLEST_HEX в makefile - размер кода/данных - работа в макете с atmega168@intRC8MHz (опция MAKE_SMALLEST_HEX для 20060421 работает, так как у себя я заменил этой версии ldscripts на более новые с KEEP() для нужных секций). Именно 20080610 у меня на компьютере нет и лень ставить. Прикладываю всё кучей аж с листингами, архив всё равно небольшой. Попробуйте сверить ключи компилятора, хотя у меня ничего такого особого не прописано. Спасибо. Ваш hex попробуем. Посмотрим на мейк. Скомпилировал в 2007. Вечером проверю. Доложу. Кстати, а оптимизация не может негативно влиять? У вас, я смотрю, оптимизация совсем никакая: опция OPT = -Os  И ещё по поводу стандарта. У вас -std=c++98, у меня не знаю что Code::Blocks компилятору подсовывает
--------------------
Благодарю заранее!
|
|
|
|
|
Jun 23 2009, 10:44
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(n_bogoyavlensky @ Jun 23 2009, 13:19)  Кстати, а оптимизация не может негативно влиять? У вас, я смотрю, оптимизация совсем никакая: опция OPT = -Os  Самая правильная оптимизация для AVR Вот за всякие дополнительные ручки по поводу лимита размера для inline и тому подобное - да, не дёргаю. И так не плохо. Не думаю, что -O2 должна сильно поменять ситуацию. Цитата(n_bogoyavlensky @ Jun 23 2009, 13:19)  И ещё по поводу стандарта. У вас -std=c++98, у меня не знаю что Code::Blocks компилятору подсовывает  Там оно вроде бы закомментировано, так что будет использоваться умолчание (gnu++98 для С++)
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Jun 23 2009, 12:03
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Цитата(ReAl @ Jun 23 2009, 14:44)  Самая правильная оптимизация для AVR Вот за всякие дополнительные ручки по поводу лимита размера для inline и тому подобное - да, не дёргаю. И так не плохо. Не думаю, что -O2 должна сильно поменять ситуацию. Виноват, буковку "s" не заметил. Я сегодня совсем сплю  Кстати, посмотрел на описание оптимизации (перевод книги по GCC), там, вроде бы, часть флагов компилятора для разных режимов оптимизации смешивается... Допустим, -Os включает -O3 и добавляет свои флаги... -O3 включает -O2 и добавляет свои флаги... -O2 включает -O и добавляет свои флаги... А -O1 и -O вообще одно и то же... Т. е., получается, что совместно использовать, например -O2 и -Os смысла никакого нет, т. к., -Os включает -O2 и добавляет свои флаги? Кстати, опции -Oi фактически являются "обёртками", которые указывают на включение других дополнительных опций, как я понял? Цитата Там оно вроде бы закомментировано, так что будет использоваться умолчание (gnu++98 для С++) Ага, этого я тоже не заметил... Ещё вопросы... ISR вызывается в контексте того процесса, который выполнялся при возникновении прерывания? Как я понимаю, оптимальное содержимое ISR - инструкция перевода какого-либо эвента в сигнальное состояние? А если в ISR модифицируются глобальные объекты, которые модифицируются так же в одном из процессов (или в нескольких), то необходимо использовать средства синхронизации для доступа к этим объектам (критические секции, семафоры)? Причём, внутри ISR прерывания запрещены всегда и получается, что критические секции в ISR использовать бессмысленно, а семафоры вообще противопоказано... и средства синхронизации нужно использовать вне ISR в процессах, работающих с нашим глобальным объектом? Помогите разобраться, пожалуйста, а то в голове каша
--------------------
Благодарю заранее!
|
|
|
|
|
Jun 23 2009, 19:16
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Откомпилировал в WinAVR 2007 - не работает. Откомпилировал в WinAVR 20090313 - не работает. То, что Вы прислали - тоже не работает!  Может, конечно, Proteus глючит... нету сейчас железки под руками проверить... Странно. Займусь сверкой ключей... А Вы в выложенной мною программе ничего не меняли? В протеусе я вижу на PC1 сигнал со скважностью отличной от двух... очень отличной. А на PC2 - вообще нуль... А Вы когда смотрели осциллографом видели на обоих выводах какие сигналы?
--------------------
Благодарю заранее!
|
|
|
|
|
Jun 23 2009, 20:21
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Огромная просьба, если Вас не затруднит, то проверьте, пожалуйста, на своём макете работу той же программы, откомпилированной у меня (файл Prob.elf.hex). Так мы и моё компилирование проверим и протеус... ATmega168. 8000000 MHz. WinAVR20090313.
Сообщение отредактировал n_bogoyavlensky - Jun 23 2009, 20:22
Прикрепленные файлы
Prob2.zip ( 7.92 килобайт )
Кол-во скачиваний: 24
--------------------
Благодарю заранее!
|
|
|
|
|
Jun 24 2009, 16:43
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(n_bogoyavlensky @ Jun 23 2009, 22:16)  То, что Вы прислали - тоже не работает!  Ну не знаю... Цитата(n_bogoyavlensky @ Jun 23 2009, 22:16)  А Вы в выложенной мною программе ничего не меняли? Я же прицепил полный проект, который я собирал. Не менял ничего, только приложил рядом сам scmRTOS и свои make-файлы Цитата(n_bogoyavlensky @ Jun 23 2009, 22:16)  А Вы когда смотрели осциллографом видели на обоих выводах какие сигналы?  Меандры около 20мс и 60мс длительности уровня. 8MHz int RC в качестве тактирования. На время прошивки очередного варианта они пропадали :-) Цитата(n_bogoyavlensky @ Jun 23 2009, 23:21)  Огромная просьба, если Вас не затруднит, то проверьте, пожалуйста, на своём макете работу той же программы, откомпилированной у меня (файл Prob.elf.hex). Ой, а это нескоро. С выходных до следующих выходных я уезжаю, а до этого не до того.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Jun 24 2009, 16:54
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Цитата(ReAl @ Jun 24 2009, 20:43)  Ой, а это нескоро. С выходных до следующих выходных я уезжаю, а до этого не до того. Спасибо Вам большое за помощь!  Нашёл железку. В четверг обязательно на ней сам проверю. Скорее всего это глюки протеуса. О результатах напишу...
--------------------
Благодарю заранее!
|
|
|
|
|
Jun 25 2009, 07:06
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
Проверил в железе. ATmega48P, 20 МГц, оба способа передачи управления. Работает замечательно. Обидно, что Proteus меня подвёл...  Побегу жаловаться ReAL, это опции линкера, как я понял (из вашего мейка)? Цитата LDFLAGS += -Wl,--gc-sections LDFLAGS += -Wl,--relax А зачем -Wl два раза указан?
--------------------
Благодарю заранее!
|
|
|
|
|
Jun 25 2009, 07:22
|

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

|
Цитата(n_bogoyavlensky @ Jun 25 2009, 10:06)  ReAL, это опции линкера, как я понял (из вашего мейка)? Это опции, которые gcc передаст линкеру (ld). Цитата(n_bogoyavlensky @ Jun 25 2009, 10:06)  А зачем -Wl два раза указан? Об этом можно прочитать в документации на gcc. -Wl "действует" до ближайшего пробела.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jun 25 2009, 07:25
|
Профессионал
    
Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061

|
По поводу нашего давнего разговора в этой ветке о сокращении размера кода при компиляции... Разобрался... Для линкера надо было писать -Wl,-Map=$(TARGET_OUTPUT_FILE).map,--cref,--gc-sections,--relaxЯ писал: -Wl,-Map=$(TARGET_OUTPUT_FILE).map,--cref --gc-sections --relax
Поэтому и не работало... Цитата(Сергей Борщ @ Jun 25 2009, 11:22)  Это опции, которые gcc передаст линкеру (ld). Это понятно. Я имею ввиду зачем две строчки с -Wl, если можно обойтись одной...
Сообщение отредактировал n_bogoyavlensky - Jun 25 2009, 07:23
--------------------
Благодарю заранее!
|
|
|
|
|
Oct 4 2009, 07:40
|

Знающий
   
Группа: Участник
Сообщений: 626
Регистрация: 3-12-07
Пользователь №: 32 910

|
Хотел попробовать запустить примеры для BF533. К сожалению проект скомилировать не удаётся, ошибка такого плана: ".\Src\main.cpp", line 112: cc0167: error: argument of type "void (*)(int, int, int)" is incompatible with parameter of type "ex_handler_fn" register_handler_ex(ik_timer, OS::SystemTimer_ISR, 1); ^
".\Src\main.cpp", line 113: cc0167: error: argument of type "void (*)(int, int, int) C" is incompatible with parameter of type "ex_handler_fn" register_handler_ex(ik_ivg14, ContextSwitcher_ISR, 1); ^
2 errors detected in the compilation of ".\Src\main.cpp". cc3089: fatal error: Compilation failed
--------------------
|
|
|
|
|
Oct 5 2009, 08:16
|

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

|
Цитата(sevstels @ Oct 4 2009, 20:19)  уже решил заменой файлов из snapshot мне только одно не понятно, почему-бы сразу не выкладывать корректную версию для скачивания или надо чтоб народ для начала немного помучился? Дело в том, что в релизе лежит версия для VDSP 4.5 (и более старых), там прототип обработчика прерывания описывался с тремя аргументами типа int. Зачем так было сделано, не знаю. В версии VDSP 5.0 они, видимо, и сами это поняли, и убрали эти инты из прототипа. В соответствии с этим были внесены изменения, которые оперативно отразились в репе и в снапах. Но поскольку релиз еще не выпускался, то в архивах лежит версия для VDSP 4.5. Видимо, надо придумать какую-то простую схему, указывающую для какой версии тулчейна предназначена та или иная версия порта. Кстати, раньше название и версия используемого тулчейна были прямо забиты в пути порта (например, директория порта прямо так и называлась /BF533/VDSP4.0, но это оказалось неудобным - каждый раз переименовывать директории в путях. Поэтому перешли к общему названию (BF533/VDSP). Самое простое писать в сопроводиловке, какой версии тулчейна соответствует порт.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Oct 5 2009, 13:41
|

Знающий
   
Группа: Участник
Сообщений: 626
Регистрация: 3-12-07
Пользователь №: 32 910

|
Это конечно удивительно, автор работает ещё 4.0 версией VDSP! Надо иметь железные нервы... был в шоке. Кстати потестил на BF561 (600/150) - всё аж летает  При компиляции есть предупреждение: ".\scmRTOS\BF533\OS_Target_cpp.cpp", line 61 (col. 5): cc1746: {D} warning: Externally defined variable Kernel, possibly used in constructor before it has been constructed Дык что тут думать? Проще не бывает. scmRTOS BF533 vdsp 4.0scmRTOS BF533 vdsp 4.5scmRTOS BF533 vdsp 5.0Или на php простенький скрипт, по какой ссылке кликнули, сервер соответствующие файлы в архив и закатал. -
Сообщение отредактировал sevstels - Oct 5 2009, 14:14
--------------------
|
|
|
|
|
Oct 6 2009, 02:56
|

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

|
Цитата(sevstels @ Oct 5 2009, 20:41)  Это конечно удивительно, автор работает ещё 4.0 версией VDSP! Надо иметь железные нервы... был в шоке. Вы на дату выхода релиза 3.05 посмотрите. На тот момент стабильной была версия 4.5, на ней все и тестилось. Поскольку совместимость между 4.0 и 4.5 была, то имя директории и не переименовывалось. В настоящее время автор работает на версии 5.0, не сомневайтесь - иначе откуда бы в репе и снапе взялась соответствующие VDSP 5.0 версии файлов. Цитата(sevstels @ Oct 5 2009, 20:41)  Кстати потестил на BF561 (600/150) - всё аж летает  Это радует.  Цитата(sevstels @ Oct 5 2009, 20:41)  При компиляции есть предупреждение: ".\scmRTOS\BF533\OS_Target_cpp.cpp", line 61 (col. 5): cc1746: {D} warning: Externally defined variable Kernel, possibly used in constructor before it has been constructed Есть такая буква. Формально компилятор прав, хотя по факту ничего опасного там нет, все в порядке. Надо, конечно, пофиксить. Пока еще не решено, как именно сделать. Самое простое - объявить таблицу указателей процессов как статический член класса. В первой версии, кстати, так и было. Цитата(sevstels @ Oct 5 2009, 20:41)  Дык что тут думать? Проще не бывает. scmRTOS BF533 vdsp 4.0scmRTOS BF533 vdsp 4.5scmRTOS BF533 vdsp 5.0Или на php простенький скрипт, по какой ссылке кликнули, сервер соответствующие файлы в архив и закатал. - Я не знаток веб технологий. Но есть кое-какие ограничения. Например, по правилам sourceforge.net нельзя на сайте хранить файлы для закачки. Все, что подлежит скачиванию, должно быть размещено на download серверах. А там все по релизам.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Oct 6 2009, 07:27
|

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

|
Цитата(sevstels @ Oct 6 2009, 10:45)  ----------------Configuration: MAIN_BF561 - Debug---------------- Linking...
[Error li1021] The following symbols referenced in processor 'p0' could not be resolved: 'ContextSwitcher_ISR [_ContextSwitcher_ISR]' referenced from 'corea.dlb[main_core_a.doj]' 'OS_Start [_OS_Start]' referenced from 'corea.dlb[main_core_a.doj]'
Linker finished with 1 error cc3089: fatal error: Link failed Я не работал с двухядерником, нюансов, связанных с ним, не знаю. Но по сообщению линкера похоже, что в объектники не попали потроха из ассемблерного файла "OS_Target_asm.sbf" - обе функции, которые не найдены, описаны в этом файле. Если собираете оболочкой, то проверьте, транслируется ли этот файл. Оболочка, помнится, не признавала для асмовых файлов никаких расширений, кроме .s, .asm и .dsp. Поменяйте расширение, попробуйте.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Oct 6 2009, 09:18
|

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

|
Цитата(sevstels @ Oct 6 2009, 14:43)  Расширение давно поменял, файл OS_Target_asm.asm Проект отлично собирался и работал в железке, пока был для одного ядра... Тем не менее, проблема именно из-за асмового файла. У вас есть еще другие ассемблерные файлы в проекте? Проверьте, транслируется ли сам файл - от него должны оставаться следы - OS_Target_asm.doj. Включается ли этот объектный файл в процесс сборки (линковки)? Если объектные файлы заключаются в библиотеку - я понял, что на двухядернике все объектные модули для одного ядра собираются в библиотеку, - посмотрите ее содержимое (утилитой elfar с ключом -р), содержится ли этот файл в ней. Где-то он потерялся.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Jan 23 2010, 21:31
|
Группа: Участник
Сообщений: 3
Регистрация: 23-07-05
Пользователь №: 7 044

|
Добрый день. Я новичок в программировании, не судите строго. у меня есть задача, которая одновременно должна ждать три события. Одно от системного твика и возможны 2 сообщения от разных источников. Получается, что я не могу использовать ни Sleep(N) ни Message.wait() Ведь по осутствию первого же из этих событий задача передаст управление операционке и не проверит остальные. Или я где-то путаю?
|
|
|
|
|
Jan 24 2010, 10:48
|

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

|
Цитата(vzuravlo @ Jan 24 2010, 03:31)  у меня есть задача, которая одновременно должна ждать три события. Одно от системного твика и возможны 2 сообщения от разных источников. Получается, что я не могу использовать ни Sleep(N) ни Message.wait() Ведь по осутствию первого же из этих событий задача передаст управление операционке и не проверит остальные. Или я где-то путаю? Вы можете использовать message<...>::wait(timeout). Задаете таймаут ожидания и все. Если пришло какое-то событие раньше таймаута, то функция вернет true, и обрабатываете событие, если события не пришли до истечения таймаута, то получаете результат функции false, и обрабатываете этот вариант. Процесс будет в любом случае "разбужен" либо по приходу события, либо по таймауту.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Jan 24 2010, 11:11
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(dxp @ Jan 24 2010, 12:48)  Вы можете использовать message<...>::wait(timeout). Задаете таймаут ожидания и все. Если пришло какое-то событие раньше таймаута, то функция вернет true, и обрабатываете событие, если события не пришли до истечения таймаута, то получаете результат функции false, и обрабатываете этот вариант. Дополнение: Если "таймерная" сетка нужна более-менее фикисрованная (пусть с дрожанием, но без накопления ошибки), то её вести в самом процессе через GetTickCount(), беря при старте процесса текущее значение и добавляя к нему период. После каждого просыпания (точнее, перед каждым вызовом wait() ) смотреть опять по GetTickCount() - сколько осталось времени и этот остаток передавать в message<...>::wait(timeout), по достижении снова добавлять период к локальноq переменной. Её при этом, кстати, не обязательно делать DWORD, если просыпаться нужно каждые, к примеру, 10 тиков, то локальная копия системного тика вполне может быть 1-байтовой.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Feb 26 2010, 15:57
|
Местный
  
Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205

|
Возник небольшой вопрос при использовании scmRTOS. Как в файле scmRTOS_CONFIG.h задавать общее количество процессов через макрос (и можно ли вообще)? Т.е. как-то так Код #include "Priority.h"
#define scmRTOS_PROCESS_COUNT TOTAL_PROCESS_NUMBER , где TOTAL_PROCESS_NUMBER задается в файле Priority.h который выглядит следующим образом Код #ifndef _BSP_MRTP4AN_PRIORITY_H #define _BSP_MRTP4AN_PRIORITY_H
#include <scmRTOS.h>
#define ANMEAS_PRI (OS::pr0) #define UART0_PRI (OS::pr1) #define UART1_PRI (OS::pr2) #define TECHNO_PRI (OS::pr3) #define PERIPH_PRI (OS::pr4)
#define TOTAL_PROCESS_NUMBER (5)
#endif /* _BSP_MRTP4AN_PRIORITY_H */ При попытке компилировать, вылазят такие ошибки CODE In file included from ../../bsp/scmRTOS/AVR/OS_Target.h:121, from ../../bsp/scmRTOS/Common/scmRTOS.h:52, from ../../bsp/MRTP4an/Priority.h:19, from ./src/scmRTOS_CONFIG.h:56, from ../../bsp/scmRTOS/AVR/OS_Target_asm.S:51: ../../bsp/scmRTOS/Common/scmRTOS_defs.h:73:2: error: #error "Error: Config macro scmRTOS_SYSTIMER_NEST_INTS_ENABLE must be defined!" ../../bsp/scmRTOS/Common/scmRTOS_defs.h:82:2: error: #error "Error: Config macro scmRTOS_SYSTEM_TICKS_ENABLE must be defined!" ../../bsp/scmRTOS/Common/scmRTOS_defs.h:92:2: error: #error "Error: Config macro scmRTOS_SYSTIMER_HOOK_ENABLE must be defined!" ../../bsp/scmRTOS/Common/scmRTOS_defs.h:101:2: error: #error "Error: Config macro scmRTOS_IDLE_HOOK_ENABLE must be defined!" ../../bsp/scmRTOS/Common/scmRTOS_defs.h:110:2: error: #error "Error: Config macro scmRTOS_CONTEXT_SWITCH_SCHEME must be defined!" ../../bsp/scmRTOS/Common/scmRTOS_defs.h:120:2: error: #error "Error: Config macro scmRTOS_PRIORITY_ORDER must be defined!" ../../bsp/scmRTOS/Common/scmRTOS_defs.h:239:14: error: #error "Invalid Process Count specification! Must be from 1 to 31." In file included from ../../bsp/scmRTOS/AVR/OS_Target.h:121, from ../../bsp/scmRTOS/Common/scmRTOS.h:52, from ../../bsp/MRTP4an/Priority.h:19, from ./src/scmRTOS_CONFIG.h:56, from ../../bsp/scmRTOS/AVR/OS_Target_asm.S:51: ../../bsp/scmRTOS/Common/scmRTOS_defs.h:73:2: error: #error "Error: Config macro scmRTOS_SYSTIMER_NEST_INTS_ENABLE must be defined!" ../../bsp/scmRTOS/Common/scmRTOS_defs.h:82:2: error: #error "Error: Config macro scmRTOS_SYSTEM_TICKS_ENABLE must be defined!" ../../bsp/scmRTOS/Common/scmRTOS_defs.h:92:2: error: #error "Error: Config macro scmRTOS_SYSTIMER_HOOK_ENABLE must be defined!" ../../bsp/scmRTOS/Common/scmRTOS_defs.h:101:2: error: #error "Error: Config macro scmRTOS_IDLE_HOOK_ENABLE must be defined!" ../../bsp/scmRTOS/Common/scmRTOS_defs.h:110:2: error: #error "Error: Config macro scmRTOS_CONTEXT_SWITCH_SCHEME must be defined!" ../../bsp/scmRTOS/Common/scmRTOS_defs.h:120:2: error: #error "Error: Config macro scmRTOS_PRIORITY_ORDER must be defined!" ../../bsp/scmRTOS/Common/scmRTOS_defs.h:239:14: error: #error "Invalid Process Count specification! Must be from 1 to 31." make: *** [obj/OS_Target_asm.o] Ошибка 1
Без моих модификаций проект собирается нормально. Используется avr-gcc 4.3.3
|
|
|
|
|
Feb 26 2010, 19:00
|

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

|
Цитата(kurtis @ Feb 26 2010, 20:43)  не помогло, те самые ошибки Я попробовал скомпилить свой проект, вставив Код #define TOTAL_PROCESS_NUMBER (5) #define scmRTOS_PROCESS_COUNT TOTAL_PROCESS_NUMBER в scmRTOS_CONFIG.h. Все скомпилилось. А, понял - у вас нарушен порядок включения заголовочных файлов. Вам нужно убрать #include <scmRTOS.h> из Priority.h Priority.h сам включается в scmRTOS.h через scmRTOS_CONFIG.h
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Mar 24 2010, 10:18
|
Группа: Участник
Сообщений: 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, 08:37
|
Группа: Участник
Сообщений: 10
Регистрация: 8-02-10
Пользователь №: 55 367

|
Цитата(jorikdima @ Mar 24 2010, 14:14)  из стека, если вы не пользуетесь динамическим выделением. А стек у каждой задачи свой, следовательно проблемы нет. В стеке задачи сохраняются только регистры, при этом не факт, что компилятор назначит регистр какой-либо локальной переменной. Например, если в подпрограмме определяются несколько float - локальных переменных, то скорее всего они создадутся из кучи, т.е из ОЗУ. Вы никогда не пробовали (в программе без ОСи) в прерываниях определить несколько локальных переменных (не static)? И что из этого вышло? Цитата(jorikdima @ Mar 24 2010, 14:14)  из стека, если вы не пользуетесь динамическим выделением. А что, разве существует какой-то другой тип распределения памяти компилятором? Как в IARe я могу изменить этот тип? Научите меня, плз.
|
|
|
|
|
Mar 25 2010, 09:01
|

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

|
Цитата(Embedder74 @ Mar 25 2010, 10:37)  Например, если в подпрограмме определяются несколько float - локальных переменных, то скорее всего они создадутся из кучи, т.е из ОЗУ. Локальные переменные выделяются на стеке. Всегда. Память из кучи выделяется функцией malloc() и подобными. В плюсах - оператором new. И никак иначе. Куча находится в ОЗУ точно так же, как и стек находится в ОЗУ. ОЗУ (RAM) != куча (heap). Цитата(Embedder74 @ Mar 25 2010, 10:37)  Вы никогда не пробовали (в программе без ОСи) в прерываниях определить несколько локальных переменных (не static)? И что из этого вышло? Пробовали. Вышло именно то, что и должно было. Цитата(Embedder74 @ Mar 25 2010, 10:37)  А что, разве существует какой-то другой тип распределения памяти компилятором? Как в IARe я могу изменить этот тип? Сначала опишите, что вы понимаете под "этим" способом. Это поможет определить, какие способы являются "другими".
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 9 2010, 17:34
|
Местный
  
Группа: Участник
Сообщений: 312
Регистрация: 9-04-10
Пользователь №: 56 532

|
atmega8 scmRTOS_SYSTIMER_NEST_INTS_ENABLE 1 scmRTOS_PROCESS_COUNT 2 Начал изучать эту ОС. Документацию прочитал. Но не пойму. Почему в моем коде никогда не выполняется TProc2? TProc1 ждет байт. Если пришел то отправить. TProc2 постоянно шлет 'b'. SystemTimerUserHook. постоянно отсылает 'v'. На выводе постоянно фижу 'v' но никогда 'b'. Если отсылаю байт то он тут же возвращается. Вывод TProc2 никогда не передается управление. Код int main() { MyUart.init(); // Start System Timer TCCR0 = (1 << CS01) | (1 << CS00); // clk/64 TIMSK |= (1 << TOIE0);
//Запускаем ОС OS::Run();
return 0; }
//--------------------------------------------------------------------------- namespace OS {
template<> OS_PROCESS void TProc1::Exec() { unsigned char c;
for(;;) { c=MyUart.receiveByte(); MyUart.sendByte(c); } } // TProc1::Exec()
template<> OS_PROCESS void TProc2::Exec() { for(;;) { MyUart.sendByte('b'); Sleep(50); } } // TProc2::Exec()
} // namespace OS
void OS::SystemTimerUserHook() { #if scmRTOS_SYSTIMER_NEST_INTS_ENABLE && !PORT_TOGGLE_BY_PIN_WRITE TCritSect cs; #endif MyUart.sendByte('v'); }
|
|
|
|
|
Apr 9 2010, 18:26
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
А всё потому, что TProc1 имеет наивысший приоритет, и не отдаёт никому управление. Вставьте в TProc1 Код MyUart.sendByte('b'); Sleep(10); и всё заработает. А если всё делать по уму, то надо чтобы функция MyUart.receiveByte(); сама вгоняла вызвавший её процесс в спячку до прихода символа.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|