|
Прерывание в прерывании, Для реализации Super Simple Tasker |
|
|
|
 |
Ответов
(1 - 72)
|
Nov 7 2017, 13:02
|

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

|
Цитата(arhiv6 @ Nov 7 2017, 15:00)  один из вариантов реализации вытесняющей многозадачности для микроконтроллеров... Может быть я стал слишком старый и "отстал от поезда", поэтому на всякий случай спрошу: НАФИГА ??? Чем не годится готовая RTOS? В частности freeRTOS позволяет использовать вложенные прерывания без подобного "дрочева"....
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Nov 7 2017, 13:30
|

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

|
Цитата(arhiv6 @ Nov 7 2017, 16:17)  А ещё есть мелкие контроллеры, у которых мало свободных ресурсов. В мелких МК прекрасно влезает классическая готовая RTOS, особенно если использовать минимум ресурсов - семафоры и на край мьютексы. Использую RTOS даже в мелких ARM CM0. Я относительно недавно перешел на KEIL RTX, она занимает меньше места, чем freeRTOS да и сделана более что-ли классически - системные вызовы используют SVC, т.е. как это изначально и было задумано ARM. Впрочем, если больше нечем заняться, то поизучайте готовые порты под разные RTOS, посмотрите как там сделано низкоуровневое "сопряжение" с конкретным ядром.
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Nov 7 2017, 13:44
|

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

|
Цитата(arhiv6 @ Nov 7 2017, 16:00)  нужно как-то сообщить микроконтроллеру, что с прерыванием закончили работать но из функции-обработчика не выходить. Т.е. нужно разрешить вложенные прерывания (одни и те же). "Всё смешалось в доме Облонских" - прерывания для того и выдуманы, чтоб, быстро отреагировав, быстро выполнить требуемое и вернуться к "рутине". Цитата В статье в примере для ПК это делается так: используется команда End Of Interrupt (EOI) - outportb(0x20, 0x20). Обычно она выполняется непосредственно перед выходом из функции-обработчика прерывания, но в SST после EOI вызывается диспетчер, прямо в контексте прерывания. Т.е. вызвав EOI, но оставаясь в контексте прерывания, мы разрешаем вложенные прерывания. Как это можно сделать для ARM (Cortex)? Вот прям "дословно" как по ссылке - никак. Но у кортекса весьма изощрённый контроллер прерываний: вложенные (если приоритет не ниже текущего (базового)) там получаются нативно.
--------------------
Пролетарий умственного труда.
|
|
|
|
|
Nov 7 2017, 14:28
|
Гуру
     
Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493

|
Цитата(Forger @ Nov 7 2017, 16:30)  В мелких МК прекрасно влезает классическая готовая RTOS, особенно если использовать минимум ресурсов - семафоры и на край мьютексы. Использую RTOS даже в мелких ARM CM0. Я относительно недавно перешел на KEIL RTX, она занимает меньше места, чем freeRTOS да и сделана более что-ли классически - системные вызовы используют SVC, т.е. как это изначально и было задумано ARM.
Впрочем, если больше нечем заняться, то поизучайте готовые порты под разные RTOS, посмотрите как там сделано низкоуровневое "сопряжение" с конкретным ядром. Я отказался от FreeRTOS, 256 К памяти не хочу транжирить, SST "х расходы стековой памяти по сравнению с традиционными операционными системами сокращается на 80%." . Так что насчет "нечем заняться" не стоит огульно, SST прекрасно ложится на мелкие 1M/256K контроллеры, на средние (16G/1G) полноценный Линукс проще. Места классическим RTOS я лично не вижу
|
|
|
|
|
Nov 7 2017, 14:45
|

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

|
Цитата(DASM @ Nov 7 2017, 17:28)  Я отказался от FreeRTOS, 256 К памяти не хочу транжирить, SST "х расходы стековой памяти по сравнению с традиционными операционными системами сокращается на 80%." Какие-то дикости вы тут рассказываете Звучит как попытка экономии на соли при мариновке огурцов  Ядро RTOS занимает всего несколько кБ флэши, а объем занимаемого ОЗУ сильно зависит от кода: стек прерываний общий, большой не нужен, обычно хватает 0.2кБ, стеки задач - зависит от самих задач, у меня их стеки крайне редко превышают 0.5 кБ, обычно хватает 128....256 байтов. Съэкономить ОЗУ можно перейдя на кооперативную многозадачность. У меня МК по 16...32к флэши (озу 4..6 кб) и при этом там прекрасно живут несколько объемных задач и делают некислый функционал. А уж что говорить про "толстые" МК с 256 кб, там вообще нет никакого смысла экономить на спичках - суём RTOS с самым серьезным функционалом (например, моя любимая трассировка под Segger SystemView). По-моему вы сильно заморачиваетесь на пустом месте ))) Цитата SST прекрасно ложится на мелкие 1M/256K контроллеры Голый ассемблер тоже прекрасно ложится на любой МК, но что-то желающих сидеть на голом асм все меньше и меньше... Нужда в RTOS пропадает в реально примитивных проектах, но таких уже и не осталось, не те времена нынче )) Цитата Места классическим RTOS я лично не вижу Вот это-то и вызывает у меня некоторое недоумение! И потому прихожу лишь к одному выводу - вы вообще не использовали RTOS. Искренне советую исправить это недочет
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Nov 7 2017, 14:53
|
Гуру
     
Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493

