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