Arlleex 178 3 декабря, 2022 Опубликовано 3 декабря, 2022 · Жалоба 24 минуты назад, jcxz сказал: Вынести этот массив адресов за пределы структуры? Да не красиво это. Понятно, что можно вынести что угодно куда угодно. Хотел, чтобы раскрывая поля структуры редактор давал возможность обратиться к "мнимому" полю адреса регистра, который на самом деле лежал бы там, где нужно (т.е. во Flash). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 3 декабря, 2022 Опубликовано 3 декабря, 2022 · Жалоба 29 minutes ago, Arlleex said: 4 сотни регистров в одной микросхеме А зачем хранить все это в озу? Ведь все равно это будут неактуальные значения и их нужно обновлять? Распишите поточнее задачу. Возможно, сообщество поможет найти более "красивое" и простое решение ) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 178 3 декабря, 2022 Опубликовано 3 декабря, 2022 · Жалоба Есть микросхемы I2C-слейвов (что за микросхемы - не важно). На одной шине висит 4 таких микросхемы. Внутри микрухи регистровая карта насчитывает около 4 сотен регистров. Адреса кусочно-линейно разбросаны, да еще и автоинкремент при чтении/записи не поддерживается. Смысл в том, что различные сервисы ПО опираются на актуальные данные в этих микросхемах (причем, настройки должны "подсасываться" вне зависимости от того, из какого состояния вышел МК - будь то включение питания или сброс по WDT, например). Моя штуковина должна быть абсолютли надежной в плане достоверности инфы, которую я записываю в микросхемы, поэтому после записи делается read-back и сравнение, причем по всем микросхемам (т.е. содержимое одного и того же регистра из 4 разных микросхем должно быть одинаковым). Так вот, сервисы. Сервисов пока что несколько (планируется еще пару добавить) - каждый из них дергает "свою" функцию чтения регистров. Каждый программный сервис требует инфу с определенного субнабора регистров. Так вот, я городить огород из очередей транзакций и программных бус-мастеров к шине I2C не хочу. Вместо этого у меня будет заведен некий кэш содержимого I2C-микросхем внутри ОЗУ МК. И этот кэш будет обновляться периодическим чтением, например, раз в секунду. А сервисы ПО лезут к микросхемам через этот кэш. Вот и вся идея. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Variant99 7 3 декабря, 2022 Опубликовано 3 декабря, 2022 · Жалоба Просто на фоне этих ваших 1600 байт несколько лишних байт не шибко то оттянут "карман". Затея с кешем отчасти верная - вместо медленного чтения из I2C получить "здесь и сейчас". Но вот действительно ли нужно сразу все 400 х 4 регистров? Актуализировать кэш тоже же как-то надо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 3 декабря, 2022 Опубликовано 3 декабря, 2022 · Жалоба 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, ...}; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 178 3 декабря, 2022 Опубликовано 3 декабря, 2022 · Жалоба 2 минуты назад, jcxz сказал: Может так? Тот же вариант, какой получился у меня, только у Вас букв больше набирать 11 минут назад, Variant99 сказал: Просто на фоне этих ваших 1600 байт несколько лишних байт не шибко то оттянут "карман". Почему несколько лишних байт? Мне минимальными синтаксическими усилиями хотелось получить некий программный объект кэша, чтобы иметь к нему доступ в виде ассоциированных пар cache.reg.addr / cache.reg.val. При этом, поскольку addr одинаковые для всех микросхем, хранить его можно во Flash, а вот val хранить в ОЗУ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 3 декабря, 2022 Опубликовано 3 декабря, 2022 · Жалоба 27 minutes ago, Arlleex said: И этот кэш будет обновляться периодическим чтением, например, раз в секунду. А сервисы ПО лезут к микросхемам через этот кэш. Вот и вся идея. Ясно, я бы тоже сделал аналогично. Но зачем вычитывать раз в сек? Один раз при старте все прочитали и из озу берем данные. Если кому-то нужно что-то изменить, то эти данные будут писаться в это же ОЗУ, а для записью обратно будет следить другой процесс, параллельно, неспеша. На этом фоне возьня со статик вместо мифической экономии ОЗУ рисует обернуться головняком. Я бы отказался от статик в пользу незначительной потери ОЗУ. Кстати, сколько всего ОЗУ в камне? И если не секрет, какой камень? )) 9 minutes ago, Arlleex said: При этом, поскольку addr одинаковые для всех микросхем, хранить его можно во Flash, а вот val хранить в ОЗУ. Если адреса точно известны и не являются переменными величинами (в процессе работы кода неизменны), то это реализуется например через шаблоны, где в одном из полей класса создаем соотв объект с припиской const, а его инициализацию при инстанцировании каждого шаблона. Можно использовать отложенную инициализацию класса, где значения хранятcz уже в отдельном const массиве Эти объекты наделить функционалом, который будет обеспечивать целостность данных и их передачу на уровень выше. Поэтому структура тут нафик не нужна, если речь идет о примитивной паре адрес/значение. Как я понимаю в этой I2C хранятся настройки девайса и журнал событий? Просто для понимания сути Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 178 3 декабря, 2022 Опубликовано 3 декабря, 2022 · Жалоба 11 минут назад, Forger сказал: Ясно, я бы тоже сделал аналогично. Но зачем вычитывать раз в сек? Один раз при старте все прочитали и из озу берем данные. Ну, тут я, наверное, выразился не правильно. Правильнее будет обновить кэш: 1) при включении питания; 2) после записи в микросхемы (read-back); 3) при принудительном запросе (это при необходимости). Вот 3-й пункт это как раз для периодических поллингов чего-либо. Для него можно, конечно же, не весь кэш обновлять, а лишь те регистры, которые нужны "прям щас и прям из печки" Для записи у меня кэшировать нельзя - по команде надо сразу начинать записывать. МК - STM32F446. - "128 кБ ОЗУ, Карл!" - скажете Вы. - "Я параною, мне еще кучу всего надо будет написать" - отвечу я. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 3 декабря, 2022 Опубликовано 3 декабря, 2022 · Жалоба 10 минут назад, Forger сказал: Если кому-то нужно что-то изменить, то эти данные будут писаться в это же ОЗУ, а для записью обратно будет следить другой процесс, параллельно, неспеша. ... Как я понимаю в этой I2C хранятся настройки девайса и журнал событий? Просто для понимания сути Вроде Arlleex нигде не писал что эти I2C-чипы - память. С чего Вы решили, что они только хранят записанное? Думаю - это регистры чипа, значение которых не зависит (или частично) от записанного в них ранее. А раз предполагается периодическое чтение, то значит могут и сами по себе время от времени меняться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 178 3 декабря, 2022 Опубликовано 3 декабря, 2022 · Жалоба 17 минут назад, Forger сказал: Как я понимаю в этой I2C хранятся настройки девайса и журнал событий? Просто для понимания сути Это не EEPROM, а хитровые...тиеватый задающий генератор частот В общем, свой вопрос я решил (технический), но изначальный - по C++ - нет =( Условно говоря, язык дал мне возможность инициализировать константу внутри структур сразу, при этом дал возможность пользоваться значением этой константы в коде. Но не дает взять адрес этой константы, выплевывая совершенно, на мой взгляд, не говорящие за себя, ошибки компиляции. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 3 декабря, 2022 Опубликовано 3 декабря, 2022 · Жалоба 2 minutes ago, Arlleex said: Это не EEPROM, а хитровые...тиеватый задающий генератор частот адреса неизменны, только значения меняются так я понял? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Variant99 7 3 декабря, 2022 Опубликовано 3 декабря, 2022 (изменено) · Жалоба Я бы вот так бы сделал: 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 ®) { 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); Изменено 3 декабря, 2022 пользователем Variant99 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 178 3 декабря, 2022 Опубликовано 3 декабря, 2022 · Жалоба 7 минут назад, Forger сказал: адреса неизменны, только значения меняются так я понял? Да, причем где-то значения могут меняться, а где-то останутся такими, какими были записаны. Но read-back обязательно надо сделать, хотя бы один раз. P.S. До шаблонов я не дорос, если что Вот прям совсем. А ситуация не такая, чтобы я сейчас штудировал учебники по плюсам. С ними я разберусь когда будет время прям сесть да почитать литературу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 3 декабря, 2022 Опубликовано 3 декабря, 2022 · Жалоба 13 minutes ago, Arlleex said: Для записи у меня кэшировать нельзя - по команде надо сразу начинать записывать. А если в этот момент уже идет запись от другого процесса? Значит подразумевается некая очередь на команды записи регистров внутрь. Получается сразу записывать нельзя. А так как I2C очень медленный, то придется ждать запросившему процессу некого события об успешном или не очень окончании этой процедуры (по привычку мыслю сразу в поле ртос) Just now, Arlleex said: Вот прям совсем. Пришло время )) Тут нет ничего сложного, вот и коллега выше привел пример ) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 178 3 декабря, 2022 Опубликовано 3 декабря, 2022 · Жалоба 1 минуту назад, Forger сказал: А если в этот момент уже идет запись от другого процесса? Процесс записи один, и вполне четко детерминирован - поэтому я и не стал его кэшировать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться