Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Начало работы with scmRTOS
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > scmRTOS
Страницы: 1, 2, 3, 4, 5, 6
a9d
А что понимается под конструкторами ? Функции вида:
Код
void Reset_Handler(void)
{
    __Init_Data();

    main();
}

Есть подобное. Но сильно отличается.

Да знак ! не заметил.
AHTOXA
Цитата(a9d @ Sep 13 2011, 15:44) *
А что понимается под конструкторами ?

Конструкторы - это конструкторы. Функции инициализации объектов.
Короче, без их вызова работать не будет.
Вызываются как раз в __Init_Data():
Код
    /* Call constructors */
    unsigned long *ctors;
    for(ctors = &__ctors_start__; ctors < &__ctors_end__; )
        ((void(*)(void))(*ctors++))();

Цитата(a9d @ Sep 13 2011, 15:44) *
Есть подобное. Но сильно отличается.

biggrin.gif
a9d
Такого нет. Но как я понимаю конструкторы нужны С++. Либы от стм все на си.

Определил виновника

Код
#pragma weak HardFault_Handler = Default_Handler1


Объявил обработчика
Код
OS_INTERRUPT void HardFault_Handler(void){
    for (;;);
}


И начал попадать в него. Теперь осталось определить что это и почему срабатывает.
Сергей Борщ
QUOTE (a9d @ Sep 13 2011, 13:38) *
Но как я понимаю конструкторы нужны С++. Либы от стм все на си.
А ОС на плюсах. И пока не будут вызываться конструкторы - ОСь работать не будет.
a9d
Все нашел косяк. У вас STM32F10X_MD_VL.ld не правильный. Возможно и другие тоже.

Использовал конфиг от stm. Немного подправил и отладка заработала. ОС тоже работает. Но это покачто сделал на скорую руку.
AHTOXA
Цитата(a9d @ Sep 13 2011, 20:25) *
Все нашел косяк. У вас STM32F10X_MD_VL.ld не правильный. Возможно и другие тоже.

А поконкретнее?
a9d
Исходя из того какое прерывание вызывается можно понят, что косяк с выделением памяти под стек.
Это я нагуглил. На форумах пишут, что HardFault_Handler происходит при некорректном выделении памяти, обычно под стек или кучу.

Сравнил ваш и стм конфиг. Они отличаются строкой
Код
/* Entry Point */
ENTRY(Reset_Handler)


Добавил ее в ваш и все заработало.
AHTOXA
Гм. Очень странно... Давайте уточним пару моментов.
1. Программа без этого работает, но при отладке виснет?
2. Какой у вас компилятор?
3. При чём здесь "косяк с выделением памяти под стек"? sm.gif
a9d
1) Да, работает. Но при отладке улетает в прерывание. Если его не объявить, то вешается. Если объявить, то отладка работать будет но смотрится как-то не кошерно такой вариант.
2) Sourcery G++ Lite самый последний.
3) Это на этом форуме нагуглил.
AHTOXA
Раз программа работает, то дело естественно не в "косяке с выделением памяти". Думаю, что отладчик без этой строчки как-то не так понимает elf-файл, и загоняет процессор куда-то не туда.
Спасибо вам за найденный косяк. Надо будет исправить...
Chudik
Не знал куда запостить свой вопрос и запостил в соседнюю тему: http://electronix.ru/forum/index.php?showt...t&p=1098216
Буду очень благодарен, если кто ответит.
a9d
Вопрос не совсем по теме.

Сейчас вожусь с портированием scmRTOS на CC2510 (ядро 8051). Кмпилятор IAR, используется программный стек. Я знаю адрес (0x11 0x10) где хранится указатель на шапку стека. Т.е. регистр SPX (хотя во время отладки он называется XSP). Этот адрес строго фиксированный ? Т.е. во всех версиях он одинаковый.

Как я понял адрес определяется R0..R7 * Колличество банков + V0..V7

В документации
Цитата
XSP
Description Holds the stack pointers to the xdata stack.
Segment memory type DATA
Memory placement 0–0x7F
Access type Read/write


Цитата
-Z(DATA)XSP=08-7F



Почему в порте для AVR размер для стеков typedef uint8_t stack_item_ ? Это каждый стек не может превышать 255 байт?
ReAl
stak_item_t -- тип хранящихся в стеке даных (его гранулярность). А не размер.
Метценгерштейн
Правильно я понимаю, что освоив данную ось, проблем с переходом от одного проца к другому нет вообще? Т.е. я не изучаю досконально работу процессора, а просто пишу код. Использую прерывания, работу с периферией и прочее, но описываю их правилами оси?
a9d
Распетлял. Ох там все и закручено.

Код
#pragma segment="XSP"
    #define  ABS_WORD()  (*((__data volatile unsigned int*)(unsigned int)(__segment_begin("XSP"))))
    int s  = ABS_WORD();

AHTOXA
Цитата(Метценгерштейн @ Nov 9 2012, 03:35) *
Правильно я понимаю, что освоив данную ось, проблем с переходом от одного проца к другому нет вообще? Т.е. я не изучаю досконально работу процессора, а просто пишу код. Использую прерывания, работу с периферией и прочее, но описываю их правилами оси?

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

Теперь я понял почему Ti не стали делать RTOS для SoC CC25xx а слепили сверх паскудную кооперативку OSAL. Там большие проблемы со стеком. Он еще хуже чем в AVR. Но все равно терпимо.
a9d
А почему в деструкторе класа TISRW//_SS выключаются прерывания ?? а не ставиться крит секция которая гарантированно включит прерывания

И нужно сохранять регистр с информацией о глобальных прерываниях во время переключения контекста? Ведь если этого не делать то после переключения контекста прерывания будут выключены (не сработает деструктор крит секции). В аналоге регистра SREG у СС2510 не хранится информация о прерываниях.

Или просто в конце переключения контекста разрешать глобальные прерывания.
ReAl
Цитата(a9d @ Nov 10 2012, 10:07) *
А почему в деструкторе класа TISRW//_SS выключаются прерывания ?? а не ставиться крит секция которая гарантированно включит прерывания
Прерывания будут в нужном (включая запрещённое!) состоянии после восстановления SREG из контекста процесса, на который переключились.

Цитата(a9d @ Nov 10 2012, 10:07) *
Или просто в конце переключения контекста разрешать глобальные прерывания.
Боюсь, придётся таки сохранять состояние бита EA в контексте процесса.
Возьмём код OS::channel<>::push()
Код
template<typename T, uint16_t Size, typename S>
void OS::channel<T, Size, S>::push(const T& item)
{
    TCritSect cs;                      // *1)

    while(!pool.get_free_size())
    {
        // channel is full, suspend current process until data removed
        suspend(ProducersProcessMap);  // *2)
    }

    pool.push_back(item);              // *3)
    resume_all(ConsumersProcessMap);
}


*1) Тут запретили прерывания

*2) Тут ушли на другой процесс, ОС сохранит *этот* SREG с запретом прерываний В другом процессе прерывания (возможно) будут разрешены *его* SREG-ом. Данный процесс ждёт свободного места и по возвращении из suspend прерывания опять запрещены SREG-ом *данного* процесса.

*3) И они должны быть запрещены, иначе кто-то другой может врезатьсся в работу с этим же каналом между возвратом из suspend() (после освобождения места в буфере), push-нуть данные в то свободное место, после чего в опять полный буфер данные затолкает и этот процесс. Или даже врежется чтение из канала, а модификация индексов в кольцевом буфере pool ничем не защищена и то чтение врежется где-то посредине, вполоть до середины модификации многобайтовой переменной.
a9d
Что-то тут нето

TISRW
Код
INLINE void ISR_Exit()
        {
            disable_interrupts();
            if(--Kernel.ISR_NestCount) return;
            Kernel.sched_isr();
        }



