реклама на сайте
подробности

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> [Вроде решено] Массив указателей на функции. Указатель на массив
psL
сообщение Jan 29 2017, 17:47
Сообщение #16


Знающий
****

Группа: Свой
Сообщений: 506
Регистрация: 5-08-05
Пользователь №: 7 390



Цитата(Dog Pawlowa @ Jan 29 2017, 20:12) *
Дифайны и енумы уже отменили? wink.gif

Нет. Просто реализация, исходя из ваших рекомендаций, у ТС получится до безобразия кривой: один глобальный массив со всеми вытекающими. И все это только потому, что указатель на массив функций не осислили)
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jan 29 2017, 18:58
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 2 657
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(psL @ Jan 29 2017, 20:47) *
Просто реализация, исходя из ваших рекомендаций, у ТС получится до безобразия кривой: один глобальный массив со всеми вытекающими.

А что там такое вытекает? Инициализация переменных состояния? Для Вас это тоже проблема? laughing.gif


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
psL
сообщение Jan 29 2017, 19:02
Сообщение #18


Знающий
****

Группа: Свой
Сообщений: 506
Регистрация: 5-08-05
Пользователь №: 7 390



Цитата(Dog Pawlowa @ Jan 29 2017, 21:58) *
А что там такое вытекает? Инициализация переменных состояния? Для Вас это тоже проблема? laughing.gif


Для меня - не проблема, потому что сам так делать не буду и другим не посоветую
Go to the top of the page
 
+Quote Post
demiurg1978
сообщение Jan 29 2017, 19:05
Сообщение #19


Местный
***

Группа: Участник
Сообщений: 317
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709



Если конечный автомат сделан по индексному переходу, то не инициализированная переменная-состояние может наделать делов. Именно поэтому хорош способ, когда нулевое состояние - инициализация всего и вся. Тем более что такой способ бесплатен. ОЗУ инициализировано нулями.
Но если switch-case и состояний много, то код становится трудночитаемым. Опять же, switch-case нагляден. Индексный вызов функций - это блудить и искать нужную функцию. Но в этом случае можно частично облегчить задачу. Например, в одном месте вывести названия состояний и соответствующие названиям функции.
Пример:
Код
//************************************************************************
//************************ Главный автомат *******************************
//************************************************************************

//========================================================================
STATE (PROC_DEVICE_INIT,             proc_device_init)
STATE (PROC_DEVICE_WAIT_SWITCH_MODE, proc_device_wait_switch_mode)
STATE (PROC_DEVICE_MANUAL,           proc_device_manual_mode)
STATE (PROC_DEVICE_AUTOMAT,          proc_device_automat_mode)
STATE (PROC_DEVICE_EMERG_MODE,       proc_device_emerg_mode)
//========================================================================


Сообщение отредактировал demiurg1978 - Jan 29 2017, 19:11
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jan 29 2017, 19:16
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 2 657
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(demiurg1978 @ Jan 29 2017, 22:05) *
ОЗУ инициализировано нулями.

ОЗУ будет инициализировано тем, что скажет программист:
int this_variable_is_not_zero=1;


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jan 30 2017, 21:34
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 3 045
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(demiurg1978 @ Jan 29 2017, 21:05) *
Но если switch-case и состояний много, то код становится трудночитаемым. Опять же, switch-case нагляден. Индексный вызов функций - это блудить и искать нужную функцию. Но в этом случае можно частично облегчить задачу. Например, в одном месте вывести названия состояний и соответствующие названиям функции.

Есть гораздо более наглядные способы организации автоматов состояний чем switch/case или туева хуча функций.
Например - переключение стека, когда значениями автомата состояний становятся значения PC (или как там в AVR называется счётчик команд?) И код автомата выглядит совершенно линейным и простым.

Цитата(Dog Pawlowa @ Jan 29 2017, 19:12) *
Дифайны и енумы уже отменили? wink.gif

Нет. PC - вот лучшее место для хранения состояния автомата состояния! yeah.gif
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jan 31 2017, 13:57
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 2 657
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(jcxz @ Jan 31 2017, 00:34) *
Нет. PC - вот лучшее место для хранения состояния автомата состояния! yeah.gif

Как же, давайте пихать RTOS во все дыры.
А даже впихнем - все равно куски кода нужно как-то комментировать, можно сказать, что case - это комментарий wink.gif


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jan 31 2017, 14:23
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 3 045
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Dog Pawlowa @ Jan 31 2017, 15:57) *
Как же, давайте пихать RTOS во все дыры.

Причём тут RTOS?? Где Вы её узрели в моём сообщении?
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jan 31 2017, 15:39
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 2 657
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(jcxz @ Jan 31 2017, 17:23) *
Где Вы её узрели в моём сообщении?

вот:
Цитата(jcxz @ Jan 31 2017, 00:34) *
PC - вот лучшее место для хранения состояния автомата состояния!


Самый лучший автомат состояния - это последовательное выполнение команд, тогда состояние однозначно отражается местом в коде. Полностью согласен.
К сожалению, это возможно только для простейших устройств (один автомат), чтобы сделать то же самое для более сложных устройств (больше одного автомата) и сохранить привязку автомата к PC, нужно иметь инструмент, который принудительно переключает PC между "автоматами".
Такой инструмент называется RTOS.
Как? wink.gif


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jan 31 2017, 17:03
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 3 045
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Dog Pawlowa @ Jan 31 2017, 17:39) *
нужно иметь инструмент, который принудительно переключает PC между "автоматами".
Такой инструмент называется RTOS.

Нет.
Вы очевидно полагаете, что ОС это нечто такое, божественное, состоящее не из команд, действующее непостижимым образом.
Нет, всё проще - ОС состоит из тех же самых команд, что и остальной код и переключение контекста (которое есть и в ОС), никто не мешает сделать вручную.
И принудительности никакой не надо - переключение надо делать там-же, где у ТС-а находится switch/case (ну или вызов очередной функции из таблицы),
только вместо этого будет сохранение контекста точки вызова (регистры, указатель стека, PC) и восстановление контекста тела автомата.
И в результате получаем тело автомата в виде линейного кода, а не разорванного на много частей switch/case-ами и не распиленное на отдельные функции.
И таких автоматов может быть сколько угодно - для каждого свой стек.

Единственное что правда, так это то, что тело такого автомата будет похоже на задачу ОС с корпоративной многозадачностью.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Feb 1 2017, 04:56
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 2 657
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(jcxz @ Jan 31 2017, 20:03) *
тело такого автомата будет похоже на

Есть такая грубая поговорка - если девушка похожа на шлюху, и ведет себя, как шлюха, то она шлюха и есть.
Так и переключение автоматов wink.gif


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 1 2017, 09:53
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 3 045
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Dog Pawlowa @ Feb 1 2017, 06:56) *
Есть такая грубая поговорка - если девушка похожа на шлюху, и ведет себя, как шлюха, то она шлюха и есть.
Так и переключение автоматов wink.gif

Следуя Вашей логике - если любую программу можно назвать RTOS. Ведь в ней те же самые команды, значит она похожа.
Переключение стека - это десяток команд всего. ОС - это не переключение стека, это гораздо больше. Переключение - это одна из мелких частей ОС. Эта мелкая часть может быть (и есть) и во многих других случаях, кроме ОС.
Go to the top of the page
 
+Quote Post
demiurg1978
сообщение Feb 1 2017, 10:05
Сообщение #28


Местный
***

Группа: Участник
Сообщений: 317
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709



Цитата(jcxz @ Jan 31 2017, 23:03) *
И в результате получаем тело автомата в виде линейного кода, а не разорванного на много частей switch/case-ами и не распиленное на отдельные функции.
И таких автоматов может быть сколько угодно - для каждого свой стек.

Во-первых: нет такого инструмента.
Во-вторых: текущий проект блок управления оборудованием. Покажите пример конечного автомата по вашему описанию. К примеру, у меня аварийный режим отдельное состояние. Линейный код в студию.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 1 2017, 11:58
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 3 045
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(demiurg1978 @ Feb 1 2017, 12:05) *
Во-вторых: текущий проект блок управления оборудованием. Покажите пример конечного автомата по вашему описанию. К примеру, у меня аварийный режим отдельное состояние. Линейный код в студию.

Классический автомат:
CODE
enum {S0, S1, S2, S3, S4, ...};
int state = S0;
switch (state) {
case S0:
{...} //полезная работа0
state = S1;
break;
case S1:
{...} //полезная работа1
state = S2;
break;
case S2:
{...} //полезная работа2
if (условие) state = S3;
else state = S4;
break;
case S3:
{...} //полезная работа3
break;
case S4:
{...} //полезная работа4
break;
...
}
Очевидно - тело автомата - участки внутри case. Но тело разорванное, плохо читаемое при большом числе состояний S...
Соберём тело воедино:
CODE
{...} //полезная работа0
SwitchStack();
{...} //полезная работа1
SwitchStack();
{...} //полезная работа2
if (условие) {
SwitchStack();
{...} //полезная работа3
} else {
SwitchStack();
{...} //полезная работа4
}
Получили линейный, хорошо читаемый код.
Теперь там, где раньше было switch (state) (назовём это - телом хозяина), будет:
SwitchStack(); - переключение стека и контекста процессора на тело автомата.
Сама SwitchStack() внутри сначала сохраняет на стек все регистры, которые по соглашениям вызова компилятора не должны разрушаться при вызове функций. И сохраняет значение PC (адрес возврата).
Потом считывает из static переменной значение указателя стека для тела автомата и сохраняет туда значение указателя стека тела хозяина.
Затем - восстанавливает со стека автомата значения сохранённых регистров и PC и выходит в тело автомата.
При вызове SwitchStack() из тела автомата, она делает обратные действия - возвращается в контекст тела хозяина.
Реализация SwitchStack() - процессоро-зависима. Я не знаю архитектуры AVR. Для Cortex-M и IAR это будет:
CODE
SECTION .text:CODE:NOROOT(2)
PUBLIC SwitchStack
THUMB
SwitchStack:
PUSH {R4-R11, LR} ;сохраним все предохраняемые регистры и адрес возврата для точки вызова на стеке вызова
LDR R0, sp ;читаем указатель на переменную для сохранения SP
LDR R1, [R0] ;читаем из этой переменной вершину стека точки возврата
STR SP, [R0] ;сохраняем вершину стека точки вызова в эту переменную
MOVS SP, R1 ;переключаем стек
POP {R4-R11, PC} ;возвращаемся уже в точку возврата с восстановлением регистров
;всё - контекст переключен
EXTERN spForStateMachine ;хранит указатель стека SP тела автомата или тела хозяина
DATA
sp DC32 spForStateMachine
При желании можно выровнять данное сохранение на 8 (нужно для аппаратной плавучки в M4F) добавив в PUSH/POP регистр R12.
Естественно перед первым переключением на контекст тела автомата, необходимо проинитить стек автомата валидными значениями регистров и переменную spForStateMachine - вершиной этого стека.
Go to the top of the page
 
+Quote Post
demiurg1978
сообщение Feb 1 2017, 14:18
Сообщение #30


Местный
***

Группа: Участник
Сообщений: 317
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709



Если честно, немного извращенно. Прототреды и то проще. Еще проще написать функции линейно, и вызывать их по указателю. Состояние - ссылка на нужную функцию. И никаких трат на сохранение-восстановление контекста.
Go to the top of the page
 
+Quote Post

4 страниц V  < 1 2 3 4 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd March 2017 - 06:09
Рейтинг@Mail.ru


Страница сгенерированна за 0.01502 секунд с 7
ELECTRONIX ©2004-2016