Jump to content

    
URAN

Начало работы с scmRTOS

Recommended Posts

Хочется научиться работать с этой штукой - scmRTOS & AVR(Atmega8) & IAR 4.30A ! Почитал темы которые есть на форуме, почитал User's Manual v2. Возникло некторое количество вопросов:

1. Какая последовательность создания проекта: мои предположения - создаем в IAR новый проект, тискаем добавить файлы в проект и добавляем OS_Kernel.cpp , OS_Services.cpp , OS_Target_asm.s90 , OS_Target_cpp.cpp , usrlib.cpp. В maim.cpp пишем

#include <scmRTOS.h>
 

. Затем каким то образом нужно создать самому как я понял scmRTOS_TARGET_CFG.h и scmRTOS_CONFIG.h, но как не ясно или их нужно тупо скопировать из примера автора и если что нада то менять.

2. Почему в примерах автор добавляет

void OS::SystemTimerUserHook() { }
void OS::IdleProcessUserHook() { }
 

 

Так нужно делать всегда ?

3. Дальше >> понятно что для AVR передачу управления можно осуществить сгенерировав прерывание например от компоратора как описано в документации, но непонятно как нужно оформить функцию обработки этого прерывания, и чем она будет отличаться от функции обработки других прерываний.

 

О взаимодействии между потоками пока вроде понятно.

 

Может кто нить может описать последовательность начальных действий и привести пример кода или хотя бы шапку , где есть процессы и обработчики прерываний и передача управления.

 

Мог написать что - нибудь глупое, потому как в круг моих понятий scmRTOS пока входит очень туманно или вообще не входит.

Share this post


Link to post
Share on other sites
. Затем каким то образом нужно создать самому как я понял scmRTOS_TARGET_CFG.h и scmRTOS_CONFIG.h, но как не ясно или их нужно тупо скопировать из примера автора и если что нада то менять.

Можно и так, и так. Как больше нравится. Чем плохо взять имеющиеся и откорретировать под свои потребности?

 

2. Почему в примерах автор добавляет

void OS::SystemTimerUserHook() { }
void OS::IdleProcessUserHook() { }

В примерах для иллюстрации. Если они нужны, оставьте и используйте, не нужны, уберите. Все в ваших руках.

 

Так нужно делать всегда ?

3. Дальше >> понятно что для AVR передачу управления можно осуществить сгенерировав прерывание например от компоратора как описано в документации, но непонятно как нужно оформить функцию обработки этого прерывания, и чем она будет отличаться от функции обработки других прерываний.

 

О взаимодействии между потоками пока вроде понятно.

 

Может кто нить может описать последовательность начальных действий и привести пример кода или хотя бы шапку , где есть процессы и обработчики прерываний и передача управления.

Есть полноценный рабочий пример. Под IAR. Возьмите его за основу.

  • Используйте в качестве "рыбы" для своего проекта.
  • Используйте его в качестве референса, когда возникает вопрос, как сделать ту или иную базовую вещь. Пока не придет собственное устойчивое понимание (тогда будете сразу делать по-своему).
  • Используйте его для исследования того, что реально происходит в процессоре, гоняя пример в отладчике.

Share this post


Link to post
Share on other sites

Вот взял из примера , это обработчик прерывания, кторый как я понял работает для передачи управления, но каким образо не понятно :

#pragma vector=TIMER1_COMPA_vect
OS_INTERRUPT void Timer1_period_ISR()
{
    OS::TISRW_SS ISRW;

    ENABLE_NESTED_INTERRUPTS();

    //--------------------------------------------------
    //
    //            Message test
    //
    //     Send data as message
    //
    TMamont m;           // create message content

    m.src  = TMamont::ISR_SRC;
    m.data = 10;
    MamontMsg = m;       // put the content to the OS::message object
    PORTB |= (1 << 4);
    MamontMsg.sendISR();    // send the message
}

 

В main разрешены 3 прерывания , а обработчик описан только один, че за .....

int main()
{
    DDRB |= (1 << 4); 

    TCCR1B |= (1 << WGM12);   // CTC mode
    OCR1A   = 10005;          // 
    TCCR1B |= (1 << CS10);    // Timer1 run with prescaling 1
    TIMSK  |= (1 << OCIE1A);  // Timer1 OC interrupt enable--------------1 ое

    TCCR0 = 0x03;             // Start System Timer
    TIMSK |=  (1 << TOIE0);   //-----------------------------------------------2 ое

    ACSR |= (1 << ACBG) | (1 << ACIE); /* Ref ON, IE ON */  -----------3 е
    DDRB |= (1 << 3);                  /* AIN1*/


    OS::Run();
}

