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

 
 
> Поиск по массиву в compile time на С
amaora
сообщение May 3 2018, 11:54
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 421
Регистрация: 2-01-08
Пользователь №: 33 778



Есть массив регистров, ссылки на переменные с именами и некоторыми параметрами, для удобного доступа по разным интерфейсам и конфигурирования устройства. Допустим вот так объявленный,

Код
typedef struct {

    const char        *sym;

    const char        *fmt;
    int            mode;

    union {

        float        *f;
        int        *i;
    }
    link;

    void            (* proc) (const void *reg, void *lval, const void *rval);
}
reg_t;

#define REG_E(link, extra, unit, fmt, mode, proc)    { #link extra "\0" unit, fmt, mode, \
                            { (void *) &link }, (void *) proc }

#define REG(link, unit, fmt, mode, proc)    REG_E(link, "", unit, fmt, mode, proc)

const reg_t        regfile[] = {

    REG(hal.USART_baud_rate,        "",    "%i",    REG_CONFIG, NULL),
    REG(hal.PWM_freq_hz,            "Hz",    "%i",    REG_CONFIG, NULL),
    REG(hal.PWM_dead_time_ns,        "ns",    "%i",    REG_CONFIG, NULL),
    REG(hal.ADC_reference_voltage,        "V",    "%3f",    REG_CONFIG, NULL),
    REG(hal.ADC_current_shunt_resistance,    "Ohm",    "%4e",    REG_CONFIG, NULL),
...
    REG(pm.probe_speed_ramp,    "rad/s",    "%2f",    REG_CONFIG, NULL),
    REG_E(pm.probe_speed_ramp, "_rpm",    "rpm",    "%2f",    REG_NORMAL, &reg_proc_rpm),
...


Регистры адресуются по именам или по номерам. Имена достаточно постоянны, а номера могут изменяться в следующих версиях. В этом проблема, нельзя в коде просто взять ссылку на регистр по номеру regfile[n], номер может измениться. Искать по имени в compile time слишком сложно, средствами C и препроцессора не обойтись. По адресам переменных нельзя, они могут повторятся. Какие еще варианты?

Сейчас думаю, генерировать из объявления массив макросов вида #define REG_hal_USART_baud_rate 0, но здесь тоже много проблем, надо как-то "спасать" недопустимые символы (точка и др.).

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

Спасибо.


Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Forger
сообщение May 3 2018, 12:15
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Масло-масляное.
Ваш некий реестр (я так понял по названию - константный, т.е compile-time), тогда все это можно сделать через некий h-файл, где через #define описать все параметры проекта.
Тогда нет никакого смысла создавать некий глобальный константный массив-реестр, ведь индексам этого массива все равно придется дать осмысленные имена, т.е. плодить те самые #define.

В своих проектах я использую такой файл и называю StaticSettings.h
Всем значениям даны понятные имена, чтобы в коде не фигурировали всякие "магические числа".
Править параметры проекта в одном файле проще, чем рыться по всему проекту в поисках нужного параметра.

Пример содержимого GlobalSettings.h (Keil), (все "лишнее" вырезал, чтобы не плодить новые вопросы)
Код
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Project:        STM32L Bootloader
// Description:    Project settings
////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Use Configuration Wizard in Context Menu
////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// ================================================= SYSTEM ====================================================
//    <h>System

//     <o>Core Frequency [MHz]
//        <24=> 24 MHz
#define CORE_FREQUENCY_MHZ                        (24)
#define CORE_FREQUENCY_HZ                            (CORE_FREQUENCY_MHZ * 1000000UL)

//     <o>HSE Quartz Frequency [MHz]
//        <12=> 12 MHz <8=> 8 MHz
#define HSE_FREQUENCY_MHZ                            (12)

//    <o>Interrupts Stack size [bytes] <128-65536>
//    <i> Defines the stack size for all interrupts (incl. nested)
//    <i> Minimum: 128
#define INTERRUPTS_STACK_SIZE_BYTES                    (512)

//    </h>

// ============================================== APPLICATION ==================================================
//    <h>Application

//    <s.32>Application Name
#define APPLICATION_NAME                            "******"

//    <s.32>CPU Chip Name
#define CPU_CHIP_NAME                                "STM32L151RCT6A"

//    <h>Bootloader version:
//    <o>Major
#define BOOTLOADER_VERSION_MAJOR                    (1)

//    <o>Minor
#define BOOTLOADER_VERSION_MINOR                    (0)

//    <o>Build
#define BOOTLOADER_VERSION_BUILD                    (1)

//    </h>

//    <h>Hardware version:
//    <o>Major
#define HARDWARE_VERSION_MAJOR                        (1)

//    <o>Minor
#define HARDWARE_VERSION_MINOR                        (2)

//    </h>

//    </h>


.........


Вот так выглядит доступ к этим настройкам этого h-файла в Keil:

Прикрепленное изображение





зы. А вот для динамических (сохраняемых настроек), которые могут изменяться в процессе работы приложения, я использую отдельный модуль Settings, который дает интерфейс к доступу к ряду параметров.
Причем, не реализуется просто доступ по некому абстрактному индексу в неком мифическом массиве, а по названию, т. е. через соотв. функции, чтобы ибежать непреднамеренно порчи "чужих" параметров - "реестр" нужно защищать, это вам не винда wink.gif


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
x736C
сообщение May 3 2018, 14:01
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 1 273
Регистрация: 3-03-06
Пользователь №: 14 942



Цитата(Forger @ May 3 2018, 15:15) *
зы. А вот для динамических (сохраняемых настроек), которые могут изменяться в процессе работы приложения, я использую отдельный модуль Settings, который дает интерфейс к доступу к ряду параметров.
Причем, не реализуется просто доступ по некому абстрактному индексу в неком мифическом массиве, а по названию, т. е. через соотв. функции, чтобы ибежать непреднамеренно порчи "чужих" параметров - "реестр" нужно защищать, это вам не винда wink.gif

Как примерно хотя бы выглядит модуль Settings, не могли бы поделиться? И как обеспечивается защита?

И еще вопрос вдогонку.
Допустим, в StaticSettings у меня есть настройка #define FW_REV "v.1.1".
Где-то должен быть, например, const char *rev = FW_REV
Где вы обычно такую информацию храните? в main.c или какой-то отдельный файл, в котором организуется хранение системных констант в памяти?
Прошу прощения за нубские вопросы.
Go to the top of the page
 
+Quote Post
Forger
сообщение May 3 2018, 14:42
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(x736C @ May 3 2018, 17:01) *
Как примерно хотя бы выглядит модуль Settings, не могли бы поделиться?

Он написан на плюсах и представляет собой набор методов для доступа к нужным параметром.
Список методов в разных проектах различный, но основной принцип неизменный.
В конструкторе - чтение сохраненных параметров. Если они "битые" (проверяется контрольная сумма), то восстанавливаются параметры по-умолчанию.
Сами рабочие параметры хранятся в ОЗУ, при сохранении они переписываются в энергонезависимую память через отдельную функцию/метод отложенно или сразу при изменении параметра (зависит от проекта).
Пишутся только те параметры, которые изменились. Разумеется, пересчитывается контрольная сумма и тоже переписывается.

Цитата
И как обеспечивается защита?

Один метод = один параметр. (в терминологии С++ "метод", в терминологии С - функция).
Внутри реализации конкретного метода проверяются входные данные.
Более сложные случае реализуются несколько иначе.

Цитата
И еще вопрос вдогонку.
Допустим, в StaticSettings у меня есть настройка #define FW_REV "v.1.1".
Где-то должен быть, например, const char *rev = FW_REV

Сами параметры хранятся естественно в виде одной большой структуры (struct), т.е. никаких элементов некого мифического массива.
Доступ к полям этой структуры ИСКЛЮЧИТЕЛЬНО через методы (функции).

В StaticSettings я объявляю рабочие характеристики проекта, которые в процессе работы никогда не меняются, а также даю значения параметрам по-умолчанию (default) для модуля Settings.

Т.е. на голом С я бы создал в Settings.c ОДИН экземпляр структуры всех параметров (в ОЗУ) с квалификатором static, разумеется.
В Settings.h объявил бы кучу функций с ОСМЫСЛЕННЫМИ именами.

Цитата
Где вы обычно такую информацию храните?
Это не принципиально, но чаще всего в EEPROM памяти, если нет, то во FLASH.

Цитата
в main.c или какой-то отдельный файл, в котором организуется хранение системных констант в памяти?

Нет, все это сделано внутри файла Settings.cpp

Почему так делаю? Да потому что принципиально не использую глобальные переменные. От слова вообще, поэтому подобные данные хранятся внутри класса Setting.

Все остальные части (у меня модули) проекта понятия не имеют о существовании некого Setting (равно как и других модулей), т.е. Settings.hpp инклудится только в одном месте и виден только классу Application.
А для доступа к методам класса Settings используются "делегаты", а Application лишь связывает модули вместе, точнее связывает их делегаты.
Впрочем, это уже совсем другая история и к этой теме не имеет отношения.

зы. Я описал чисто свой способ реализации этой задачи - мне ТАК проще. Поэтому прошу не разводить на базе моих выкладок очередной холивар на тему C vs C++.


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- amaora   Поиск по массиву в compile time на С   May 3 2018, 11:54
- - Kabdim   А зачем так сделано? Выглядит как кусок для внешне...   May 3 2018, 12:09
|- - jcxz   Цитата(Forger @ May 3 2018, 15:15) В свои...   May 5 2018, 09:33
|- - Forger   Цитата(jcxz @ May 5 2018, 12:33) Лучше ра...   May 5 2018, 10:26
|- - jcxz   Цитата(Forger @ May 5 2018, 13:26) К тому...   May 5 2018, 11:02
|- - Forger   Цитата(jcxz @ May 5 2018, 14:02) Вобщем -...   May 5 2018, 14:50
- - amaora   Параметры не константные, все разные, есть настрой...   May 3 2018, 13:16
- - Kabdim   А точка в ваших определениях регистров всегда буде...   May 3 2018, 13:40
- - amaora   Функции доступа я тоже мог бы написать, но в этом ...   May 5 2018, 08:15
- - amaora   Вот так сделал Кодcat regfile.c | sed -n ...   Aug 11 2018, 18:54
|- - Arlleex   Цитата(amaora @ Aug 11 2018, 21:54) Вот т...   Aug 12 2018, 07:00
- - amaora   Ну, здесь я обычно не задаю вопросов по своей осно...   Aug 12 2018, 16:52
- - Nixon   Для доступа по индексу можно так сделать Кодenum V...   Aug 13 2018, 13:58
|- - Forger   Цитата(Nixon @ Aug 13 2018, 16:58) Для до...   Aug 13 2018, 14:51
- - DASM   Вот чтобы не плодить тем, возник вопрос. Есть стру...   Aug 13 2018, 17:36
|- - Forger   Цитата(DASM @ Aug 13 2018, 20:11) ... Пыт...   Aug 13 2018, 17:39
|- - Сергей Борщ   QUOTE (DASM @ Aug 13 2018, 20:36) max_enu...   Aug 13 2018, 18:31
|- - DASM   Цитата(Сергей Борщ @ Aug 13 2018, 21:31) ...   Aug 13 2018, 18:37
|- - Forger   Цитата(DASM @ Aug 13 2018, 21:37) Но как ...   Aug 13 2018, 18:39
|- - Сергей Борщ   QUOTE (DASM @ Aug 13 2018, 21:37) да оно ...   Aug 13 2018, 19:47
|- - DASM   Цитата(Сергей Борщ @ Aug 13 2018, 22:47) ...   Aug 13 2018, 20:08
|- - Forger   Цитата(DASM @ Aug 13 2018, 23:08) Можно с...   Aug 13 2018, 20:17
|- - Сергей Борщ   QUOTE (DASM @ Aug 13 2018, 23:08) Выше вы...   Aug 13 2018, 22:49
|- - DASM   Цитата(Сергей Борщ @ Aug 14 2018, 01:49) ...   Aug 14 2018, 02:53
|- - Nixon   Цитата(Сергей Борщ @ Aug 14 2018, 01:49) ...   Aug 14 2018, 06:14
|- - DASM   Цитата(Nixon @ Aug 14 2018, 09:14) Не обя...   Aug 14 2018, 06:18
|- - Nixon   Цитата(DASM @ Aug 14 2018, 09:18) О, кста...   Aug 14 2018, 06:24
- - DASM   А наоборот как ? Кодtypedef enum {t1, t2, t3 = ...   Aug 13 2018, 18:15
|- - Forger   По-ходу я ошибся с явным указанием типа enum, у ме...   Aug 13 2018, 18:25
|- - DASM   Цитата(Forger @ Aug 13 2018, 21:25) По-хо...   Aug 13 2018, 18:43
|- - Forger   Цитата(DASM @ Aug 13 2018, 21:43) А вот т...   Aug 13 2018, 19:28
- - DASM   Гы, const struct а тут мы возвращаемся к вопросу и...   Aug 13 2018, 19:39
|- - Forger   Цитата(DASM @ Aug 13 2018, 22:39) Гы, con...   Aug 13 2018, 19:49
- - Nixon   Может ещё кому полезно будет: В анонимных структу...   Aug 13 2018, 20:31
|- - Forger   Цитата(Nixon @ Aug 13 2018, 23:31) Наприм...   Aug 13 2018, 20:37
- - Nixon   Я без привязки к вашему примеру. Просто довольно п...   Aug 13 2018, 20:49
|- - Forger   Цитата(Nixon @ Aug 13 2018, 23:49) Просто...   Aug 13 2018, 20:51
- - DASM   Вот нашел ответ, как удобно пользовать enum class....   Aug 14 2018, 05:53
- - Kabdim   По факту тип указанный в энуме, года 3 назад работ...   Aug 14 2018, 06:32
- - DASM   Да, лучше. Но пока не знал об этом - много писанин...   Aug 14 2018, 06:34
|- - Kabdim   Цитата(DASM @ Aug 14 2018, 09:34) "3...   Aug 14 2018, 06:49
- - Nixon   В стандарте то стандарте, но не совсем "С...   Aug 14 2018, 06:39
|- - DASM   Цитата(Nixon @ Aug 14 2018, 09:39) В стан...   Aug 14 2018, 07:10
|- - Kabdim   Цитата(DASM @ Aug 14 2018, 10:10) это как...   Aug 14 2018, 07:17
- - DASM   Цитатаtypedef enum { tst, tst2, tst3 } test; #pra...   Aug 16 2018, 06:32
|- - Kabdim   Цитата(DASM @ Aug 16 2018, 09:32) А что т...   Aug 16 2018, 14:29
|- - DASM   Цитата(Kabdim @ Aug 16 2018, 17:29) А чег...   Aug 16 2018, 14:41
|- - Forger   После sizeof ( некого enum ), недалеко и до sizeof...   Aug 16 2018, 14:56
||- - DASM   Цитата(Forger @ Aug 16 2018, 17:56) После...   Aug 16 2018, 15:09
||- - Forger   Цитата(DASM @ Aug 16 2018, 18:09) А все ж...   Aug 16 2018, 15:13
|- - Kabdim   Цитата(DASM @ Aug 16 2018, 17:41) Просто ...   Aug 17 2018, 10:39
|- - Arlleex   Цитата(Kabdim @ Aug 17 2018, 14:39) Как э...   Aug 17 2018, 10:54
|- - DASM   Цитата(Kabdim @ Aug 17 2018, 13:39) Как э...   Aug 17 2018, 12:04
|- - Forger   Цитата(DASM @ Aug 17 2018, 15:04) offseto...   Aug 17 2018, 12:23
|- - Kabdim   Применительно к этой ситуации, как раз Кейл - непр...   Aug 17 2018, 12:45
- - sigmaN   Извиняюсь, если это уже предлагали(не читал все со...   Aug 17 2018, 08:08
- - Kabdim   Я не вижу. Вопрос был DASM'у цитата к которой ...   Aug 17 2018, 11:51
- - sigmaN   From Standard C++ 7.2/5: ЦитатаThe underlying type...   Aug 19 2018, 06:25
- - DASM   Да ладно, фиг с ним.   Aug 19 2018, 20:41


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

 


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


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