Re: EEPROM, C++ a řetěžování operátorů
Petr Labaj
labaj na volny.cz
Úterý Květen 30 15:28:50 CEST 2023
Omlouvám se za odbočku.
Můj laicko-uživatelský pohled na věc: je myslím dobře, když je práce s
EEPROM udělaná úplně jinak než s ostatní paměti.
Tady přes nějaké funkce.
EEPROM podle mě není paměť, ale "periferie, která si pamatuje".
Aspoň si programátor (a to i BFU) uvědomí, že je to něco hodně jiného
než něco zapsat do pole, které má (na rozdíl od EEPROM) neomezený počet
přepisů.
Zacházení s EEPROM jako s běžnou pamětí pak vede k tomu, že spousta
přístrojů umírá na destrukci EEPROM pro příliš velký počet přepisů.
Vzpomněl jsem si na to i proto, že zrovna řeším dilema jak zachránit
svůj oblíbený monitor, kde odešla EEPROM v ceně 3 Kč, a tím pádem je
skvělý monitor nepoužitelný.
Asi měl programátor taky hodně usnadněný zápis do EEPROM a tak tam pořád
něco zapisoval.
PL
********************
Dne 30.5.2023 v 9:40 Miroslav Mraz napsal(a):
> C++ je hodně tvárné. Ono je to vlastně ještě jednodušší, celkem není
> potřeba přetěžovat všechny potřebné operátory, stačí vytvořit
> operátor, který vrací nějaký "rozumný" typ. Tedy pokud máte v EEPROM
> jen nějaké konstanty, se kterými pak dále počítáte. Ano, adresace
> EEPROM je problém, ale asi by šel nějak vyřešit např. pomocí linker
> skriptu.
>
> #include <string.h>
> #include <stdio.h>
>
> unsigned char EEPROM [256];
>
> static bool EEReadBytes (const size_t StartAddr, void * pval, const
> size_t len) {
> printf("Read from %zd, len=%zd\n", StartAddr, len);
> memcpy(pval, EEPROM + StartAddr, len);
> return true;
> }
> static bool EEWriteBytes (const size_t StartAddr, const void * pval,
> const size_t len) {
> memcpy(EEPROM + StartAddr, pval, len);
> return true;
> }
> static void setEEPROMdata () {
> const unsigned a = 0x12345678;
> EEWriteBytes(0, &a, sizeof(unsigned));
> const float pi = 3.14159f;
> EEWriteBytes(4, &pi, sizeof(float));
> }
> /*******************************************************************/
> template<typename T> class EESEG {
> T data;
> public:
> explicit EESEG (const size_t StartAddr) noexcept {
> EEReadBytes (StartAddr, & data, sizeof(T));
> }
> operator const T () const {
> return data;
> }
> };
>
> int main () {
> setEEPROMdata();
> EESEG<unsigned> x(0);
> EESEG<float> r(4);
> const float d = 2 * r; // počítat s tím jde -
> operator const T dosadí překladač automaticky, pokud nemá jinou možnost
> printf("x=%X\n", static_cast<unsigned> (x)); // tady už to není
> jednoznačné, nutno explicitně přetypovat
> printf("d=%g\n", d);
> return 0;
> }
>
> Mrazík
>
> On 30. 05. 23 1:15, Pavel Hudeček wrote:
>> U Arduina to vyřešili tak, že mají prostě EEPROM.read a EEPROM.write
>> pro jednobajtové operace a pak put a get pro data různých typů. Dá se
>> říct, že je to totéž jako ta sada funkcí z normálního eeprom.h, jenže
>> teda až na to, že tam se aspoň adresy vyřeší v rámci deklarací,
>> arduinisti si musí "alokovat" ručně.
>>
>> Nakonec jsem zjistil, že dosažení mého cíle je mnohem jednodušší než
>> jsem si myslel, protože nejspíš stačí vytvořit kostruktory, operátory
>> na implicitní konverzi a operátory přiřazení, když se má hodnota
>> měnit. Ostatní už pak proběhne samo. Teda kromě ++, -- a zkratek jako
>> +=. Ale dejme tomu, že to bez nich přežiju:-)
>>
>> Kostruktor je ale trochu složitější, musí si alokovat místo, protože
>> uvnitř třídy nejde deklarovat proměnná typu s eemem. Ještě by teda
>> bylo super, kdyby ten konstruktor nešlo vyvolat jinou než globální
>> deklarací, ale to nevím zda nějak jde.
>>
>> Oproti původní variantě z eeprom.h to teda bude mít i nevýhody:
>> 1. Navíc sežraná RAM, kam konstruktory uloží adresy
>> 2. Přeplnění EEPROM se nepozná při kompilaci, musí vyvolat nějakej
>> runtime errorhandler.
>>
>> Mám objednáno AVR64DD32 CNANO, pak si stím trochu víc pohraju.
>>
>> Co se cout vs prinft týče, tak nejvíc by se mi líbilo něco jako je
>> print v klasickým Basicu, kdy tam napíšu seznam parametrů libovolných
>> typů oddělených čárkama. Vlastně by se toho dalo dosáhnout přetížením
>> operátoru čárka místo <<, jen to bude nestandardně vypadat:-)
>>
>> printf je v podstatě taky OK, ale vlastní implementace je dost pracná
>> a donutit standardní printf k použití mých nastavení sériáku je na
>> můj vkus moc složitý, nedej Bože kdybych chtěl vlastní implementaci
>> odesílání, třeba za použití přerušení. Což chci celkem často:-)
>>
>> PH
> _______________________________________________
> HW-list mailing list - sponsored by www.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list
Další informace o konferenci Hw-list