исать читать члены структуры генерик способом. Язык C.

jenya7
Дата: 20.07.2017 14:43:05
Есть структура с разными данными
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[arguments[0]-1].член_структуры. Получается одна переменная - одна функция.
Для того чтоб написать одну генерик функцию я думал создать указатель на член структуры
uint32_t *ptr;
ptr = &mot_data.max_ovc;
//write
*ptr = arguments[0];
//read
Parser_SendInt(COM_USART, *ptr, 1, 0);

и изменять только его в функции.
но тут возникает вопрос - получается мне нужна еще одна функция которая тупо переберет 20 (или сколько там членов структуры) кейсов и найдет на какой член структуры указывать.
как то получается довольно монструозно и не гибко.
Dima T
Дата: 20.07.2017 16:29:52
jenya7
получается мне нужна еще одна функция которая тупо переберет 20 (или сколько там членов структуры) кейсов и найдет на какой член структуры указывать.

Нужна. Думаю по-другому никак не получится.
Изопропил
Дата: 20.07.2017 16:39:45
таблицу со смещениями можно сгенерировать
jenya7
Дата: 20.07.2017 17:10:58
я ,s мог засунуть указатель в структуру принятой команды
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 передается аргументом в команде.

абсолютный адрес mot_data+(sizeof(mot_data)*array_index) + struct_member

то есть uint8_t *base_ptr = mot_data+(sizeof(mot_data)*array_index) - как мне динамически передать struct_member - base_ptr->struct_member
Dima T
Дата: 20.07.2017 17:20:40
jenya7
ситуация несколько усложнилась. у меня мултиаксис поэтому массив структур mot_data[AXIS_NUM] . то есть мне надо инициализировать так
.vp = &mot_data[AXIS].pfb
проблема что AXIS передается аргументом в команде.

Инициализируй указателем на первый элемент
.vp = &mot_data[0].pfb

а при использовании смещайся на AXIS * sizeof(mot_data)
jenya7
Дата: 20.07.2017 17:20:58
то есть надо получить в ран тайм mot_data[индекс_пришел_из_команды].переменная_пришла_из_комманды

к примеру комманда - pfb 1 1000 => mot_data[1].pfb = 1000
jenya7
Дата: 20.07.2017 17:21:54
Dima T
jenya7
ситуация несколько усложнилась. у меня мултиаксис поэтому массив структур mot_data[AXIS_NUM] . то есть мне надо инициализировать так
.vp = &mot_data[AXIS].pfb
проблема что AXIS передается аргументом в команде.

Инициализируй указателем на первый элемент
.vp = &mot_data[0].pfb

а при использовании смещайся на AXIS * sizeof(mot_data)


а член структуры?
jenya7
Дата: 20.07.2017 17:23:24
jenya7
Dima T
пропущено...

Инициализируй указателем на первый элемент
.vp = &mot_data[0].pfb

а при использовании смещайся на AXIS * sizeof(mot_data)


а член структуры?


ааа. понял. спасибо.
jenya7
Дата: 20.07.2017 17:25:17
jenya7
jenya7
пропущено...


а член структуры?


ааа. понял. спасибо.


несколько смущает привязка .vp = &mot_data[0].pfb. теряется гибкость.
jenya7
Дата: 20.07.2017 17:27:51
jenya7
jenya7
пропущено...


ааа. понял. спасибо.


несколько смущает привязка .vp = &mot_data[0].pfb. теряется гибкость.

pfd имеет свой offset в структуре. нельзя его прибавить? тупо приплюсовать