|
"прихожу лишь к одному выводу " - приходите ", обычно хватает 128....256 байтов"- просто у вас " в реально примитивных проектах" Вы лучше скажите, каким образом вы доказываете, что данная задача никогда не превысит отведенный стек, при условии, что если такое возникнет - аппарат под контролем процессора с вашим замечательным ртос со стеком задачи 128 байт отрежет например рабочему руку. " "толстые" МК с 256 кб" вы серьезно считаете, что это толсто? Это копейки с нынешними стеками и протоколами, стек BLE один сожрет 300 кб флеша, порядка 100 к ОЗУ, а к нему еще Thread прикуртить надо, оный тоже 250 кбайт и ОЗУ немерянно. Очень интересно глянуть вашу "сурьезную задачу" с 128 байт ОЗУ
|
|
|
|
|
Nov 7 2017, 15:00
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(arhiv6 @ Nov 7 2017, 15:17)  Как минимум, это интересно - попробовать разные подходы к построению ПО. А ещё есть мелкие контроллеры, у которых мало свободных ресурсов. Вот на них особенно интересно попробовать SST - тут при наличии вытесняющей многозадачности очень эффективное использование памяти. Сначала освойте хотя-бы одно ядро, а потом сразу поймёте где это возможно (и как), а где (нет и почему). И какие есть лучшие решения. PS: При задавании подобных вопросов, очень уместно указывать ядро о котором спрашивается. Ибо реализация очень сильно зависит от этого самого ядра.
|
|
|
|
|
Nov 7 2017, 15:18
|

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

|
Цитата(DASM @ Nov 7 2017, 17:53)  "прихожу лишь к одному выводу " - приходите ", обычно хватает 128....256 байтов"- просто у вас " в реально примитивных проектах" Я не кладу в стек гигантские структуры, а стараюсь их использовать статически. Динамическую память не использую. Там, где это нужно, память выделяю пулами (фиксированными кусками). Цитата Вы лучше скажите, каким образом вы доказываете, что данная задача никогда не превысит отведенный стек, Это делается средствами RTOS, разумеется, соотв. аварийные ситуации обрабатываются. Перед запуском проекта, он долгое время отрабатывается под systemview, где видно, кто и сколько чего кушает. Это позволяет подстроить стеки более тонко (если нужно). Используются ГОТОВЫЕ решения. Это работает и переполнения стека отлично отлавливаются (при тестировании это проверяю - занижаю размеры стеков и контролирую работу кода в таких условиях). Цитата " "толстые" МК с 256 кб" вы серьезно считаете, что это толсто? Для любой примитивной RTOS (та же freeRTOS -одна из них) эти ТТХ контроллера вполне толстые. Речь об этом. Цитата Это копейки с нынешними стеками и протоколами, стек BLE один сожрет 300 кб флеша, порядка 100 к ОЗУ, а к нему еще Thread прикуртить надо, оный тоже 250 кбайт и ОЗУ немерянно. Речь не про это, речь про совсем про другое - гипотетическую экономию на абсолютно ровном месте. В конце-концов, существует cmsisOS, даже cmsisOS-II, стандарт. Но нет же, ведь всегда найдутся энтузиасты, которым нужно "изобрести велосипед с квадратными колесами" и пытаться на нем ехать, делая вид, что это нормально Цитата Очень интересно глянуть вашу "сурьезную задачу" с 128 байт ОЗУ Мы сейчас говорим про проекты для бытовых МК, а не толстых CPU с мб флэши и озу. Второй случай требует RTOS другого класса, скорее всего платной RTOS. Здесь же речь про простые вещи, где экономия на спичках выглядит очень и очень странно - вместо простой готовой RTOS колхозить некий самодельный костыльный SST ... Вот мне лично совсем не ясна реальная мотивация подобной задумки.... Пытаюсь разобраться, может быть что-то упускаю )))
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Nov 7 2017, 15:29
|
Гуру
     
Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493

|
Цитата(jcxz @ Nov 7 2017, 18:11)  А в чём разница между стеком задачи под ОС и стеком той же самой задачи без ОС? У Вас, что ОС сама ваш код компилирует? Или может даже пишет?  Тем, что без ОС такой - стек общий, и памяти не хватит тогда, когда ее не хватит вообще. А с потоками вытесняющими - это как коробка конфет , места много займет, а конфет мало, в отличии от единого стека. Второй пример фрагментации памяти с malloc - памяти до хрена, а получаем NULL - ибо впихнуть нужный кусок некуда. Я надеюсь вы уже решили эту проблему сборщиками мусора на микроконтроллерах?  Короче не стоит далее спорить, все останутся при своих это очевидно. Меня недетерминированность поведения таких РТОС во многих задачах не устраивает, расход памяти тоже "другого класса, скорее всего платной RTOS. " - то есть все бесплатное - это дерьмо по умолчанию? Странная мысль.
|
|
|
|
|
Nov 7 2017, 15:38
|

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

|
Цитата(DASM @ Nov 7 2017, 18:11)  Эти РТОС замечательны для обучения студентов имхо, только вот в реальной аппаратуре, с более ответсвенными целями чем очередной вебсервер - очень неуверен. По-вашему выходит, что ручная ножовка по дереву годится только для обучения и пару тонких дощечек для полочки под цветы всякий нужно раз пилить мощной бензопилой .... Хм, необычный подход, кардинальный :D Каждая задача требует своего инструмента. А всякая попытка недооценивать и хаять готовые инструменты выставляет их автора в не самом лучшем свете ... по крайней мере перед теми, кто успешно использует эти инструменты  Точно так же очень странно выглядит попытка пилить вековую сосну лобзиком под фанеру .... Цитата(DASM @ Nov 7 2017, 18:29)  Тем, что без ОС такой - стек общий, и памяти не хватит тогда, когда ее не хватит вообще. А с потоками вытесняющими - это как коробка конфет , места много займет, а конфет мало, в отличии от единого стека. Видать, первые попытки применения RTOS в лоб оказались для вас негативными... Однако, остальным почему-то повезло больше  Может быть дело не в "инструменте" вовсе, а в "слесаре", который пытался его использовать не очень удачно  Цитата Второй пример фрагментации памяти с malloc - памяти до хрена, а получаем NULL - ибо впихнуть нужный кусок некуда. Сходу на тракторе да в соседский забор ... с дин. памятью в МК нужно быть аккуратнее. Это во всех книжках написано )) Цитата Я надеюсь вы уже решили эту проблему сборщиками мусора на микроконтроллерах?  Удивитесь, но да - проблема решена: не использовать дин. память в каждой дырке, или вообще не использовать. Это не так сложно, как кажется )) Цитата Меня недетерминированность поведения таких РТОС во многих задачах не устраивает Все верно! Криво спроектированный код именно так себя и ведет А RTOS тут совсем ни при чем ))
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Nov 7 2017, 15:39
|
Гуру
     
Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493

|
Да никто не хает, каждый до..ит как хочет. Просто Вы так огульно говорите вопрошавшему "занять вам нечем" что именно это и вам выставляет в таком свете. Ваши РТОС далеко не панацея. Мало того, если мы посмотрим профессиональные проекты, нет статистики, но навскидку 70-80 процентов используют либо суперлюп, либо свой простенький кооператив. Нужели мозгов им не хватило? Не думаю. Можем дальше спорить , но зачем? Вот например С - зачем на нем писать, у нас же аж 256 кбайт памяти! Язык устарел, примитивен, от асма ушел недалеко . Ну и так далее. Просто не стоит, изучив и используя что-то одно говорить, что сие есть истина, а остальным нечем заняться " Криво спроектированный именно так себя и ведет. RTOS тут ни при чем ))))" ртос тут вообщем непричем, давайте MMU, нет памяти - page fault - выделяем, едем дальше. А без MMU - "если заняться нечем" (с)
|
|
|
|
|
Nov 7 2017, 15:46
|

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

|
Цитата(DASM @ Nov 7 2017, 18:39)  Ваши РТОС далеко не панацея... если мы посмотрим профессиональные проекты, нет статистики ... Ну, хорошо, хорошо, слив защитан  Проехали )) Цитата Просто не стоит, изучив и используя что-то одно говорить, что сие есть истина, а остальным нечем заняться Мне стало интересно, что такого вносит этот SST по сравнению с готовыми решениями, в частности с RTOS. Оказалось, что он приносит лишь головную боль, причем, на ровном месте: без нужды усложняет структуру кода, от суперлупа со всеми его костылями в целом ничем не отличается. (С) "Те же яйца, только в профиль." Вот и пытаюсь увидеть мотивацию ... пока не увидел... Любопытно все же, что заставляет народ изобретать велосипеды с квадратными колесами
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Nov 7 2017, 15:58
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(DASM @ Nov 7 2017, 17:29)  Тем, что без ОС такой - стек общий, и памяти не хватит тогда, когда ее не хватит вообще. А с потоками вытесняющими - это как коробка конфет , "Без ОС" - это значит всё в одной задаче. Если вы, не меняя алгоритма, перенесёте эту задачу в одну из задач (потоков) РТОС, что что изменится с потреблением стека? Ничего! Так в чём разница??? Далее - конечно под РТОС вы потом можете эту же задачу реализовать в виде многих потоков РТОС. Это разве будет тем же самым алгоритмом? Нет конечно, это новая реализация, совершенно по другому написанная. И да, если писать не включая голову, можно сколько угодно памяти израсходовать. Так в чём преимущество "без РТОС" по-вашему, в том что в таком случае заведомо меньше возможностей и криворукий программист сделает меньше багов? Не уверен что это преимущество.... Цитата(DASM @ Nov 7 2017, 17:29)  места много займет, а конфет мало, в отличии от единого стека. Так если задачу можно реализовать в виде одного потока ОС, то зачем его делить на несколько? Или всё-таки нельзя (или будет заведомо худшее решение), то очевидно тогда что с РТОС - лучше? Разве не? Цитата(DASM @ Nov 7 2017, 17:29)  Второй пример фрагментации памяти с malloc "Смешались в кучу люди кони"... динамическая память-то тут причём??? Разговор про стеки вроде шёл. Нафига стеки в дин. память пихать??? Да ещё выделять/освобождать периодически. Какие-то нереальные примеры выдумываете.... PS: За последние ~15 лет в отрасли и десятках реализованных проектов, я ни разу ещё не использовал malloc() в embedded-проектах. Что делаю не так?
|
|
|
|
|
Nov 7 2017, 15:59
|

Знающий
   
Группа: Свой
Сообщений: 633
Регистрация: 21-05-10
Из: Томск
Пользователь №: 57 423