Значит ситуация следующая. Три процесса.

Код
template<> void TProc1::exec()
{
    for(;;)
    {
        sleep(20);
    }
}

template<> void TProc2::exec()
{
    for(;;)
    {
        sleep(20);
    }
}

template<> void TProc3::exec()
{
    for(;;)
    {
        sleep(20);
    }
}



После старта они все уснули и управление получил IdleProc

Код
template<> void TIdleProc::exec()
    {
        for(;;)
        {
        #if scmRTOS_IDLE_HOOK_ENABLE == 1
            idle_process_user_hook();
        #endif

        #if scmRTOS_TARGET_IDLE_HOOK_ENABLE == 1
            idle_process_target_hook();
        #endif
        }
    }


Тут он вертится и ждет прерывание. Далее попадаем в таймер и на выходе мы уже тут

Код
INLINE void ISR_Exit()
        {
            disable_interrupts();                                           <--- Выключили прерывания
            if(--Kernel.ISR_NestCount) return;
            Kernel.sched_isr();                                             <--- Все спят, значит контекст не переключился и прерывание выключено
        }


Зависание в IdleProc.
ReAl
Контекст переключится на IdleProc.
В конце переключения на IdleProc будет занесено значение SREG из его контекста.
А в нём прерывания разрешены -- если Вы сами их не запретили.

Собственно, раз управление вообще попало в таймер, значит до этого (до прерывания таймера) прерывания были разрешены. wink.gif Это состояние было сохранено при входе в прерывание и оно будет восстановлено при обратном переключении на IdleProc (возможно, далеко не сразу, походив по остальным процессам). То же самое со всеми остальными процессами.
a9d
В Idle прерывания разрешены. Здесь все в порядке.

Из него мы попадаем в прерывание,где Kernel.sched_isr(); определяет, что контекст переключать не нужно. А значит и прерывание останеца выключенным.
_Артём_
Цитата(a9d @ Nov 10 2012, 19:22) *
Из него мы попадаем в прерывание,где Kernel.sched_isr(); определяет, что контекст переключать не нужно. А значит и прерывание останеца выключенным.

Возможно команда выхода из прерывания разрешит их (по крайней мере на АВР так).
a9d
В 8051 нужно в ручную это делать. Я просмотрел весь код, если контекст не переключается то это приводит к зависанию.

Значит disable_interrupts(); нужно заменить на крит секцию. Это приведет к проблемам ? Или включать прерывания на выходе из системного таймера?
_Артём_
Цитата(a9d @ Nov 10 2012, 19:34) *
В 8051 нужно в ручную это делать. Я просмотрел весь код, если контекст не переключается то это приводит к зависанию.

Значит можно
Цитата(a9d @ Nov 10 2012, 19:34) *
disable_interrupts(); нужно заменить на крит секцию.

.
Цитата(a9d @ Nov 10 2012, 19:34) *
Это приведет к проблемам ?

каким проблемам? В порте для CM3 так и сделано.

Цитата(a9d @ Nov 10 2012, 19:34) *
Или включать прерывания на выходе из системного таймера?

Зачем?
Код
OS_INTERRUPT void OS::Default_SystemTimer_ISR()
{
    scmRTOS_ISRW_TYPE ISR;
#if scmRTOS_SYSTIMER_HOOK_ENABLE == 1
    system_timer_user_hook();
#endif

    Kernel.system_timer();

#if scmRTOS_SYSTIMER_NEST_INTS_ENABLE == 0
    DISABLE_NESTED_INTERRUPTS();
#endif
        
}

Если scmRTOS_ISRW - это TISRW, то он сам их и разрешит.
a9d
Порт готов. Еще немного погоняю в отладчике и покажу.

Он получился уж слишком привязанным к конкретному микроконтроллеру. Некоторые важные дефайны находятся в файле линковцика и я незнаю как их достать от туда во время сборки.
a9d
Код
stack_item_t*  Next_SP      = ProcessTable[NextPrty]->StackPointer;
        stack_item_t** Curr_SP_addr = &(ProcessTable[CurProcPriority]->StackPointer);
        CurProcPriority = NextPrty;

        os_context_switcher(Curr_SP_addr, Next_SP);


А почему при переключение контекста передается в os_context_switcher ссылка на адрес Curr_SP_addr а не сам адрес?
_Артём_
Цитата(a9d @ Nov 11 2012, 02:10) *
А почему при переключение контекста передается в os_context_switcher ссылка на адрес Curr_SP_addr а не сам адрес?

Передаётся не ссылка, а указатель на указатель.

a9d, мне не понятно, но интересно, вы пытаетесь реализовать
scmRTOS_CONTEXT_SWITCH_SCHEME =0

,
но контроллер прерываний, вроде поддерживает вложенные прерывания(или не так)? Прерывание для переключения контекста нельзя выделить?
a9d
Ну указатель на адрес. Ведь удобней передать адрес или нет?

Я уже сделал прямую передачу. Уже отадил и готовлю к показу. Надеюсь отловил все ошибки.

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

Я думаю, можно использовать прерывание DMA пятого канала.
_Артём_
Цитата(a9d @ Nov 11 2012, 03:23) *
Ну указатель на адрес. Ведь удобней передать адрес или нет?

По указаному адресу (ProcessTable[CurProcPriority]) записывается содержимое SP текущего процесса(уже не самого приоритетного или не готового к исполнению). А в SP загружается Next_SP из ProcessTable[NextPrty]. Как-то так...примерно.

Цитата(a9d @ Nov 11 2012, 03:23) *
Я уже сделал прямую передачу. Уже отадил и готовлю к показу. Надеюсь отловил все ошибки.

Имеет ли смысл реализовывать прямую передачу управления, если контроллер прерываний поддерживает вложенные прерывания (а если уровней несколько)? Тут могут быть сложности...или всё просто?


Цитата(a9d @ Nov 11 2012, 03:23) *
Я думаю, можно использовать прерывание DMA пятого канала.

Так может и не париться с прямой передачей управления?
a9d
Прямая уже готова.

Там четыре уровня прерываний. И возможно с ними будут проблемы, но я пока что их не заметил.
_Артём_
Цитата(a9d @ Nov 11 2012, 04:22) *
Там четыре уровня прерываний. И возможно с ними будут проблемы, но я пока что их не заметил.


Допустим в программе задействованны два прерывания с разными приоритетами Int0 и Int1. Приоритет Int0 выше приоритета Int1.
В некоторый момент времени возникло прерывание Int1, процессор начал его отрабатывать. И затем возникает прерывание Int0,
которое вытесняет прерывание Int1. В конце прерывания Int0 выполняется ISR_Exit и если прерывание Int1 не успело инкрементировать
Kernel.ISR_NestCount, то начнётся выполнятся переключение контекста.
Прерывание Int1 потеряется и возможно будет заблокировано.
То есть Kernel.ISR_NestCount не может быть использован со схемой прямого переключения контекста, если контроллер прерываний поддерживает вложенные приоритетные прерывания.

Или я не прав?
a9d
Так крит. секция на выходе из обработчика разрешит прерывания. Значит прерывание не будет вытеснено.


Понял проблему нужно посмотреть что будет.


Это можно решить только запретом прерывания перед ISR_Enter и разрешением после.
ReAl
Цитата(_Артём_ @ Nov 11 2012, 15:26) *
То есть Kernel.ISR_NestCount не может быть использован со схемой прямого переключения контекста, если контроллер прерываний поддерживает вложенные приоритетные прерывания.

Или я не прав?
Обязанность сделать это правильно лежит на авторе порта. TISRW определяется в OS_Target.h.
Если вложенных прерываний нет, то
Код
        INLINE void ISR_Enter()
        {
            Kernel.ISR_NestCount++;
        }
