Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: scmRTOS (версия 310) IAR AVR 5511 (mega128a)
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > scmRTOS
Acvarif
Попытался скомпилировать scmRTOS (версия 310) IAR AVR 5511 (mega128a) - (Error[Pe020]: identifier "SPMCR" is undefined ...\scmRTOS_TARGET_CFG.h 119). Похоже на несовместимость версий ОС и IAR? Может кто сталкивался. Как можно подправить?

С какой версией IAR AVR scmRTOS (версия 310) работает без исправлений?
Acvarif
Цитата(Acvarif @ Jun 30 2011, 11:29) *
Попытался скомпилировать scmRTOS (версия 310) IAR AVR 5511 (mega128a) - (Error[Pe020]: identifier "SPMCR" is undefined ...\scmRTOS_TARGET_CFG.h 119). Похоже на несовместимость версий ОС и IAR? Может кто сталкивался. Как можно подправить?

С какой версией IAR AVR scmRTOS (версия 310) работает без исправлений?


Вроде понял.
Если компилировать тестовый проект (во вложении) под Atmega32 все работает. Под 128a появляется вышеописанная ошибка потому, как в 128а име6ется регистр SPMCSR (Store Program Memory Control and Status Register), а в scmRTOS забит только SPMCR регистр (подходит для меги32).

Вот только где он забит и как это дело подправить пока не найду.

Помогите please, кому не лень

Цитата(Acvarif @ Jun 30 2011, 14:22) *
Вроде понял.
Если компилировать тестовый проект (во вложении) под Atmega32 все работает. Под 128a появляется вышеописанная ошибка потому, как в 128а име6ется регистр SPMCSR (Store Program Memory Control and Status Register), а в scmRTOS забит только SPMCR регистр (подходит для меги32).

Вот только где он забит и как это дело подправить пока не найду.

Помогите please, кому не лень


Нашел. Достаточно в файле scmRTOS_TARGET_CFG.h в строке #define SPM_CONTROL_REG SPMCR - SPMCR заменить на SPMCSR

Вообще у IAR какой-то кавардак с этими регистрами, в частности с их названиями. Неужели нельзя одни и те же по функциональности регистры называть одинаково? Хотя с другой стороны они поддерживаются того, что прописано в даташитах на девайсы.
ReAl
Цитата(Acvarif @ Jun 30 2011, 14:42) *
Нашел. Достаточно в файле scmRTOS_TARGET_CFG.h в строке #define SPM_CONTROL_REG SPMCR - SPMCR заменить на SPMCSR

Вообще у IAR какой-то кавардак с этими регистрами, в частности с их названиями. Неужели нельзя одни и те же по функциональности регистры называть одинаково? Хотя с другой стороны они поддерживаются того, что прописано в даташитах на девайсы.
Вот именно. Кавардак у Атмела.

У avr-gcc имена регистров -- простые #define на адреса, поэотму нет проблем с
Код
#ifdef SPMCR
#define SPM_CONTROL_REG SPMCR
#elif defined(SPMCSR)
#define SPM_CONTROL_REG SPMCSR
#else
#error SPM_CONTROL_REG is not defined
#endif
У IAR так сделать не выйдет, нужно поимённо проверять модели контроллеров. На всех не напасёшся, так что примеры сделаны под какие-то конкретные модели, при смене нужно менять.
В AVR-ских примерах под 4.0 я постарался напихать комментариев вида "пример рассчитан на XXX, для других может понадобиться изменение имён регистров", в документации коротко упомняуто где и что сидит по файлам примеров.
Acvarif
Цитата(ReAl @ Jun 30 2011, 15:47) *
В AVR-ских примерах под 4.0 я постарался напихать комментариев вида "пример рассчитан на XXX, для других может понадобиться изменение имён регистров", в документации коротко упомняуто где и что сидит по файлам примеров.


Да, верно. У Atmel.
А примеры под 4.0 где можно взять?
Acvarif
И все же скажите пожалуйста под какую версию IAR AVR выполнены примеры scmRTOS v3.10? В Iar avr 5511 (mega32) (1_EventFlag) все компилится нормально, но в симуляторе работает с предупреждениями и неверно - зацикливается в ядре здесь

Код
        RaiseContextSwitch();
        do
        {
            EnableContextSwitch();
            DUMMY_INSTR();
            DisableContextSwitch();
        }
        while(!IsContextSwitchDone());


и в OS_Target.h здесь

Код
INLINE inline void EnableInterrupts() { __enable_interrupt();  }
INLINE inline void DisableInterrupts() { __disable_interrupt(); }

#pragma segment="CSTACK"
#pragma segment="RSTACK"

#define  ABS_WORD(x)  (*((volatile word*)x))

INLINE inline TStackItem* GetDataSP()   { return reinterpret_cast<TStackItem*>(ABS_WORD(28)); }
INLINE inline TStackItem* GetReturnSP() { return reinterpret_cast<TStackItem*>(SP); }

INLINE inline void SetISRStackPointers()
{
    ABS_WORD(28) = reinterpret_cast<word>(__segment_end("CSTACK"));
    SP = reinterpret_cast<word>(__segment_end("RSTACK")) - 1;
}

INLINE inline void SetDataSP(TStackItem* sp)   { ABS_WORD(28) = reinterpret_cast<word>(sp); }
INLINE inline void SetReturnSP(TStackItem* sp) { SP = reinterpret_cast<word>(sp); }

namespace OS
{
    INLINE inline void EnableContextSwitch()  { EnableInterrupts();  }
    INLINE inline void DisableContextSwitch() { DisableInterrupts(); }
}


(Thu Jun 30 19:04:28 2011: The stack pointer for stack 'RStack' (currently DATA:0x0001A5) is outside the stack range (DATA:0x000080 to
DATA:0x0000A0)
)

При переходе на mega128a в симуляторе виснуть начинает гораздо раньше (все время сидит на OS::Run();
И все же попробовал запустил в железе, надеясь увидеть дергание PINB4 по прериванию таймера 1 . В железе (под mega128a) не работает совсем. Очевидно так же как и в симуляторе висит.

Подскажите пожалуйста как все же запустить OS в симуляторе (в железе тоже должна заработать).
Очень уж хочется опробовать ее возможности и сравнить с обычной программой на C.
Привлекают (по документации) ее шустрость и небольшие требования к ресурсам железа.
Какраз для этого и железо имеется под рукой и реальная задача (асинхронный обмен и обработка данных по двум USART)
AHTOXA
Цитата(Acvarif @ Jun 30 2011, 18:54) *
А примеры под 4.0 где можно взять?

Примерно здесь.
Acvarif
Цитата(AHTOXA @ Jun 30 2011, 20:04) *
Примерно здесь.


Спасибо. Попробую разобраться...

Совсем запутался в файлах, где что куда.
Может есть где одним архивом Samples для AVR IAR?
Acvarif
Цитата(Acvarif @ Jun 30 2011, 20:48) *
Спасибо. Попробую разобраться...

Совсем запутался в файлах, где что куда.
Может есть где одним архивом Samples для AVR IAR?


Ничего не получается. Полная путаница.
Если у кого есть Samples для AVR IAR в сборе выложите пожалуйста.
Скажите пожалуйста под какую версию IAR AVR выполнены примеры в scmRTOS v 3.10?

Спасибо.
ReAl
Поставьте себе SVN
Сделайте
Код
svn co http://scmrtos.svn.sourceforge.net/svnroot/scmrtos/branches/pre-v400/Samples/AVR/IAR scmRTOS-samples
для получения кода примеров AVR/IAR.
Потом перейдите в образовавшийся каталог scmRTOS-samples (ну или дайте в строке выше другое понравившееся имя) и запустите батник switch.bat для подкачки кода ОС.

Потом достаточно будет запускать
Код
svn up
для получения апдейтов.
AHTOXA
Цитата(Acvarif @ Jun 30 2011, 23:48) *
Может есть где одним архивом Samples для AVR IAR?

Там же внизу есть ссылка "Download GNU tarball". Это как раз и есть одним архивом sm.gif
А вообще конечно лучше поставить клиент svn, всяко пригодится.
Acvarif
Цитата(ReAl @ Jun 30 2011, 22:29) *
Поставьте себе SVN
Сделайте
Код
svn co http://scmrtos.svn.sourceforge.net/svnroot/scmrtos/branches/pre-v400/Samples/AVR/IAR scmRTOS-samples
для получения кода примеров AVR/IAR.
Потом перейдите в образовавшийся каталог scmRTOS-samples (ну или дайте в строке выше другое понравившееся имя) и запустите батник switch.bat для подкачки кода ОС.

Потом достаточно будет запускать
Код
svn up
для получения апдейтов.



Виноват, но, что такое SVN я понятия не имею. Разбираться с этим... разберусь конечно. Наверняка еще понадобится.
Если у кого есть возможность буду признателен за архив Samples/AVR/IAR
И всетаки под какой версией AVR/IAR корректно работают Samples/AVR/IAR scmRTOS версии 3.10?


Цитата(AHTOXA @ Jun 30 2011, 22:39) *
Там же внизу есть ссылка "Download GNU tarball". Это как раз и есть одним архивом sm.gif
А вообще конечно лучше поставить клиент svn, всяко пригодится.


Прошу прощения. Не врубился. GNU tarball я скачал. Там все пустое. Как этим всем пользоваться?
AHTOXA
Цитата(Acvarif @ Jul 1 2011, 01:49) *
Прошу прощения. Не врубился. GNU tarball я скачал. Там все пустое. Как этим всем пользоваться?

Хм. Проверил вот эту ссылку - всё скачалось, все примеры и сама ось.
Acvarif
Цитата(AHTOXA @ Jun 30 2011, 22:56) *
Хм. Проверил вот эту ссылку - всё скачалось, все примеры и сама ось.


Спасибо. Все скачалось нормально (не по той ссылке ходил). Попробую разобраться...

Цитата(Acvarif @ Jun 30 2011, 23:05) *
Спасибо. Все скачалось нормально (не по той ссылке ходил). Попробую разобраться...


Запустил в IAR AVR 5511 все прошло нормально. При переходе на симулятор та же картина:

Предупреждения типа

Thu Jun 30 23:19:57 2011: The stack pointer for stack 'CStack' (currently DATA:0x00022A) is outside the stack range (DATA:0x000100 to
DATA:0x000120)

при заходе в main на Timer1_Ovf.wait();
и повисание на тех же местах (код выше). Думаю в железе будет все то же. Или я не прав? Может я чего не понимаю.

Неужели в симуляторе так и не плучится увидеть работу хотя бы двух процессов?

Цель простая - увидеть в дебагере простое дергание ногами (типа PORTB ^= (1<<4)) хотя бы в одном процессе (например по прерываниям таймера 1)

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

Что я делаю не так?
shreck
Цитата(Acvarif @ Jul 1 2011, 03:36) *
Thu Jun 30 23:19:57 2011: The stack pointer for stack 'CStack' (currently DATA:0x00022A) is outside the stack range (DATA:0x000100 to
DATA:0x000120)

Это нормально, ведь ОСь использует свои стеки для задач. Не обращайте внимание.

Цитата(Acvarif @ Jul 1 2011, 03:36) *
Неужели в симуляторе так и не плучится увидеть работу хотя бы двух процессов?

В симуляторе IAR надо ручками запустить необходимые прерывания. И это очень неудобно. А без прерываний Ось как будет работать.
Сергей Борщ
QUOTE (Acvarif @ Jun 30 2011, 19:32) *
но в симуляторе работает с предупреждениями и неверно - зацикливается в ядре здесь
Симулятор ИАРа от рождения никогда не симулировал периферию. Никогда. И не собирается. А в переключателе контекста используется свойство периферии вызывать прерывание. Хотите в симуляторе - используйте scmRTOS_CONTEXT_SWITCH_SCHEME 0, но это будет уже другая программа, с другими требованиями к стекам и т.д. Не мучайте себя - отлаживайте сразу в железе.
Acvarif
Цитата(Сергей Борщ @ Jul 1 2011, 09:12) *
Симулятор ИАРа от рождения никогда не симулировал периферию. Никогда. И не собирается. А в переключателе контекста используется свойство периферии вызывать прерывание. Хотите в симуляторе - используйте scmRTOS_CONTEXT_SWITCH_SCHEME 0, но это будет уже другая программа, с другими требованиями к стекам и т.д. Не мучайте себя - отлаживайте сразу в железе.


Понял. Спасибо. Попробую в железе.
Интересно а с AVR JTAG ice ОС будет крутиться? Или все будет как в симуляторе?
Сергей Борщ
QUOTE (Acvarif @ Jul 1 2011, 09:56) *
Интересно а с AVR JTAG ice ОС будет крутиться? Или все будет как в симуляторе?
А что ей объективно может помешать?
Acvarif
Цитата(Acvarif @ Jul 1 2011, 09:56) *
Понял. Спасибо. Попробую в железе.
Интересно а с AVR JTAG ice ОС будет крутиться? Или все будет как в симуляторе?


В железе (mega128a) пока ничего не получилось.

Пробую пока версию оси 310.

Код
//---------------------------------------------------------------------------
#include <scmRTOS.h>
//---------------------------------------------------------------------------
// Типы процессов

typedef OS::process<OS::pr0, 120, 32> TProc1;
typedef OS::process<OS::pr1, 160, 32> TProc2;

//---------------------------------------------------------------------------
// Создание объектов процессов (выделение под них памяти)

TProc1 Proc1;
TProc2 Proc2;
//---------------------------------------------------------------------------
dword T;                         // global variable for OS::GetTickCount testing
                                 //
OS::TEventFlag ef;               //
OS::TEventFlag Timer1_Ovf;       //

dword Count;
dword Value;

//---------------------------------------------------------------------------
int main()
{
    // Порт C0 на вывод
    DDRC |= (1 << 0);
    // Порт C1 на вывод
    DDRC |= (1 << 1);

    // Старт таймера 1 с прескаллером 1
    TCCR1B |= (1 << CS10);    
    // Разрешить прерывания таймера 1
    TIMSK  |= (1 << OCIE1A);  

    // Старт системного таймера (таймер 0)
    TCCR0 = 0x03;            
    // Разрешить прерывания таймера 0
    TIMSK |=  (1 << TOIE0);  
    
    // Пуск ОС
    OS::Run();
}
//---------------------------------------------------------------------------
template<> void TProc1::Exec()
{
    // бесконечный цыкл процесса 1
    for(;;)
    {
        // ожидание переполнения таймера 1
        Timer1_Ovf.Wait();
        PORTC ^= (1 << 0);
    }
}
//---------------------------------------------------------------------------
template<> void TProc2::Exec()
{
    // бесконечный цыкл процесса 2
    for(;;)
    {
       // ef.Wait();
        PORTC ^= (1 << 1);
        T += OS::GetTickCount();
        Sleep(10);

    }
}
//---------------------------------------------------------------------------
void OS::SystemTimerUserHook() { }
//---------------------------------------------------------------------------
void OS::IdleProcessUserHook() { }
//---------------------------------------------------------------------------
#pragma vector=TIMER1_COMPA_vect
OS_INTERRUPT void Timer1_period_ISR()
{
    OS::TISRW_SS ISRW;

    ENABLE_NESTED_INTERRUPTS();
    PORTC ^= (1 << 0);

    Timer1_Ovf.SignalISR();
}
//---------------------------------------------------------------------------


После загрузки в железо я по идее должен увидеть по крайней мере дрыгание PC0. Или нет?

Пока не допонимаю этот участок

Код
//---------------------------------------------------------------------------
void OS::SystemTimerUserHook() { }
//---------------------------------------------------------------------------
void OS::IdleProcessUserHook() { }
//---------------------------------------------------------------------------
#pragma vector=TIMER1_COMPA_vect
OS_INTERRUPT void Timer1_period_ISR()
{
    OS::TISRW_SS ISRW;

    ENABLE_NESTED_INTERRUPTS();
    PORTC ^= (1 << 0);

    Timer1_Ovf.SignalISR();
}


Если кому не сложно, подпишите пожалуйста комменты к этому участку

Щас попробую ос версии 400...

ОС 400 на mega128а не хочет компилиться. Известная ошибка Error[Pe020]: identifier "SPMCR" is undefined c:\Temp\ScmRtos\pre-v400\Samples\AVR\IAR\1-EventFlag\Src\scmRTOS_TARGET_CFG.h 104

закомментировал

Код
#  if defined(SPM_READY_vect)
#    define CONTEXT_SWITCH_ISR_VECTOR  SPM_READY_vect
#    define SPM_CONTROL_REG SPMCSR
#  elif defined(SPM_RDY_vect)
#    define CONTEXT_SWITCH_ISR_VECTOR  SPM_RDY_vect
#    define SPM_CONTROL_REG SPMCR
#  else
#    error "SPM ready interrupt vector not defined"


записал просто
Код
#    define SPM_CONTROL_REG SPMCSR


Дальше больше

Error[Pe020]: identifier "TIMSK0" is undefined c:\Temp\ScmRtos\pre-v400\Samples\AVR\IAR\scmRTOS\Common\OS_Kernel.h 447
Error[Pe020]: identifier "TIMSK0" is undefined c:\Temp\ScmRtos\pre-v400\Samples\AVR\IAR\scmRTOS\Common\OS_Kernel.h 448
Error[Pe020]: identifier "TIMSK1" is undefined c:\Temp\ScmRtos\pre-v400\Samples\AVR\IAR\1-EventFlag\Src\main.cpp 130
Error[Pe020]: identifier "TCCR0B" is undefined c:\Temp\ScmRtos\pre-v400\Samples\AVR\IAR\1-EventFlag\Src\main.cpp 133
Error[Pe020]: identifier "TIMSK0" is undefined c:\Temp\ScmRtos\pre-v400\Samples\AVR\IAR\1-EventFlag\Src\main.cpp 134

Щас попробую побороть.

Подправил main

Код
int main()
{
    TCCR1B = (1 << WGM12) | (1 << CS10);    // CTC mode, clk/1
    OCR1A  = 40000U;
    TIMSK = (1 << OCIE1A); // Timer1 OC interrupt enable

    // Start System Timer
    TCCR0  = (1 << CS01) | (1 << CS00); // clk/64
    TIMSK |= (1 << TOIE0);

    DRIVER(TIMER1_ISR,OUT);
    DRIVER(TIMER_HOOK,OUT);
    DRIVER(IDLE_HOOK,OUT);
    //
    OS::run();
}


Это убрать не удается
Error[Pe020]: identifier "TIMSK0" is undefined c:\Temp\ScmRtos\pre-v400\Samples\AVR\IAR\scmRTOS\Common\OS_Kernel.h 447
Error[50]: Undefined symbol:'CONTEXT_SWITCH_ISR_VECTOR' c:\Temp\ScmRtos\pre-v400\Samples\AVR\IAR\scmRTOS\AVR\OS_Target_asm.s90 281

Помогите, кому не сложно...
Acvarif
Пока ничего не получается. Перешел опять на версию оси 310.

Казалось бы, что может быть проще двух процессов...

В main устанавливается порт PC0 на вывод и запускается системный таймер

Код
    DDRC |= (1 << 0);

    TCNT0 = 0xf0;
    TCCR0 = 0x05;                  
    TIMSK |=  (1 << TOIE0);

теперь после запуска оси OS::Run();
прописываем процессы и перезагрузку системного таймера

Код
template<> void TProc1::Exec()
{
    for(;;)
    {
        PORTC ^= (1 << 0);
        Sleep(500);
    }
}
//---------------------------------------------------------------------------
template<> void TProc2::Exec()
{
    for(;;)
    {
        Sleep(10);
    }
}
//---------------------------------------------------------------------------
void OS::SystemTimerUserHook()
{
    TCNT0 = 0xf0;
}

в первом процессе я должен увидеть дергание ноги PC0.

Но... ничего подобного не видать.

Архив с проектом и настройками в скрепке...

Подсобите пожалуйста запустить ОС в железе.
Неуверен в настройках (файл scmRTOS_config.h)
Не могут ли фьюсы mega128a к этому иметь какое-то отношение? Хотя врядли потому, как обычный процедурный код на нем работает без проблем.
ReAl
Только сегодня добрался до этого вопроса.
По дороге противно зашипел и погасил экран мой любимый Hameg HM1507-3 :-(

Всего-то нужно было добавить выделенную строку в файл OS_Target_asm.s90
Цитата
#if defined(__ATmega103__) || \
defined(__ATmega128__) || \
defined(__ATmega128A__) || \
defined(__ATmega1280__) || \
defined(__ATmega1281__) || \
defined(__ATmega2560__) || \
defined(__ATmega2561__) || \
defined(__AT90CAN128__) || \
defined(__AT90USB1286__) || \
defined(__AT90USB1287__) || \
defined(__AT90USB1287__)

#define HAS_RAMPZ 1
#endif
В pre-400 это и atmega1284 были добавлены, а сюда уже никто не лазил.
После этого пример из Вашего ScmRtos310.rar работает с обеими видами переключателя контекстов.

«повбивав би» c этими отдельными ключами компилятора для А-версий, которые ничем не отличаются от «просто» и «V-версий» :-)
Заодно тюкнул бы легонько по темечку IAR, который для С/С++ даёт макрос __HAS_RAMPZ__, а для ассемблера -- нет. Потому и приходиться городить процитированное выше.
Если собирать как для ATmega128 либо как для ATmega64(тут уже можно и A) -- работало и так.
А для ATmega128A в результате рассинхронизации мнения о размере стекового кадра у констурктора процесса в OS_Target_cpp.cpp и у переключателя контекстов в OS_Target_asm.s90 (в функцию которого входит и начальное «переключение» по OS_Start) «возврат» из OS_Start шёл куда попало.


p.s. Немного подчистил примеры и порт 3.10 и обновил в репозитории.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.