|
Цитата(AHTOXA @ Nov 7 2017, 21:17)  Здесь была тема про SST. Посмотрите там, может, там есть ответ. Да, тоже вспомнил про эту тему, перечитываю. Но, насколько я помню, копкретной реализации переключения контекстов для SST там нет. Цитата(DASM @ Nov 7 2017, 21:28)  Я отказался от FreeRTOS, 256 К памяти не хочу транжирить, SST "х расходы стековой памяти по сравнению с традиционными операционными системами сокращается на 80%." . Так что насчет "нечем заняться" не стоит огульно, SST прекрасно ложится на мелкие 1M/256K контроллеры, на средние (16G/1G) полноценный Линукс проще. Места классическим RTOS я лично не вижу О, Вы на практике используете SST? А под какие процессоры? Цитата(jcxz @ Nov 7 2017, 22:00)  PS: При задавании подобных вопросов, очень уместно указывать ядро о котором спрашивается. Ибо реализация очень сильно зависит от этого самого ядра. Как указано в первом посте - ARM, Cortex. Пусть будет STM32F030 (Cortex-M0). Цитата(scifi @ Nov 7 2017, 22:04)  Гугл вводит на гитхаб. Возможно, всё украдено до нас? Видел. Но насколько я понял, там использую один обработчик прерывания PendSV (без его вложенного вызова), и можно реализовать всего 2 уровня приоритетов - idle в основном цикле в main + все остальные задачи в контексте PendSV_Handler. Они будут выполняться синхронно, в порядке приоритетов. А в SST из статьи более приоритетные задачи могут асинхронно прерывать менее приоритетные. Пожалуйста, не нужно писать про FreeRTOS и KEIL RTX. Это отличные системы, с первой работал (и работаю), но в этом топике речь идёт о реализации SST.
--------------------
|
|
|
|
|
Nov 7 2017, 16:11
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(DASM @ Nov 7 2017, 17:39)  но навскидку 70-80 процентов используют либо суперлюп 90% железных "программистов" используют ардуйню. Предлагаете на них равняться и бросать наши кортексы/DSP? Цитата(Forger @ Nov 7 2017, 17:46)  Мне стало интересно, что такого вносит этот SST по сравнению с готовыми решениями, в частности с RTOS. Когда автор наконец-то реализует свой SST (если конечно реализует  , он с удивлением обнаружит, что у него получился шедулер обычной РТОС. Поэтому и совет ему: сразу идти и посмотреть как это сделано в какой-нить РТОС. Чтобы попусту время не терять. Цитата(arhiv6 @ Nov 7 2017, 17:59)  Да, тоже вспомнил про эту тему, перечитываю. Но, насколько я помню, копкретной реализации переключения контекстов для SST там нет. Возьмите порт под нужное ядро любой РТОС и посмотрите на "конкретную реализацию". Цитата(arhiv6 @ Nov 7 2017, 17:59)  Как указано в первом посте - ARM, Cortex. Пусть будет STM32F030 (Cortex-M0). Ну наконец-то! Cortex-M всё-таки. На первой странице указано "ARM, Cortex". И всё. А среди них есть как Cortex-M, так и Cortex-A. И др. И да будет Вам известно, что система прерываний у них устроена совершенно по разному.
|
|
|
|
|
Nov 7 2017, 16:16
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(arhiv6 @ Nov 7 2017, 17:59)  Пожалуйста, не нужно писать про FreeRTOS и KEIL RTX. Это отличные системы, с первой работал (и работаю)... Не верю! Если бы Вы реально с ней работали, то знали бы как в ней переключается контекст. И не спрашивали бы. И другого, лучшего метода переключения Вам не придумать. Ибо используется именно тот метод, который был заложен специально для РТОС при проектировании ядра. Цитата(Forger @ Nov 7 2017, 18:13)  Похоже, это - совсем не тот случай  Человек пишет, что работает с системой, но не знает как она работает. Это то же самое, если-б водитель самосвала написал, что он работает на самосвале, но не знает от чего у него колёса крутятся. "Вот залазю туда и колёса начинают крутиться, кто его знает от чего они крутятся. Наверное потому что круглые"
|
|
|
|
|
Nov 7 2017, 17:28
|

Знающий
   
Группа: Свой
Сообщений: 633
Регистрация: 21-05-10
Из: Томск
Пользователь №: 57 423

|
Смотрел я исходники ОС, но они все по похожему принципу сделаны - переключение между разными стеками. Вот например: для каждого потока выделен свой стек. Для переключения между двумя контекстами вызывается прерывание PendSV (при этом на стек складываются R0-R3) и в PendSV_Handler сохраняются оставшиеся регистры (R4-R11), потом вызывается функция os_context_switch_hook, которая возвращает указатель на стек другой задачи. С этого стека восстанавливаем (R11-R4) , переписываем LR и выходим из PendSV_Handler, при этом восстанавливаются (R3-R0). Всё, мы переключились на другую задачу/другой стек. А можете примерно так-же объяснить, что мне сделать для пререключения задач по методике SST? Выполняем мы задачу А. Так же через вызов прерывания PendSV хотим запустить более приоритетную задачу (запустить функцию). Попали в PendSV_Handler, сохранили (R4-R11) на текущем стеке. Всё, контекст задачи A сохранён. Как теперь правильно запустить задачу В? Сделать просто вызов LDR R1, =taskB, BLX R1 нельзя - функция будет выполняться в контексте прерывания. Как правильно сделать? Из прерывания если выйдем ( BX LR) мы попадём обратно в задачу А. Как мне выйти из прерывания и при этом запустить функцию taskB?
--------------------
|
|
|
|
|
Nov 7 2017, 17:56
|

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

|
Цитата(jcxz @ Nov 7 2017, 19:16)  Наверное потому что круглые"  Не тот случай - тут колеса НЕкруглые, сделаны Цитата по методике SST
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Nov 7 2017, 18:27
|

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

|
Цитата(arhiv6 @ Nov 7 2017, 20:28)  Как правильно сделать? Как бы вы не старались, по методике SST правильно не будет никак, поскольку ядро ARM (в частности контроллер прерываний) разрабатывался изначально под классические принципы работы RTOS. Очевидно, что для этого были веские основания. Если вам принципиально нужно "по методике SST", то придется городить адские костыли с полной потерей всех прелестей вложенного приоритетного контроллера прерываний. Отлаживать такой говнокод - еще тот мартышкин труд. Мало того, что полностью теряется полезнейшая функция sleep/delay, так еще и "задачи" теряют свой привычный очень многим смысл. Невозможно будет применить чужой код без его тотальной переделки. Зачастую будет написать его заново. Мифическая экономия ОЗУ и флэши (я бы сказал копеешная экономия) превратиться в неоправданные траты памяти там, где в этом не было нужды под обычной RTOS. Особенно сочувствую тем, кому придется работать с вашим кодом ... Вангую, что такой код будет напрочь переписан под привычную и понятную всем схему, где задачи выполняются в фоне задач, а прерывания - в фоне прерываний.... Впрочем, если вы по-прежнему упорно настроены на SST (задачи работают в фоне прерываний), то придется поломать голову и сделать свое решение самостоятельно, тогда только в этом случае вы поймете тупиковость этой затеи, как минимум на ARM процах. Для убедительности моих слов разместите тут код простейшей задачи моргания светодиода с различной скважностью в бесконечном цикле "по методике SST". Время включенного и выключенного состояния - параметры изменяемые и кратны 1мс. Разумеется, процессорное время должно тратиться лишь на включение и выключение светодиода, но не на задержки. Вот так эта задачка выглядит на привычной OS (все времена в мс): Код while(true) { led.on(); sleep(onTime); led.off(); sleep(offTime); } Как это будет выглядеть под мифической SST?
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Nov 7 2017, 18:50
|
Гуру
     
Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493

|
Меня устраивает карусель кооперативная на таймерах, не столь удобно писать код, но мне его поведение выглядит более понятным. Это скорее "железный" стиль, а не программисткий. Да и задач у меня нет промежуточных почти, либо простые, где достаточно прерываний и таймеров с флагами, либо на Линукс всякие видеокамеры. Мутить что то достаточно сложное на малых ресурсах не доводилось. Круто конечно сервер на коппечном проце замутить, только интерес это академический, никому это не надо. Железо стоит копейки, тот же расперри за 10 баксов имеет полноценный линукс, зачем жать доллар в российской реальности, где тиражи малы, конкурентоспособность определяется родственными связями начальникам и величиной откатов заказчику, в время разработки важнее этого несчастного доллара Цитата void LedTaskOn (void *pparam) { SetTimer (LedTaskOff, onTime); led.on(); } void LedTaskOff (void *pparam) { SetTimer (LedTaskOn, offTime); led.off(); } Можно и одной функцией Стек не жрет, дискретность микросекнды, никаких проблем с разделением ресурсов - все работают из прерываний. Недостаток - функция такого потока реализуется как машина состояний, что вобщем то не напрягает Все эти Цитата led.on(); sleep(onTime); led.off(); sleep(offTime); хороши как заманилово студентам как все красиво и прекрасно. В реальной задаче все увы не совсем так, обрастает критическими секциями, мьютексам итп. Где-то удобно, а где-то - не нужно. Мне - не нужно пока что точно
|
|
|
|
|
Nov 7 2017, 19:00
|

Знающий
   
Группа: Свой
Сообщений: 633
Регистрация: 21-05-10
Из: Томск
Пользователь №: 57 423

|
Цитата(Forger @ Nov 8 2017, 01:27)  Как бы вы не старались, по методике SST правильно не будет никак, поскольку ядро ARM (в частности контроллер прерываний) разрабатывался изначально под классические принципы работы RTOS. Да,похоже всё так. Цитата(Forger @ Nov 8 2017, 01:27)  Для убедительности моих слов разместите тут код простейшей задачи моргания светодиода с различной скважностью в бесконечном цикле "по методике SST". Время включенного и выключенного состояния - параметры изменяемые и кратны 1мс. Разумеется, процессорное время должно тратиться лишь на включение и выключение светодиода, но не на задержки. Вот так эта задачка выглядит на привычной OS (все времена в мс): ... Как это будет выглядеть под мифической SST? Не знаю, я же ещё толком и не работал с SST. Первое, что приходит в голову так: Код void task_ledBlinker_on() { led.on(); setTask(task_ledBlinker_off, onTime, 0); }
void task_ledBlinker_on() { led.off(); setTask(task_ledBlinker_on, offTime, 0); } или так: Код task_ledBlinker() { led.toggle();
if (led.state()) setTask(task_ledBlinker, onTime, 0); else setTask(task_ledBlinker, offTime, 0); }
--------------------
|
|
|
|
|
Nov 7 2017, 19:01
|

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

|
Цитата(DASM @ Nov 7 2017, 21:50)  void LedTaskOn (void *pparam) { SetTimer (LedTaskOff, onTime); led.on(); } void LedTaskOff (void *pparam) { SetTimer (LedTaskOn, offTime); led.off(); } Очень печальное зрелище - простейший пример усложнил читаемость и очевидность кода на порядки. Также вырос размер кода во флэш. Уж боюсь предположить, во что превратить более объемный код после переписывания его под SST. Короче, прихожу к очевидному выводу: SST - это для потомственных мазахистов.... Я пас
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Nov 7 2017, 19:05
|
Гуру
     
Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493

|
Первое, что приходит в голову так:  о как, у меня также, только я не знал что это SST называется. Просто каруселька и все "простейший пример усложнил читаемость и очевидность кода на порядки. Также вырос размер кода во флэш.", а насколько вырос ваш пример в ОЗУ? И можно плиз зажечь диод через 13.65845 мс ровно? И не надо про отладка на порядок сложнее, многопоточные приложения всегда отлаживать сложнее. К тому же ваш пример содержит ошибку, вы шину GPIO не захватили, а по ней сейчас другой поток занят важным делом - писк на зумер выводит. А потом жалуются, почему динамик хрипит на 1 кГц  Добавьте плиз SemaphoreGet. SemaphorePost с кодом иниициализации семафора. А то как-то нечестно.
|
|
|
|
|
Nov 7 2017, 19:21
|

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

|
Цитата(DASM @ Nov 7 2017, 22:05)  Первое, что приходит в голову так:  о как, у меня также, только я не знал что это SST называется. Просто каруселька и все "простейший пример усложнил читаемость и очевидность кода на порядки. Также вырос размер кода во флэш.", а насколько вырос ваш пример в ОЗУ? И можно плиз зажечь диод через 13.65845 мс ровно?Можно, но в данном случае - в этом нет нужды. Это - главное отличие RTOS от самодельных "каруселек" - не делать то, что не нужно делать. Цитата И не надо про отладка на порядок сложнее, многопоточные приложения всегда отлаживать сложнее. Нет, все в точности наоборот. Именно поэтому везде, где возможно, ставлю RTOS. Это сильно упрощает код и делает его легко переносимым из одного проекта в другой. Цитата К тому же ваш пример содержит ошибку, вы шину GPIO не захватили, Во-первых, чтобы зажечь светодиод, не нужно как выговорите "захватывать шину GPIO". Читайте матчасть по ARM Cortex. Не позорьтесь )) Во-вторых, тут не указана реализация методов класса led - on и off. Да и не имеет это отношения к делу. Цитата а по ней сейчас другой поток занят важным делом - писк на зумер выводит. Читайте матчасть. Цитата А потом жалуются, почему динамик хрипит на 1 кГц  Хрипит он скорее всего по другой причине - меандр сделан средствами RTOS, без использования аппаратных таймеров. Бывшие ардуинщики именно так и делают. Правильно будет - реализовывать разные задачи разными инструменты, а не городить все одним. Цитата Добавьте плиз SemaphoreGet. SemaphorePost с кодом иниициализации семафора. А то как-то нечестно. Вот: Код // создаем семафор OS::Semaphore semaphore;
// гипотетическая задача: while(true) { semaphore.waitForever(); // что-нить делаем }
// обработчик прерываний или другая задача { semaphore.signal(); } Для примера, ожидание семафора бесконечное, но есть другие методы у этого класса OS::Semaphore, в частности позволяющие ждать его не более указанного времени. Ваша очередь ... Цитата(DASM @ Nov 7 2017, 22:08)  давненько тут гастролеров с хабра не было Такая реакция говорит о том, что "про песочницу" я попал в самую точку  Кстати, кто такие "гастролеры" с некого "хабра"?
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Nov 7 2017, 19:36
|

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

|
Цитата(DASM @ Nov 7 2017, 22:29)  @ Читайте матчасть по ARM Cortex.@ Ладно, спорить тут не о чем. ОК, слив опять защитан. Счет 2:0  Для тех, кто не в теме: в ARM Cortex есть такой механизм - BitBanging (вроде правильно написал). Он позволяет упростить работу с обращениями типа чтение-модификация-запись. В частности, изменение состояния пинов не требует создания критических секций и т. п, как это было необходимо в более архаичных ARM. Цитата В молодости я тоже был такой горячий и восторженный. В молодости я тоже страдал всякой херней наподобие SST ("каруселек") и т. п. подобной дребедени лишь чисто ради "академического" интереса (в ту пору на Microchip процах). Кстати, на Microchip только так и можно было использовать RTOS - кооперативная с вагоном соотв. костылей. Но это было давно и осталось в далеком прошлом (к счастью)... Но времена меняются, и, чтобы не отстать от поезда, нужно осваивать новые решения.
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Nov 7 2017, 20:41
|

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

|
Цитата(Forger @ Nov 7 2017, 21:36)  Для тех, кто не в теме: в ARM Cortex есть такой механизм - BitBanging (вроде правильно написал). Да чего сейчас только нету в этих ARM-ах. В последнее время у меня светодиоды RGB и управляются строго по DMA. Никаких обращений в порты. Пишу шаблон работы типа микроскрипта, гружу в автомат, а тот расчитанные RGB коды пишет просто в память, никаких портов. Код const uint32_t RGB_ptrn_Green_blink[6] = {VAL_LEV(0), 250, HSV_GREEN+SAT_LEV(100)+VAL_LEV(50), 50, B_JMP, (uint32_t)&RGB_ptrn_Green_blink[0] };
Set_RGB_led_ptrn((uint32_t *)RGB_ptrn_Green_blink); Мигает, плавно меняет цвет, интенсивность, цветность. Все что хочешь. Само собой автомат сделан в отдельной задаче RTOS.
|
|
|
|
|
Nov 7 2017, 21:33
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(arhiv6 @ Nov 7 2017, 19:28)  Смотрел я исходники ОС, но они все по похожему принципу сделаны - переключение между разными стеками. ... Да, примерно так и есть. Цитата(arhiv6 @ Nov 7 2017, 19:28)  А можете примерно так-же объяснить, что мне сделать для пререключения задач по методике SST? Выполняем мы задачу А. Так же через вызов прерывания PendSV хотим запустить более приоритетную задачу (запустить функцию). Попали в PendSV_Handler, сохранили (R4-R11) на текущем стеке. "На текущем" - это на каком? На стеке обработчиков прерываний что-ль? Вы имеете представление, что в ядре Cortex-M есть два стека (аппаратных) - MSP/PSP? И зачем так сделано? Цитата(arhiv6 @ Nov 7 2017, 19:28)  Всё, контекст задачи A сохранён. Как теперь правильно запустить задачу В? Сделать просто вызов LDR R1, =taskB, BLX R1 нельзя - функция будет выполняться в контексте прерывания. Как правильно сделать? Из прерывания если выйдем ( BX LR) мы попадём обратно в задачу А. Как мне выйти из прерывания и при этом запустить функцию taskB? Так Вы же читали как это делают переключатели задач РТОС - сделайте точно так же. Сохраните все регистры на стеке прерванной задачи, также в сегмент данных прерванной задачи сохраните её SP, загрузите SP новой задачи в PSP, восстановите со стека новой задачи ту часть регистров, которая программно сохраняется (R4-R11) и всё - можете выходить из прерывания в контекст уже новой задачи (так как на её стеке сейчас остались регистры, аппаратно сохраняемые при входе в ISR). Естественно - перед первым запуском каждой задачи, её стек нужно проинициализировать корректными значениями регистров расположенных именно в том порядке, в котором они сохраняются/восстанавливаются при входе и внутри PendSV. Если нужно возбуждать переключение задач из ISR аппаратного прерывания, то естественно в ядре Cortex-M для этого нужно программно возбудить PendSV, выйти из аппаратного ISR и уже в ISR PendSV переключить контекст. Именно такой метод и был задуман проектировщиками ядра. Чтобы такой механизм работал, необходимо чтобы приоритет PendSV был ниже приоритета любого аппаратного прерывания. И вот когда вы всё это проделаете, то получите стандартную РТОС для Cortex-M  Именно поэтому вам и пишут, что смысла изобретать свой лисапед нет никакого. Разве что в целях собственного ликбеза. Остаться внутри ISR аппаратного прерывания каким-то образом не выходя из него, а что-то там замутив со стеком - невозможно без нарушения работы всей системы прерываний - пока не выйдете из этого ISR это прерывание больше не вызовется (и менее приоритетные тоже). Так что такой способ, который Вы описали в первом сообщении, на Cortex-M - нереализуем. PS: И прежде, чем что-то подобное делать - настоятельно рекомендую изучить мануал на ядро. Особенно в части касаемой режимов процессора, входов и выходов в ISR.
|
|
|
|
|
Nov 7 2017, 21:46
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(DASM @ Nov 7 2017, 21:05)  вы шину GPIO не захватили, а по ней сейчас другой поток занят важным делом - писк на зумер выводит. А зачем её захватывать? Как почту/телефон/телеграф /интернет? (сегодняшняя дата навеяла  Во всех МК на Cortex-M с которыми мне приходилось иметь дело, периферия GPIO имеет средства для атомарной модификации отдельных битов порта (ну или хотя-бы находится в области bit-band). Можете пиликать вашим динамиком сколько угодно. После того как ознакомитесь с мануалом на периферию своего МК. Цитата(DASM @ Nov 7 2017, 21:05)  Первое, что приходит в голову так:sm.gif о как, у меня также, только я не знал что это SST называется. Просто каруселька и все У Вас на вашей карусельке в любимом суперцикле, пока процессор сидит в очередной паузе (для ногодрочества динамиком), никакая полезная работа не выполняется. А в случае с РТОС на время такой паузы, время CPU будет передано другой менее приоритетной задаче, которая в нём сейчас нуждается, либо процессор будет выполнять WFI/WFE экономя миллиамперы. А у вас просто будет всё тупо висеть и впустую жрать миллиамперы. Вот в этом как раз и есть главное преимущество РТОС с её задачами/потоками от суперцикла. И с современными объёмами ОЗУ в МК, как правило не составляет труда выделить каждой задаче необходимое кол-во стека. Ну если руки конечно не совсем из неподходящего места растут, то памяти это много не займёт.
|
|
|
|
|
Nov 7 2017, 22:35
|
Гуру
     
Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493

|
Ну не знаю, у меня на Ардуино все проще, а на малинке тем более, на питоне.  А у вас сложно как то, dma какие то, А как это "зачем захватывать". Под gpio драйвер надо, может gpio в Калифорнии висят и управляются какими нибудь post запросами. А вот тут вроде проще https://developer.microsoft.com/en-us/windo...les/helloblinky но я не уверен, что win10 iot влезет в процессор без mmu. О, кстати идея, сейчас залью винду эту на малину, интересно какая частота в цикле мигания получится
|
|
|
|
|
Nov 8 2017, 06:13
|

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

|
Цитата(DASM @ Nov 7 2017, 23:01)  А где тут DMA и что и куда оно грузит? О, это длинная запутанная история - https://geektimes.ru/post/284248/Цитата(DASM @ Nov 8 2017, 00:35)  Ну не знаю, у меня на Ардуино все проще, а на малинке тем более, на питоне.  Эт как гнаться за семью зайцами. Нет, хардварная платформа должна быть своя. Тогда из нее можно выжать максимум: и прерывания в прерываниях, и SST, и RTOS, и всё вместе.
|
|
|
|
|
Nov 8 2017, 16:41
|
Местный
  
Группа: Участник
Сообщений: 317
Регистрация: 16-09-17
Пользователь №: 99 334

|
Цитата(Forger @ Nov 7 2017, 16:02)  Цитата(arhiv6 @ Nov 7 2017, 15:00)  Super Simple Tasker - один из вариантов реализации вытесняющей многозадачности для микроконтроллеров. Может быть я стал слишком старый и "отстал от поезда", поэтому на всякий случай спрошу: НАФИГА ??? Чем не годится готовая RTOS? В частности freeRTOS позволяет использовать вложенные прерывания без подобного "дрочева"....  Сейчас каждый джуниор считает своим долгом написать свою RTOS При этом НИХРЕНА в этом не понимая. И при этом считает, что его RTOS - это какое-то откровение в мире RTOS. Кто из нас по молодости не писал свою RTOS, и кто из нас в старости не осознал, что маялся дурью и тратил время на всякую не нужную ерунду  Я сейчас вспоминаю сколько времени я на это угрохал. Лучше б тёлок молодых порол. Тогда они мне ещё теоретически могли "дать". Не то что сейчас Цитата(arhiv6 @ Nov 7 2017, 16:17)  Как минимум, это интересно - попробовать разные подходы к построению ПО. Вот вот. О чём я и сказал
Сообщение отредактировал Студент заборстроительного - Nov 8 2017, 16:38
|
|
|
|
|
Nov 8 2017, 20:41
|

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

|
Цитата(Студент заборстроительного @ Nov 8 2017, 19:41)  Я сейчас вспоминаю сколько времени я на это угрохал. Лучше б тёлок молодых порол. Аналогичная ситуация! Но только мне удалось наваять свою простейшую ось относительно быстро, после "наиграться" с ней и в итоге поставил готовую чужую и больше этот вопрос не поднимал. С другой стороны, до сих пор вот мне очень интересно познавать новые фишки в мире эмбедед ПО, в частности, относительно недавно "изучал" .netmicro, недавно чуть "по-тискал" micro java (или как там она зовется) .... Короче, удалил их к чертовой бабушке - рано еще, времена еще не пришли, нынешние МК пока еще слишком ватные для таких "вещей". Кстати, в данный момент уперся в необходимость применения такой вещи (пишу под плюсами) - паттерн "фабрика объектов", а совсем недавно освоил паттерн "делегатов" . Удивительно, но теперь они реально мне понадобились, хотя в свое время хихикал над другими: "гы-гы, плюсы, шаблоны, паттерны" ... Но, ребяты, изобретать самодельный колхозный шедулер = городить "велосипед с квадратными колесами" "из говна и палок" - это уже, прям, лютая дикость
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Nov 8 2017, 20:54
|

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

|
Цитата(jcxz @ Nov 8 2017, 23:49)  может есть, а может и нет. Суть от этого не меняется - лаконичный код под классической RTOS после переписывания под SST превращается в банальный говнокод (см. посты #31 и #33). Отсюда мораль: если вы видите перед собой говнокод, то смотрите на тип шедулера. Если стоит SST, "карусельку" или "супер-мега-гипер-луп", то шансы для этого кода все еще есть ... Если этот говонокод умудрились соорудить даже под классической RTOS, то код - в помойку, автора кода - за кассу в "магнит"
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Nov 8 2017, 23:29
|

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

|
Цитата(DASM @ Nov 9 2017, 00:23)  склетон освоите Паттерна "склетон" не существует, но вангую, что речь шла про синглтон. Опиской это не назовешь, поэтому очевидно вы даже не пользовались им ни разу ... Короче, счет 3:0К слову: по-началу, по неопытности я использовал синглтон слишком активно где надо и не надо ... но это было давным-давно и больше так не делаю )) Цитата(DASM) "С возрастом пройдет" Суперлуп (или "карусельки") проходят у подавляющего большинства настоящих программеров (не ардуинщиков или куберов) еще в "ясельном" возрасте. Но, судя по всему, еще попадаются редкие уникальные исключения.... Расслабьтесь, никто не собирается менять ваш образ мышления: "поздно пить боржоми ..."  Цитата Большая ошибка судить людей по паре постов, думая что они ничего не знают Однако, ваших "пары постов" вполне для этого хватило - что не пост, то "пук в лужу" Цитата А только все это фигня, сейчас функциональное программирование в моде. Да, что вы говорите?! Ну, засуньте в обычный МК (не распберри) хотя бы что-то напоминающее эту "моду". Покажите пример...
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Nov 9 2017, 20:15
|
Местный
  
Группа: Свой
Сообщений: 437
Регистрация: 27-08-04
Пользователь №: 551

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

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

|
Цитата(ig_z @ Nov 9 2017, 23:15)  в каждой бочке затычка Ну, да, а влезать в чужую беседу, особенно если сам в ней "не в зуб ногой" - это по-Вашему норм Цитата И ни в коем случае по теме ничего не говорите А у вас-то есть что добавить по теме - SST ("каруселька" и т. п.)? Или тоже можно "открывать счет"?
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Nov 17 2017, 10:45
|
Профессионал
    
Группа: Свой
Сообщений: 1 817
Регистрация: 14-02-07
Из: наших, которые работают за бугром
Пользователь №: 25 368

|
Возвращаясь к оригинальной теме по поводу прерывания из прерывания. У меня попроще задача и я не думал, что в 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 будет не нужна.
|
|
|
|
|
Nov 17 2017, 11:07
|

Профессионал
    
Группа: Свой
Сообщений: 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 будет не нужна. Это вы сейчас так говорите, в данный момент. А в перспективе?  Но, если же проект такой примитивный, то все можно сделать на паре/тройке аппаратных таймеров. В самом убогом ARM как минимум два-три штуки найдутся (помимо стандартного SysTimer). Такое решение простое, наглядное и железобетонное. Если правильно назначить приоритеты этим таймерам, то получится относительно работоспособный "шедулер" с поддержкой приоритетов. Еще еще вариант - простейший супер-луп, использующий лишь один таймер (systimer), где код из фона прерываний переносится в фон задач. Фактически пишете шедулер RTOS самостоятельно руками (со всеми вытекающими). зы. В любом проекте в фоне прерываний не должны вызываться никакие толстые функции! Иначе другие толстые функции поплывут и в итоге поплывет времянка всего проектика. Кто пытался писать сложные проекты в супер-лупе (продвинутые ардуинщики), то понимает, что я имею ввиду )))
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Nov 17 2017, 11:37
|

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

