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

Плавный переход C -> C++ под МК

24 минуты назад, jcxz сказал:

Вынести этот массив адресов за пределы структуры?

Да не красиво это. Понятно, что можно вынести что угодно куда угодно.

Хотел, чтобы раскрывая поля структуры редактор давал возможность обратиться к "мнимому" полю адреса регистра, который на самом деле лежал бы там, где нужно (т.е. во Flash).

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


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

29 minutes ago, Arlleex said:

4 сотни регистров в одной микросхеме

А зачем хранить все это в озу?  Ведь все равно это будут неактуальные значения и их нужно обновлять?

Распишите поточнее задачу. Возможно, сообщество поможет найти более "красивое" и простое решение )

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


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

Есть микросхемы I2C-слейвов (что за микросхемы - не важно). На одной шине висит 4 таких микросхемы. Внутри микрухи регистровая карта насчитывает около 4 сотен регистров. Адреса кусочно-линейно разбросаны, да еще и автоинкремент при чтении/записи не поддерживается. Смысл в том, что различные сервисы ПО опираются на актуальные данные в этих микросхемах (причем, настройки должны "подсасываться" вне зависимости от того, из какого состояния вышел МК - будь то включение питания или сброс по WDT, например). Моя штуковина должна быть абсолютли надежной в плане достоверности инфы, которую я записываю в микросхемы, поэтому после записи делается read-back и сравнение, причем по всем микросхемам (т.е. содержимое одного и того же регистра из 4 разных микросхем должно быть одинаковым). Так вот, сервисы. Сервисов пока что несколько (планируется еще пару добавить) - каждый из них дергает "свою" функцию чтения регистров. Каждый программный сервис требует инфу с определенного субнабора регистров. Так вот, я городить огород из очередей транзакций и программных бус-мастеров к шине I2C не хочу. Вместо этого у меня будет заведен некий кэш содержимого I2C-микросхем внутри ОЗУ МК. И этот кэш будет обновляться периодическим чтением, например, раз в секунду. А сервисы ПО лезут к микросхемам через этот кэш. Вот и вся идея.

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


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

Просто на фоне этих ваших 1600 байт несколько лишних байт не шибко то оттянут "карман".

Затея с кешем отчасти верная - вместо медленного чтения из I2C получить "здесь и сейчас". Но вот действительно ли нужно сразу все 400 х 4 регистров? Актуализировать кэш тоже же как-то надо. 

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


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

25 минут назад, Arlleex сказал:

Хотел, чтобы раскрывая поля структуры редактор давал возможность обратиться к "мнимому" полю адреса регистра, который на самом деле лежал бы там, где нужно (т.е. во Flash).

Может так?:

struct Chip1 {
  struct RegA {
    enum {addr = XX};
    u32 val;
  } regA;
  struct RegB {
    enum {addr = XX};
    u32 val;
  } regB;
  ...
};
static u32 const chip1regAddr[] = {Chip1::RegA::addr, Chip1::RegB::addr, ...};

 

 

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


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

2 минуты назад, jcxz сказал:

Может так?

Тот же вариант, какой получился у меня, только у Вас букв больше набирать:wink:
 

11 минут назад, Variant99 сказал:

Просто на фоне этих ваших 1600 байт несколько лишних байт не шибко то оттянут "карман".

Почему несколько лишних байт? Мне минимальными синтаксическими усилиями хотелось получить некий программный объект кэша, чтобы иметь к нему доступ в виде ассоциированных пар cache.reg.addr / cache.reg.val. При этом, поскольку addr одинаковые для всех микросхем, хранить его можно во Flash, а вот val хранить в ОЗУ.

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


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

27 minutes ago, Arlleex said:

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

Ясно, я бы тоже сделал аналогично. Но зачем вычитывать раз в сек? Один раз при старте все прочитали и из озу берем данные.

Если кому-то нужно что-то изменить, то эти данные будут писаться в это же ОЗУ, а для записью обратно будет следить другой процесс, параллельно, неспеша.

На этом фоне возьня со статик вместо мифической экономии ОЗУ рисует обернуться головняком. Я бы отказался от статик в пользу незначительной потери ОЗУ.

Кстати, сколько всего ОЗУ в камне? И если не секрет, какой камень? ))

9 minutes ago, Arlleex said:

При этом, поскольку addr одинаковые для всех микросхем, хранить его можно во Flash, а вот val хранить в ОЗУ.

Если адреса точно известны и не являются переменными величинами (в процессе работы кода неизменны), то это реализуется например через шаблоны, где в одном из полей класса создаем соотв объект с припиской const, а его инициализацию при инстанцировании каждого шаблона.

Можно использовать отложенную инициализацию класса, где значения хранятcz уже в отдельном const массиве

