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