Re: EEPROM, C++ a řetěžování operátorů
Miroslav Mraz
mrazik na volny.cz
Úterý Květen 30 09:40:37 CEST 2023
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
Další informace o konferenci Hw-list