Plácnutí tabulky na specifickou adresu

Ahoj,

Mám program viz. příloha. Tři tabulky hodnot 00-FF pro sinus, obdelník, trojúhelník. Dále je pak budu v programu číst a něco s nima provádět ve vnořeném assembleru. Proto tyhle tabulky potřebuju dostat na specifické adresy ve flash. Jmenovitě:

sinus na 0x0100-0x01FF
obdelnik na 0x0200-0x02FF
obedlnik na 0x0300-0x03FF

  • nebo na jakokoliv jiné začínajcí xx00-xxFF

Vyřešil jsem to (fušersky) prostě tak, že jsem před ně plácnul pár nul a jednoduše je na správné hodnoty posunul.

Ale chci se zeptat, jestli neexistuje nějaké jiné, trochu víc “programátorské” řešení?

Děkuji.
c.txt (5.38 KB)

Obecně se doporučuje nechat umístění proměnných na překladači.
Ani v tomto případě není důvod dávat pole na pevné adresy.
Vložený asembler má přístup ke globálním proměnným, takže snadno zjistíme jejich adresy.

Příklad:

[code]const uint8_t vypln] PROGMEM = {0x99,0x11,0x22,0x33,0x44,0x55,0x66,0x77};

int main (void)
{
asm volatile(“ldi r31,hi8(vypln)”); //adresa “vypln” do registru Z
asm volatile(“ldi r30,lo8(vypln)”);
asm volatile(“lpm r10,Z+”); //cti vypln[0] (99h)
asm volatile(“lpm r10,Z+”); //cti vypln[1] (11h)
asm volatile(“lpm r10,Z+”); //cti vypln[2] (22h)
//atd
[/code]

Bohužel, já se chystám generovat signály o vysoké frekvenci. Pokud budu takto načítat tabulku, kradu procesoru drahocený čas, díky kterému by mohl vygenerovat vyžší frekvenci signálu.

A můžeš předvést jak jinak ji budeš načítat, když tabulka bude dejme tomu na adr 0x300?

Promiň možná sem se vyjádřil špatně, načtu to už předtím, jen ten kód, který bude generovat sinusovku(obdelnik, trojúhelní) bude běhat ve smyčce a je potřeba, aby měl co nejmíň cyklů. Až dojde na hodnotu 0xFF přeteče a generovaný průběh se tak bude periodicky opakovat(tudíž už ho pak nebude potřeba znovu načítat). Kdyby to bylo na jiné adrese, přetekl by a generoval by pak část jiného průběhu…

Aha, už chápu.
Ale není potom lepší napsat to celé v asembleru, jak to má na svých stránkách Jesper Hansen?
myplace.nu/avr/minidds/minidds.asm

:arrow_right: administrator: přiloženy externí soubory
minidds.asm (12.9 KB)

Potíž je v tom, že k tomu bude připojeno dost periferií… Z toho bych se zjančil psát to jen v assembleru. Asi to budu muset nechat odcouvané těmi nulami, dokud nenajdu elegantnější řešení… :frowning:

Project->Configuration Options->Memory Settings

tam si nieco zapis a v programe by sa malo dat na to odvolavat. Osobne som to nikdy nepotreboval.

Ak to ale naozaj chces rychlo, preco nepouzit pole v RAM? Pred spustenim nacitas tabulku z Flash do RAM, bude jedno kde je umiestnena a potom uz iba vyberas hodnoty z pola.

co sa rychlosti tyka, nasledovny zdrojak

volatile static uint8_t pole_gen[256], vystup, podmienka_behu =  TRUE;
uint8_t aktual_index = 0, *p_pole = NULL, *p_pole_pom;


/*
	while (podmienka_behu) {
		vystup = pole_gen[aktual_index];
		aktual_index++;
	}
*/
	aktual_index = 0;
	p_pole_pom = (uint8_t *)pole_gen;
	while (podmienka_behu) {
		if (aktual_index == 0) p_pole = p_pole_pom;
		vystup = *p_pole;
		p_pole++;
		aktual_index++;
	}
	return;
}

mi prekladac prelozil


