Re: EEPROM, C++ a řetěžování operátorů

Pavel Hudeček edizon na seznam.cz
Úterý Květen 30 16:26:05 CEST 2023


Nebo právě naopak, pro složitost s obsluhou EEPROM zapomněl, že by to se 
zápisy neměl přehánět:-)

Připomnělo mi to zákazníka jedné firmy, který reklamoval jejich 
krabičky, léta běžně používané v průmyslu, že mu po pár dnech odcházejí. 
Závěr byl, že přes MODBUS pořád dokola, snad každou sekundu, updatoval 
kofiguraci. Ta se ukládala do interní flashky.

Ale zpět k tématu: Spolehlivost fungování zařízení do značné míry 
souvisí s přehledností kódu. Když výpočet teploty obsahuje 5 funkcí s 
pointery a přetypováním, může se stát lecos, třeba že od 111,233 do 
189,978 °C vyjde výsledek posunutý o 108,325 dolů. Zařízení normálně 
funguje, až jednou, hodně praží slunce, teplota baterky překročí 
magickou hranici a začne rychlonabíjení, jakoby nic ... vyšetřování 
požáru odhalí závadu v elektrickém přístroji.

Proto mám radši, když výpočet vypadá jako výpočet, ať jsou data kdekoli.

PH

Dne 30.05.2023 v 15:28 Petr Labaj napsal(a):
> 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:-)



Další informace o konferenci Hw-list