Если есть, то
Код
        INLINE void ISR_Enter()
        {
            // STM8 can (atomically) increment byte in memory, but IAR 1.20 and 1.30 - can't :-(
            TCritSect cs;
            Kernel.ISR_NestCount++;
        }
В данном конкретном случае STM8 можно было бы даже со вложенными прерываниями обойтись без крит. секции, но конкретные версии компилятора не умели использовать атомарную инструкцию инкремента байта в памяти. Более свежий компилятор не проверял, да и STM8 Discovery вернул хозяину. Да и времени нет.
_Артём_
Цитата(a9d @ Nov 11 2012, 15:34) *
Это можно решить только запретом прерывания перед ISR_Enter и разрешением после.


Если возможно запретить - зависит от архитектуры и компилятора.

Цитата(ReAl @ Nov 11 2012, 15:41) *
В данном конкретном случае STM8 можно было бы даже со вложенными прерываниями обойтись без крит. секции, но конкретные версии компилятора не умели использовать атомарную инструкцию инкремента байта в памяти.

Перед этим "атомарным инкрементом" нет никаких других инструкций (push-ей, jump-ов и др)?
Тогда можно обойтись без критической секции (или запрета прерываний). Иначе и TCritSect не поможет.
a9d
Вариант с крит секцией не подходит да и работать он не будет как задумывалось. Ведь сначала будет сохраняться состояние и в этот момент может произойти вытеснение.

С запретом прерывания тоже не работает. Даже если запрет стоит самым первым, то перед ним все равно есть код где в программный стек сохраняются регистры. Думаю как это исправить.
_Артём_
Цитата(a9d @ Nov 11 2012, 16:19) *
С запретом прерывания тоже не работает. Даже если запрет стоит самым первым, то перед ним все равно есть код где в программный стек сохраняются регистры. Думаю как это исправить.

Смотря где запрет поставить...
Как у CC25 выглядит таблица векторов?
Если как у классических 51-ых (на каждый вектор кажеется выделялось 8 байт, в которые можно было вставить короткий обработчик или переход на длинную функцию). Если так, то можно первой же командой сделать запрет а потом вызывать обработчик. Всё это на асме придётся делать, наверное.

PS. Нет ли в CC25 чего-нибудь наподобие xmeg-овского PMIC.STATUS? Может можно задействовать?
a9d
Я тоже подумал про таблицу векторов. Там 8байт дано. Сейчас думаю как перед джампами лочить глобальное прерывание.

Исправил таблицу векторов. Теперь проблемы с вытеснением точно нет.
ReAl
Цитата(a9d @ Nov 11 2012, 16:19) *
Вариант с крит секцией не подходит да и работать он не будет как задумывалось. Ведь сначала будет сохраняться состояние и в этот момент может произойти вытеснение.
Речь идёт об TISRW ?
Самое худшее, что произойдёт, так это будет несколько большее использование стека. Но оно при вложенных прерываниях и так бывает.
Ну ещё дважды вызовется перепланировщик. Так он и так дважды вызовется, если во время отработки какого-то прерывания в очередь встанет следующее.

Пусть прерывания разрешены
  • работает какой-то процесс
  • прерывание
  • push-push-push
  • начало ISR_Enter. Тут может быть сохранение состояния прерываний от TCritSect, но ещё не запретили, инкрементировать вложенность не успели
    • Хопа! пошло другое прерывание
    • push-push
    • ISR_Enter - инкремент счётчика вложенности 0->1
    • обработка прерывания
    • ISR_Exit - декремент счётчика, 1->0, перепланировка, тут уже другие стек и PC, мы уже не из этого прерывания "возвращаемся". Может вообще не из прерывания, а из sleep() или event.wait(), а из этого прерывания "вернёмся", когда тот первый процесс будет самым приоритетным.
    • pop-pop-pop-pop
    • возврат
  • продолжение прерванного ISR_Enter - инкремент счётчика вложенности 0->1
  • обработка прерывания
  • ISR_Exit - декремент счётчика, 1->0, перепланировка
  • pop-pop
  • возврат
  • работа какого-то другого процесса

Пусть прерывания запрещены
  • работает какой-то процесс
  • прерывание
  • push-push-push
  • ISR_Enter - инкремент счётчика вложенности 0->1
  • обработка прерывания
  • ISR_Exit - декремент счётчика, 1->0, перепланировка
  • pop-pop
  • где-то тут перед концом возврата всё равно разрешение прерываний
  • пошло второе, ранее отложенное прерывание
  • push-push
  • ISR_Enter - инкремент счётчика вложенности 0->1
  • обработка прерывания
  • ISR_Exit - декремент счётчика, 1->0, перепланировка
  • pop-pop-pop-pop
  • "возврат"
  • работа


Что так, что так -- при наложении прерываний может оказаться две перепланировки.

Если бы в первом варианте второе прерывание пришло капельку позже, после инкремента счетчика вложенности, то перепланировка была бы одна. Но стек всё равно на два прерывания.
a9d
Произойдет все немного по другому.

Вошли в первое прерывание.
До ISR_Enter вытеснили. Произошла перепланировка и мы влетаем повторно в первое прерывание. Ведь мы не успели сбросить флаг прерывания. И того у нас произошел ложный вызов прерывания. Это уже аварийная ситуация.
ReAl
Возможно я что-то забыл по 8051-ым.

Прервать текущее прерывание может только прерывание более высокого приоритета. Такого же -- не может.

reti в конце прерывания более высокого приоритета очищает тот уровень прерывания, данный не очищает.

После возврата в данное прерывание флаг-то не сброшен, но и уровень этого прерывания не очищен, так что повторного входа не произойдет. Иначе бы без никаких ОС сразу после ljmp из вектора мы бы заново входили в данное прерывание.
a9d
Провел эксперимент.


Повысил прерывание WDT.
В системном таймере до обвертки вызываю прерывание WDT. Таки да повторного прерывания не происходит. Но контекст восстанавливается неправильно.

Если произвести вытеснение после обвертки. То контекст восстанавливается верно.
_Артём_
Цитата(ReAl @ Nov 11 2012, 21:44) *
Пусть прерывания разрешены
  • работает какой-то процесс
  • прерывание
  • push-push-push
  • начало ISR_Enter. Тут может быть сохранение состояния прерываний от TCritSect, но ещё не запретили, инкрементировать вложенность не успели
    • Хопа! пошло другое прерывание
    • push-push
    • ISR_Enter - инкремент счётчика вложенности 0->1
    • обработка прерывания
    • ISR_Exit - декремент счётчика, 1->0, перепланировка, тут уже другие стек и PC, мы уже не из этого прерывания "возвращаемся". Может вообще не из прерывания, а из sleep() или event.wait(), а из этого прерывания "вернёмся", когда тот первый процесс будет самым приоритетным.
    • pop-pop-pop-pop
    • возврат
  • продолжение прерванного ISR_Enter - инкремент счётчика вложенности 0->1
  • обработка прерывания
  • ISR_Exit - декремент счётчика, 1->0, перепланировка
  • pop-pop
  • возврат
  • работа какого-то другого процесса

Звучит логично.
Возможно я был частично или совсем неправ, говоря о возможных проблемах. Пока сам не понял.

Цитата(ReAl @ Nov 11 2012, 21:44) *
а из этого прерывания "вернёмся", когда тот первый процесс будет самым приоритетным.

То есть прерывание отложится на неизестное время и может вообще навсегда? А уровень так и будет заблокированным? Тагда это аварийная ситуация.
ReAl
Цитата(_Артём_ @ Nov 11 2012, 23:27) *
То есть прерывание отложится на неизестное время и может вообще навсегда? А уровень так и будет заблокированным? Тагда это аварийная ситуация.
Возврат из прерывания. Само-то прерывание отработали и нужные флаги сбросило.
А вот дальше...

У STM8 уровень (всё запрещено и три уровня разрешённости) записан в двух битах статусного регистра.

Для MCS51 с аппаратным отслеживанием по reti тут, похоже, таки бяка. Для рассмотрения и вложенные прерывания не нужны.
Разблокировать может только выход по reti из любого переключения контекста.
Но переключение может быть на возврат из some_event.wait() (и прерывание этот event и подняло), а там по дороге только ret.
Хотя почему только ret? Собственно переключатель-то на асме написан, там можно и reti написать.

Или делать переключение свободным отложенным прерыванием. Тогда из всех тех прерыываний вышли, все уровни очистили и только потом пойдёт прерывание переключения, кторое тоже за собой почистит.

Цитата(a9d @ Nov 11 2012, 23:03) *
В системном таймере до обвертки вызываю прерывание WDT. Таки да повторного прерывания не происходит. Но контекст восстанавливается неправильно.
Если произвести вытеснение после обвертки. То контекст восстанавливается верно.
Ну тут помочь не могу. Это нужно бы копаться с живой платой и компилятором, а у меня нет ни времени, ни желания ни ещё одну версию IAR в виртуалбоксе ставить, ни с 51-ыми играться.
a9d
Определил причину. Из-за лишних переключений контекста происходило переполнение софтварного стека процесса Idle.

ReAl
Цитата(ReAl @ Nov 11 2012, 23:53) *
Или делать переключение свободным отложенным прерыванием. Тогда из всех тех прерыываний вышли, все уровни очистили и только потом пойдёт прерывание переключения, кторое тоже за собой почистит.
Ой!
Что-то мне начинает казаться, что для AVR (порт MEGA, на XMEGA я так толком и не смотрел) как раз в переключении прерыванием могут быть неприятности, там ситуация зеркальная.

Тут reti не влияет на бит глобального разрешения EA, но приоритеты обслуживаются аппаратно и очищаются reti

Там вход в прерывание выключает, а reti включает прерывания. Но при синхронном переключении (те же .wait() или там .push()) в недрах вызова ОС могла быть критическая секция и восстановить надо бы состояние запрещённых прерываний, как выше писано. Что-то я сейчас уже сонный, а с понедельника не до того. Забил гвоздик в scmRTOS-блокнотике tomboy, но вот не забыть бы туда заглянуть.
a9d
А где спрятан SystemTimer_ISR ??? При программном прерывании должен срабатывать он, нигде нет примера как он должен выглядеть.

Все понял. Это неправильный дефайн в порте avr
ReAl
Цитата(a9d @ Nov 12 2012, 05:01) *
Все понял. Это неправильный дефайн в порте avr
Какой именно и где?
a9d
порт AVR
scmRTOS_TARGET_CFG.h

Код
namespace OS
{
#if scmRTOS_CONTEXT_SWITCH_SCHEME == 0
    #pragma vector=SYSTEM_TIMER_VECTOR
    OS_INTERRUPT void OS_SystemTimer_ISR();
#else
    #pragma vector=SYSTEM_TIMER_VECTOR
    __interrupt void SystemTimer_ISR();
#endif // scmRTOS_CONTEXT_SWITCH_SCHEME
}


Если scmRTOS_CONTEXT_SWITCH_SCHEME =1 , то пользователю нужно в обязательном порядке писать обработчик системного таймера.
_Артём_
Цитата(a9d @ Nov 14 2012, 15:45) *
Если scmRTOS_CONTEXT_SWITCH_SCHEME =1 , то пользователю нужно в обязательном порядке писать обработчик системного таймера.

Почему это?

Обработчик находится в OS_Target_cpp.cpp уже готовый. Может у вас версия не последняя?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.