arhiv6 20 25 сентября, 2016 Опубликовано 25 сентября, 2016 (изменено) · Жалоба Добрый день. Есть вопрос по правильному применению PendSV в Cortex-M4. Пару раз использовал простой планировщик, написанный на Си. В нем задачи - это простые функции, которые, в отличии от обычных вытесняющих OS, не содержат в своем теле бесконечного цикла, а выполняются до завершения. Решил добавить задачам приоритеты и добавить возможность более приоритетным задачам приостанавливать менее приоритетные, как в Super Simple Tasker (SST). Как я это вижу: Стек общий на все задачи. При выполнении задачи (A), если требуется передать управлении более приоритетной (B) - в кольцевой буфер кладём указатель на необходимую задачу и вызываем прерывание PendSV. Попадаем в обработчик прерывания PendSV_Handler (при этом стек предыдущей задачи сохранился, в него мы попадём при выходе из прерывания). В обработчике видим, что есть потребность исполнения более приоритетной задачи B -> вызываем её (как функцию), выполняем, возвращаемся в тело обработчика прерывания и выходим из прерывания, возвращаясь задачу A и продолжаем её выполнение. Проблема в том, что вызывая задачу В я остаюсь в контексте прерывания PendSV и я не смогу передать (если это потребуется) управление ещё более приоритетной задаче (С), т.к. нельзя ещё раз вызвать прерывание PendSV. Как-то можно это обойти? Изменено 25 сентября, 2016 пользователем arhiv6 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 25 сентября, 2016 Опубликовано 25 сентября, 2016 · Жалоба Есть вопрос по правильному применению PendSV в Cortex-M4. Как-то можно это обойти? Воспользоваться любой готовой бесплатной RTOS (где есть порт под CM4) или подсмотреть как сделаны обработчики у них, если нравится изобретать велосипед :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kolobok0 0 25 сентября, 2016 Опубликовано 25 сентября, 2016 · Жалоба ...Стек общий на все задачи. ... Присоединюсь к мысли прозвучавшей выше: - или по другому = если не использовать опыт ранее накопленный то останешься на уровне обезьяны... сам обычно делаю следующим образом(в похожих случаях): выбираю из информации в сети более подходящую под задачу ось. выбираю версию. форматирую ручками весь текст(заодно и знакомлюсь с потрохами, контролирую ошибки(которые кстати встречаются всегда как правило), переписываю те блоки которые можно решить лучше в рамках данной задачи. вышесказанное не отменяет знакомство с документацией (естественно), и поиском решения тех или иных проблем в инете. без таких похожих шагов - Вы либо будете строить свой велосипед, либо как пионэр с гранатой. Если отвечать на Ваш вопрос на уровне велосипеда, то в кортексах есть азм команда загрузки-переключения стэков одной командой. Именно это и используется обычно в РТОС... Думаю понятно, что одна команда лучше чем несколько:) удачи Вам (круглый) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
arhiv6 20 25 сентября, 2016 Опубликовано 25 сентября, 2016 · Жалоба Для совсем простых вещей работаю без ОС, для некоторых - хватает упомянутого планировщика, для чего-то сложнее - разумеется, использую готовую ОС. Появилась идея немного доработать планировщик, это скорее для самообразования (для этих же целей, например, писал простой кооперативный планировщик на setjmp/longjmp - чтобы научиться работать с setjmp/longjmp, чтобы на своём опыте попробовать карусельную ОС). Исходники смотрел. Например, scmRtos - на сколько хватает моего понимания - для каждой задачи выделяется в памяти своя область для хранения стека, в PendSV_Handler происходит сохранение текущего указателя на стек, сохранение регистров, восстановление значений регистров новой задачи, в регистр указателя стека записывается указатель на стек новой задачи и происходит выход из прерывания - и т.к. указатель на стек мы поменял -> автоматически переходим в новую задачу. Но, к сожалению, у меня не хватает знаний о том, какой алгоритм должен быть для переключения задач в моём случае. Первое, что пришло в голову - использование прерывания и работа в его контексте. При этом при вызове обработчика прерывания автоматически сохранится контекст текущей задачи, создастся новый - для обработчика прерывания. Даже ассемблер не нужен, всё сделает компилятор. Но, т.к. вложенные прерывания запрещены, все ограничивается одним уровнем приоритета. Какие есть средства обойти это? Только использовать подмену адреса в указателе на стек и выходить из обработчика прерывания? Или можно как-то сообщить ядру что обработка прерывания закончена и при этом остаться в контексте прерывания (по сути - разрешить вложенные прерывания)? Или как-то по другому? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 25 сентября, 2016 Опубликовано 25 сентября, 2016 · Жалоба Для совсем простых вещей работаю без ОС, для некоторых - хватает упомянутого планировщика, для чего-то сложнее - разумеется, использую готовую ОС По своему опыту уверенно скажу, что право на жизнь имеют тока первый и третий варианты, а второй вариант лучше забыть как кошмарный сон! В любой проект можно всунуть ОСь и также любой проект может жить без ОСи, но самодельные костыли в виде чего-то промежуточного принесут только горе и страдания ;) Некоторым, чтобы это понять, все же приходится городить эти костыли, но сука-жисть расставит все на свои места - рано или поздно костыли будут выброшены и навсегда забыты :) Я так говорю, поскольку сам в свое время баловался этим ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 56 25 сентября, 2016 Опубликовано 25 сентября, 2016 · Жалоба По своему опыту уверенно скажу, что право на жизнь имеют тока первый и третий варианты, а второй вариант лучше забыть как кошмарный сон! И в чем там кошмарный сон? Сам использую простой переключатель задач, без всяких очередей и прочих наворотов. Вполне хватает мьютексов и глобальных переменных или структур. ИМХО для себя считаю это простым и понятным. ЗЫ. на этих принципах написана своя графическая операционка, если кто считает, что сложные задачи так не пишутся.. "...Стек общий на все задачи. ..." - а вот это глупость, конечно, можно выделить какую-либо общую область памяти, причем статически, но указатели для каждой задачи должны быть свои. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 25 сентября, 2016 Опубликовано 25 сентября, 2016 · Жалоба И в чем там кошмарный сон?Я лишь поделился своими впечатлениями )) использую простой переключатель задач, без всяких очередей и прочих наворотов.В любой готовой ОСи нет никакой нужды использовать все ее фишки. В прошивку попадают только те функции, которые используются, остальное линковщик игнорирует. Под разные ядра я заранее скомпилировал свои ОСи и к каждом проекту подключаю нужную либу, чтобы не подключать все ее исходники. Удобно. Это касается не только оси, но и других сторонних библиотек. Вполне хватает мьютексовСогласен, я сам редко использую более "толстые" сервисы )) и глобальных переменных или структур.Ось дает возможность вообще отказаться от глобальных переменных, т.к. они весьма коварное зло, которое пакостит так, что невозможно понять откуда ноги растут :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Johnny81 0 26 сентября, 2016 Опубликовано 26 сентября, 2016 · Жалоба Для совсем простых вещей работаю без ОС, для некоторых - хватает упомянутого планировщика, для чего-то сложнее - разумеется, использую готовую ОС. Появилась идея немного доработать планировщик Простейший вариант - заюзать приоритеты прерываний. И каждый набор задач одного приоритета дергать из программного прерывания (под которые отдать неиспользуемые аппаратные). При этом автоматом более приоритетная задача вытеснит менее приоритетную. При этом задачи с наименьшим приоритетом будут дергаться прямо из main, дальше идет требуемое кол-во прерываний с разными приоритетами, и затем - аппаратные прерывания Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AVI-crak 0 26 сентября, 2016 Опубликовано 26 сентября, 2016 · Жалоба Даже ассемблер не нужен, всё сделает компилятор. Очень большое заблуждение. GCC настолько оптимизирует код - что функции ос размазываются по всему контексту. Прямые вставки на асме заставляют выполнятся код в нужном месте, в уникальном порядке. Второе, сам переключатель не столь важен, он просто должен быть быстрым. Важна сама организация стеков. Тут всего три подхода: Глобальное использование препроцесора, при этом новых задач создать невозможно, так-же как и удалить - но зато моментальный старт. Создание/удаление задач в области хелпа, когда маллок выделяет кусок памяти единый для переменных и стека одной задачи - применяется почти всеми ос, недостатки - система деревянная по пояс. В случае когда в задаче временно используется массив большого размера - остальное время получим перерасход памяти. Третий вариант: статический стек прерываний + динамический стек задач - есно вниз. Динамическое выделение памяти под переменные в области хелпа - есно в верх. Ещё больше гибкости, но и больше накладных расходов. Четвёртый вариант: аналог третьего с небольшим исключением - плавающая граница между нижней планкой стека и верхней планкой памяти переменных. Позволяет впихнуть невпихуемое в самый маленький мк, и заставить двигаться то - что двигаться чисто физически не может. (почти автоваз) Литература для обучения и создания собственной ос http://badembed.ru/assembler-pereklyuchenie-konteksta/ Моё https://bitbucket.org/AVI-crak/rtos-cortex-.../branch/default на орфографию не обращать внимания - это глюки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 38 26 сентября, 2016 Опубликовано 26 сентября, 2016 (изменено) · Жалоба В "области хелпа" - я рекомендую разместить heap (; …Тут всего три подхода: Третий вариант: … Четвёртый вариант: … Литература для обучения и создания собственной ос http://badembed.ru/assembler-pereklyuchenie-konteksta/ Моё https://bitbucket.org/AVI-crak/rtos-cortex-.../branch/default на орфографию не обращать внимания - это глюки. А за литературу спасибо от души. Изменено 26 сентября, 2016 пользователем Obam Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться