jcxz 243 18 ноября, 2022 Опубликовано 18 ноября, 2022 · Жалоба 1 минуту назад, Solonovatiy сказал: Что это вопрос внутренней реализации. У вас вообще нет инфы как реализовано HTTP и контроль мотора и что там внутри? Для управления PMSM-мотором, алгоритм его обслуживания должен выполняться с частотами порядка 10-30 кГц. А HTTP-сервер (тем более HTTPS) требует иногда выполнения обработки большого единого HTTP-запроса, с формированием HTTP-ответа может быть в десятки КБ. Такая обработка никак не успеет выполниться между двумя обслуживаниями мотора если пытаться запихнуть это в один цикл. PS: Это вам для информации что такое то и другое. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Solonovatiy 0 18 ноября, 2022 Опубликовано 18 ноября, 2022 (изменено) · Жалоба 6 minutes ago, jcxz said: Для управления PMSM-мотором, алгоритм его обслуживания должен выполняться с частотами порядка 10-30 кГц. А HTTP-сервер (тем более HTTPS) требует иногда выполнения обработки большого единого HTTP-запроса, с формированием HTTP-ответа может быть в десятки КБ. Такая обработка никак не успеет выполниться между двумя обслуживаниями мотора если пытаться запихнуть это в один цикл. PS: Это вам для информации что такое то и другое. Что мешает на практике сделать в HTTP огромнейшую стейт машину, которая будет по паре строк обрабатывать, а потом руками "елдить"? Ну кроме здравого смысла конечно (блин причем видал подобное, на дурных проектах, где битбангом интерфейсы делали и больше не хочу). Я в предыдущем посте все это расписал (и еще подправлял минут 5 после поста.) Изменено 18 ноября, 2022 пользователем Solonovatiy Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tgruzd 11 18 ноября, 2022 Опубликовано 18 ноября, 2022 (изменено) · Жалоба 18 минут назад, Solonovatiy сказал: Но вопрос как раз про поиск этой грани и принципах ее поиска. Вот с какого момента стоит разделять таски, а когда стоит жаться в одном. Вроде с двух сторон ограничения есть: с одной стороны производительность процессора, с другой - сложность кода. Нужно искать баланс, в общем. Изменено 18 ноября, 2022 пользователем tgruzd Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Solonovatiy 0 18 ноября, 2022 Опубликовано 18 ноября, 2022 · Жалоба Just now, tgruzd said: Вроде с двух сторон ограничения есть: с одной стороны производительность процессора, с другой - сложность кода. Нужно искать баланс, в общем. Да и про него поиск весь этот топик. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 18 ноября, 2022 Опубликовано 18 ноября, 2022 · Жалоба 8 минут назад, Solonovatiy сказал: Что мешает на практике сделать в HTTP огромнейшую стейт машину, которая будет по паре строк обрабатывать, а потом руками "елдить"? Ну кроме здравого смысла конечно Ну вот здравый смысл и мешает. Я ещё ранее говорил - никто не мешает надевать трусы через голову. Но так сложнее. А вот футболку наоборот - удобнее через голову одевать, а не так как трусы. Вот видите - для всего есть свой удобный путь: для трусов - один, для футболок - другой. И не надо пытаться всегда идти одним путём. Хотя и возможно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Solonovatiy 0 18 ноября, 2022 Опубликовано 18 ноября, 2022 (изменено) · Жалоба 4 minutes ago, tgruzd said: Вроде с двух сторон ограничения есть: с одной стороны производительность процессора, с другой - сложность кода. Нужно искать баланс, в общем. Да и про него поиск весь этот топик. 1 minute ago, jcxz said: Вот видите - для всего есть свой удобный путь: для трусов - один, для футболок - другой. И не надо пытаться всегда идти одним путём. Хотя и возможно. Я там же выше написал. Ваш пример очень очень простой с точки зрения выбора. Есть однозначно трусы, есть однозначно футболка. Но не всегда все так очевидно. Об этом и хотел изначально поговорить. Изменено 18 ноября, 2022 пользователем Solonovatiy Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tgruzd 11 18 ноября, 2022 Опубликовано 18 ноября, 2022 (изменено) · Жалоба Вы всё-таки кусочек своего хидера скиньте, а то уже все втроём ни о чём пишем. Уже всем всё понятно Изменено 18 ноября, 2022 пользователем tgruzd Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Solonovatiy 0 18 ноября, 2022 Опубликовано 18 ноября, 2022 (изменено) · Жалоба 19 minutes ago, tgruzd said: Вы всё-таки кусочек своего хидера скиньте, а то уже все втроём ни о чём пишем. Уже всем всё понятно Пример автогенерации Spoiler EEPROM_ADDR_CONFIG_BEGIN = (0x100) MODULE_A_CONFIG_SIZE = (sizeof(module_a_config_t)) EEPROM_ADDR_MODULE_A_CONFIG = (EEPROM_ADDR_CONFIG_BEGIN) MODULE_B_CONFIG_SIZE = (sizeof(module_b_config_t)) EEPROM_ADDR_MODULE_B_CONFIG = (EEPROM_ADDR_MODULE_A_CONFIG + MODULE_A_CONFIG_SIZE) MODULE_C_CONFIG_SIZE = (sizeof(module_c_config_t)) EEPROM_ADDR_MODULE_C_CONFIG = (EEPROM_ADDR_MODULE_B_CONFIG + MODULE_B_CONFIG_SIZE) Использование: #include "eeprom_addresses.h" Somewhere in module B { ... Eeprom.Write(this.config, EEPROM_ADDR_MODULE_B_CONFIG); ... } Пример ручного забивания, для переносимости и известности адресов Spoiler MODULE_A_CONFIG_SIZE = (sizeof(module_a_config_t)) EEPROM_ADDR_MODULE_A_CONFIG = (0x100) MODULE_B_CONFIG_SIZE = (sizeof(module_b_config_t)) EEPROM_ADDR_MODULE_B_CONFIG = (0x200) MODULE_C_CONFIG_SIZE = (sizeof(module_c_config_t)) EEPROM_ADDR_MODULE_C_CONFIG = (0x300) #if((EEPROM_ADDR_MODULE_A_CONFIG + MODULE_A_CONFIG_SIZE) >= EEPROM_ADDR_MODULE_B_CONFIG) #error "EEPROM address conflict" #endif Отдельно веселье начинается, когда не надо все сохранять или не надо все сохранять постоянно, а лишь одну переменную. Изменено 18 ноября, 2022 пользователем Solonovatiy Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tgruzd 11 18 ноября, 2022 Опубликовано 18 ноября, 2022 · Жалоба typedef struct{ module_a_config_t a; module_b_config_t b; module_c_config_t c; }config_t; config_t config; и т.д с этим уже проще будет работать Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Solonovatiy 0 18 ноября, 2022 Опубликовано 18 ноября, 2022 (изменено) · Жалоба 5 minutes ago, tgruzd said: typedef struct{ module_a_config_t a; module_b_config_t b; module_c_config_t c; }config_t; config_t config; и т.д с этим уже проще будет работать Предлагаете перезаписывать весь конфиг при каждом изменении в любом из модулей? А представьте что там не 3 модуля, а штук 40 их? (вот у меня так и было). В догонку конфиг это пример, а если это какой нибудь довольно часто меняющийся параметр. Давайте по вопросам разобьем: 1. Как это поможет знать\четко устанавливать адрес для записи и переносить информацию между изменениями? 2. Чем это принципиально отличается от ручной забивки макросами? 3. Это все еще файл знающий все обо всех. 4. Для инициирования записи, надо все так же его инклудить же. Изменено 18 ноября, 2022 пользователем Solonovatiy Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tgruzd 11 18 ноября, 2022 Опубликовано 18 ноября, 2022 · Жалоба Только что, Solonovatiy сказал: Предлагаете перезаписывать весь конфиг при каждом изменении в любом из модулей? так вопрос-то был про известные адреса. И не каждая флэш стирается по 0x100 Говорю же: внятно опишите суть проблемы. А то опять ни о чём на 3 страницы будет. Я - спать Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Solonovatiy 0 18 ноября, 2022 Опубликовано 18 ноября, 2022 (изменено) · Жалоба Вот ща попытаюсь псевдокодом, как по моему должно в идеале быть. ModuleA { Init: try: remoteConfig = storage.GetAccess('moduleA', 'rw'); catch(e) if(e == storage.NotAllocatedException) : storage.Allocate('moduleA') else : throw ModuleExceptionInitFailed(e) config = remoteConfig.Read(); SaveConfig: remoteConfig.Write(config); } Это не сложно сделать в рантайме. Ага. Но не хочу рантайм. Хочу компайлтайм. Наверное это можно сделать на шаблонах... но нужны очень глубокие познания в них. 1 minute ago, tgruzd said: так вопрос-то был про известные адреса. И не каждая флэш стирается по 0x100 0х100 это прост начальный адрес, у вас до него может другая важная инфа быть. Хз с чего вы взяли, что это размер страницы. А как вам известные адреса помогут то? Вот допустим вы знаете адреса и хотите писать модульА в 0х100, модульБ в 0х200. У вас есть структура со структурами. А таблицы структура - адрес, нет. Как их писать? Как использование этого выглядит? Изменено 18 ноября, 2022 пользователем Solonovatiy Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tgruzd 11 19 ноября, 2022 Опубликовано 19 ноября, 2022 · Жалоба 10 часов назад, Solonovatiy сказал: А как вам известные адреса помогут то? А вы чего хотите-то? Сказали же вам: нет волшебной таблетки тут погорячился я: 11 часов назад, tgruzd сказал: typedef struct{ module_a_config_t a; module_b_config_t b; module_c_config_t c; }config_t; //config_t config; // это конечно же лишнее предполагалось просто задать структуру файла, чтобы вычислять смещения конкретных конфигов Хотите однозначно генерировать адреса? Тут могли бы помочь структуры с их sizeof, offsetof плюс несколько макроопределений. Плюс, возможно, какие-то грязные трюки препроцессора. В итоге, вам не придётся каждый адрес каждого параметра конфига вручную забивать 10 часов назад, Solonovatiy сказал: 1. Как это поможет знать\четко устанавливать адрес для записи и переносить информацию между изменениями? 2. Чем это принципиально отличается от ручной забивки макросами? 3. Это все еще файл знающий все обо всех. 4. Для инициирования записи, надо все так же его инклудить же. не знаю даже, все зависит от ограничений которые вы ещё наложите на свой файл с конфигами, все возможные случаи не могу рассмотреть. Вы хотите всё и сразу: и ничего не инклюдить, и чтобы в компайлтайме работало. А может через три сообщения вы захотите "чтобы ещё и на питоне работало"? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Solonovatiy 0 19 ноября, 2022 Опубликовано 19 ноября, 2022 (изменено) · Жалоба 54 minutes ago, tgruzd said: А вы чего хотите-то? Сказали же вам: нет волшебной таблетки тут погорячился я: Хотите однозначно генерировать адреса? Тут могли бы помочь структуры с их sizeof, offsetof плюс несколько макроопределений. Плюс, возможно, какие-то грязные трюки препроцессора. В итоге, вам не придётся каждый адрес каждого параметра конфига вручную забивать не знаю даже, все зависит от ограничений которые вы ещё наложите на свой файл с конфигами, все возможные случаи не могу рассмотреть. Вы хотите всё и сразу: и ничего не инклюдить, и чтобы в компайлтайме работало. А может через три сообщения вы захотите "чтобы ещё и на питоне работало"? Ну вы начали утверждать, что пилюля, хотя-бы облегчающая, есть =). Я пока накидал псевдокод выше, сильнее убедился, что наверняка можно решить или улучшить ситуацию с помощью шаблонов. Вообще я выше написал, как я решил случай, когда переносимость между версиями не была столь важна. 1) У вас есть конфиг. 2) Вы с помощью компилятора и линкера трамбуете его жестко в один блок памяти. 3) Пишете некоторую макросовую магию танцы с бубнами. 4) Одним вызовом функции сохраняете переменную. 5) В драйвере транслируете адрес ОЗУ в ПЗУ. А т.к. у вас все конфиги лежат рядом, то все довольно утрамбовано. Но это все еще не решает вопроса переносимости и стабильных адресов. Ща копипастну из реального проекта. Spoiler // БИБЛИОТЕЧНЫЙ ФАЙЛ ИНКЛУДИТСЯ В МОДУЛИ // Объявление структуры с описанием переменной. // Эта штука сидит В ПЗУ микроконтроллера. Не еепрома и не ОЗУ. typedef const __near struct{ byte size; - Размер переменной в байтах union{ void* ram; - Адрес в ОЗУ МК word rom; - Адрес в ПЗУ ЕЕПРОМ byte* as_byte; - ущербный type-punning word* as_word; - ущербный type-punning }addr; }var_description; /** * Writes variable to EEPROM * @param - Variable description struct * @param - New value * @param - BOOL_PTR, for "write complete" callback */ void VAR_Save(var_description* description, void* new_value, bool* ready) { byte var_size = description->size; if(var_size > VAR_SIZE_MAX) { var_size = VAR_SIZE_MAX; } // просто прекраснейшая и безопаснейшая обработка ошибок memcpy(description->addr.ram, new_value, var_size); // Постановка задачи драйверу STR_WriteRequest( description->addr.rom, description->addr.ram, var_size, ready); } // VARM - от VARMacro // Для удобства, неизвестные макросы описаны ниже #define VARM_Save(var_id, value) \ VAR_Save(VARM_DESCRIPTION_BODY(var_id), value, NULL) #define VARM_SaveP(var_id, value) \ VAR_SaveP(VARM_DESCRIPTION_BODY(var_id), value, NULL) #define VARM_SaveSync(var_id, value) \ VAR_SaveSync(VARM_DESCRIPTION_BODY(var_id), value) #define VARM_SaveSyncP(var_id, value) \ VAR_SaveSyncP(VARM_DESCRIPTION_BODY(var_id), value) #define VARM_LoadSync(var_id) \ VAR_LoadSync(VARM_DESCRIPTION_BODY(var_id)) // Внезапно - одно из основных действующих лиц. Облегчает создание описания переменной. #define VARIABLE(variable, var_index) \ [var_index] = { sizeof(variable), &variable } // ФАЙЛ МОДУЛЯ // Служебный дефайн, что бы заработали макросы, что выше. #define VARM_DESCRIPTION_BODY(x) (&const_description.variables[x]) // Энум переменных, он в этом монстре увы требуется. typedef enum{ MODULE_VARIABLE_A, MODULE_VARIABLE_B, MODULE_VARIABLE_C, MODULE_VAR_COUNT, }module_variables_enum; // Описание константных настроек модуля (тут у меня еще что-то лежало, что в ПЗУ МК должно сидет, но я удалил, тут только массив.) typedef const struct{ var_description variables[MODULE_VAR_COUNT]; }module_const_description_str; typedef const struct{ byte A; word B; dword C; }module_str; // Тут создается реальное описание переменных module_str module; static module_const_description_str const_description = { // Имя для работы макросов должны быть строго таким { VARIABLE(module.A, MODULE_VARIABLE_A), VARIABLE(module.B, MODULE_VARIABLE_B), }; // Синхронная подгрузка во время инициализации static void Init() { VARM_LoadSync(MODULE_VARIABLE_A); VARM_LoadSync(MODULE_VARIABLE_B); VARM_LoadSync(MODULE_VARIABLE_C); } // Изменение переменной и отправка ее на сохранение static void ChangeAndSaveA(byte new_a_value) { module.A = new_a_value; VARM_Save(MODULE_VARIABLE_A); } Кривенькое, но работает и позволяет расширять переменные, не создавая глобального файла, куда заинклужена вся фигня. Наоборот, модули начинают зависеть от одного маленького общего файла. И самое главное - оно полностью константное и статичное. Никакой генерации в рантайме, все определяется в компайлтайме. Но увы, че перекомпилировал, даже без изменений переменных - адреса сменились. Изменено 19 ноября, 2022 пользователем Solonovatiy Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tgruzd 11 19 ноября, 2022 Опубликовано 19 ноября, 2022 · Жалоба 51 минуту назад, Solonovatiy сказал: Ну вы начали утверждать, что пилюля, хотя-бы облегчающая, есть 😃 после этого, да: В 18.11.2022 в 04:19, Solonovatiy сказал: 5. Я не знаю как сохранять данные на бинарный носитель (еепром какой), иначе, как хреначить какой очередной хидер на 2000 строк, в котором вы обязательно ошибетесь во время очередных правок\удаления адресов. А потом выяснилось что вы и структуры используете и в препроцессор умеете и хотите универсальное решение, которое всем вашим требованиям удовлетворяет. Не знаю, возможно и не существует решения вашей задачи. Как-нибудь попробую ваши макросы применить, в голове их раскручивать нет желания. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться