|
|
  |
Начало работы with scmRTOS, Несколько вопросиков |
|
|
|
Nov 9 2012, 03:58
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(Метценгерштейн @ Nov 9 2012, 03:35)  Правильно я понимаю, что освоив данную ось, проблем с переходом от одного проца к другому нет вообще? Т.е. я не изучаю досконально работу процессора, а просто пишу код. Использую прерывания, работу с периферией и прочее, но описываю их правилами оси? Нет, думаю что не так. Ось позволяет лишь организовать несколько потоков выполнения программы и их взаимодействие. А работа с железом процессора всё равно остаётся на пользователе. Вам в любом случае придётся выполнить инициализацию процессора, и всей нужной периферии. Вам в любом случае придётся писать обработчики прерываний. То есть, весь нижний уровень никуда не девается, и его по-прежнему надо делать.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Nov 10 2012, 12:01
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(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 ничем не защищена и то чтение врежется где-то посредине, вполоть до середины модификации многобайтовой переменной.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Nov 10 2012, 17:07
|
Местный
  
Группа: Участник
Сообщений: 312
Регистрация: 9-04-10
Пользователь №: 56 532

|
Что-то тут нето 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 - Nov 10 2012, 17:07
|
|
|
|
|
Nov 10 2012, 17:19
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Контекст переключится на IdleProc. В конце переключения на IdleProc будет занесено значение SREG из его контекста. А в нём прерывания разрешены -- если Вы сами их не запретили. Собственно, раз управление вообще попало в таймер, значит до этого (до прерывания таймера) прерывания были разрешены.  Это состояние было сохранено при входе в прерывание и оно будет восстановлено при обратном переключении на IdleProc (возможно, далеко не сразу, походив по остальным процессам). То же самое со всеми остальными процессами.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Nov 10 2012, 17:55
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(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, то он сам их и разрешит.
|
|
|
|
|
Nov 11 2012, 00:10
|
Местный
  
Группа: Участник
Сообщений: 312
Регистрация: 9-04-10
Пользователь №: 56 532

|
Код 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 а не сам адрес?
|
|
|
|
|
Nov 11 2012, 01:12
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(a9d @ Nov 11 2012, 02:10)  А почему при переключение контекста передается в os_context_switcher ссылка на адрес Curr_SP_addr а не сам адрес? Передаётся не ссылка, а указатель на указатель. a9d, мне не понятно, но интересно, вы пытаетесь реализовать scmRTOS_CONTEXT_SWITCH_SCHEME =0 , но контроллер прерываний, вроде поддерживает вложенные прерывания(или не так)? Прерывание для переключения контекста нельзя выделить?
|
|
|
|
|
Nov 11 2012, 01:50
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(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 пятого канала. Так может и не париться с прямой передачей управления?
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|