Easyelectronics.ru

Электроника для всех
Текущее время: 22 апр 2019, 03:27

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/10pcs (Любой цвет!)
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 5 ] 
Автор Сообщение
 Заголовок сообщения: Писать читать члены структуры генерик способом.
СообщениеДобавлено: 20 июл 2017, 16:37 
Старожил

Зарегистрирован: 17 фев 2016, 17:31
Сообщения: 216
Есть структура с разными данными
Код:
typedef struct MOTOR_DATA_S
{
    //run time
    uint32_t state;
    uint32_t dir;
    uint32_t speed;
    int32_t position;
    uint32_t current;
    uint32_t ovc;

    //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;
   
    //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 (или сколько там членов структуры) кейсов и найдет на какой член структуры указывать
как то получается довольно монструозно и не гибко.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Писать читать члены структуры генерик способом.
СообщениеДобавлено: 21 июл 2017, 12:11 
Старожил
Аватара пользователя

Зарегистрирован: 01 ноя 2011, 23:51
Сообщения: 750
МОжно структуру объединить в UNION с массивом и обращаться к данным как к элементу массива ,например по указателю, вопрос насколько это будет легче.. НО иногда это бывает удобно.

Тем более что вроде как у Вас все поля структуры одного типа..


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Писать читать члены структуры генерик способом.
СообщениеДобавлено: 21 июл 2017, 13:43 
Старожил

Зарегистрирован: 10 июн 2011, 23:01
Сообщения: 3161
offsetof ?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Писать читать члены структуры генерик способом.
СообщениеДобавлено: 21 июл 2017, 14:40 
Старожил

Зарегистрирован: 19 мар 2013, 19:37
Сообщения: 2567
Откуда: Санкт-Петербург
Говномакросы?
Код:
#define MOT\
  OP(state) \
  OP(dir) \
  ...

#define OP(x) uint32_t x;
typedef struct MOTOR_DATA_S
{
  MOT
} MOTOR_DATA;
#undef OP

#define OP(x) if(!strcmp(name,#x)) mot_data.x=value;
void process(name, value) {
  MOT
}
#undef OP

Не факт, что так стОит делать, но понимать такой код всё равно надо.
Да, использовать, как я написал, не надо, это лишь иллюстрация принципа - как из одного списка полей развернуть и структуру, и функцию перебора полей по именам.
Можно ту же технологию использовать, чтобы создать массив пар имя - указатель.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Писать читать члены структуры генерик способом.
СообщениеДобавлено: 24 июл 2017, 10:32 
Старожил

Зарегистрирован: 17 фев 2016, 17:31
Сообщения: 216
спасибо за советы.
решил проблему следующим образом. в структуре принятой команды добавил var_offset = offsetof(structure, member)
а в команде получаю указатель на член структуры
(uint8_t *) param_ptr = (uint8_t *)mot_data+(sizeof(mot_data)*mot_num) + command.var_offset;


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 5 ] 

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB