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

 
 
> [Вроде решено] Массив указателей на функции. Указатель на массив
demiurg1978
сообщение Jan 29 2017, 05:14
Сообщение #1


Местный
***

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



Запутался. Честно скажу, с указателями я не всегда дружу. sm.gif Помогите написать правильно. Нужно: есть массивы указателей на функцию. И переменные-состояния конечных автоматов, индексы для массивов.
CODE

//************************************************************************
//************************ Главный автомат *******************************
//************************************************************************

//========================================================================
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)
//========================================================================

enum _proc_device
{
#define STATE(name, func) name,
#include "_proc_device.h"
#undef STATE

PROC_DEVICE_STATES,
};

//========================================================================
typedef void (*FUNC)(void);
//========================================================================

__flash FUNC proc_device_func [PROC_DEVICE_STATES] =
{
#define STATE(name, func) func,
#include "_proc_device.h"
#undef STATE
};

static u08 _proc_device;
static u08 _proc_device_slave;

void proc_device (void)
{
// proc_sens_pwr (SAVE_EEPROM_PARAMETERS); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

proc_device_func [_proc_device] (); // В данный момент работает так.
}


Мне нужна функция, у которой в качестве параметров proc_device_func и _proc_device.
Что-то вроде proc_fsm_func (proc_device_func, get_proc_device_state ())

Мои пробы выдают ошибки.

Сообщение отредактировал demiurg1978 - Jan 29 2017, 14:47
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Dog Pawlowa
сообщение Jan 29 2017, 10:27
Сообщение #2


Гуру
******

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



Определяем тип переменной PROCEDURE - указатель на функцию

Код
typedef void (*PROCEDURE)(void);


Пишем текст функций.

Код
void function1(void) { ... }
void function2(void) { ... }
void function3(void) { ... }


Определяем, сколько у нас функций в массиве.

Код
#define STATES 3


Создаем массив указателей на функции в программной памяти, что у нас, AVR..

Код
__flash const PROCEDURE function[STATES_QTY] = { function1, function2, function3 };


Все, в программе вызываем вызываем функцию, соответствующую номеру состояния state:

Код
function[state]();





Цитата(demiurg1978 @ Jan 29 2017, 08:14) *
Мне нужна функция, у которой в качестве параметров proc_device_func и _proc_device.
Что-то вроде proc_fsm_func (proc_device_func, get_proc_device_state ())


А зачем так сложно - в функцию передавать указатель на функцию? Чтобы вызвать? Ну так вызовите добавлением скобок.


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


Местный
***

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



Цитата(Dog Pawlowa @ Jan 29 2017, 16:27) *
А зачем так сложно - в функцию передавать указатель на функцию? Чтобы вызвать? Ну так вызовите добавлением скобок.

Покажите, как.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jan 29 2017, 13:09
Сообщение #4


Гуру
******

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



Цитата(demiurg1978 @ Jan 29 2017, 15:16) *
Покажите, как.

Уже сделано! Функция вызывается по индексу в таблице:

Код
function[state]();


Что не устраивает?


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


Местный
***

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



Все приведенные примеры по сути повторяют то, что написано в первом сообщении. Излишняя навороченность кода в том сообщении, по сути enum и массив, обвернутые в макросы. И вызов функции один в один как у вас.
Код
   proc_device_func [_proc_device] ();
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jan 29 2017, 13:25
Сообщение #6


Гуру
******

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



Цитата(demiurg1978 @ Jan 29 2017, 16:16) *
Все приведенные примеры по сути повторяют то, что написано в первом сообщении. Излишняя навороченность кода в том сообщении, по сути enum и массив, обвернутые в макросы. И вызов функции один в один как у вас.

Правильно, макросы вредны, а все остальное - классика, которую использует каждый второй.
Что не устраивает то?

Вам то зачем дополнительная прослойка в виде функции, в которую будете передавать указатель на функцию?
Будьте проще, пишите как есть, все же работает.




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


Местный
***

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



Вроде решил вопрос.
CODE

//========================================================================
typedef void (*FUNC)(void);
//========================================================================

void proc_fsm_func (FUNC __flash *ptr_func, u08 s);

void func_1 (void);
void func_2 (void);
void func_3 (void);
void func_4 (void);

extern FUNC __flash list_func [];
void __flash * get_list_func (void);

void func_1 (void)
{

}

void func_2 (void)
{

}

void func_3 (void)
{

}

void func_4 (void)
{

}

__flash FUNC list_func [4] =
{
func_1,
func_2,
func_3,
func_4,
};

void proc_fsm_func (FUNC __flash *ptr_func, u08 s)
{
ptr_func [s] ();
}

void __flash * get_list_func (void)
{
return list_func;
}

proc_fsm_func (get_list_func (), 2);


Задумка такая: что-то вроде ядра обработчика конечных автоматов. Можно было и так оставить, как сделано в первом сообщении. Для каждого автомата своя строка вызова функции по индексу.
А когда задумал ядро обработчика, тут и возникли трудности. Честно говоря, я еще думаю, стоит ли дальше работать над этим ядром и применять его в проектах.

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


Гуру
******

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



Цитата(demiurg1978 @ Jan 29 2017, 18:02) *
Для каждого автомата своя строка вызова функции по индексу.

Это реализуется очень просто - одним массивом всех функций, но группы индексов массива для каждого автомата не должны перекрываться.
Например, первые 6 функций - автомат А, следующие 19 функций автомат B, и еще 9 функций автомата C.
тогда если массив называется f, обработка всех автоматов будет выглядеть так:

Код
f[stateA]();
f[stateB]();
f[stateC]();


Я так делал один раз в очень специфическом проекте.


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


Знающий
****

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



Цитата(Dog Pawlowa @ Jan 29 2017, 19:14) *
Например, первые 6 функций - автомат А, следующие 19 функций автомат B, и еще 9 функций автомата C.
Я так делал один раз в очень специфическом проекте.

Допустим нужно добавить еще несколько состояний в автомат A, что делать? Менять условия всякий раз?wink.gif
Насколько понимаю, ТС разбивает весь код на задачи и у каждой задачи - свой автомат состояний. Т.е. при переключении на соответствующую задачу должен подключаться соответствующий автомат состояния.
В принципе, очень типичная задача. Ничего специфического. Даже тема была https://electronix.ru/forum/index.php?showt...=136908&hl=
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jan 29 2017, 17:12
Сообщение #10


Гуру
******

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



Цитата(psL @ Jan 29 2017, 19:56) *
Менять условия всякий раз?wink.gif

Дифайны и енумы уже отменили? wink.gif


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


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 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
Сообщение #12


Гуру
******

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



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

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


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


Местный
***

Группа: Участник
Сообщений: 333
Регистрация: 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
jcxz
сообщение Jan 30 2017, 21:34
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 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
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 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
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 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
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 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

Сообщений в этой теме
- demiurg1978   [Вроде решено] Массив указателей на функции. Указатель на массив   Jan 29 2017, 05:14
- - psL   Цитата(demiurg1978 @ Jan 29 2017, 08:14) ...   Jan 29 2017, 09:35
|- - demiurg1978   Мне нужна функция, в качестве параметров которой у...   Jan 29 2017, 09:43
|- - psL   Цитата(demiurg1978 @ Jan 29 2017, 12:43) ...   Jan 29 2017, 09:54
|- - andrew_b   Цитата(demiurg1978 @ Jan 29 2017, 12:43) ...   Jan 29 2017, 10:00
|- - demiurg1978   Еще на ассемблере я использовал функции очистки ОЗ...   Jan 29 2017, 16:27
|- - Dog Pawlowa   Цитата(demiurg1978 @ Jan 29 2017, 22:05) ...   Jan 29 2017, 19:16
||- - jcxz   Цитата(Dog Pawlowa @ Jan 31 2017, 17:39) ...   Jan 31 2017, 17:03
||- - Dog Pawlowa   Цитата(jcxz @ Jan 31 2017, 20:03) тело та...   Feb 1 2017, 04:56
|||- - jcxz   Цитата(Dog Pawlowa @ Feb 1 2017, 06:56) Е...   Feb 1 2017, 09:53
||- - demiurg1978   Цитата(jcxz @ Jan 31 2017, 23:03) И в рез...   Feb 1 2017, 10:05
||- - jcxz   Цитата(demiurg1978 @ Feb 1 2017, 12:05) В...   Feb 1 2017, 11:58
||- - demiurg1978   Если честно, немного извращенно. Прототреды и то п...   Feb 1 2017, 14:18
|||- - jcxz   Цитата(demiurg1978 @ Feb 1 2017, 16:18) Е...   Feb 1 2017, 14:30
|||- - demiurg1978   Я единственный раз использовал дополнительную пере...   Feb 1 2017, 14:45
||- - Dog Pawlowa   Цитата(jcxz @ Feb 1 2017, 15:58) Получили...   Feb 2 2017, 07:52
||- - jcxz   Цитата(Dog Pawlowa @ Feb 2 2017, 09:52) А...   Feb 2 2017, 09:38
||- - demiurg1978   Цитата(jcxz @ Feb 2 2017, 15:38) А вот в ...   Feb 2 2017, 09:56
||- - jcxz   Цитата(demiurg1978 @ Feb 2 2017, 11:56) Х...   Feb 2 2017, 13:19
||- - demiurg1978   Цитата(jcxz @ Feb 2 2017, 19:19) Вариант ...   Feb 2 2017, 14:26
||- - jcxz   Цитата(demiurg1978 @ Feb 2 2017, 16:26) В...   Feb 2 2017, 15:07
||- - Dog Pawlowa   Цитата(jcxz @ Feb 2 2017, 19:07) занимает...   Feb 2 2017, 15:50
||- - demiurg1978   Что-то мне это баловство со стеком не нравится. Хо...   Feb 2 2017, 16:33
||- - jcxz   Цитата(demiurg1978 @ Feb 2 2017, 18:33) И...   Feb 3 2017, 09:35
||- - Dog Pawlowa   Цитата(jcxz @ Feb 3 2017, 12:35) Цель: ка...   Feb 3 2017, 11:24
||- - jcxz   Цитата(Dog Pawlowa @ Feb 3 2017, 13:24) Б...   Feb 3 2017, 13:46
||- - Dog Pawlowa   >> Покажите как Вы с помощью этого макроса р...   Feb 4 2017, 10:28
||- - zltigo   Цитата(Dog Pawlowa @ Feb 4 2017, 12:28) Д...   Feb 4 2017, 12:29
|||- - Dog Pawlowa   Цитата(zltigo @ Feb 4 2017, 16:29) нет ЕС...   Feb 5 2017, 07:53
|||- - zltigo   Цитата(Dog Pawlowa @ Feb 5 2017, 09:53) Е...   Feb 5 2017, 12:14
|||- - Dog Pawlowa   Цитата(zltigo @ Feb 5 2017, 15:14) При эт...   Feb 5 2017, 14:18
|||- - zltigo   Цитата(Dog Pawlowa @ Feb 5 2017, 16:18) С...   Feb 5 2017, 18:17
|||- - Dog Pawlowa   Цитата(zltigo @ Feb 5 2017, 21:17) Быстры...   Feb 5 2017, 18:35
|||- - zltigo   Цитата(Dog Pawlowa @ Feb 5 2017, 20:35) Т...   Feb 6 2017, 04:08
||- - jcxz   Цитата(Dog Pawlowa @ Feb 4 2017, 12:28) Я...   Feb 7 2017, 00:59
||- - Dog Pawlowa   Цитата(jcxz @ Feb 7 2017, 03:59) PC сохра...   Feb 7 2017, 14:36
|- - k155la3   Цитата(jcxz @ Jan 31 2017, 01:34) . . . ....   Feb 4 2017, 12:07
- - Obam   ЦитатаВаш вызов функции против моего вызова функци...   Feb 3 2017, 11:46


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

 


RSS Текстовая версия Сейчас: 24th June 2025 - 18:11
Рейтинг@Mail.ru


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