98:       	while (podmienka_behu) {
+0000056C:   C008        RJMP      PC+0x0009      Relative jump
99:       		if (aktual_index == 0) p_pole = p_pole_pom;
+0000056D:   2388        TST       R24            Test for Zero or Minus
+0000056E:   F411        BRNE      PC+0x03        Branch if not equal
+0000056F:   E5E1        LDI       R30,0x51       Load immediate
+00000570:   E0F5        LDI       R31,0x05       Load immediate
100:      		vystup = *p_pole;
+00000571:   9191        LD        R25,Z+         Load indirect and postincrement
+00000572:   93900550    STS       0x0550,R25     Store direct to data space
102:      		aktual_index++;
+00000574:   5F8F        SUBI      R24,0xFF       Subtract immediate
98:       	while (podmienka_behu) {
+00000575:   91900102    LDS       R25,0x0102     Load direct from data space
+00000577:   2399        TST       R25            Test for Zero or Minus
+00000578:   F7A1        BRNE      PC-0x0B        Branch if not equal
108:      }

a jeden cyklus trva 0.65us

zaREMovany kod trva 0.71us

no a da sa to aj takto brutalne ak ide o rychlost a nie o velkost pamate:
jeden krok trva 0.16us

107:      	while (podmienka_behu) {	
+00000569:   C050        RJMP      PC+0x0051      Relative jump
108:      		vystup = *(p_pole + 0);
+0000056A:   91800551    LDS       R24,0x0551     Load direct from data space
+0000056C:   93800550    STS       0x0550,R24     Store direct to data space
109:      		vystup = *(p_pole + 1);
+0000056E:   91800552    LDS       R24,0x0552     Load direct from data space
+00000570:   93800550    STS       0x0550,R24     Store direct to data space
110:      		vystup = *(p_pole + 2);
+00000572:   91800553    LDS       R24,0x0553     Load direct from data space
+00000574:   93800550    STS       0x0550,R24     Store direct to data space
111:      		vystup = *(p_pole + 3);
+00000576:   91800554    LDS       R24,0x0554     Load direct from data space
+00000578:   93800550    STS       0x0550,R24     Store direct to data space
112:      		vystup = *(p_pole + 4);
+0000057A:   91800555    LDS       R24,0x0555     Load direct from data space
+0000057C:   93800550    STS       0x0550,R24     Store direct to data space
113:      		vystup = *(p_pole + 5);
+0000057E:   91800556    LDS       R24,0x0556     Load direct from data space
+00000580:   93800550    STS       0x0550,R24     Store direct to data space
114:      		vystup = *(p_pole + 6);
+00000582:   91800557    LDS       R24,0x0557     Load direct from data space
+00000584:   93800550    STS       0x0550,R24     Store direct to data space
115:      		vystup = *(p_pole + 7);
+00000586:   91800558    LDS       R24,0x0558     Load direct from data space
+00000588:   93800550    STS       0x0550,R24     Store direct to data space
116:      		vystup = *(p_pole + 8);
+0000058A:   91800559    LDS       R24,0x0559     Load direct from data space
+0000058C:   93800550    STS       0x0550,R24     Store direct to data space
117:      		vystup = *(p_pole + 9);
+0000058E:   9180055A    LDS       R24,0x055A     Load direct from data space
+00000590:   93800550    STS       0x0550,R24     Store direct to data space
118:      		vystup = *(p_pole + 10);
+00000592:   9180055B    LDS       R24,0x055B     Load direct from data space
+00000594:   93800550    STS       0x0550,R24     Store direct to data space
119:      		vystup = *(p_pole + 11);
+00000596:   9180055C    LDS       R24,0x055C     Load direct from data space
+00000598:   93800550    STS       0x0550,R24     Store direct to data space
120:      		vystup = *(p_pole + 12);
+0000059A:   9180055D    LDS       R24,0x055D     Load direct from data space
+0000059C:   93800550    STS       0x0550,R24     Store direct to data space
121:      		vystup = *(p_pole + 13);
+0000059E:   9180055E    LDS       R24,0x055E     Load direct from data space
+000005A0:   93800550    STS       0x0550,R24     Store direct to data space
122:      		vystup = *(p_pole + 14);
+000005A2:   9180055F    LDS       R24,0x055F     Load direct from data space
+000005A4:   93800550    STS       0x0550,R24     Store direct to data space
123:      		vystup = *(p_pole + 15);
+000005A6:   91800560    LDS       R24,0x0560     Load direct from data space
+000005A8:   93800000    STS       0x0000,R24     Store direct to data space
124:      		vystup = *(p_pole + 16);
+000005AA:   91800561    LDS       R24,0x0561     Load direct from data space
+000005AC:   93800550    STS       0x0550,R24     Store direct to data space
125:      		vystup = *(p_pole + 17);
+000005AE:   91800562    LDS       R24,0x0562     Load direct from data space
+000005B0:   93800550    STS       0x0550,R24     Store direct to data space
126:      		vystup = *(p_pole + 18);
+000005B2:   91800563    LDS       R24,0x0563     Load direct from data space
+000005B4:   93800550    STS       0x0550,R24     Store direct to data space
127:      		vystup = *(p_pole + 19);
+000005B6:   91800564    LDS       R24,0x0564     Load direct from data space
+000005B8:   93800550    STS       0x0550,R24     Store direct to data space
107:      	while (podmienka_behu) {	
+000005BA:   91800102    LDS       R24,0x0102     Load direct from data space
+000005BC:   2388        TST       R24            Test for Zero or Minus
+000005BD:   F009        BREQ      PC+0x02        Branch if equal
+000005BE:   CFAB        RJMP      PC-0x0054      Relative jump
130:      }

alebo ak je pocet prvkov do 64
jeden krok trva tak isto 0.16us

volatile static uint8_t pole_gen[256], pole_gen2[256], vystup, podmienka_behu =  TRUE;
register uint8_t aktual_index = 0, *p_pole = NULL, *p_pole_pom;

	if (nejaka_podmienka) p_pole = (uint8_t *)pole_gen;
	else p_pole = (uint8_t *) pole_gen2;
	while (podmienka_behu) {	
		vystup = *(p_pole + 0);
		vystup = *(p_pole + 1);
		vystup = *(p_pole + 2);
		vystup = *(p_pole + 3);
		vystup = *(p_pole + 4);
		vystup = *(p_pole + 5);
		vystup = *(p_pole + 6);
		vystup = *(p_pole + 7);
		vystup = *(p_pole + 8);
		vystup = *(p_pole + 9);
		vystup = *(p_pole + 10);
		vystup = *(p_pole + 11);
		vystup = *(p_pole + 12);
		vystup = *(p_pole + 13);
		vystup = *(p_pole + 14);
		vystup = *(p_pole + 15);
		vystup = *(p_pole + 16);
		vystup = *(p_pole + 17);
		vystup = *(p_pole + 18);
		vystup = *(p_pole + 19);
	}

sa prelozi ako


105:      	if (vystup) p_pole = (uint8_t *)pole_gen;
+00000569:   91800550    LDS       R24,0x0550     Load direct from data space
+0000056B:   2388        TST       R24            Test for Zero or Minus
+0000056C:   F019        BREQ      PC+0x04        Branch if equal
+0000056D:   E5E1        LDI       R30,0x51       Load immediate
+0000056E:   E0F6        LDI       R31,0x06       Load immediate
+0000056F:   C03F        RJMP      PC+0x0040      Relative jump
106:      	else p_pole = (uint8_t *) pole_gen2;
+00000570:   E5E1        LDI       R30,0x51       Load immediate
+00000571:   E0F5        LDI       R31,0x05       Load immediate
+00000572:   C03C        RJMP      PC+0x003D      Relative jump
108:      		vystup = *(p_pole + 0);
+00000573:   8180        LDD       R24,Z+0        Load indirect with displacement
+00000574:   93800550    STS       0x0550,R24     Store direct to data space
109:      		vystup = *(p_pole + 1);
+00000576:   8181        LDD       R24,Z+1        Load indirect with displacement
+00000577:   93800550    STS       0x0550,R24     Store direct to data space
110:      		vystup = *(p_pole + 2);
+00000579:   8182        LDD       R24,Z+2        Load indirect with displacement
+0000057A:   93800550    STS       0x0550,R24     Store direct to data space
111:      		vystup = *(p_pole + 3);
+0000057C:   8183        LDD       R24,Z+3        Load indirect with displacement
+0000057D:   93800550    STS       0x0550,R24     Store direct to data space
112:      		vystup = *(p_pole + 4);
+0000057F:   8184        LDD       R24,Z+4        Load indirect with displacement
+00000580:   93800550    STS       0x0550,R24     Store direct to data space
113:      		vystup = *(p_pole + 5);
+00000582:   8185        LDD       R24,Z+5        Load indirect with displacement
+00000583:   93800550    STS       0x0550,R24     Store direct to data space
114:      		vystup = *(p_pole + 6);
+00000585:   8186        LDD       R24,Z+6        Load indirect with displacement
+00000586:   93800550    STS       0x0550,R24     Store direct to data space
115:      		vystup = *(p_pole + 7);
+00000588:   8187        LDD       R24,Z+7        Load indirect with displacement
+00000589:   93800550    STS       0x0550,R24     Store direct to data space
116:      		vystup = *(p_pole + 8);
+0000058B:   8580        LDD       R24,Z+8        Load indirect with displacement
+0000058C:   93800550    STS       0x0550,R24     Store direct to data space
117:      		vystup = *(p_pole + 9);
+0000058E:   8581        LDD       R24,Z+9        Load indirect with displacement
+0000058F:   93800550    STS       0x0550,R24     Store direct to data space
118:      		vystup = *(p_pole + 10);
+00000591:   8582        LDD       R24,Z+10       Load indirect with displacement
+00000592:   93800550    STS       0x0550,R24     Store direct to data space
119:      		vystup = *(p_pole + 11);
+00000594:   8583        LDD       R24,Z+11       Load indirect with displacement
+00000595:   93800550    STS       0x0550,R24     Store direct to data space
120:      		vystup = *(p_pole + 12);
+00000597:   8584        LDD       R24,Z+12       Load indirect with displacement
+00000598:   93800550    STS       0x0550,R24     Store direct to data space
121:      		vystup = *(p_pole + 13);
+0000059A:   8585        LDD       R24,Z+13       Load indirect with displacement
+0000059B:   93800550    STS       0x0550,R24     Store direct to data space
122:      		vystup = *(p_pole + 14);
+0000059D:   8586        LDD       R24,Z+14       Load indirect with displacement
+0000059E:   93800550    STS       0x0550,R24     Store direct to data space
123:      		vystup = *(p_pole + 15);
+000005A0:   8587        LDD       R24,Z+15       Load indirect with displacement
+000005A1:   93800550    STS       0x0550,R24     Store direct to data space
124:      		vystup = *(p_pole + 16);
+000005A3:   8980        LDD       R24,Z+16       Load indirect with displacement
+000005A4:   93800550    STS       0x0550,R24     Store direct to data space
125:      		vystup = *(p_pole + 17);
+000005A6:   8981        LDD       R24,Z+17       Load indirect with displacement
+000005A7:   93800550    STS       0x0550,R24     Store direct to data space
126:      		vystup = *(p_pole + 18);
+000005A9:   8982        LDD       R24,Z+18       Load indirect with displacement
+000005AA:   93800550    STS       0x0550,R24     Store direct to data space
127:      		vystup = *(p_pole + 19);
+000005AC:   8983        LDD       R24,Z+19       Load indirect with displacement
+000005AD:   93800550    STS       0x0550,R24     Store direct to data space
107:      	while (podmienka_behu) {	
+000005AF:   91800102    LDS       R24,0x0102     Load direct from data space
+000005B1:   2388        TST       R24            Test for Zero or Minus
+000005B2:   F009        BREQ      PC+0x02        Branch if equal
+000005B3:   CFBF        RJMP      PC-0x0040      Relative jump
130:      }

A toto mi prekladac prelozil s nastaveni -O3 zza cas 0.38us na jednu vzorku, je pravda ze uz treba mat napasovany index pola na adresu nula co v predchadzajucich pripadoch nebolo treba

aktual_index = 0;
	p_pole_pom = (uint8_t *)pole_gen;
	while (podmienka_behu) {
		vystup = *p_pole + aktual_index;
		aktual_index++;
	}
93:       	while (podmienka_behu) {
+0000064E:   91800102    LDS       R24,0x0102     Load direct from data space
+00000650:   2388        TST       R24            Test for Zero or Minus
+00000651:   F049        BREQ      PC+0x0A        Branch if equal
94:       		vystup = *p_pole + aktual_index;
+00000652:   91800000    LDS       R24,0x0000     Load direct from data space
+00000654:   93800550    STS       0x0550,R24     Store direct to data space
93:       	while (podmienka_behu) {
+00000656:   91900102    LDS       R25,0x0102     Load direct from data space
+00000658:   5F8F        SUBI      R24,0xFF       Subtract immediate
+00000659:   2399        TST       R25            Test for Zero or Minus
+0000065A:   F7C9        BRNE      PC-0x06        Branch if not equal

trosku som a rozvlacne rozpisal, ale snad ma tato pozdna hodina ospravedlni :slight_smile:
Si si isty, ze ten asm je az taky zasadny prinos aby si ho do C-cka vobec montoval?

Xtal 18.432MHz

Tabulku umístíš např. na adresu 0x200 takto:

[code]uint8_t sinus] attribute((section(“.sinus”)));
uint8_t sinus] =
{
0x99,0x11,0x22,0x33,0x44,0x55,0x66,0x77

};
[/code]
A v Options napíšeš podle obrázku.
section.gif

Tady čtení z pole v RAM není rychlejší než z Flash.

Nádhera, děkuju