MPLAB - prace s EEPROM

Jan Waclawek konfera na efton.sk
Pátek Leden 7 18:48:17 CET 2022


>> Mimochodom, neprezradil si, o ktory prekladac ide, a tak som trocha
>> guglil... a klucove slovo EEMEM je... zda sa... ze avr-gcc, premenovany
>> Microchipom na XC8. Takze ide o AVR, je to tak? Ak ano, tak bohuzial, na
>> citanie/zapis EEPROM nie je ina cesta ako pouzivat obezlicky/funkcie.
>
>Ano je to tak...xc8 a mcu je ATmega328...vsechno je pro me bohuzel uplne 
>nove.

Aha. Takze je to avr-gcc resp. konkretne EEMEM je avr-libc (k comu
dokumentacia je https://www.nongnu.org/avr-libc/user-manual/index.html), a
najlepsie miesto na otazky je avrfreaks.net. 

Je neuveritelne, ako uporne manageri v Microchipe pracuju na "zahladeni
minulosti", ako z ich pohladu je to pochopitelne, ale pre uzivatelov je to
defacto podraz.

>no me mate prave to rozsireni EEMEM, ktere rika prekladaci, ze ma tu 
>promennou umistit do EEPROM...

To EEMEM
https://www.nongnu.org/avr-libc/user-manual/group__avr__eeprom.html#ga79a42ec6c6c8bbbe6e34ed57a52aac59
nie je nic ine ako makro 
#define EEMEM   __attribute__((section(".eeprom")))

a __attribute__((section(...))) je spominana metoda, ako kompilator
oznackuje premennu pre linker
https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-section-variable-attribute


>tak jsem zavahal, ze treba je pak 
>cteni/zapis transparentni via nejake rozsireni...mimochodem cekal jsem 
>treba ze aspon cteni (prirazeni) by byl takovej bonbonek co by chodit mohlo

No tak bohuzial.

avr-gcc ma implementovane named address spaces, ale len pre FLASH
https://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html . Pre EEPROM
je fundamentalny problem samotne gcc,
https://www.avrfreaks.net/comment/781649#comment-781649 (SprinterSB
(vlastnym menom G.-J. Lay) je autorom implementacie named address spaces
pre avr-gcc) - "EEPROM address spaces cannot be implemented..." - v
podstate ide o to, ze jadro prekladaca nevie, pre ktory konkretny model
AVR preklada, a kedze EEPROM sa v roznych AVR pristupuje rozne, preto nie
je mozne generovat z gcc efektivny kod...

Inak rovnako ako premenne v EEPROM, aj premenne vo FLASH su vynimka, nedaju
sa citat rovnako ako RAM. Tam sice tie named address spaces funguju, ale
je otazne, nakolko sa oplati nimi zaoberat - tie named address spaces
neriesia automaticky vsetky suvislosti, lebo to by bolo na ukor
efektivnosti prace so standardnymi premennymi, takze kym napriklad mozem
napisat

__flash uint32_t a = 10;
uint32_t b;
b = a + b;

toto
memcpy(&b, &a, sizeof(uint32_t));
uz nebude fungovat, lebo [dlhe a nudne rozpravanie o smernikoch].

Takze je otazne, ci sa vobec oplati tym named address spaces venovat.


#include <avr/eeprom.h>
#include <avr/pgmspace.h>
typedef struct __attribute__((packed)) {
  uint16_t gain, offset;
  uint8_t channel;
} cfg_t;

#define EECFG_NR     10
EEMEM   cfg_t ee_cfg[EECFG_NR];
PROGMEM cfg_t flash_cfg[] = {
  {.gain = 10, .offset = 20, .channel = 2},
  {.gain = 4,  .offset = 4,  .channel = 1},
};
#define FLASHCFG_NR (sizeof(flash_cfg) / sizeof(flash_cfg[0]))
my_struct_t working_cfg;

_Bool ReadCfg(uint8_t idx) {
  if (idx < EECFG_NR) {
    eeprom_read_block(&working_cfg, &ee_cfg[idx], sizeof(cfg_t));
    return 1;
  } 
  idx -= EECFG_NR;
  if (idx < FLASHCFG_NR) {
    memcpy_P(&working_cfg, &flash_cfg[idx], sizeof(cfg_t));
  }
  return 0;
}

_Bool WriteCfg(uint8_t idx) {
  if (idx < EECFG_NR) {
    eeprom_update_block(&working_cfg, &ee_cfg[idx], sizeof(cfg_t));
    return 1;
  } 
}



Pozn. eeprom_write_block() bezhlavo blok zapise do EEPROM, kdezto
eeprom_update_block() zapisuje len tie byty, ktore sa zmenili; obe tieto
funkcie maju opacne poradie smernikov ako ma memcpy().

wek



Další informace o konferenci Hw-list