Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Прерывание в прерывании
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Страницы: 1, 2
Forger
Цитата(AVR @ Nov 8 2017, 11:44) *
Ради него старался и нашел такую опцию. Ничего не потерял cool.gif

Хм, удобная функция, спасибо за подсказку! Пригодится wink.gif
Студент заборстроительного
Цитата(Forger @ Nov 7 2017, 16:02) *
Цитата(arhiv6 @ Nov 7 2017, 15:00) *

Super Simple Tasker - один из вариантов реализации вытесняющей многозадачности для микроконтроллеров.


Может быть я стал слишком старый и "отстал от поезда", поэтому на всякий случай спрошу: НАФИГА ???
Чем не годится готовая RTOS? В частности freeRTOS позволяет использовать вложенные прерывания без подобного "дрочева".... laughing.gif

Сейчас каждый джуниор считает своим долгом написать свою RTOS biggrin.gif
При этом НИХРЕНА в этом не понимая.
И при этом считает, что его RTOS - это какое-то откровение в мире RTOS.

Кто из нас по молодости не писал свою RTOS, и кто из нас в старости не осознал, что маялся дурью и тратил время на всякую не нужную ерунду biggrin.gif

Я сейчас вспоминаю сколько времени я на это угрохал. Лучше б тёлок молодых порол. Тогда они мне ещё теоретически могли "дать". Не то что сейчас




Цитата(arhiv6 @ Nov 7 2017, 16:17) *
Как минимум, это интересно - попробовать разные подходы к построению ПО.

Вот вот.
О чём я и сказал
Forger
Цитата(Студент заборстроительного @ Nov 8 2017, 19:41) *
Я сейчас вспоминаю сколько времени я на это угрохал. Лучше б тёлок молодых порол.

Аналогичная ситуация! biggrin.gif
Но только мне удалось наваять свою простейшую ось относительно быстро, после "наиграться" с ней и в итоге поставил готовую чужую и больше этот вопрос не поднимал.

С другой стороны, до сих пор вот мне очень интересно познавать новые фишки в мире эмбедед ПО, в частности, относительно недавно "изучал" .netmicro, недавно чуть "по-тискал" micro java (или как там она зовется) ....
Короче, удалил их к чертовой бабушке - рано еще, времена еще не пришли, нынешние МК пока еще слишком ватные для таких "вещей".

Кстати, в данный момент уперся в необходимость применения такой вещи (пишу под плюсами) - паттерн "фабрика объектов", а совсем недавно освоил паттерн "делегатов" .
Удивительно, но теперь они реально мне понадобились, хотя в свое время хихикал над другими: "гы-гы, плюсы, шаблоны, паттерны" ...

Но, ребяты, изобретать самодельный колхозный шедулер = городить "велосипед с квадратными колесами" "из говна и палок" - это уже, прям, лютая дикость 01.gif
jcxz
Цитата(Forger @ Nov 7 2017, 21:36) *
Для тех, кто не в теме: в ARM Cortex есть такой механизм - BitBanging (вроде правильно написал).

может есть, а может и нет.
Forger
Цитата(jcxz @ Nov 8 2017, 23:49) *
может есть, а может и нет.

Суть от этого не меняется - лаконичный код под классической RTOS после переписывания под SST превращается в банальный говнокод (см. посты #31 и #33).
Отсюда мораль: если вы видите перед собой говнокод, то смотрите на тип шедулера. Если стоит SST, "карусельку" или "супер-мега-гипер-луп", то шансы для этого кода все еще есть ...
Если этот говонокод умудрились соорудить даже под классической RTOS, то код - в помойку, автора кода - за кассу в "магнит" sm.gif
DASM
Да уж.. сколько чудных открытий sm.gif человек недавно паттерны открыл и берется судить о говнокоде. Ничего, склетон освоите, посетителя - про свой прошлый код также писать будете. А только все это фигня, сейчас функциональное программирование в моде. И снова все говнокодом покажется. Большая ошибка судить людей по паре постов, думая что они ничего не знают, а я такой плюсанутый и ртоснутый на всю голову. С возрастом пойдет
Forger
Цитата(DASM @ Nov 9 2017, 00:23) *
склетон освоите

Паттерна "склетон" не существует, но вангую, что речь шла про синглтон.
Опиской это не назовешь, поэтому очевидно вы даже не пользовались им ни разу ...
Короче, счет 3:0

К слову: по-началу, по неопытности я использовал синглтон слишком активно где надо и не надо ... но это было давным-давно и больше так не делаю ))

Цитата(DASM)
"С возрастом пройдет"

Суперлуп (или "карусельки") проходят у подавляющего большинства настоящих программеров (не ардуинщиков или куберов) еще в "ясельном" возрасте.
Но, судя по всему, еще попадаются редкие уникальные исключения....

Расслабьтесь, никто не собирается менять ваш образ мышления: "поздно пить боржоми ..." sm.gif

Цитата
Большая ошибка судить людей по паре постов, думая что они ничего не знают

Однако, ваших "пары постов" вполне для этого хватило - что не пост, то "пук в лужу" laughing.gif

Цитата
А только все это фигня, сейчас функциональное программирование в моде.

Да, что вы говорите?!
Ну, засуньте в обычный МК (не распберри) хотя бы что-то напоминающее эту "моду". Покажите пример...
ig_z
QUOTE (Forger @ Nov 8 2017, 22:41) *
С другой стороны, до сих пор вот мне очень интересно познавать новые фишки в мире эмбедед ПО, в частности, относительно недавно "изучал" .netmicro, недавно чуть "по-тискал" micro java (или как там она зовется) ....
Короче, удалил их к чертовой бабушке - рано еще, времена еще не пришли, нынешние МК пока еще слишком ватные для таких "вещей".

Кстати, в данный момент уперся в необходимость применения такой вещи (пишу под плюсами) - паттерн "фабрика объектов", а совсем недавно освоил паттерн "делегатов" .
Удивительно, но теперь они реально мне понадобились, хотя в свое время хихикал над другими: "гы-гы, плюсы, шаблоны, паттерны" ...

Держите нас в курсе, несдержанный вы наш. И ни в коем случае по теме ничего не говорите, потеряете реноме в каждой бочке затычка
Forger
Цитата(ig_z @ Nov 9 2017, 23:15) *
в каждой бочке затычка

Ну, да, а влезать в чужую беседу, особенно если сам в ней "не в зуб ногой" - это по-Вашему норм 01.gif

Цитата
И ни в коем случае по теме ничего не говорите

А у вас-то есть что добавить по теме - SST ("каруселька" и т. п.)? Или тоже можно "открывать счет"? biggrin.gif
syoma
Возвращаясь к оригинальной теме по поводу прерывания из прерывания.
У меня попроще задача и я не думал, что в ARM ее не так просто решить в лоб.

Грубо говоря допустим нужен примитивный Preemptive Scheduler, который бы запускал две функции Step_10ms() и Step_1s() с определенными интервалами 10мс и 1с соответственно. Step_10ms имеет высший приоритет, чем Step_1s(). Функции полностью независимые, железа и общей памяти не используют. Step_10ms() исполняется миллисекунды за 3, Step_1s() - за 100мс. То есть Step_10ms() должна прерывать исполнение Step_1s(), когда нужно.
Обе функции защищены от overrun - при запуске выставляют флаг, так что если функция вдруг вызовется опять во время своего исполнения - она это проконтролирует и система вылетит в ошибку.

Я, недолго думая, дописал в SysTick_handler (обработчик SysTick, который вызывается раз в 1мс) указанную конструкцию (псевдокод без намека на правильный синтаксис, приоритеты не расставлены)
Код
void SysTick_handler(void)
{
static uint16_t Timer_10ms = 9;
static uint16_t Timer_1s = 999;

if (Timer_10ms) Timer_10ms--;
   else
  {
   Timer_10ms = 9u;
   Step_10ms(); //Вызываем 10мс функцию
  }

if (Timer_1s) Timer_1s--;
   else
  {
   Timer_1s = 999u;
   Step_1s(); //Вызываем 1с функцию
  }
}


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

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

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

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

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

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

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

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

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

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

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

А вытесняющие прерывания называются иначе - nesting interrupts, т.е. вложенные прерывания (в некоторой литературе может встречаться другое название - preemptive).
Они подразумевают вытеснение одного обработчика прерываний ДРУГИМ обработчиком.
Если же прерывание от того же самого источника произойдет в то время, пока обрабатывается прерывание от этого же источника (скажем, байты по USART сыпятся быстрее, чем успеваем их обрабатывать),
то новое прерывание станет отложенным (pending) и вызовется сразу же после обработки текущего (если конечно никто более приоритетный его не прервет). Другими словами, встанет в очередь.
Это если объяснять грубо и на пальцах, на деле там полно своих нюансов.
Timmy
Цитата(syoma @ Nov 17 2017, 13:45) *
Каково же было мое удивление, когда оказалось, что ARM не поддерживает reentrant прерывания и выполнение Step_1s() полностью блокирует прерывание и Step_10ms() при этом не исполняется. Нашел в инете, что народ играется ассемблером и пытается восстанавливать стек и прочие вещи, чтобы процессор опять мог заходить в это же прерывание, но хотелось бы узнать - есть ли простое решение, без RTOS, так как кроме этой функции RTOS будет не нужна.

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

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

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

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

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

Видно что Вы со времён этого самого 8051 больше ничего другого не изучали.
Почитайте мануал на ARM-ядро и узнаете, что на нём всё что нужно легко реализуется.
А пока - рано вам ещё ISR-ы писать, не понимая как ядро работает.
syoma
Знающие люди подсказали такой вариант. У них работает:

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 будет самовложенной. Что скажете?
AlexandrY
Цитата(syoma @ Nov 17 2017, 20:04) *
Знающие люди подсказали такой вариант. У них работает:

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

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

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

Они запрещены перед вызовом rt_OneStep.
Прикреплять надо весь проект.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.