реклама на сайте
подробности

 
 
5 страниц V  « < 3 4 5  
Reply to this topicStart new topic
> Прерывание в прерывании, Для реализации Super Simple Tasker
Forger
сообщение Nov 17 2017, 11:07
Сообщение #61


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(syoma @ Nov 17 2017, 13:45) *
что ARM не поддерживает reentrant прерывания

Дык, это вполне логично, и касается не только для ARM ))

Цитата
и выполнение Step_1s() полностью блокирует прерывание и Step_10ms() при этом не исполняется. Нашел в инете, что народ играется ассемблером и пытается восстанавливать стек и прочие вещи, чтобы процессор опять мог заходить в это же прерывание, но хотелось бы узнать - есть ли простое решение, без RTOS, так

В ARM (не во всех) реализована поддержка вложенных прерываний.
Почитайте про PendSV и заодно про SVC вызовы. Про это уже давно исписаны все заборы интернеты.
Это если желаете толстые фунции вызывать в фоне прерываний (кстати, за подобные "дела" в некоторых конторах очень сурово карают).

Цитата
как кроме этой функции RTOS будет не нужна.

Это вы сейчас так говорите, в данный момент. А в перспективе? wink.gif

Но, если же проект такой примитивный, то все можно сделать на паре/тройке аппаратных таймеров.
В самом убогом ARM как минимум два-три штуки найдутся (помимо стандартного SysTimer). Такое решение простое, наглядное и железобетонное.
Если правильно назначить приоритеты этим таймерам, то получится относительно работоспособный "шедулер" с поддержкой приоритетов.

Еще еще вариант - простейший супер-луп, использующий лишь один таймер (systimer), где код из фона прерываний переносится в фон задач.
Фактически пишете шедулер RTOS самостоятельно руками (со всеми вытекающими).

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


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
scifi
сообщение Nov 17 2017, 11:15
Сообщение #62


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(syoma @ Nov 17 2017, 13:45) *
Каково же было мое удивление, когда оказалось, что ARM не поддерживает reentrant прерывания и выполнение Step_1s() полностью блокирует прерывание и Step_10ms() при этом не исполняется.

Всё он поддерживает.
Обработчик прерывания не будет вызван повторно, пока он выполняется. Вообще-то это разумно, не находите? Для того, чтобы он был прерван, должно произойти прерывание с более высоким приоритетом, а не с равным.
Go to the top of the page
 
+Quote Post
Forger
сообщение Nov 17 2017, 11:37
Сообщение #63


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(scifi @ Nov 17 2017, 14:15) *
Всё он поддерживает.

Здесь под словом reentrant имеется ввиду возможность обработчика прервать самого себя.
Наподобие вызова функции внутри самой себя.

А вытесняющие прерывания называются иначе - nesting interrupts, т.е. вложенные прерывания (в некоторой литературе может встречаться другое название - preemptive).
Они подразумевают вытеснение одного обработчика прерываний ДРУГИМ обработчиком.
Если же прерывание от того же самого источника произойдет в то время, пока обрабатывается прерывание от этого же источника (скажем, байты по USART сыпятся быстрее, чем успеваем их обрабатывать),
то новое прерывание станет отложенным (pending) и вызовется сразу же после обработки текущего (если конечно никто более приоритетный его не прервет). Другими словами, встанет в очередь.
Это если объяснять грубо и на пальцах, на деле там полно своих нюансов.


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
Timmy
сообщение Nov 17 2017, 12:01
Сообщение #64


Знающий
****

Группа: Участник
Сообщений: 835
Регистрация: 9-08-08
Из: Санкт-Петербург
Пользователь №: 39 515



Цитата(syoma @ Nov 17 2017, 13:45) *
Каково же было мое удивление, когда оказалось, что ARM не поддерживает reentrant прерывания и выполнение Step_1s() полностью блокирует прерывание и Step_10ms() при этом не исполняется. Нашел в инете, что народ играется ассемблером и пытается восстанавливать стек и прочие вещи, чтобы процессор опять мог заходить в это же прерывание, но хотелось бы узнать - есть ли простое решение, без RTOS, так как кроме этой функции RTOS будет не нужна.

Эта задача легко решается при помощи программных прерываний с различным приоритетом. Для программных прерываний можно использовать любые вектора неиспользуемых в проекте периферийных устройств.
Для инициализации вызываем, как обычно, NVIC_SetPriority() и NVIC_EnableIRQ(),
а чтобы позвать программное прерывание вызываем NVIC_SetPendingIRQ().
Go to the top of the page
 
+Quote Post
syoma
сообщение Nov 17 2017, 12:02
Сообщение #65


Профессионал
*****

Группа: Свой
Сообщений: 1 817
Регистрация: 14-02-07
Из: наших, которые работают за бугром
Пользователь №: 25 368



Цитата(scifi @ Nov 17 2017, 14:15) *
Всё он поддерживает.
Обработчик прерывания не будет вызван повторно, пока он выполняется. Вообще-то это разумно, не находите? Для того, чтобы он был прерван, должно произойти прерывание с более высоким приоритетом, а не с равным.

Ну я нахожу разумным, если есть возможность выбора - так или этак. И мое представление об обработчике прерывания очень простое - произошло прерывание - процессор должен безусловно перейти на адрес обработчика. Если пользователь хочет - не снимает флаг, пока не обработает все прерывание и теряет возможность поимки следующего прерывания, пришедшего во время обработки. Если хочет - снимает, и не теряет. Насколько я помню 8051-ых так было реализовано.
Go to the top of the page
 
+Quote Post
Forger
сообщение Nov 17 2017, 12:17
Сообщение #66


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(syoma @ Nov 17 2017, 15:02) *
И мое представление об обработчике прерывания очень простое - произошло прерывание - процессор должен безусловно перейти на адрес обработчика.

Напишите свое видение этой "проблемы" в компанию ARM wink.gif


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
Obam
сообщение Nov 17 2017, 13:03
Сообщение #67


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



Цитата(syoma @ Nov 17 2017, 16:02) *
…Если пользователь хочет - не снимает флаг, пока не обработает все прерывание и теряет возможность поимки следующего прерывания, пришедшего во время обработки. Если хочет - снимает, и не теряет. Насколько я помню 8051-ых так было реализовано.

"Пешим по-конному" (;


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Nov 17 2017, 13:42
Сообщение #68


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(syoma @ Nov 17 2017, 14:02) *
Ну я нахожу разумным, если есть возможность выбора - так или этак. И мое представление об обработчике прерывания очень простое - произошло прерывание - процессор должен безусловно перейти на адрес обработчика. Если пользователь хочет - не снимает флаг, пока не обработает все прерывание и теряет возможность поимки следующего прерывания, пришедшего во время обработки. Если хочет - снимает, и не теряет. Насколько я помню 8051-ых так было реализовано.

Т.е. любой хакер берет подает внешние сигналы для прерываний чуть быстрее и переполняет стек настолько насколько ему нужно.
Это уже не программа будет, а настоящая диверсия.
К счастью ARM это дело пресёк.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Nov 17 2017, 13:44
Сообщение #69


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(syoma @ Nov 17 2017, 14:02) *
Насколько я помню 8051-ых так было реализовано.

Видно что Вы со времён этого самого 8051 больше ничего другого не изучали.
Почитайте мануал на ARM-ядро и узнаете, что на нём всё что нужно легко реализуется.
А пока - рано вам ещё ISR-ы писать, не понимая как ядро работает.
Go to the top of the page
 
+Quote Post
syoma
сообщение Nov 17 2017, 18:04
Сообщение #70


Профессионал
*****

Группа: Свой
Сообщений: 1 817
Регистрация: 14-02-07
Из: наших, которые работают за бугром
Пользователь №: 25 368



Знающие люди подсказали такой вариант. У них работает:

CODE
__attribute__ ((naked)) void SysTick_Handler(void)
{
/* Multi tasking, enable re-entrancy to interrupt */
arm_cortex_m_call_thread_with_context_switch(SysTick_Isr);
}

/* Re-entrant function for multi-tasking: arm_cortex_m_call_thread_with_context_switch*/

__attribute__ ((naked)) void arm_cortex_m_call_thread_with_context_switch(void (* isr_routine_ptr)(void)) {
#if (defined(__FPU_PRESENT) && (__FPU_PRESENT == 1)) && (defined(__FPU_USED) && (__FPU_USED == 1))
__asm volatile (" TST LR, #0x10");
__asm volatile (" IT EQ");
__asm volatile (" VMOVEQ S0, S0");
#endif
__asm volatile (" PUSH {R0, R1}");
__asm volatile (" SUB SP, SP, #0x20");
__asm volatile (" ADR R0,Call_isr_routine_in_thread_mode");
__asm volatile (" STR R0,[SP, #24]");
__asm volatile (" MOV R0,#0x01000000");
__asm volatile (" STR R0,[SP, #28]");
__asm volatile (" MVNS R0,#0x6");
__asm volatile (" MOV LR, R0");
__asm volatile (" BX LR");
__asm volatile ("Call_isr_routine_in_thread_mode:");
__asm volatile (" POP {R0, R1}");
__asm volatile (" BLX R0");
__asm volatile (" ISB");
__asm volatile (" SVC #0");
__asm volatile ("Unknown_Execution:");
__asm volatile (" B Unknown_Execution");
}
/* SVC Interrupt service routine to restore the context: SVC_Handler*/

__attribute__ ((naked)) void SVC_Handler(void) {
#if (defined(__FPU_PRESENT) && (__FPU_PRESENT == 1)) && (defined(__FPU_USED) && (__FPU_USED == 1))
__asm volatile (" TST LR, #0x10");
__asm volatile (" IT EQ");
__asm volatile (" VMOVEQ S0, S0");
#endif
__asm volatile (" TST LR, #0x4");
__asm volatile (" ITE EQ");
__asm volatile (" MRSEQ R0, MSP");
__asm volatile (" MRSNE R0, PSP");
__asm volatile (" LDR R1, [R0, #24]");
__asm volatile (" LDRB.W R0, [R1, #-2]");
__asm volatile (" CBZ R0, svc_service_0");
__asm volatile (" B Unknown_SVC_Request");
__asm volatile ("svc_service_0:");
#if (defined(__FPU_PRESENT) && (__FPU_PRESENT == 1)) && (defined(__FPU_USED) && (__FPU_USED == 1))
__asm volatile (" TST LR, #0x10");
__asm volatile (" ITE EQ");
__asm volatile (" ADDEQ SP, SP, #104");
__asm volatile (" ADDNE SP, SP, #32");
#else
__asm volatile (" ADD SP, SP, #32");
#endif
__asm volatile (" POP {R0, R1}");
__asm volatile (" MSR APSR_nzcvq, R0");
__asm volatile (" BX R1");
__asm volatile ("Unknown_SVC_Request:");
__asm volatile (" B Unknown_SVC_Request");
}


В итоге SysTick_Isr будет самовложенной. Что скажете?

Сообщение отредактировал IgorKossak - Nov 17 2017, 20:08
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Nov 17 2017, 18:56
Сообщение #71


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(syoma @ Nov 17 2017, 20:04) *
Знающие люди подсказали такой вариант. У них работает:

В итоге SysTick_Isr будет самовложенной. Что скажете?

Кто-то что-то наковырял в симулинке?
А кто тогда покажет файл SysTickScheduler.c?
Там невооруженным глазом видно, что обработчик вызывает функцию rt_OneStep в течении которой все! прерывания запрещены.
Вот у них и работает.
Лузеры!
Go to the top of the page
 
+Quote Post
syoma
сообщение Nov 17 2017, 20:51
Сообщение #72


Профессионал
*****

Группа: Свой
Сообщений: 1 817
Регистрация: 14-02-07
Из: наших, которые работают за бугром
Пользователь №: 25 368



Цитата(AlexandrY @ Nov 17 2017, 21:56) *
Кто-то что-то наковырял в симулинке?
А кто тогда покажет файл SysTickScheduler.c?
Там невооруженным глазом видно, что обработчик вызывает функцию rt_OneStep в течении которой все! прерывания запрещены.
Вот у них и работает.
Лузеры!

Если бы в rt_OneStep были бы запрещены прерывания, разве был бы смысл в данных извращениях? Поэтому прерывания в rt_OneStep разрешены и приветствуются. Могу прикрепить файл, если хотите.
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Nov 17 2017, 21:35
Сообщение #73


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(syoma @ Nov 17 2017, 22:51) *
Если бы в rt_OneStep были бы запрещены прерывания, разве был бы смысл в данных извращениях? Поэтому прерывания в rt_OneStep разрешены и приветствуются. Могу прикрепить файл, если хотите.

Они запрещены перед вызовом rt_OneStep.
Прикреплять надо весь проект.
Go to the top of the page
 
+Quote Post

5 страниц V  « < 3 4 5
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 21:02
Рейтинг@Mail.ru


Страница сгенерированна за 0.01477 секунд с 7
ELECTRONIX ©2004-2016