Перейти к содержанию
    

Архитектура программ во встраиваемой электронике

1 минуту назад, Solonovatiy сказал:

Что это вопрос внутренней реализации. У вас вообще нет инфы как реализовано HTTP и контроль мотора и что там внутри?

Для управления PMSM-мотором, алгоритм его обслуживания должен выполняться с частотами порядка 10-30 кГц.

А HTTP-сервер (тем более HTTPS) требует иногда выполнения обработки большого единого HTTP-запроса, с формированием HTTP-ответа может быть в десятки КБ. Такая обработка никак не успеет выполниться между двумя обслуживаниями мотора если пытаться запихнуть это в один цикл.

PS: Это вам для информации что такое то и другое.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 minutes ago, jcxz said:

Для управления PMSM-мотором, алгоритм его обслуживания должен выполняться с частотами порядка 10-30 кГц.

А HTTP-сервер (тем более HTTPS) требует иногда выполнения обработки большого единого HTTP-запроса, с формированием HTTP-ответа может быть в десятки КБ. Такая обработка никак не успеет выполниться между двумя обслуживаниями мотора если пытаться запихнуть это в один цикл.

PS: Это вам для информации что такое то и другое.

Что мешает на практике сделать в HTTP огромнейшую стейт машину, которая будет по паре строк обрабатывать, а потом руками "елдить"? Ну кроме здравого смысла конечно (блин причем видал подобное, на дурных проектах, где битбангом интерфейсы делали и больше не хочу). 
Я в предыдущем посте все это расписал (и еще подправлял минут 5 после поста.)

Изменено пользователем Solonovatiy

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 

18 минут назад, Solonovatiy сказал:

Но вопрос как раз про поиск этой грани и принципах ее поиска. Вот с какого момента стоит разделять таски, а когда стоит жаться в одном.

Вроде с двух сторон ограничения есть:  с одной стороны производительность процессора, с другой - сложность кода.  Нужно искать баланс, в общем.

 

Изменено пользователем tgruzd

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Just now, tgruzd said:

Вроде с двух сторон ограничения есть:  с одной стороны производительность процессора, с другой - сложность кода.  Нужно искать баланс, в общем.

image.png

Да и про него поиск весь этот топик. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8 минут назад, Solonovatiy сказал:

Что мешает на практике сделать в HTTP огромнейшую стейт машину, которая будет по паре строк обрабатывать, а потом руками "елдить"? Ну кроме здравого смысла конечно

Ну вот здравый смысл и мешает. Я ещё ранее говорил - никто не мешает надевать трусы через голову. Но так сложнее.

А вот футболку наоборот - удобнее через голову одевать, а не так как трусы.

Вот видите - для всего есть свой удобный путь: для трусов - один, для футболок - другой. И не надо пытаться всегда идти одним путём. Хотя и возможно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 minutes ago, tgruzd said:

Вроде с двух сторон ограничения есть:  с одной стороны производительность процессора, с другой - сложность кода.  Нужно искать баланс, в общем.

Да и про него поиск весь этот топик. 

1 minute ago, jcxz said:

Вот видите - для всего есть свой удобный путь: для трусов - один, для футболок - другой. И не надо пытаться всегда идти одним путём. Хотя и возможно.

Я там же выше написал. Ваш пример очень очень простой с точки зрения выбора. Есть однозначно трусы, есть однозначно футболка.
Но не всегда все так очевидно. Об этом и хотел изначально поговорить.

 

Изменено пользователем Solonovatiy

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы всё-таки кусочек своего хидера скиньте, а то уже все втроём ни о чём пишем. Уже всем всё понятно

Изменено пользователем tgruzd

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Отдельно веселье начинается, когда не надо все сохранять или не надо все сохранять постоянно, а лишь одну переменную.

Изменено пользователем Solonovatiy

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

typedef struct{
		module_a_config_t a;
		module_b_config_t b;
		module_c_config_t c;

}config_t;


config_t config;

и т.д

с этим уже проще будет работать

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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. Для инициирования записи, надо все так же его инклудить же.

 

 

 

Изменено пользователем Solonovatiy

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Только что, Solonovatiy сказал:

Предлагаете перезаписывать весь конфиг при каждом изменении в любом из модулей? 

так  вопрос-то был про известные адреса.

И не каждая флэш стирается по  0x100 

Говорю же: внятно опишите суть проблемы. А то опять ни о чём на 3 страницы будет.

Я - спать

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот ща попытаюсь псевдокодом, как по моему должно в идеале быть.

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.
У вас есть структура со структурами. А таблицы структура - адрес, нет. 
Как их писать? Как использование этого выглядит? 

Изменено пользователем Solonovatiy

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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. Для инициирования записи, надо все так же его инклудить же.

 

не знаю даже, все зависит от ограничений которые вы ещё наложите на свой файл с конфигами, все возможные случаи не могу рассмотреть. 

Вы хотите всё и сразу: и ничего не инклюдить, и чтобы в компайлтайме работало.  А может через три сообщения вы захотите "чтобы ещё и на питоне работало"?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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);
}
  
  

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

И самое главное - оно полностью константное и статичное. Никакой генерации в рантайме, все определяется в компайлтайме.

Но увы, че перекомпилировал, даже без изменений переменных - адреса сменились.

Изменено пользователем Solonovatiy

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

51 минуту назад, Solonovatiy сказал:

Ну вы начали утверждать, что пилюля, хотя-бы облегчающая, есть 😃

после этого, да:

В 18.11.2022 в 04:19, Solonovatiy сказал:

5. Я не знаю как сохранять данные на бинарный носитель (еепром какой), иначе, как хреначить какой очередной хидер на 2000 строк, в котором вы обязательно ошибетесь во время очередных правок\удаления адресов. 

 

А потом выяснилось что вы и структуры используете  и в препроцессор умеете и хотите универсальное решение, которое всем вашим требованиям удовлетворяет.

Не знаю, возможно и не существует решения вашей задачи. 

Как-нибудь попробую ваши макросы применить, в голове их раскручивать нет желания.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...