Перейти к содержанию
    

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

Изменено пользователем a9d

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А почему в деструкторе класа TISRW//_SS выключаются прерывания ?? а не ставиться крит секция которая гарантированно включит прерывания

 

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

 

Или просто в конце переключения контекста разрешать глобальные прерывания.

Изменено пользователем a9d

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А почему в деструкторе класа TISRW//_SS выключаются прерывания ?? а не ставиться крит секция которая гарантированно включит прерывания
Прерывания будут в нужном (включая запрещённое!) состоянии после восстановления SREG из контекста процесса, на который переключились.

 

Или просто в конце переключения контекста разрешать глобальные прерывания.
Боюсь, придётся таки сохранять состояние бита 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 ничем не защищена и то чтение врежется где-то посредине, вполоть до середины модификации многобайтовой переменной.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что-то тут нето

 

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.

Изменено пользователем a9d

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Контекст переключится на IdleProc.

В конце переключения на IdleProc будет занесено значение SREG из его контекста.

А в нём прерывания разрешены -- если Вы сами их не запретили.

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В Idle прерывания разрешены. Здесь все в порядке.

 

Из него мы попадаем в прерывание,где Kernel.sched_isr(); определяет, что контекст переключать не нужно. А значит и прерывание останеца выключенным.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Из него мы попадаем в прерывание,где Kernel.sched_isr(); определяет, что контекст переключать не нужно. А значит и прерывание останеца выключенным.

Возможно команда выхода из прерывания разрешит их (по крайней мере на АВР так).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 8051 нужно в ручную это делать. Я просмотрел весь код, если контекст не переключается то это приводит к зависанию.

 

Значит disable_interrupts(); нужно заменить на крит секцию. Это приведет к проблемам ? Или включать прерывания на выходе из системного таймера?

Изменено пользователем a9d

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 8051 нужно в ручную это делать. Я просмотрел весь код, если контекст не переключается то это приводит к зависанию.

Значит можно

disable_interrupts(); нужно заменить на крит секцию.

.

Это приведет к проблемам ?

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

 

Или включать прерывания на выходе из системного таймера?

Зачем?

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, то он сам их и разрешит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Порт готов. Еще немного погоняю в отладчике и покажу.

 

Он получился уж слишком привязанным к конкретному микроконтроллеру. Некоторые важные дефайны находятся в файле линковцика и я незнаю как их достать от туда во время сборки.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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 а не сам адрес?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А почему при переключение контекста передается в os_context_switcher ссылка на адрес Curr_SP_addr а не сам адрес?

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

 

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

scmRTOS_CONTEXT_SWITCH_SCHEME =0

 

,

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну указатель на адрес. Ведь удобней передать адрес или нет?

 

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

 

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

 

Я думаю, можно использовать прерывание DMA пятого канала.

Изменено пользователем a9d

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну указатель на адрес. Ведь удобней передать адрес или нет?

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

 

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

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

 

 

Я думаю, можно использовать прерывание DMA пятого канала.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...