Эти объекты наделить функционалом, который будет обеспечивать целостность данных и их передачу на уровень выше.

Поэтому структура тут нафик не нужна, если речь идет о примитивной паре адрес/значение.

 

 

Как я понимаю в этой I2C хранятся настройки девайса и журнал событий? Просто для понимания сути

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


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

11 минут назад, Forger сказал:

Ясно, я бы тоже сделал аналогично. Но зачем вычитывать раз в сек? Один раз при старте все прочитали и из озу берем данные.

Ну, тут я, наверное, выразился не правильно. Правильнее будет обновить кэш:
1) при включении питания;
2) после записи в микросхемы (read-back);
3) при принудительном запросе (это при необходимости).

Вот 3-й пункт это как раз для периодических поллингов чего-либо. Для него можно, конечно же, не весь кэш обновлять, а лишь те регистры, которые нужны "прям щас и прям из печки":smile:

Для записи у меня кэшировать нельзя - по команде надо сразу начинать записывать.

МК - STM32F446.

- "128 кБ ОЗУ, Карл!" - скажете Вы.
- "Я параною, мне еще кучу всего надо будет написать" - отвечу я.

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


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

10 минут назад, Forger сказал:

Если кому-то нужно что-то изменить, то эти данные будут писаться в это же ОЗУ, а для записью обратно будет следить другой процесс, параллельно, неспеша.

...

Как я понимаю в этой I2C хранятся настройки девайса и журнал событий? Просто для понимания сути

Вроде Arlleex нигде не писал что эти I2C-чипы - память. С чего Вы решили, что они только хранят записанное? Думаю - это регистры чипа, значение которых не зависит (или частично) от записанного в них ранее. А раз предполагается периодическое чтение, то значит могут и сами по себе время от времени меняться.

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


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

17 минут назад, Forger сказал:

Как я понимаю в этой I2C хранятся настройки девайса и журнал событий? Просто для понимания сути

Это не EEPROM, а хитровые...тиеватый задающий генератор частот:biggrin:

В общем, свой вопрос я решил (технический), но изначальный - по C++ - нет =(

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

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


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

2 minutes ago, Arlleex said:

Это не EEPROM, а хитровые...тиеватый задающий генератор частот:biggrin:

адреса неизменны, только значения меняются

так я понял?

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


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

Я бы вот так бы сделал:

template<class T>
class I2C_Cache: public T {
public:
	I2C_Cache(unsigned char bussAddress)
	{
		this->bussAddress = bussAddress;
	}

	void UpdateCache(T &device)
	{

	}

	unsigned char getReg(unsigned char &reg)
	{
		return reg;
	}

private:
	unsigned char bussAddress;
	T regs;
};


struct Device1{
	unsigned char reg1;
	unsigned char reg2;
	unsigned char reg3;
	unsigned char regN;
};

struct Device2{
	unsigned char reg1;
	unsigned char regN;
};

struct Device3{
	unsigned char reg1;
	unsigned char reg2;
	unsigned char regN;
};

struct Device4{
	unsigned char reg1;
	unsigned char reg2;
	unsigned char reg3;
	unsigned char reg4;
	unsigned char regN;
};


================================
	I2C_Cache<Device1> cache1(0x60);
	I2C_Cache<Device2> cache2(0x75);
	I2C_Cache<Device3> cache3(0x10);
	I2C_Cache<Device4> cache4(0x12);

	cache1.getReg(cache1.reg1);
	cache2.getReg(cache2.regN);

 

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

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


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

7 минут назад, Forger сказал:

адреса неизменны, только значения меняются

так я понял?

Да, причем где-то значения могут меняться, а где-то останутся такими, какими были записаны. Но read-back обязательно надо сделать, хотя бы один раз.

P.S. До шаблонов я не дорос, если что:biggrin: Вот прям совсем. А ситуация не такая, чтобы я сейчас штудировал учебники по плюсам. С ними я разберусь когда будет время прям сесть да почитать литературу.

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


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

13 minutes ago, Arlleex said:

Для записи у меня кэшировать нельзя - по команде надо сразу начинать записывать.

А если в этот момент уже идет запись от другого процесса?

Значит подразумевается некая очередь на команды записи регистров внутрь. Получается сразу записывать нельзя.

А так как I2C очень медленный, то придется ждать запросившему процессу некого события об успешном или не очень окончании этой процедуры (по привычку мыслю сразу в поле ртос)

Just now, Arlleex said:

Вот прям совсем.

Пришло время ))

Тут нет ничего сложного, вот и коллега выше привел пример )

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


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

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

А если в этот момент уже идет запись от другого процесса?

Процесс записи один, и вполне четко детерминирован - поэтому я и не стал его кэшировать.

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


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

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

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

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

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

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

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

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

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

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