[C] [ESP8266] Hoe werkt de 4 byte aligned geheugen allocatie

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 21:51
Ik probeer al een tijdje een rules library te maken voor de ESP8266. Ik weet prima met alle beperkingen van de ESP8266 om te gaan. Zo zit er nauwelijks recursie in en daar waar het onmogelijk is doe ik dat tail-recursive. Ik weet vrij goed om te gaan met de minimale geheugengrootte. Waar ik wel mee loop te stoeien is met een tweetal exceptions: 9 en 29. Exceptie 9 gaat over de 4 byte alignment. Exception 29 gaat over het schrijven in een verboden geheugengebied.

Aangezien geheugenbeheer nogal kritisch is doe ik veel en vaak realloc en memmove. Zo wordt syntax die op het FS staat ingeladen in het geheugen. Die ingeladen syntax wordt token voor token omgezet naar een AST in bytecode. Dat doe ik ook zo efficiënt mogelijk. Dus de syntax alloc wordt token voor token kleiner, de AST wordt token voor token groter.

Voorbeeld:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#define VM_GENERIC_FIELDS \
  uint8_t type; \
  uint16_t ret;

typedef struct vm_tif_t {
  VM_GENERIC_FIELDS
  uint16_t go;
  uint16_t true_;
  uint16_t false_;
} __attribute__((packed)) vm_tif_t;

typedef struct vm_toperator_t {
  VM_GENERIC_FIELDS
  uint8_t token;
  uint16_t left;
  uint16_t right;
  uint16_t value;
} __attribute__((packed)) vm_toperator_t;


Er is ook een stack waarin de (tijdelijke) variabelen worden opgeslagen:

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
typedef struct vm_vchar_t {
  VM_GENERIC_FIELDS
  char value[];
} __attribute__((packed)) vm_vchar_t;

typedef struct vm_vnull_t {
  VM_GENERIC_FIELDS
} __attribute__((packed)) vm_vnull_t;

typedef struct vm_vinteger_t {
  VM_GENERIC_FIELDS
  int value;
} __attribute__((packed)) vm_vinteger_t;

typedef struct vm_vfloat_t {
  VM_GENERIC_FIELDS
  float value;
} __attribute__((packed)) vm_vfloat_t;


Nu heb ik een aantal vragen over de ESP8266:

1. Moet elke allocatie 4 byte aligned zijn of mag ik een 4 byte aligned pool aanmaken waarbinnen ik mijn AST opsla? De vm_tif_t neemt 9 bytes in beslag. Vier byte aligned moet dit in een geheugengebied van 12 bytes worden opgeslagen. Als ik 4 vm_tif_t tokens opsla dan zou in dat geval 48 bytes nodig hebben. Terwijl ik ook een pool kan aanvragen van 36 bytes waarbinnen ik vier 9 bytes vm_tif_t kan plaatsen. De pool is dan 4 bytes aligned. De individuele blokken die ik daarbinnen bewerk niet.

Een 4 bytes aligned pool is véél geheugenvriendelijker dan elke allocatie 4 bytes aligned te doen.

2. Kan exception 29 komen doordat er geen ruimte vrij is om bij een realloc een nieuw geheugengebied te vinden die voldoet aan de nieuwe grootte? Oftewel, het geheugen is te gefragmenteerd om mijn realloc te plaatsen. Wat ik wel typisch zou vinden aangezien er nog 5472 bytes beschikbaar heb. Welke andere oorzaak zou exception 29 kunnen hebben?

Er is jammer genoeg erg weinig hardcore informatie te vinden over het ESP8266 programmeren dus ik leg mijn hoop bij mijn mede tweakers.

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • Vuikie
  • Registratie: December 2003
  • Laatst online: 20:40
Ik werk ook wel 'ns met een ESP8266 en ik wist niet dat het dingetje zo'n inefficiënte geheugen manager heeft.
Hier wordt een beetje uitgelegd. Ik weet niet of jij dat ook al had gelezen @CurlyMo ?
Wat ik ervan begrijp is dat de ESP 4 byte aligned is, maar wel blokken van 16 byte per keer inleest. Hmmm :?
En op Wikipedia staat dat ie zelfs 4 types RAM heeft...

Maar goed, even voor de duidelijkheid. Welke ontwikkelomgeving gebruik jij? En waar in je code komen de exceptions voor? Die exception 29, kan die alleen voorkomen bij user RAM(80KiB, wat 10KB is) of kan het ook voorkomen bij instruction RAM(32KiB, wat 4KB is).

Bij die exception 9 heb ik, denk ik, echt inzage in je geheugen management nodig, want dat kan natuurlijk met van alles te maken hebben ;)

Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 21:51
Vuikie schreef op dinsdag 6 april 2021 @ 11:04:
Hier wordt een beetje uitgelegd. Ik weet niet of jij dat ook al had gelezen @CurlyMo ?
Die nog niet. Dank daarvoor!
Wat ik ervan begrijp is dat de ESP 4 byte aligned is, maar wel blokken van 16 byte per keer inleest. Hmmm :?
Volgens mij ben ik hier nog niet tegenaan gelopen.
En op Wikipedia staat dat ie zelfs 4 types RAM heeft...
Klopt, waarin de interrupts dan weer in een specifieke geheugen register container functioneert :s
Maar goed, even voor de duidelijkheid. Welke ontwikkelomgeving gebruik jij?
Arduino CLI en GUI
En waar in je code komen de exceptions voor?
Hoe specifiek wil je dat weten :) De volledige repo staat hier. De documentatie is trouwens wat verouderd:
https://github.com/CurlyMoo/rules/
Die exception 29, kan die alleen voorkomen bij user RAM(80KiB, wat 10KB is) of kan het ook voorkomen bij instruction RAM(32KiB, wat 4KB is).
Hoe weet ik in welk geheugengebied ik werk?
Bij die exception 9 heb ik, denk ik, echt inzage in je geheugen management nodig, want dat kan natuurlijk met van alles te maken hebben ;)
Die is ook een stuk zeldzamer, die heb ik wel redelijk weten af te dwingen. Ik denk echter dat 29 nu nog komt door te grote blokken in de realloc te gooien. Ik had namelijk de AST en de variabele stack in één geheugen blok gestopt. Dus bij een realloc vanuit de geheugenstack werd ook de volledige AST meegenomen. Die AST is met name vrij groot. De variable stack juist niet. Het kan zijn dat door de fragmentatie van het geheugen er dus geen ruimte is voor een nieuw tijdelijk (groot) geheugengebied.

C:
1
2
3
4
5
  unsigned char *bytecode;
  unsigned int nrbytes;

  unsigned char *varstack;
  unsigned int varbytes;

Oftewel, of alleen de eerste bytecode of nu gesplitst in twee geheugenblokken. Een relatief statische (eerste) en een dynamische (tweede).

Dat probeer ik nu te testen. Deze code staat alleen nog niet op github. Daar zie je alles in één grote bytecode blok staan.

[ Voor 6% gewijzigd door CurlyMo op 06-04-2021 11:12 ]

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 21:51
@Vuikie Ik heb het stuk gelezen. Het geeft me niet super veel duidelijkheid behalve dat hij bevestigd dat ik wel prima een memory pool kan gebruiken. Dat is sowieso goed om te weten.

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • Vuikie
  • Registratie: December 2003
  • Laatst online: 20:40
Ja klopt, de problemen die jij hebt met die exceptions worden niet door hem behandeld, maar ik vond het wel interessant om te lezen over de verschillende geheugens.

Wat jouw'n projectje betreft, dat is wel hardcore en gaat wel een beetje boven mijn pet O-)

Ik heb wel wat proberen te zoeken, maar ook nog niet wat nuttigs gevonden over die exception 29. Behalve dat je in protected geheugen probeert te schrijven/lezen. Dat doet idd. vermoeden dat je meer geheugen nodig hebt dan beschikbaar.

Van mij was het dan ook een vraag waar die exception 29 zich voordoet... Ik weet dat ESP8266 exceptions cryptisch zijn, maar je zou erachter moeten kunnen komen waar je naar toe wil schrijven/van wil lezen. Alleen dat wordt, denk ik, duiken in de ASM files die ergens moeten staan >:)

[ Voor 22% gewijzigd door Vuikie op 07-04-2021 11:38 ]


Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 21:51
Ik ben er vrijwel zeker van dat mijn probleem ontstaat door defragmentatie. Dat lijkt ik nu opgelost te hebben. Volgende de stap is proberen om de AST in progmem op te slaan, omdat als die eenmaal is aangemaakt, er alleen nog maar gelezen hoeft te worden.

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 21:51
Het is me gelukt de finale AST grootte op voorhand te berekenen zodat ik die stroom realloc's niet meer nodig heb. Ik kan nu gewoon één malloc doen. Dat scheelt een hele hoop geheugen fragmentatie.

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 21:51

Sinds de 2 dagen regel reageer ik hier niet meer


Acties:
  • 0 Henk 'm!

  • CurlyMo
  • Registratie: Februari 2011
  • Laatst online: 21:51
Mijn laatste versie van mijn library werkt nu al een paar uur prima op een ESP8266 dus ik heb het denk ik door :)

Sinds de 2 dagen regel reageer ik hier niet meer

Pagina: 1