0
Ну, раз опробовали — уже не только «теоретики», а также и «экспериментаторы»… Значит, в теме были — «просто болтуны»! ;))

В любом случае: каждое замечание или вопрос — это обратная связь, реакция аудитории — значит, полезно!

Меня этот «Диспетчер задач RTOS» почему увлёк? Понадобилось совместить на одном МК параллельные задачи: Динамическую индикацию, Опрос кнопок (интерфейс), и Отработку основного цикла (прикладной логики) в фоне… Эти задачи решаются также на самых слабых МК (и на ассемблере, конечно). Поэтому, надеюсь, что такая RTOS найдёт свою нишу применения. Позиционирование данной RTOS — я так, сразу, и описал: в разделе «Назначение», головной статьи...
А на Си и на мощных микроконтроллерах — думаю, от такого ограниченного «Диспетчера» будет, действительно, мало толку. Незачем, поскольку там есть целый сонм полноценных кооперативных и вытесняющих RTOS…
  • avatar
  • Celeron
  • 18 февраля 2014, 19:18
0
Рецепт!Чтобы портировать проект на другой микроконтроллер, нужно сделать всего две вещи:
1) Включить определение HAL нужного микроконтроллера:
.include "m2560def.inc"
2) И изменить под него Таблицу векторов на обработчики прерываний:
.include "ivectors_mega2560.inc"

Теорию «что? как? зачем?» — см. в учебном курсе DI HALT'а: «Скелет программы» и «Подпрограммы и прерывания»… Кстати, эти вопросы уже выходят за рамки RTOS и касаются только «Шаблона проекта». Код RTOS, в этом плане, универсален. Для создания прошивок к AVR без RTOS — существует аналогичный пустой «Шаблон нового проекта».

Я портировал: Тот же проект, на последнем релизе RTOS v2.1, и для микроконтроллера ATmega2560: «MaketboardTest_ATmega2560_RTOSv2.1.zip». (У меня нет такой железки, но симуляция в «AVR Studio» работает правильно.)

p.s. Наконец-то, в тему, кроме болтунов-теоретиков, пришли экспериментаторы — я приветствую это! :)
  • avatar
  • Celeron
  • 18 февраля 2014, 16:48
0
они не актуальны для программирования МК
Да, я совсем не настаиваю ни на каких языках. И действительно, для программирования МК нужны императивные ЯП! Просто, я — профессиональный программист, и мне аналогии приходят в образах языков программирования…

Если вам это не даёт покоя — ок, я заменю:
в обычных [функциональных] языках
на
в высокоуровневых языках


По теме «функционального программирования»:
В функциональных языках цикл обычно реализуется в виде рекурсии...
тыц, тыц, тыц, тыц.
  • avatar
  • Celeron
  • 18 февраля 2014, 13:34
0
Релиз!RELEASE: RTOS v2.1-alpha

+ Что сделано: "Служба таймеров RTOS" была вынесена из прерывания в "рабочий цикл"...
  Код ядра оптимизирован: занимает меньше места (за счет повторного использования метода RTOS_METHOD_AddTask).
  Но главный Profit: теперь Системе требуется глубина Стека на 4 байта меньше (ранее требовалось 12 байт, теперь 8 байт). Что актуально для МК с малым объёмом ОЗУ.
  Логика работы Системы и API - не изменились!
  • avatar
  • Celeron
  • 18 февраля 2014, 02:21
0
Но тут пришёл Vga и всё разъяснил. Хорошо, убедил! Статью подкорректировал… ;)
  • avatar
  • Celeron
  • 17 февраля 2014, 16:01
0
или если ее добавляют в очередь другие задачи (не считая первого добавления, которое и запускает задачу-цикл)
Да, вот именно это и происходит в этом [неправильно спроектированном] алгоритме! От этого я и хочу предостеречь будущих программистов.
  • avatar
  • Celeron
  • 17 февраля 2014, 14:55
0
Другие события добьют очередь — вот это проблема.
  • avatar
  • Celeron
  • 17 февраля 2014, 14:16
0
Диспетчер-то переварит… Но такой Таск — не даст Очереди опустеть никогда! (Потому что будет замещать обработанные вызовы равнозначным количеством запланированного наперёд.) Но ведь, не только SomeTask является источником событий в системе, не так ли?
  • avatar
  • Celeron
  • 16 февраля 2014, 20:32
0
* Точнее: я увидел, в том моменте, аллюзию на рекурсию…
А в ситуации «переполнения Очереди» — аллюзию на «переполнение Стека». Ибо это обе: «динамические структуры данных», хотя и разной алгоритмической организации (одна FIFO, другая LIFO)…
  • avatar
  • Celeron
  • 16 февраля 2014, 20:27
0
с точки зрения программирования...
А с точки зрения «абстрактного математического моделирования» — я вижу здесь рекурсию. Ведь Задачи для RTOS (на её фундаменте) проектируются уже больше на «абстрактно-математическом» уровне… Понимаете?

Я описываю особенности абстрактного API, чтобы не вникая в подробности работы ядра RTOS, можно было избежать граблей, при проектировании кода Задач.
  • avatar
  • Celeron
  • 16 февраля 2014, 20:18
0
что эквивалентно: «Вызову функцией самой себя!» (А что происходит в обычных [или функциональных] языках программирования, при [безусловном] вызове функцией самой себя? Бесконечная рекурсия! И итоге, переполнение Стека, и крах с Exception...)
  • avatar
  • Celeron
  • 16 февраля 2014, 19:50
0
Не следует трактовать отдельные фразы столь буквально. Своими построениями я стремлюсь вызвать у читателей некоторые ассоциации, через которые донести то, что я хочу передать.
  • avatar
  • Celeron
  • 16 февраля 2014, 18:38
0
Данная цитата — это абстрактный авторский пример. К теме статьи относится очень опосредованно. Темы «языков программирования», их преимуществ и особенностей, я здесь не касался.
  • avatar
  • Celeron
  • 16 февраля 2014, 18:31
+1
Есть такой человек… И у него было просто хобби
  • avatar
  • Celeron
  • 16 февраля 2014, 02:36
0
Да, здесь, та же самая таймерная служба!
Задачи в таймерной службе запускаются из других задач.
И не только Таймеры, но и Выжидатели, и регулярная Очередь Задач — все они запускаются из других Задач...




«Дамоклов меч» аварийной ситуации можно разрулить по разному:
можно «убить задачи» в таймере. Но откуда нам знать, какие задачи нужны-не нужны в данный конкретный момент
При возникновении критической аварийной ситуации — я бы убил ВСЕ задачи, и запустил одну задачу аварийного режима (всё равно система заблокирована), но это подходит только для простейших станков:
RCALL  RTOS_METHOD_ClearTimers
RCALL  RTOS_METHOD_ClearWaiters
RCALL  RTOS_METHOD_ClearTaskQueue
PLAN_TASK  TS_Task_EMERGENCY_MODE


Также, я бы, в обязательном порядке, ввел «глобальный регистр статуса» в системе (хранил бы байт в SRAM), одним из битов которого был бы: FAILURE_OCCURRED_EMERGENCY_MODE. И каждая Задача, управляющая резаками и прессами — должна, при запуске, в первую очередь, проверять этот бит: если установлен — мгновенный выход… Но это уже элемент «автоматного программирования»!




Но «дамоклов меч» — это ещё далеко не все недостатки данной [ограниченной] RTOS. Остановить Задачи — это не Проблема, а вопрос логической организации… А вот как быть с запуском Задач по цепочке, если «Очередь Задач» или «Пул Таймеров/Выжидателей» переполнен?

Если в некоторый момент МК будет перегружен, Очеред Задач переполнена, и тут срабатывает Таймер или просто вызывается метод PLAN_TASK из прикладного кода — Задачу добавить некуда, она игнорируется! (Примечание: для отслеживания и разруливания таких ситуаций, предназначена Ловушка Исключений RTOS_METHOD_ErrorHandler. Но, по сути, это костыль...)

Дальнейшая цепочка воспроизводства Задач нарушается — система «зависает», причём функционал отпадает по частям, в хаотичном неконтролируемом порядке. Пример и Предупреждение об этих ситуациях — я выложу в следующей статье: «Пример использования RTOS 2.0»…



Выводы:

Для программирования ответственных устройств, типа станков, использовать данную RTOS — нельзя, я считаю! Тут нужно использовать дубовое «автоматное программирование» — примитивное и надёжное. Надёжное! Пусть и сильно ограничивающее логические навороты. Во избежание ситуации: как с той «заклинившей дроссельной заслонкой в автомобиле Toyota Camry, приведшей к резонансной аварии»

