Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Обсуждение из scmRTOS ветки
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы
altlogic
Здравствуйте!

Кто-нибудь может сказать как собрать пример использования scmRTOS для avr-gcc. Мэйк-файлы gcc-avr.mak и avreal.mak не хотят ничего у меня собирать... В командной строке сообщяется
Device: Unknown
и процесс сборки завершается. С мэйкфайлами столкнулся во второй раз. В первый раз - собирал jacOS:) Наверное там нужно чего-то подправить?
spf
Цитата(Clavyan @ Jan 5 2008, 11:24) *
Кто-нибудь может сказать как собрать пример использования scmRTOS для avr-gcc. Мэйк-файлы gcc-avr.mak и avreal.mak не хотят ничего у меня собирать... В командной строке сообщяется
Device: Unknown
и процесс сборки завершается. С мэйкфайлами столкнулся во второй раз. В первый раз - собирал jacOS:) Наверное там нужно чего-то подправить?

Эхе-хе, вот не пойму почему надо подобные вопросы задавать именно в теме новостей по оське.
Неужели так трудно сделать новую конкретную тему?

Указанные мейки не надо пытаться запускать, они вспомогательные.
Надо запускать GNU make находясь в каталоге 1-EventFlag, он сам найдет makefile.
В последнем можно порулить параметрами сборки и путем до тулчейна.



Цитата(Сергей Борщ @ Dec 20 2007, 14:46) *
Обновления в основной ветке репозитория:
- Исправлен баг в сервисах, проявлялся при одновременном доступе к сервису нескольких процесов. Описание бага применительно к TMutex тут: Bug Tracker. Баг проявляется независимо от платформы, поэтому обновление рекомендуется всем пользователям.

В ближайшем будущем будет выпущен релиз 3.01 в виде архивов, а пока можно получить последние версии из репозитория subversion.
ReAl
Цитата(Clavyan @ Jan 5 2008, 08:24) *
Кто-нибудь может сказать как собрать пример использования scmRTOS для avr-gcc. Мэйк-файлы gcc-avr.mak и avreal.mak не хотят ничего у меня собирать...
Это "общие" файлы, одинаковые для всех проектов. Каталог makefiles можно даже вынести из каталога проекта и поместить на одном уровне с каталогом scmRTOS (изменив соответственно makefile примера), возможно, я это и сделаю после добавления остальных примеров перед внесением порта в основную ветвь проекта.
Для компиялции примера надо запускать утилиту make в каталоге, где находится makefile примера, указывать этот файл утилите не нужно.
В самом начале makefile примера надо правильно установить переменную AVRGCC - специально сделано для того, чтобы можно было держать на компьютере несколько версий avr-gcc ("ту, в которой уверен", "свеженькую", ...) и компилировать проекты желаемой, в том числе для каждого проекта своей. Можно установить переменную окружения AVRGCC и тогда при отсутствии таковой в makefile проекта будет использоваться заданная глобально.

makefile примера должен работать и при единственном установленном с опциями по умолчанию WinAVR (он тогда сам добавляет в PATH пути на свои bin и utils\bin). У меня обычно стоит несколько версий и при установке я не даю им прописывать PATH.
Необходимое условие - доступность по PATH утилит make.exe, sh.exe, mkdir.exe, rm.exe, rmdir.exe (при установке WinAVR по умолчанию это условие выполняется автоматически).
altlogic
Спасибо за ответы, хотя я и впрямь написал не в ту ветку. Проблема была в то, что у меня не оказалось мэйк файла в папке с примером, вот я и стал искать его по всем директориямsmile.gif
Neyron
Выкачал порт avr-gcc 3.00.

Раньше пользовался 1.10. Системой очень доволен, за что спасибо авторам и поддерживающим её людям.

Мега 128. Тик системного таймера ~4.4 мс. Если время выполнения процесса превышает это время, происходит сбой.

Установил scmRTOS_CONTEXT_SWITCH_SCHEME равным 0. Хотя рекомендуют оставить 1. Не помню в какой ветке читал.

Если установить 1, то непонятно назначение следующего фрагмента. Нужен ли он?
#if scmRTOS_CONTEXT_SWITCH_SCHEME == 1
// Setup analog comparator as software interrupt source
#if PORT_TOGGLE_BY_PIN_WRITE
ACSR = (1 << ACBG); // Ref ON, interrupt on both edges
#else
ACSR = (1 << ACBG) | (1 << ACIS1); // Ref ON, falling edge
#endif
DRIVER(RAISE_PIN,OUT); // AIN1 - output
// analog comparator propagation and synchronization delay
_delay_us(2);
ACSR |= (1 << ACI);
ACSR |= (1 << ACIE); // ACIE ON, ACI OFF
#endif

а также этот код
DRIVER(TIMER_HOOK,OUT);
DRIVER(IDLE_HOOK,OUT);
//
DRIVER(ISR_ENTER_PIN,OUT);
DRIVER(ISR_EXIT_PIN,OUT);

У себя все это удалил, работает при scmRTOS_CONTEXT_SWITCH_SCHEME=0. Можно выполнение процесса впихнуть в 4.4 мс. Это нормальная работа системы? Раньше с такой ситуацией не приходилось иметь дело.
Сергей Борщ
Цитата(Neyron @ Jan 11 2008, 18:20) *
DRIVER(TIMER_HOOK,OUT);
DRIVER(IDLE_HOOK,OUT);
//
DRIVER(ISR_ENTER_PIN,OUT);
DRIVER(ISR_EXIT_PIN,OUT);

У себя все это удалил, работает при scmRTOS_CONTEXT_SWITCH_SCHEME=0. Можно выполнение процесса впихнуть в 4.4 мс. Это нормальная работа системы? Раньше с такой ситуацией не приходилось иметь дело.
Эти строчки для наблюдения осциллографом за поведением - когда переключаются контексты и когда проц спит. Естественно, в боевой системе это не нужно.
Цитата(Neyron @ Jan 11 2008, 18:20) *
Если установить 1, то непонятно назначение следующего фрагмента. Нужен ли он?
Там в случае scmRTOS_CONTEXT_SWITCH_SCHEME==1 в качестве прерывания перепланировки используется прерывание компаратора. Для генерации этого прерывания используется дерганье ногой, которая дергает вход компаратора. Этот кусок выбиает - какой из вариантов "возбуждения" ноги используется - если процессор позволяет инвертировать состояние ноги записью в PINx, то выбирается прерывание по любому изменению выхода компаратора и прерывание возбуждается инвертированием ноги. Если не позволяет - то приходится записью в PORTx формировать импульс и, соответственно, компаратор настраивать на один из фронтов.


У меня зреет идея использовать для переключения контекста прерывание SPM (как наиболее бесполезное), но задача под AVR пока в стадии охмурения заказчика, поэтому идея пока только обдумывается. Можете принять участие в реализации.
Аналогичный вариант с переключением от несбрасываемого прерывания у меня реализован в порте на STR71x, прогон на ките позволил сделать вывод, что идея работоспособна.

Цитата(Neyron @ Jan 11 2008, 18:20) *
Мега 128. Тик системного таймера ~4.4 мс. Если время выполнения процесса превышает это время, происходит сбой.
Про это рассказывайте подробнее - такого быть не должно. Для начала, что такое "время выполнения процесса"?
ReAl
Цитата(Neyron @ Jan 11 2008, 18:20) *
Мега 128. Тик системного таймера ~4.4 мс. Если время выполнения процесса превышает это время, происходит сбой.
Это действительно непонятно. В смысле непонятно, что означают эти слова.

Цитата
Установил scmRTOS_CONTEXT_SWITCH_SCHEME равным 0. Хотя рекомендуют оставить 1. Не помню в какой ветке читал.
При 0 переключение осуществляется немнооожечко быстрее, но больше пиковое использование стека. При 1 - наоборот. Тестовый проект 1-EventFlag проверялся в железе с осциллографом при всех комбинациях (включая TISRW/TISRW_SS).
Neyron
(Neyron @ Jan 11 2008, 18:20) *
Мега 128. Тик системного таймера ~4.4 мс. Если время выполнения процесса превышает это время, происходит сбой.

Использую TCCR0 = 0x06 при кварце 14,74560.
Т.е. таймер переполняется при 256(макс TCNT0)*256(делительTCCR0 )* 1/14.7456 МГц = 4.(4) мс

Теперь о времени выполнения процесса. main.cpp

uint8_t sec_tik;
uint8_t WaitFilter;
namespace OS {
template<> OS_PROCESS void TTechnolog::Exec()
{
DDRB |= 1 << PB6; - Нога по которой вычисляется время выполнения процесса
WaitFilter=2; - ожидание фильтрации
for(;;) {
PORTB &= ~(1 << PB6); - Старт процесса по осциллографу
if((!(OS::GetTick200ms())) && (!(OS::GetTick1s()))) sec_tik=0;
else sec_tik=0xff; - служебная переменная. если sec_tik=0, то пришла новая секунда. См. ниже.
if(!WaitFilter)
{
Work_drv();- собственно работа. Здесь выполняется алгоритм поиска циклом for.
}
else if(!sec_tik) WaitFilter--;

PORTD ^= (1<<PD7); - сброс собаки
PORTB |= 1<<PB6;- Стоп процесса по осциллографу
Sleep(9);//40 ms
}
}

} // namespace OS

В Work_drv() задаю поиск по индексу от 0 до 127.
На PB6 визуально наблюдаю время выполнения процесса. Без поиска оно составляет 25 мкс...
Потом включаю поиск... С увеличением индекса время выполнения процесса растет (см. PB6). При достижении величины в 4.4 мс (тик системного таймера) идет сбой. Зависание на ноге PD7, потом возобновление работы... и так циклически.

P.S. По исходниках понял, что SysTickCount в ОС не используется... Можно ли безопасно использовать следующие доработки.. В верси 1.10 все работает без проблем.
Для засекания секундных и 200м-секундных интервалов использую следующий код в OS_Kernel.h:
void OS::TKernel::SystemTimer()
....
#if scmRTOS_SYSTEM_TICKS_ENABLE == 1
SysTickCount++;
if(SysTickCount>8) //40ms множитель 9
{
SysTickCount = 0;
SysTick200ms++;
if(SysTick200ms>4)//200ms
{
SysTick200ms = 0;
SysTick1s++;
if(SysTick1s>4)//1s
{
SysTick1s = 0;
}
}
}
#endif
.....

