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

Pavel Hudeček edizon na seznam.cz
Úterý Květen 30 01:15:22 CEST 2023


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

Dne 29.05.2023 v 20:24 Miroslav Mraz napsal(a):
> Tak jsem do těch zdrojáků koukal, ale mám takový dojem, že řeší úplně 
> něco jiného, než byl ten původní dotaz. Původní dotaz jsem pochopil 
> tak, že chcete udělat objekt (třídu), která se bude chovat jako 
> číselná proměnná (int, nebo float, patrně konstantní), která si načte 
> hodnotu z EEPROM (patrně v konstruktoru) a dále se pak bude používat 
> jako normální proměnná.
> To by ani nemuselo být tak složité, ale počítám, že v Arduinu už něco 
> takového bude. Většinou to psali lidi, co C++ docela ovládají a dost 
> věcí vypadá blbě jen proto, že to optimalizovali na 8-bit AVR.
>
> Přetížení operátoru << se běžně používá, ale já to nemám moc rád, je 
> to poněkud nepřehledné a rozumně formátovat výstup čísel je obtížné. 
> Proto mám raději rodinu printf(const char * fmt, ...).
>
> Mrazík
>
> On 27. 05. 23 22:42, Pavel Hudeček wrote:
>> Žádná odpověď nepřišla, tak jsem zatím přetěžoval operátor << v rámci 
>> pokusů na téma jestli by v AVR nešlo používat sériák C++ stylem cout 
>> << ...
>> A zdá se, že to jde a docela snadno. Výsledek sice sežral velkou část 
>> flashky v ATtiny416, ale vzhledem k tomu, že cílem je to použít v 
>> AVR64DD32, kde 64 je velikost flashky a 32 má blízko k ceně v Kč...
>> A předpokládám, že na ARMech to taky nebude problém.
>>
>> Kdo chce prozkoumat, v příloze je zdroják.
>> Má to několik nastavení, třeba zda automaticky oddělovat čísla, nebo 
>> jestli char má brát jako písmenko nebo číslo.
>>
>> Všechny řádky v tom while jsou funkční, ale při spuštění na 
>> ATtiny416-Xnano se všechny najednou nevejdou. Ten s floatama vyžaduje 
>> zakomentování všech ostatních:-)
>>
>> PH
>>
>> Dne 26.05.2023 v 14:05 Pavel Hudeček napsal(a):
>>> Dobrý den všem,
>>>
>>> jsem poměrně zmlsanej používáním EEPROM v CodeVisionu. Typické 
>>> zpracování naměřených dat vypadá cca takto:
>>>
>>> for (n=0; n<ADC_chanCnt; n++) {
>>>     adData[n] = (float)(adc_data[n] + eCalOffs[n]) * eCalMult[n];
>>> }
>>>
>>> Můžou se tam ale vyskytnout i složitější výpočty, třeba po 
>>> if(n==ADC_idxTemp).
>>>
>>> Když ale totéž chci udělat v Atmel Studiu, což je zas jinak mnohem 
>>> lepší IDE než CodeVision, navíc je zdarma a bez komplikací po 
>>> vypršení doby podpory k online licenci, vzniknou z toho hrůzy 
>>> obsahující funkce jako eeprom_read_float(&eCalOffs + n), případně se 
>>> třeba u int musí ten pointer přetypovávat, aby ho sežrala funkce 
>>> eeprom_read_word a když jde o zápis, tak přetypovávat i vstupní 
>>> hodnotu. Prostě fakt otravný.
>>>
>>> Tak jsem si řekl, že tohle by přece šlo napsat v C++. Udělat si na 
>>> to nějakej class, jen to bude jednou hodně práce.
>>>
>>> Narazil jsem na problém, že nevím, jak udělat přetížení operátorů 
>>> pro všech 8 kombinací RAM a EEPROM na vstupech a výstupu. Nějaké 
>>> nápady?
>>>
>>> Druhá věc je, že určitě nejsem provní ani poslední koho něco 
>>> takového napadlo. Má tu někdo zkušenosti s používáním nějkakého 
>>> takového již hotového, nejlépe open source projektu?


Další informace o konferenci Hw-list