Share this post


Link to post
Share on other sites

С предыдущим вроде разобрался, все оказалось проще чем я думал, вопросы о следующем:

 

Что зачит вот это

ENABLE_NESTED_INTERRUPTS();

написанное в обработчике прерывания

 

Почему в main нету глобального разрешения прерывания, как без него может произойти прерывание от таймера да и вообще любое, или где то в ядре прописывается (я понял что так и есть ) ?,

 

Зачем нужны прерывания от системного таймера ?

 

Все относится к примерам из папки самой операционки.

 

И еще как в IAR можно изменить имя проекта ?

Edited by URANst

Share this post


Link to post
Share on other sites

ENABLE_NESTED_INTERRUPTS(); - разрешить вложенные прерывания.

Прерывания разрешаются при выполнении OS::Run(); которая, как изволите видеть, вызывается именно из main.

Прерывания от системного таймера нужны для выполнения функции Sleep() с параметром и для осуществления ожиданий сигналов, семафоров и прочих сервисов с задержкой.

Имя проекта можно заменить в проводнике Windows, а потом открыть новый проект в IAR.

Share this post


Link to post
Share on other sites

Так получается что 1 прерывание сис таймера - это единица задержки для сервисов ?

Т.е. если кварц 8 МГц, то единица задержки для сервисов == 1/(8 MГц/64)*256 (установлен делитель 64 для TIMER0), тогда что возвращает GetTickCount == количество прерываний сис таймера с момента начала работы ОС ?

 

Зачем может понадобиться прерывать апаратное прерывание контроллера, разве это хорошо ?

Share this post


Link to post
Share on other sites
Так получается что 1 прерывание сис таймера - это единица задержки для сервисов ?

Т.е. если кварц 8 МГц, то единица задержки для сервисов == 1/(8 MГц/64)*256 (установлен делитель 64 для TIMER0), тогда что возвращает GetTickCount == количество прерываний сис таймера с момента начала работы ОС ?

Да и да.

Ответы на это есть в документации :)

Share this post


Link to post
Share on other sites

Тоже решил попробовать эту ОС. Долго не мог решится из-за отсутствия опыта работы в С++. Хочу "прикрутить" эту ОС к своему проекту на Си. Кстати, как это правильней сделать : добавить мои исходники на Си к smcRTOS или можно еще как-то? Взял тестовый пример. Удачно скомпилился под Megs32. А под Megs324P выдает кучу ошибок (порядка 270). В чем засада, не пойму. Ведь Мега324 должна быть полностью совместима с Мегой32 ?

 

PS. Может быть проблема в этом:

I/O Mapping and SRAM

The I/O memory space contains 64 addresses for CPU peripheral control registers.

The ATmega164P/324P/644P I/O space and I/O range are changed and extended

compared to ATmega16/32. The extended I/O space goes from 0x60 to 0xFF in data

memory space where ST/STS/STD and LD/LDS/LDD instructions must be used.

The memory map is slightly different between the ATmega16/32 and the

ATmega164P/324P/644P due to extended I/O space. The ATmega164P/324P/644P

internal data SRAM addressing starts at 0x100 as opposed to 0x60 in ATmega16/32.

Это из документа

AVR505: Migration between ATmega16/32 and ATmega164P/324P/644P

 

PS2///

Вот так всегда. Ломаешь голову второй день... А как-только напишешь в форум, так сразу нашел в чем проблема. У Меги324 в файле iom324p.h есть определения:

/* SREG */

#define I 7

#define T 6

#define H 5

#define S 4

#define V 3

#define N 2

#define Z 1

#define C 0

Выдает первые ошибки на эти строки:

Error[Pe040]: expected an identifier 

        template<typename T, word size, class S> friend class channel;
        template<typename T>                     friend class message;

Т.е. я так понял имеется переопределение идентификаторов T и S.

Главное, что раньше я сталкивался с такой проблемой, когда присваивал переменным одну букву... И все-таки, как бы эту проблему "красиво" решить?

 

PS3. Я могу ошибиться, но разве OS_Kernel не имеет собственного namespace дабы избегать подобные проблемы? :unsure:

Share this post


Link to post
Share on other sites
Выдает первые ошибки на эти строки:

Error[Pe040]: expected an identifier 

        template<typename T, word size, class S> friend class channel;
        template<typename T>                     friend class message;

Т.е. я так понял имеется переопределение идентификаторов T и S.