#if scmRTOS_SYSTEM_TICKS_ENABLE == 1
volatile dword SysTickCount; - счетчик системных тиков
volatile dword SysTick200ms; - счетчик 200мс тиков (поездка регулятором)
volatile dword SysTick1s; - считчик 1с тиков (посекундная отработка по технологогии)
#endif

И соответственно, функции...
#if scmRTOS_SYSTEM_TICKS_ENABLE == 1
INLINE inline dword GetTickCount() { TCritSect cs; return Kernel.SysTickCount; }
INLINE inline dword GetTick200ms() { TCritSect cs; return Kernel.SysTick200ms; }
INLINE inline dword GetTick1s() { TCritSect cs; return Kernel.SysTick1s; }
#endif
Сергей Борщ
Цитата(Neyron @ Jan 12 2008, 10:07) *
А у вас снаружи, физически, замкнуты нога, вызывающая переключение контекста и вход компаратора? Возможно, у вас просто не происходит перепланировка.


P.S. просьба к модераторам выделить обсуждение в отдельную ветку - к новостям оно отношения не имеет.
ReAl
Цитата(Neyron @ Jan 12 2008, 10:07) *
P.S. По исходниках понял, что SysTickCount в ОС не используется... Можно ли безопасно использовать следующие доработки.. В верси 1.10 все работает без проблем.
void OS::TKernel::SystemTimer()
....
В принципе, можно. Но я бы рекомендовал не трогать ядро, а поместить нужный код в пользовательскую функцию SystemTimerUserHook(), которая вызывается из

Код
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
}


При этом можно сделать
#define scmRTOS_SYSTEM_TICKS_ENABLE 0
завести свои счётчики нужной разрядности и всё (в данном случае SysTickCount и SysTick200ms точно не нужны dword).

Если очень нужно уменьшить время работы - можно сделать SystemTimerUserHook() как inline-функцию в файле проекта scmRTOS_TARGET_CFG.h

Код
namespace OS
{

inline void SystemTimerUserHook()
{
    ..
}

}

Только сделать это обязательно внутри #ifndef __ASSEMBLER__
Не очень красиво выходит, так как приходится определять функцию раньше, чем она упоминается в OS_Kernel.h, но работает.

Остальное позже посмотрю, это надо упрощённый натурный эксперимент поставить.
Neyron
Цитата(Сергей Борщ @ Jan 12 2008, 14:20) *
А у вас снаружи, физически, замкнуты нога, вызывающая переключение контекста и вход компаратора? Возможно, у вас просто не происходит перепланировка.
P.S. просьба к модераторам выделить обсуждение в отдельную ветку - к новостям оно отношения не имеет.


Т.е. Вы предлагаете все-таки установи scmRTOS_CONTEXT_SWITCH_SCHEME равным 1 и вернуть код
инициализации прерывания от компаратора? У меня был scmRTOS_CONTEXT_SWITCH_SCHEME 0.

Хорошо, ещё поэксперементирую.
ReAl
Ой, это даже не заметил - не надо снаружи никаких ног соединять, по задумке одна из ног компаратора делается выходом (вход компаратора всё равно подключен) и она и дёргается, другая внутри контроллера подключается к источнику опорного.
Neyron
Похоже я не прав... Это у меня где-то процесс улетает при превышении определенного времени.
Протестировал систему на 1-EventFlag, работает и в режиме scmRTOS_CONTEXT_SWITCH_SCHEME = 0 и =1.

Сначала не обратил внимания также на RAISE_PIN. Для меги 128 нужно установить E,3,H.
ReAl
Цитата(Neyron @ Jan 12 2008, 15:48) *
Сначала не обратил внимания также на RAISE_PIN. Для меги 128 нужно установить E,3,H.

Ну, комментариями пока тот текст не перегружен :-)

Я в TProc2::Exec() в примере затолкал задержку тупо через _delay_ms(). При тике системного таймера около 2мс ставил задержки в 1.5мс, 2.5мс, 5.5мс - по осциллографу всё отрабатывает как положено для обеих методов переключения процессов, всё отлично. Даже если нагло эту задержку в критическую секцию взять - тогда, естественно, замирает и более приоритетный процесс, и системный таймер, но всё ведёт себя правильно.
Сергей Борщ
Цитата(ReAl @ Jan 12 2008, 13:00) *
Ой, это даже не заметил - не надо снаружи никаких ног соединять,
Значит я в свое время неправильно понял объяснения dxp. Извиняюсь, что невольно пытался ввести в заблуждение.
solosh
Цитата(Neyron @ Jan 12 2008, 12:07) *
PORTD ^= (1<<PD7); - сброс собаки


А период собаки какой ?
Neyron
Цитата(solosh @ Jan 13 2008, 02:16) *
А период собаки какой ?


ADM695 1.6 сек, если я правильно понял
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.