Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.78/72: Рейтинг темы: голосов - 72, средняя оценка - 4.78
x0rOS
0 / 0 / 0
Регистрация: 17.03.2013
Сообщений: 16
1

STM32 Алгоритм

20.03.2013, 18:48. Просмотров 13115. Ответов 26
Метки нет (Все метки)

Привет.
Суть: имеется бесконечный цикл в котором непрерывно выполняется Задача1.
По прерыванию(от нажатия кнопки) в бесконечном цикле должна выполняться Задача2.
При следующем нажатии - снова запуск Задачи1 и т.д.
В основном цикле не должно быть проверок - какой режим включен. (т.е. менять флажки в прерывании не подходит)

Пока остановился на двух вариантах решения:
1. Каждый раз переписывать тело цикла. Очевидно, не самое рациональное решение и насколько я понимаю, трудно осуществимо в микроконтроллерах.
2. Создать две функции с циклами для Задачи1 и Задачи2. И по прерыванию завершать одну функцию и вызывать другую.
Но проблема в том, как именно это осуществить. Точнее, не понятно как завершать предыдущую функцию из прерывания. А если не завершать то в стеке будет копиться мусор и ничем хорошим это не закончится.

-----
Контроллер STM32, Си.

Спасибо!
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.03.2013, 18:48
Ответы с готовыми решениями:

Общение с барометром MS5540 на STM32 (Arduino to STM32)
Получил от китайца сей аппарат, пошел тут же гуглить что нибудь готовое, но не тут то было....

Чем связать STM32 + STM32 в одном корпусе?
Есть 2 платы: (1) - STM32 (Вывод на LCD + запись SD) и (2) - STM32F4 (обработка сигналов +...

Алгоритм ГОСТ ( простой) для STM32
//таблица замены static const char Table={...

STM32 - STM32 I2C
*****ПРОБЛЕМА ИСПРАВЛЕНА****ОТВЕТ НИЖЕ , НЕ ВЧИТЫВАЙТЕСЬ В КОД ПРОГРАММЫ,УТОНЕТЕ)), НУ ЕСЛИ ТОЛЬКО...

stm32 + FSMC + stm32
Доброе времени суток. Возможно ли к Ftosh памяти подцепить два Stm32F4. Один МК будет записывать...

26
itysiy
0 / 0 / 0
Регистрация: 18.01.2012
Сообщений: 1,418
20.03.2013, 20:48 2
а какое время реакции нужно на кнопку? если не критично, то можно в прерывании в бесконечном цикле софтверно проверять не нажата ли кнопка. Если нажата - выход из прерывания.
0
dosykus_2
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 4,017
20.03.2013, 21:11 3
Цитата Сообщение от x0rOS
Привет.
Суть: имеется бесконечный цикл в котором непрерывно выполняется Задача1.
По прерыванию(от нажатия кнопки) в бесконечном цикле должна выполняться Задача2.
При следующем нажатии - снова запуск Задачи1 и т.д.
В основном цикле не должно быть проверок - какой режим включен. (т.е. менять флажки в прерывании не подходит)
Какая то странная хотелка .
В основном цикле не должно быть проверок - какой режим включен.
Это чем навредит ? Почему не должно быть проверок ?
Думается проблема надуманная и из за непонимания.
В основном цикле автомат состояний на два состояния , кои меняются в прерывании от нажатия .

А вообщем или описаны не все хотелки или ТС просто не понимает чего хочет.
0
x0rOS
0 / 0 / 0
Регистрация: 17.03.2013
Сообщений: 16
20.03.2013, 21:36 4
itysiy, нет смысла, или я не так понял. Можно же просто проверять состояние ножки и из цикла. И чем это поможет поставленной задаче?
dosykus_2, возможно можно обойтись и без "оригинальных" решений. И вы правы, задач будет намного больше чем две. Обходить эти условия, каждую итерацию цикла очень накладно, т.к. каждый такт на счету(это когда уже задача запущена).

Непонимания чего? Просветите же меня.
----
itysiy, перепрочел и понял=) т.е. идея - задачи делать в программных прерываниях?
0
20.03.2013, 21:36
itysiy
0 / 0 / 0
Регистрация: 18.01.2012
Сообщений: 1,418
20.03.2013, 21:43 5
2x0rOS
Нажатие кнопки ловится по прерыванию. Если мы были в главном цикле - поймали прерывание, перешли в него и там делаем Задачу 2. Попутно проверяем кнопку на повторное нажатие. Если она была опять нажата - выходим из прерывания и выполняем задачу 1. Все повторяется снова.
Но какие требования к времени реакции на нажатие?
Если это обычные кнопки, то эти свистопляски вообще не нужны. И без прерываний флаговый или конечный автомат будет работать нормально.
0
dosykus_2
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 4,017
20.03.2013, 21:48 6
Цитата Сообщение от x0rOS
Обходить эти условия, каждую итерацию цикла очень накладно, т.к. каждый такт на счету(это когда уже задача запущена).

Непонимания чего? Просветите же меня.
----
itysiy, перепрочел и понял=) т.е. идея - задачи делать в программных прерываниях?
Вы представляете сам автомат ? Крутимся в суперлупе без каких либо задержек проверяя на ходу одну пременную , значение которой и есть состояние автомата .

Код
while (1)
{
if(state == STATE1) do_operation1();
if(state == STATE2)do_operation2();
... и .д.
}
Состояние (значение) state меняем в прерывании.
Естественно в функциях do_operationx не должно быть каких либо задержек , выполнили что то и съе.....сь.
И далее если состояний куча меняем ifы на switch-case .
0
x0rOS
0 / 0 / 0
Регистрация: 17.03.2013
Сообщений: 16
20.03.2013, 21:49 7
itysiy, в принципе, для двух задач и одной кнопки вполне приемлемое решение. Только тоже не совсем понятно. Не завершившийся обработчик прерывания не составит трудностей при повторном нажатии?
----
Понял, можно же просто запретить прерывание на ноге и в ручную опрашивать.
Хотя это тоже не совсем рационально, мало того задач будет больше. И еще проблема с обработкой дребезга контактов.
0
x0rOS
0 / 0 / 0
Регистрация: 17.03.2013
Сообщений: 16
20.03.2013, 21:56 8
dosykus_2, хм.
А если у меня 10 состояний и каждую итерацию цикла мы будем проверять по 10 "if"(в худшем случае конечно же и то если заменить на switch) пока не найдем требуемый.
Вы представляете сколько лишних команд? Загрузить в регистр значение состояния, сравнить с требуемым, сделать условный переход и так много раз! Много много бессмысленной работы каждую итерацию! А на счету каждый такт.
Я правильно вас понял?

Куда логичнее бы выглядела программа вида:
//бесконечный цикл первой задачи
метка1:
задача1;
jmp метка1;
-------------
//цикл второй задачи
метка2:
задача2;
jmp метка2;
-------------
Прерывание:
Если(включить выполнение второй задачи) тогда
Перезаписать "jmp метка1" на "jmp метка2";
Иначе
Перезаписать "jmp метка2" на "jmp метка1";

Все. В основном цикле никаких лишних проверок.
Простите за идиотский псевдокод, если смысл остался не ясен могу проиллюстрировать=)
(в коде ошибка, править надо и предыдущую метку и метку текущей задачи, но не суть)
0
Kimyus
0 / 0 / 0
Регистрация: 19.01.2012
Сообщений: 19
20.03.2013, 22:23 9
Может попробовать приспособить что-то типа событийного диспетчера?
К примеру, задачи пишутся в виде функций. В основном цикле крутится диспетчер и вызывает функцию, находящуюся в данный момент в очереди задач. В прерывании, соответственно, записывать в очередь другую задачу.
0
Kimyus
0 / 0 / 0
Регистрация: 19.01.2012
Сообщений: 19
20.03.2013, 22:27 10
Цитата Сообщение от x0rOS
dosykus_2, хм.
А если у меня 10 состояний и каждую итерацию цикла мы будем проверять по 10 "if"(в худшем случае конечно же и то если заменить на switch) пока не найдем требуемый.
Вы представляете сколько лишних команд? Загрузить в регистр значение состояния, сравнить с требуемым, сделать условный переход и так много раз! Много много бессмысленной работы каждую итерацию! А на счету каждый такт.
Я правильно вас понял?

Куда логичнее бы выглядела программа вида:
//бесконечный цикл первой задачи
метка1:
задача1;
jmp метка1;
-------------
//цикл второй задачи
метка2:
задача2;
jmp метка2;
-------------
Прерывание:
Если(включить выполнение второй задачи) тогда
Перезаписать "jmp метка1" на "jmp метка2";
Иначе
Перезаписать "jmp метка2" на "jmp метка1";

Все. В основном цикле никаких лишних проверок.
Простите за идиотский псевдокод, если смысл остался не ясен могу проиллюстрировать=)
(в коде ошибка, править надо и предыдущую метку и метку текущей задачи, но не суть)
Собственно тут вы описали что-то типа событийной системы и применение указателей на функцию)
В простейшем случае вы в главном цикле вызываете некую функцию по указателю, а в прерывании всего лишь записываете в указатель адрес функции с задачей 2. Как то так я думаю
0
x0rOS
0 / 0 / 0
Регистрация: 17.03.2013
Сообщений: 16
20.03.2013, 22:31 11
Kimius, можно. Только проблема одна, эти задачки зациклены. И прерывание будет возвращаться в этот цикл, до диспетчера не дойдет. А если вы предлагаете диспетчеру выделять время для оценки состояния - то это ничем не лучше чем просто if.
Вся проблема в том как корректно выйти из уже работающей задачи.
---
>Собственно тут вы описали что-то типа событийной системы и применение указателей на функцию)
>В простейшем случае вы в главном цикле вызываете некую функцию по указателю, а в прерывании всего лишь записываете в указатель адрес функции с задачей 2. Как то так я думаю

Именно, но проблема в том, что каждый раз когда я буду нажимать на кнопку, прерванная предыдущая функция не завершается и мусорит стек.
Как уже говорил, это может кончиться плохо.
0
dosykus_2
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 4,017
20.03.2013, 22:37 12
Цитата Сообщение от x0rOS
dosykus_2, хм.
А если у меня 10 состояний и каждую итерацию цикла мы будем проверять по 10 "if"(в худшем случае конечно же и то если заменить на switch) пока не найдем требуемый.
Вы представляете сколько лишних команд? Загрузить в регистр значение состояния, сравнить с требуемым, сделать условный переход и так много раз! Много много бессмысленной работы каждую итерацию! А на счету каждый такт.
Я правильно вас понял?
Согласитесь подобные вводные надо было озвучивать сразу же.
Выше вам решение Kimius предложил . Но и мой вариант так же жизни_способен ибо все проверки будут иметь заранее известную длительность и так уж много, как вы думаете, не займут .
Ваш же вариант с самомодфицирующемся кодом это что то из области вирусописательства и фантастики , а точней просто от непонимания МК .
0
Kimyus
0 / 0 / 0
Регистрация: 19.01.2012
Сообщений: 19
20.03.2013, 22:40 13
Цитата Сообщение от x0rOS
Kimius, можно. Только проблема одна, эти задачки зациклены. И прерывание будет возвращаться в этот цикл, до диспетчера не дойдет. А если вы предлагаете диспетчеру выделять время для оценки состояния - то это ничем не лучше чем просто if.
Вся проблема в том как корректно выйти из уже работающей задачи.
---
>Собственно тут вы описали что-то типа событийной системы и применение указателей на функцию)
>В простейшем случае вы в главном цикле вызываете некую функцию по указателю, а в прерывании всего лишь записываете в указатель адрес функции с задачей 2. Как то так я думаю

Именно, но проблема в том, что каждый раз когда я буду нажимать на кнопку, прерванная предыдущая функция не завершается и мусорит стек.
Как уже говорил, это может кончиться плохо.
Разве после обработки прерывания не произойдет возврат на то место в котором оно произошло?
Т.е. во время выполнения задачи 1 происходит прерывание, обработчик делает свое дело и возвращается в то место, в котором и была прервана задача 1. И лишь по ее окончании в следующем проходе главного цикла будет вызвана задача 2.
0
dosykus_2
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 4,017
20.03.2013, 22:40 14
x0rOS, обычно подобные задачи легко решаются когда ТС озвучит саму задачу , а не видимый ему вариант реализации.
И так же обычно все выливается в "изобретение велосипеда"...
0
x0rOS
0 / 0 / 0
Регистрация: 17.03.2013
Сообщений: 16
20.03.2013, 22:47 15
Не хочу вступать в полемику, мой первый пост
>В основном цикле не должно быть проверок - какой режим включен. (т.е. менять флажки в прерывании не подходит)
И ваши
>точней просто от непонимания МК
И в чем же заключается мое непонимание? Конкретнее пожалуйста!
Давайте не будем переходить на личности, а просто выскажите мнение по поводу способов решения данной задачи.
0
x0rOS
0 / 0 / 0
Регистрация: 17.03.2013
Сообщений: 16
20.03.2013, 22:59 16
Kimius, да произойдет. Но до начала выполнения новой задачи время не жалко!
>И лишь по ее окончании в следующем проходе главного цикла будет вызвана задача 2.
И как это сделать?
-------------------
dosykus_2, хотите пойти простым путём? Ладно!
Задача1 - реализует КИХ фильтр, приличного порядка(около 200го, разумеется используется циклический буфер). Частота поступления нового отсчета 48кГц(при частоте мк72мгц). Т.е. за это время значение уже должно быть подсчитано и передано. Согласитесь, критично по времени.

Имеется блок переключателей - напрмер один вызывает Задачу2(которая например реализует другой вид демодуляции и фильтрацию другого порядка) и т.д.

Не отрицаю, что такой автомат может и справиться(а может и нет), но на мой взгляд возможно было бы найти и более рациональное решение.
0
Kimyus
0 / 0 / 0
Регистрация: 19.01.2012
Сообщений: 19
20.03.2013, 23:08 17
Код
void (*pf)(void) = &task_1;   // Инициализируем указатель первой задачей

void task1(void)
{
}

void task2(void)
{
}

void interrupt()
{
if(pf == &task1){pf = &task2;}    // Вот тут выбирать следующую задачу
else{pf = &task1;}
}

main()
{
while(1)
{
(*pf)();
}
}
Но! Это собственно и есть диспетчер, то есть тот самый велосипед)

P.S. Кстати, если функций много и порядок их следования известен, то можно сделать массив из указателей на эти функции, а в прерывании менять только индекс. = тоже диспетчер

P.P.S. А по классике развития таких тем Вам кто-то рано или поздно должен сказать, что если каждый такт на счету, то МК выбран неверно) Хотя, конечно, жизнь она такая жизнь...
0
x0rOS
0 / 0 / 0
Регистрация: 17.03.2013
Сообщений: 16
20.03.2013, 23:12 18
Kimius, спасибо. Это то что я имел ввиду. Но! Разве, выйдя из прерывания мы не окажемся по среди нашей задачи и вызов по новому указателю не произойдет?
И если я правильно понимаю, задача не должна быть зациклена. Но тогда каждый раз в цикле идет call и ret. А это еще грузнее чем условия.
----
Благодарю за последней PS. Вы правы, по хорошему надо было бы мощный DSP ставить. Но ведь обсуждаем конкретную задачу. Если вариантов нет - значит нет, если есть идеи - пожалуйста.
0
kysoft
0 / 0 / 0
Регистрация: 13.01.2013
Сообщений: 140
20.03.2013, 23:26 19
На самом деле никто не заставляет выходить из прерывания. Считайте, что прерывание - это завершение текущей задачи.
Т.е. в прерывании инициализируем указатель стека и прыгаем в диспетчер задач.
Но это если можно прервать любую задачу в любом месте.
0
x0rOS
0 / 0 / 0
Регистрация: 17.03.2013
Сообщений: 16
20.03.2013, 23:33 20
>Т.е. в прерывании инициализируем указатель стека и прыгаем в диспетчер задач.
Зачем в диспетчер? Я могу сразу в стек адрес нужной задачи кинуть. Но снова же. Стек предыдущей незавершенной функции будет мусорить. Или нет?
0
20.03.2013, 23:33
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.03.2013, 23:33

STM32 F4 ??
Только что заметил. Stm добавила серию F4. Это что такое??? Погуглил. Это cortex-m4. Но...

stm32+wi fi
Здравствуйте есть идея разработать движущую машинку с управлением через смартфон/ноутбук. Хочу...

CAN в STM32
Разбираюсь с CAN модулем, появились несколько вопросов. 1. В файле stortup есть несколько векторов...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru