AHTOXA 15 9 ноября, 2012 Опубликовано 9 ноября, 2012 · Жалоба Правильно я понимаю, что освоив данную ось, проблем с переходом от одного проца к другому нет вообще? Т.е. я не изучаю досконально работу процессора, а просто пишу код. Использую прерывания, работу с периферией и прочее, но описываю их правилами оси? Нет, думаю что не так. Ось позволяет лишь организовать несколько потоков выполнения программы и их взаимодействие. А работа с железом процессора всё равно остаётся на пользователе. Вам в любом случае придётся выполнить инициализацию процессора, и всей нужной периферии. Вам в любом случае придётся писать обработчики прерываний. То есть, весь нижний уровень никуда не девается, и его по-прежнему надо делать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
a9d 0 9 ноября, 2012 Опубликовано 9 ноября, 2012 (изменено) · Жалоба А как из файла конфигурации для линковщика можно получить дефайны? Некоторые дефайны указывают конкретное положение виртуальных регистров и эти значения меняются в зависимости от микроконтроллера. Теперь я понял почему Ti не стали делать RTOS для SoC CC25xx а слепили сверх паскудную кооперативку OSAL. Там большие проблемы со стеком. Он еще хуже чем в AVR. Но все равно терпимо. Изменено 9 ноября, 2012 пользователем a9d Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
a9d 0 10 ноября, 2012 Опубликовано 10 ноября, 2012 (изменено) · Жалоба А почему в деструкторе класа TISRW//_SS выключаются прерывания ?? а не ставиться крит секция которая гарантированно включит прерывания И нужно сохранять регистр с информацией о глобальных прерываниях во время переключения контекста? Ведь если этого не делать то после переключения контекста прерывания будут выключены (не сработает деструктор крит секции). В аналоге регистра SREG у СС2510 не хранится информация о прерываниях. Или просто в конце переключения контекста разрешать глобальные прерывания. Изменено 10 ноября, 2012 пользователем a9d Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 10 ноября, 2012 Опубликовано 10 ноября, 2012 · Жалоба А почему в деструкторе класа 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 ничем не защищена и то чтение врежется где-то посредине, вполоть до середины модификации многобайтовой переменной. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
a9d 0 10 ноября, 2012 Опубликовано 10 ноября, 2012 (изменено) · Жалоба Что-то тут нето 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. Изменено 10 ноября, 2012 пользователем a9d Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 10 ноября, 2012 Опубликовано 10 ноября, 2012 · Жалоба Контекст переключится на IdleProc. В конце переключения на IdleProc будет занесено значение SREG из его контекста. А в нём прерывания разрешены -- если Вы сами их не запретили. Собственно, раз управление вообще попало в таймер, значит до этого (до прерывания таймера) прерывания были разрешены. ;) Это состояние было сохранено при входе в прерывание и оно будет восстановлено при обратном переключении на IdleProc (возможно, далеко не сразу, походив по остальным процессам). То же самое со всеми остальными процессами. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
a9d 0 10 ноября, 2012 Опубликовано 10 ноября, 2012 · Жалоба В Idle прерывания разрешены. Здесь все в порядке. Из него мы попадаем в прерывание,где Kernel.sched_isr(); определяет, что контекст переключать не нужно. А значит и прерывание останеца выключенным. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 10 ноября, 2012 Опубликовано 10 ноября, 2012 · Жалоба Из него мы попадаем в прерывание,где Kernel.sched_isr(); определяет, что контекст переключать не нужно. А значит и прерывание останеца выключенным. Возможно команда выхода из прерывания разрешит их (по крайней мере на АВР так). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
a9d 0 10 ноября, 2012 Опубликовано 10 ноября, 2012 (изменено) · Жалоба В 8051 нужно в ручную это делать. Я просмотрел весь код, если контекст не переключается то это приводит к зависанию. Значит disable_interrupts(); нужно заменить на крит секцию. Это приведет к проблемам ? Или включать прерывания на выходе из системного таймера? Изменено 10 ноября, 2012 пользователем a9d Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 10 ноября, 2012 Опубликовано 10 ноября, 2012 · Жалоба В 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, то он сам их и разрешит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
a9d 0 10 ноября, 2012 Опубликовано 10 ноября, 2012 · Жалоба Порт готов. Еще немного погоняю в отладчике и покажу. Он получился уж слишком привязанным к конкретному микроконтроллеру. Некоторые важные дефайны находятся в файле линковцика и я незнаю как их достать от туда во время сборки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
a9d 0 11 ноября, 2012 Опубликовано 11 ноября, 2012 · Жалоба 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 а не сам адрес? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 11 ноября, 2012 Опубликовано 11 ноября, 2012 · Жалоба А почему при переключение контекста передается в os_context_switcher ссылка на адрес Curr_SP_addr а не сам адрес? Передаётся не ссылка, а указатель на указатель. a9d, мне не понятно, но интересно, вы пытаетесь реализовать scmRTOS_CONTEXT_SWITCH_SCHEME =0 , но контроллер прерываний, вроде поддерживает вложенные прерывания(или не так)? Прерывание для переключения контекста нельзя выделить? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
a9d 0 11 ноября, 2012 Опубликовано 11 ноября, 2012 (изменено) · Жалоба Ну указатель на адрес. Ведь удобней передать адрес или нет? Я уже сделал прямую передачу. Уже отадил и готовлю к показу. Надеюсь отловил все ошибки. Вложенные прерывания есть. Я не знаю будит ли у меня время допилить порт до конца и реализовать все. Я думаю, можно использовать прерывание DMA пятого канала. Изменено 11 ноября, 2012 пользователем a9d Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 11 ноября, 2012 Опубликовано 11 ноября, 2012 · Жалоба Ну указатель на адрес. Ведь удобней передать адрес или нет? По указаному адресу (ProcessTable[CurProcPriority]) записывается содержимое SP текущего процесса(уже не самого приоритетного или не готового к исполнению). А в SP загружается Next_SP из ProcessTable[NextPrty]. Как-то так...примерно. Я уже сделал прямую передачу. Уже отадил и готовлю к показу. Надеюсь отловил все ошибки. Имеет ли смысл реализовывать прямую передачу управления, если контроллер прерываний поддерживает вложенные прерывания (а если уровней несколько)? Тут могут быть сложности...или всё просто? Я думаю, можно использовать прерывание DMA пятого канала. Так может и не париться с прямой передачей управления? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться