|
Писать/читать члены структуры генерик способом. |
|
|
|
Jul 20 2017, 11:30
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Есть структура с разными данными CODE typedef struct MOTOR_DATA_S { uint32_t mot_num; uint32_t mot_ena; uint32_t sprof_ena; uint32_t tprof_ena; //run time uint32_t state; uint32_t dir; uint32_t speed; int32_t position; uint32_t current; uint32_t ovc; uint32_t soft_start; uint32_t soft_stop; //hardware interface uint32_t lim_sw_fwd; uint32_t lim_sw_rev; uint32_t pwm_tim; uint32_t pwm_num; uint32_t fwd_pwm_chan; uint32_t rev_pwm_chan; uint32_t adc_chan; uint32_t enc_num; uint32_t enc_type; uint32_t start_stop; //max limits uint32_t fwd_pwm_run; uint32_t rev_pwm_run; uint32_t fwd_max_pos; uint32_t rev_max_pos; uint32_t max_current; uint32_t max_ovc; SPEED_PROFILE fwd_profile[MAX_PROFILES]; SPEED_PROFILE rev_profile[MAX_PROFILES]; TRAPEZ_PROFILE start_profile; TRAPEZ_PROFILE stop_profile; } MOTOR_DATA;
MOTOR_DATA mot_data;
Я пишу читаю члены структуры посредством команд пришедших с терминала. Ну например так Код uint32_t COM_Ovc(uint32_t argc, char** args) { uint32_t arguments[argc]; uint32_t addr_offset; if (GetIntArguments(argc, args, arguments) == MSG_OK) { if (ValidateArgument(arguments[0], 0, 0xFFFF)) { if (argc >0) // argument - write { mot_data.max_ovc = arguments[0]; EE_WriteVariable(EPR_ADR_OVC, arguments[0]); } else //no argument - read Parser_SendInt(COM_USART, mot_data.max_ovc, 1, 0); } else return MSG_INV_ARG; } else return MSG_MIS_ARG; return MSG_OK; В общем все команды одинаковы за исключением mot_data.член_структуры. Получается одна переменная - одна функция. Для того чтоб написать одну генерик функцию я думал создать указатель на член структуры Код uint32_t *ptr; ptr = &mot_data.max_ovc; //write *ptr = arguments[0]; //read Parser_SendInt(COM_USART, *ptr, 1, 0); и изменять только его в функции. но тут возникает вопрос - получается мне нужна еще одна функция которая тупо переберет 20 (или сколько там членов структуры) кейсов и найдет на какой член структуры указывать. как то получается довольно монструозно и не гибко.
Сообщение отредактировал Jenya7 - Jul 20 2017, 11:31
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 27)
|
Jul 20 2017, 11:50
|
Знающий
   
Группа: Свой
Сообщений: 781
Регистрация: 3-10-04
Из: Санкт-Петербург
Пользователь №: 768

|
Цитата(Jenya7 @ Jul 20 2017, 14:30)  Есть структура с разными данными CODE typedef struct MOTOR_DATA_S { uint32_t mot_num; uint32_t mot_ena; uint32_t sprof_ena; uint32_t tprof_ena; //run time uint32_t state; uint32_t dir; uint32_t speed; int32_t position; uint32_t current; uint32_t ovc; uint32_t soft_start; uint32_t soft_stop; //hardware interface uint32_t lim_sw_fwd; uint32_t lim_sw_rev; uint32_t pwm_tim; uint32_t pwm_num; uint32_t fwd_pwm_chan; uint32_t rev_pwm_chan; uint32_t adc_chan; uint32_t enc_num; uint32_t enc_type; uint32_t start_stop; //max limits uint32_t fwd_pwm_run; uint32_t rev_pwm_run; uint32_t fwd_max_pos; uint32_t rev_max_pos; uint32_t max_current; uint32_t max_ovc; SPEED_PROFILE fwd_profile[MAX_PROFILES]; SPEED_PROFILE rev_profile[MAX_PROFILES]; TRAPEZ_PROFILE start_profile; TRAPEZ_PROFILE stop_profile; } MOTOR_DATA;
MOTOR_DATA mot_data;
Структура маленькая, получайте и заполняйте ее целиком, парсить каждую уставку бессмысленно.
|
|
|
|
|
Jul 20 2017, 12:07
|
Знающий
   
Группа: Свой
Сообщений: 781
Регистрация: 3-10-04
Из: Санкт-Петербург
Пользователь №: 768

|
Цитата(Jenya7 @ Jul 20 2017, 15:05)  оператор хочет изменить/прочитать один параметр. он в команде передает мне какой. А кто протокол обмена придумал? Изменил один параметр, шлешь все уставки. P.S. Если нет команды поменять все, то начнется беда. Нужно применить набор новых уставок - будешь менять по одной. Так и вижу, как шлются и парсятся 20+ пакетов на изменение содержимого структуры )) А что, процессор зато занят )) P.P.S. К тому же писать сразу в ЕЕПРОМ совершенно незачем. Есть и врЕменные уставки.
|
|
|
|
|
Jul 20 2017, 12:31
|
Знающий
   
Группа: Свой
Сообщений: 781
Регистрация: 3-10-04
Из: Санкт-Петербург
Пользователь №: 768

|
Цитата(Jenya7 @ Jul 20 2017, 15:24)  Изменил один параметр, шлешь все уставки? Зачем? А какие противопоказания? Цитата вопрос когда записать в ЕЕПРОМ если не сразу? По команде. Можно и по другим признакам, кол-во перемен или время. Но надо ли? Команда "сохранить уставки" все решит.
|
|
|
|
|
Jul 20 2017, 12:40
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Цитата(Jenya7 @ Jul 20 2017, 14:30)  . . . но тут возникает вопрос - получается мне нужна еще одна функция которая тупо переберет 20 (или сколько там членов структуры) кейсов и найдет на какой член структуры указывать. как то получается довольно монструозно и не гибко. Если параметров достаточно много и разных ( а даже - и немного) имеет смысл все параметры перечислить в некой "базе", и далее работать с ними для записи-чтения по коду (номеру в базе) Причем при такой методе параметры могут быть самые "разношерстные", а доступ ведется перебором или по номеру-индексу. Можно создавать списки из различных наборов переменных для записи. Пишу "все оптом", тк использую флеш, а для нее - что байт, что страница - всеравно. Код struct SVarBase { int VarID; // уникальный код переменной по e_VarIdCode void * VarPtr; // адрес переменной int VarType; // тип переменной по кодификации enum e_TypeVar // VarTypes.h };
typedef const SVarBase TVarBase;
__root TVarBase VarBase[] = { // ------------------- DATA -------------------------- [eV_MM_Au ] = { eV_MM_Au, &MM_Au, T_REAL }, // ---------- [eV_MM_A1234_0] = { eV_MM_A1234_0, &MM_A1234[0], T_REAL }, [eV_MM_A1234_1] = { eV_MM_A1234_1, &MM_A1234[1], T_REAL }, . . . .
|
|
|
|
|
Jul 20 2017, 12:44
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(k155la3 @ Jul 20 2017, 18:40)  Если параметров достаточно много и разных ( а даже - и немного) имеет смысл все параметры перечислить в некой "базе", и далее работать с ними для записи-чтения по коду (номеру в базе) Причем при такой методе параметры могут быть самые "разношерстные", а доступ ведется перебором или по номеру-индексу. Можно создавать списки из различных наборов переменных для записи. Пишу "все оптом", тк использую флеш, а для нее - что байт, что страница - всеравно. Код struct SVarBase { int VarID; // уникальный код переменной по e_VarIdCode void * VarPtr; // адрес переменной int VarType; // тип переменной по кодификации enum e_TypeVar // VarTypes.h };
typedef const SVarBase TVarBase;
__root TVarBase VarBase[] = { // ------------------- DATA -------------------------- [eV_MM_Au ] = { eV_MM_Au, &MM_Au, T_REAL }, // ---------- [eV_MM_A1234_0] = { eV_MM_A1234_0, &MM_A1234[0], T_REAL }, [eV_MM_A1234_1] = { eV_MM_A1234_1, &MM_A1234[1], T_REAL }, . . . . а ну если так то я могу засунуть указатель в структуру принятой команды Код typedef struct COMMAND_S { char *name; //command name uint32_t command_type; uint32_t minargs; uint32_t maxargs; uint32_t (*fp)(unsigned int, char **); //fuction poiner
//это я добавляю uint32_t *vp; //variable pointer }COMMAND; я все равно инициализирую структуру команд. так я добавлю указатель на переменную Код COMMAND commands[] = { [0] = { "stop", 0, 1, MAX_ARGS, .fp = OneGlobFunc, .vp = NULL }, [1] = { "start", 0, 1, MAX_ARGS, .fp = OneGlobFunc, .vp = NULL }, [2] = { "fwd", 0, 1, MAX_ARGS, .fp = OneGlobFunc, .vp = NULL}, [3] = { "rev", 0, 1, MAX_ARGS, .fp = OneGlobFunc, .vp = NULL}, [4] = { "mot", 0, 1, MAX_ARGS, .fp = OneGlobFunc, .vp = NULL }, [5] = { "pfb", 0, 1, MAX_ARGS, .fp = OneGlobFunc, .vp = &mot_data.pfb}, [6] = { "ifb", 0, 1, MAX_ARGS, .fp = OneGlobFunc, .vp = &mot_data.ifb}, [7] = { "ftop", 0, 1, MAX_ARGS, .fp = OneGlobFunc .vp = &mot_data.fwd_max_pos }, [8] = { "rtop", 0, 1, MAX_ARGS, .fp = OneGlobFunc .vp = &mot_data.rev_max_pos} }; ситуация несколько усложнилась. у меня мултиаксис поэтому массив структур mot_data[AXIS_NUM] . то есть мне надо инициализировать так .vp = &mot_data[AXIS].pfb проблема что AXIS передается аргументом в команде.
Сообщение отредактировал Jenya7 - Jul 20 2017, 12:57
|
|
|
|
|
Jul 20 2017, 12:55
|
Знающий
   
Группа: Свой
Сообщений: 781
Регистрация: 3-10-04
Из: Санкт-Петербург
Пользователь №: 768

|
Цитата(k155la3 @ Jul 20 2017, 15:40)  Если параметров достаточно много и разных ( а даже - и немного) имеет смысл все параметры перечислить в некой "базе", и далее работать с ними для записи-чтения по коду (номеру в базе) Причем при такой методе параметры могут быть самые "разношерстные", а доступ ведется перебором или по номеру-индексу. Вот только не понятно зачем по номеру? Для кого придуманы структуры "struct" и объединения "union"? Они позволяют доступ на этапе связывания (линковки) по адресу. Без функций, номеров и т.п. программазма. Используете в программе структуру уставок/параметров - отлично. Заменяйте их все одновременно. Как? Имейте 3 записи: 1-ЕЕПРОМ, 2-уставки в ОЗУ, 3-рабочие копии в ОЗУ. Пришла команда - изменяем уставки 2. Подгоняем уставки 3. Устроили "оператора" - пишем уставки 2 в 1. Иначе зачем они там? Программирование это не только "coding", это еще и структурирование и декомпозиция т.п. А программизм ради структурирования сродни (сами придумаете).
|
|
|
|
|
Jul 20 2017, 13:46
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Цитата(Tiro @ Jul 20 2017, 15:55)  (1) Вот только не понятно зачем по номеру? . . . (2) . . . Заменяйте их все одновременно. (3) Программирование это не только "coding", это еще и структурирование и декомпозиция т.п. А программизм ради структурирования сродни (сами придумаете). (1) одна из многих причин - обмен данными прибора и PC. Чтобы избежать "шизофрении" - на порядок удобнее работать с кодом параметра (фактически его уникальным Id) и базой параметров. Для "синхронизации" проектов для прибора и PC достаточно чтобы они использовали один файл - базы, где указано соотв-ие параметра, его Id, тип_данных --> размер поля итд. Для "упаковки" в пакет или страницу флеш использую сериализацию. Это надежнее. (2) пока все парам. влазят в страницу (264 байта) - я так и делаю. (3) да  Я привел пример только как один из многих-бесконечных вариантов реализации. ps - структуры отличное решение, еслиб...... не выравнивание, а темболее - для разных платформ. А также зависимость от опций компилятора. Цитата(Jenya7 @ Jul 20 2017, 15:44)  а ну если так то я могу засунуть указатель в структуру принятой команды . . . . я все равно инициализирую структуру команд. так я добавлю указатель на переменную Да, где-то так. У меня по такой идее постоены работа HMI прибора - меню и работа с внешним терминалом по USART. По меню проскакивало обсуждение, тег кажется micromenu.
|
|
|
|
|
Jul 20 2017, 13:58
|
Знающий
   
Группа: Свой
Сообщений: 781
Регистрация: 3-10-04
Из: Санкт-Петербург
Пользователь №: 768

|
Цитата(k155la3 @ Jul 20 2017, 16:46)  (1) одна из многих причин - обмен данными прибора и PC. Чтобы избежать "шизофрении" - на порядок удобнее работать с кодом параметра (фактически его уникальным Id) и базой параметров. Для "синхронизации" проектов для прибора и PC достаточно чтобы они использовали один файл - базы, где указано соотв-ие параметра, его Id, тип_данных --> размер поля итд. Для "упаковки" в пакет или страницу флеш использую сериализацию. Это надежнее. Этот аргумент хорош для придания совместимости с ранее разработанными приборами. И при этом все равно лучше передавать блок параметров. Заметьте, что сериализация все равно машиннозависимая. Если слать параметры и размеры, то это то, от чего хотел уйти. (2) пока все парам. влазят в страницу (264 байта) - я так и делаю. Цитата(k155la3 @ Jul 20 2017, 16:46)  Я привел пример только как один из многих-бесконечных вариантов реализации. ps - структуры отличное решение, еслиб...... не выравнивание, а темболее - для разных платформ. А также зависимость от опций компилятора. Вот с выравниванием тут хорошо. Я сказал "передавать блок параметров", рассортируйте по адресам.
|
|
|
|
|
Jul 20 2017, 14:18
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(Tiro @ Jul 20 2017, 20:07)  Если правильно понял, то достаточно прочесть Карнегина и Ричина. После присвоения base_ptr = mot_data без твоих выражений доступ по base_ptr[array_index].mot_number это не base_ptr[array_index]. mot_number - это base_ptr[array_index]. зависит_от_команды_пришедшей_по_терминалу - мне надо чтоб указатель указывал на base_ptr[array_index]. зависит_от_команды_пришедшей_по_терминалу
Сообщение отредактировал Jenya7 - Jul 20 2017, 14:19
|
|
|
|
|
Jul 20 2017, 14:24
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Цитата(Jenya7 @ Jul 20 2017, 16:59)  uint32_t *base_ptr; base_ptr = mot_data+(sizeof(mot_data)*array_index); как мне динамически передать struct_member - base_ptr->struct_member может offsetof(x,y) ? И зачем динамически, ОНОж вроде, константа ? ps - смещения offsetof(x,y) занесите в массив - "описатель" структуры.
|
|
|
|
|
Jul 20 2017, 14:47
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(k155la3 @ Jul 20 2017, 20:24)  может offsetof(x,y) ? И зачем динамически, ОНОж вроде, константа ? ps - смещения offsetof(x,y) занесите в массив - "описатель" структуры. а да? offsetof(структура, член) вернет офсет члена в структуре? Цитата(Tiro @ Jul 20 2017, 20:44)  Одна сущность или разные? Первая - статический член структуры, второе - перегруженный оператор. Определись. ну что то должно быть статическим. либо &mot_data[0].член_структуры, либо offsetof(структура, член) если это работает.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|