|
Цитата(scifi @ Nov 17 2017, 14:15)  Всё он поддерживает. Здесь под словом reentrant имеется ввиду возможность обработчика прервать самого себя. Наподобие вызова функции внутри самой себя. А вытесняющие прерывания называются иначе - nesting interrupts, т.е. вложенные прерывания (в некоторой литературе может встречаться другое название - preemptive). Они подразумевают вытеснение одного обработчика прерываний ДРУГИМ обработчиком. Если же прерывание от того же самого источника произойдет в то время, пока обрабатывается прерывание от этого же источника (скажем, байты по USART сыпятся быстрее, чем успеваем их обрабатывать), то новое прерывание станет отложенным (pending) и вызовется сразу же после обработки текущего (если конечно никто более приоритетный его не прервет). Другими словами, встанет в очередь. Это если объяснять грубо и на пальцах, на деле там полно своих нюансов.
--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
|
|
|
|
|
Nov 17 2017, 12:01
|
Знающий
   
Группа: Участник
Сообщений: 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().
|
|
|
|
|
Nov 17 2017, 12:02
|
Профессионал
    
Группа: Свой
Сообщений: 1 817
Регистрация: 14-02-07
Из: наших, которые работают за бугром
Пользователь №: 25 368

|
Цитата(scifi @ Nov 17 2017, 14:15)  Всё он поддерживает. Обработчик прерывания не будет вызван повторно, пока он выполняется. Вообще-то это разумно, не находите? Для того, чтобы он был прерван, должно произойти прерывание с более высоким приоритетом, а не с равным. Ну я нахожу разумным, если есть возможность выбора - так или этак. И мое представление об обработчике прерывания очень простое - произошло прерывание - процессор должен безусловно перейти на адрес обработчика. Если пользователь хочет - не снимает флаг, пока не обработает все прерывание и теряет возможность поимки следующего прерывания, пришедшего во время обработки. Если хочет - снимает, и не теряет. Насколько я помню 8051-ых так было реализовано.
|
|
|
|
|
Nov 17 2017, 18:04
|
Профессионал
    
Группа: Свой
Сообщений: 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] - для короткого!
|
|
|
|
|
Nov 17 2017, 18:56
|

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

|
Цитата(syoma @ Nov 17 2017, 20:04)  Знающие люди подсказали такой вариант. У них работает:
В итоге SysTick_Isr будет самовложенной. Что скажете? Кто-то что-то наковырял в симулинке? А кто тогда покажет файл SysTickScheduler.c? Там невооруженным глазом видно, что обработчик вызывает функцию rt_OneStep в течении которой все! прерывания запрещены. Вот у них и работает. Лузеры!
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|