Главное, что раньше я сталкивался с такой проблемой, когда присваивал переменным одну букву... И все-таки, как бы эту проблему "красиво" решить?

 

PS3. Я могу ошибиться, но разве OS_Kernel не имеет собственного namespace дабы избегать подобные проблемы? :unsure:

Тут дело не в пространствах имен, а в том, что препроцессор работает до компилятора и делает просто тупую текстовую подстановку, поэтому к моменту работы компилятора (анализа текста, разрешения имен и прочего) вместо T уже все подставлено. Яркий пример кривизны препроцессора и хорошая иллюстрация, почему его желательно по максимуму избегать.

 

Ну, а в данном конкретном случае можно только "порадоваться" за разработчиков IAR, слепивших такую пакостную "бомбочку". Это ж надо догадаться задефайнить такие короткие имена! Как-то я на MSP430 тоже плотно присел, пока выяснял, что локальное имя N работает не так, как задумано - тоже иаровский дефайн был. Только там хитрее получилось - не так явно вылезало, ошибка была совсем не про конфликт имен. Препроцессор мастдай.

Share this post


Link to post
Share on other sites

Так что же мне делать в этом конкретном случае кроме как закоментировать проблемные дефайны в iom324p.h ? Как бы потом это не вылезло боком...

Может не в тему(вопроса) будет сказано. Нашел еще одну интересную ОС - eXtreme Minimal Kernel XMK

Почему-то на форуме о ней даже не упоминалось. Разработчик утверждает, что нет других мультизадачных preemtive free RTOS, которая будет работать в такой минимальной конфигурации (340 bytes of ROM and 18 bytes of RAM).

Share this post


Link to post
Share on other sites
Может не в тему(вопроса) будет сказано. Нашел еще одну интересную ОС - eXtreme Minimal Kernel XMK

Судя по последним обновлениям (октябрь 2004) автор утратил к ней интерес.

А вот что касается потребностей памяти, то по-моему в этих прогнозах кое-что умалчивается, а именно, расход ОЗУ на стеки процессов.

Share this post


Link to post
Share on other sites

При включении моих исходников проекта на Си в проект smcRTOS (пример 1-EventFlag)возникла проблема.

Error[e18]: Range error,  
PC offset out of range. Valid range is -4096 (-0x1000) to 4094 (0x0FFE). 
File: D:\...\scmRTOS\AVR\OS_Target_asm.s90, Line: 234  
Source:      xjmp ContextSwitcher_ISR 
  Where $ = #no label found# + 0x5C  [0x5C] 
            in module "scmRTOS_Asm" (D:\...\1-EventFlag\Release\Obj\OS_Target_asm.r90), 
            offset 0x5C in segment part 1, segment INTVEC 
  What: #no label found# - ($ + 2) [0x1388] 
  Allowed range: 0xFFFFF000 - 0xFFF 
  Operand: #no label found# [0x13e6] 
           in module scmRTOS_Asm (D:\...\1-EventFlag\Release\Obj\OS_Target_asm.r90), 
           Offset 0x0 in segment part 2, segment CODE

Мой проект пока состоит из последовательного вызовов функций инициализации различной переферии. Ошибка возникает при подключении lcd_Init(); Отдельно мой проект отлажен под Мега324P. Занимал около 20кБ ROM и около 500 байт RAM. Пробовал изменить на Мега 644P и изменить размеры CSTACK, RSTACK. Не помогло. Как решить эту проблему?

Share this post


Link to post
Share on other sites
Судя по последним обновлениям (октябрь 2004) автор утратил к ней интерес.

В overview XMK, которое можно найти в исходниках указана сегодняшняя дата (March 4, 2008). Выглядит подозрительно ;)

Share this post


Link to post
Share on other sites
Мой проект пока состоит из последовательного вызовов функций инициализации различной переферии.
Каким-то образом обработчик прерывания переключения контекста оказывается в месте, куда не "дотягивается" xjmp из области векторов. Судя по ограничению +/- 4К вместо макроса xjmp подставляется RJMP, хотя нужен JMP. Глянул в исходники:
#if (A90_PROC_OPTION == 0) || (A90_PROC_OPTION == 1)
#define xcall   rcall
#define xjmp    rjmp
#else
#define xcall   call
#define xjmp    jmp
#endif

Где определяется A90_PROC_OPTION я не нашел - ни в исходниках, ни в описании ассемблера. Неопределенный символ считается равным нулю. Можно предположить, что перед этим должна быть (утерянная) строка

#define A90_PROC_OPTION   ((__TID__ >> 4) & 0x0F)

dxp завтра разберется, откуда вылезла эта бага.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.