А вообще, при мало-мальски сложной задаче, данная RTOS позволяет наговнокодить «спагетти-код» гораздо быстрее иных систем (поскольку каждый кусок кода «Задача» — слабо и неочевидно связан с другими)… «Диспетчер задач RTOS» предназначен только для простой автоматики.

Я не буду выгораживать данную RTOS. Я знаю её недостатки. Но мне нравятся также её преимущества и красота…
  • avatar
  • Celeron
  • 14 февраля 2014, 12:41
0
На семейство AVR XMEGA, признаться, не рассчитывал/не тестировал. А оно востребовано?
  • avatar
  • Celeron
  • 14 февраля 2014, 01:44
0
Язык — это мировоззрение…
  • avatar
  • Celeron
  • 12 февраля 2014, 13:14
0
Я сейчас говорю об ассемблере, не как об инструменте, не о средстве. Но говорю, как про мировоззрение: взгляд на программную реальность через призму ассемблера — совершенно другой, чем в алгоритмических языках. Ассемблер здесь — не «язык», а «глаза» и «руки»…
Когда мой Ум входит в мир ассемблера — он начинает функционирует как автомат. Здесь, тренинг ума ассемблером — даёт способность сходить с «ума алгоритмического», в «ум автоматный».

Инструкции ассемблера (машинные команды) — это «руки», которыми микроконтроллер перекладывает кусочки информации (разновидность материи) между имеющимися у него аппаратными регистрами. Как простой автомат: взять оттуда (бит или байт) переложить туда; если здесь пусто («глаза» — условные конструкции) то переложить сюда; и так далее…
У автомата нет алгоритма — вы творец!
  • avatar
  • Celeron
  • 10 февраля 2014, 14:58
+1
Не ломает, а тренерует!
Да, это распространённое заблуждение для новичков относительно ассемблера. (Я когда-то тоже так думал, не так уж давно...) На самом же деле, ассемблер отличается от Си на столько же, как Си отличается от SQL — совершенно разные парадигмы программирования!
В то время как Си — «алгоритмический язык» (то что вы называете «главным»), но ассемблер является «машинным языком» (в нём другие сущности манипулирования: регистры, порты, инструкции АЛУ). В Си отсутствуют такие понятия, как и средства для манипуляции этими сущностями (Си знает только «переменные») — доступ к аппаратным ресурсам осуществляется через HAL-библиотеки и костыли компилятора…
Например, у «декларативного языка» SQL есть строго ограниченная ниша применения: общие запросы к БД. Причём, в отдельных случаях, функционал Запросов можно расширить пользовательскими агрегатными или скалярными хранимыми процедурами/функциями, написанными на Си. Но равным образом, применяются ассемблерные вставки в Си-код (уродливые костыли) — там, где Си, ну никак, не справляется.
Программировать простые автоматы, с примитивным алгоритмом, на Си — всё равно что ковырять миниатюрную схему толстыми плоскогубцами: не удобно, не эффективно, иногда невозможно. Всякой задаче — свой инструмент.

p.s. Вот ещё: «когда я был молодой», то думал, что языки Java и JavaScript — похожи. Но оказалось — ну, совсем разные вещи: как носорог и дерево (хотя оба — в серой морщинистой коже, казалось бы)…
  • avatar
  • Celeron
  • 10 февраля 2014, 03:57
0
Чтобы добить вопрос: Переименовал метку в просто «LOOP»…
Так компилится нормально:
.MACRO	RAMFLUSH
		;...
		LOOP:
		ST	Z+, temp
		CPI	ZH, High(RAMEND+1)
		BRNE	LOOP
		CPI	ZL, Low(RAMEND+1)
		BRNE	LOOP
	.ENDM


А так — нет (макрос использован только раз):
.MACRO	RAMFLUSH
		;...
		$LOOP:
		ST	Z+, temp
		CPI	ZH, High(RAMEND+1)
		BRNE	LOOP
		CPI	ZL, Low(RAMEND+1)
		BRNE	LOOP
	.ENDM

...\test2\project1.asm(53) : error : Syntax error
...\test2\project1.asm(53) : error : Undefined variable referenced
...\test2\project1.asm(53) : error : Undefined variable referenced


Тут дело не в этом. Лучше, всё же, символ $ не использовать с Метками в AVRASM… Что-то вы напутали. Может то был другой компилятор, или AVRASM ранней версии?
p.s. В общем, для себя, я уже прояснил этот вопрос. Так что, эту дискуссию, в принципе, можно не продолжать.
  • avatar
  • Celeron
  • 04 февраля 2014, 22:34