 |
www.elektronik.si Forum o elektrotehniki in računalništvu
|
Poglej prejšnjo temo :: Poglej naslednjo temo |
Avtor |
Sporočilo |
aly Član



Pridružen-a: Tor 28 Sep 2004 14:51 Prispevkov: 9407 Aktiv.: 39.62 Kraj: Kranj - struževo
|
Objavljeno: Tor Avg 23, 2011 4:22 pm Naslov sporočila: |
|
|
Še en nasvet, če bo kdo rabil...
Če je deklarirana ena sama (samostojna) številka kot const, potem compiler v programu uporablja direktno vrednost te konstante. Sploh ne hodi gledat na željeno lokacijo v Flash, ampak se v disassemlerju pojavi ukaz MOV s konstantno vrednostjo. In program ne deluje več po pričakovanjih.
Torej, tudi če je za vpisat ena sama številka, mora biti deklarirana kot tabela (array):
Koda: |
const u32 serijska_stevilka_Flash[] __at(FLASH_WRITE_START_ADDR + 0x01EC) = {200}; |
_________________ I'm going to stand outside, so if anyone asks, I'm outstanding  |
|
Nazaj na vrh |
|
 |
gumby Član


Pridružen-a: Sob 28 Apr 2007 12:32 Prispevkov: 4066 Aktiv.: 18.37
|
Objavljeno: Tor Avg 23, 2011 8:48 pm Naslov sporočila: |
|
|
aly je napisal/a: |
Če je deklarirana ena sama (samostojna) številka kot const, potem compiler v programu uporablja direktno vrednost te konstante. |
Emmm... const ne pomeni "konstanta", ampak read only oz. not modifiable. Torej "nekaj", kar se ne more spreminjat v samem programu, lahko se pa vrednost spremeni zaradi zunanjih vplivov (naprimer vhodni in status registri).
Da ne bo nesporazuma...
_________________ Tule nisem več aktiven. |
|
Nazaj na vrh |
|
 |
aly Član



Pridružen-a: Tor 28 Sep 2004 14:51 Prispevkov: 9407 Aktiv.: 39.62 Kraj: Kranj - struževo
|
Objavljeno: Tor Avg 23, 2011 9:56 pm Naslov sporočila: |
|
|
Na začetku sem pisal const zato, da je vrednost ostala v flash-u in je ni kopiral v RAM.
Mogoče bi bilo zanimivo pustit deklaracijo naslova ("__at" ...) in samo zbrisat const.
Da vidimo v kaj, če sploh, prevede.
Mimogrede,
ali je kdo na mikrokrmilnikih že preizkušal dinamično alokacijo prostora v ram-u?
Ko v funkciji deklariraš novo lokalno spremenljivko, jo menda postavi v "heap". Jaz pa bi rad takšno spremenljivko obdržal med parimi funkcijami. Tole bo verjetno kar pravšnje:
http://www.exforsys.com/tutorials/c-language/dynamic-memory-allocation-in-c.html
Koda: |
ptr=(int*)malloc(100*sizeof(int));
free(ptr);
|
pa še eno drugo varianto sem zasledil (C++):
Koda: |
int *ptr;
ptr = new int;
*ptr = 7;
delete ptr; ali ptr = NULL;
int *a;
a = new int[3];
*a = 300;
*(a+1) = 301;
*(a+2) = 302;
delete[] a; |
https://users.cs.jmu.edu/bernstdh/web/common/lectures/slides_cpp_dynamic-memory.php
http://www.cplusplus.com/forum/articles/416/
_________________ I'm going to stand outside, so if anyone asks, I'm outstanding  |
|
Nazaj na vrh |
|
 |
chaos Član


Pridružen-a: Sob 16 Sep 2006 22:12 Prispevkov: 1063 Aktiv.: 4.65 Kraj: Zagorje ob Savi
|
Objavljeno: Sre Avg 24, 2011 12:31 pm Naslov sporočila: |
|
|
gumby je napisal/a: |
Emmm... const ne pomeni "konstanta", ampak read only oz. not modifiable. Torej "nekaj", kar se ne more spreminjat v samem programu, lahko se pa vrednost spremeni zaradi zunanjih vplivov (naprimer vhodni in status registri).
Da ne bo nesporazuma...  |
const lahko v dolocenih primerih pomeni ravno konstanta, kot je aly videl, npr:
Koda: |
#define I 10
const int i = 10;
|
Zgornja dva izraza sta, kar se prevajalnika tice, ekvivalentna. Po potrebi bo prevajalnik to spremenljivko zamenjal s konstanto in jo uporabljal kot immediate value v ukazih.
V drugih primerih pa se lahko uporablja const kot navodilo prevajalniku, naj dolocene spremenljivke ne dovoli spreminjati, a ce hoces, da ne bo optimiziral vsakokratnega branja spremenljivke (zunanji vplivi, kot si ti napisal), moras spremenljivki dodati se volatile, npr:
Koda: |
const volatile int * const i;
|
kjer je i konstantni kazalec na const volatile integer - ne mores spreminjati samega pointerja, ne lokacije, na katerega kaze (integer), a prevajalnik ne sme optimizirati branj te vrednosti, ker je specificirana kot volatile - torej obstaja moznost spremembe spremenljivke izven normalnega poteka programa (ISR, hardverski registri, ...)
LP!
|
|
Nazaj na vrh |
|
 |
aly Član



Pridružen-a: Tor 28 Sep 2004 14:51 Prispevkov: 9407 Aktiv.: 39.62 Kraj: Kranj - struževo
|
Objavljeno: Pet Feb 24, 2012 11:29 am Naslov sporočila: |
|
|
// *** čez pol leta *** //
Zadeva z zapisovanjem in branjem je lepo delovala do danes, ko sem vključil optimiziranje kode iz 0 na 2. Sedaj pa me spet heca
Torej, imam tabelo v RAM-u in tabelo v Flash-u.
Ker ima Flash nekaj wait-stateov, v programu uporabljam tabelo v RAM-u.
Ob zagonu se podatki iz Flash-a prekopirajo v RAM. Oziroma naj bi se, kar pa se ne zgodi, ko je program optimiziran.
Koda: |
const u32 serijska_stevilka_Flash[] __at(FLASH_WRITE_START_ADDR) = {200};
volatile u32 serijska_stevilka=0;
serijska_stevilka = serijska_stevilka_Flash[0]; |
V Flash je ob prevajanju vpisana vrednost 200 (glej kodo).
V Flash je naknadno vpisana vrednost 99. Po resetu procesorja je številka dejansko tam.
Ko pa se po resetu program izvaja, ne uporablja nove vrednosti 99, ki bi jo moral prebrati, ampak vrednost 200, ki je bila ob prevajanju očitno zabetonirana v RAM.
Spremenljivka v RAMu obstaja (prevajalnik je ni nadomestil s konstanto).
Ampak namesto da bi prebral iz flash-a, flikne nori konstantno vrednost:
Ali se da s kakimi ukazi prevajalniku povedati, katerih delov kode naj ne optimizira ?!
Ker optimizirat bi rabil samo eno zanko, ostalo ni časovno občutljivo.
Takole pa bi moralo biti in dela (brez optimizacije):
Opis: |
|
 Download |
Ime datoteke: |
flash-ram.png |
Velikost datoteke: |
4.25 KB |
Downloadano: |
70 krat |
Opis: |
|
 Download |
Ime datoteke: |
flash-ram-ok.png |
Velikost datoteke: |
4.41 KB |
Downloadano: |
65 krat |
_________________ I'm going to stand outside, so if anyone asks, I'm outstanding  |
|
Nazaj na vrh |
|
 |
Umnik Član

Pridružen-a: Čet 16 Sep 2004 17:52 Prispevkov: 958 Aktiv.: 4.03 Kraj: Novo mesto
|
Objavljeno: Pet Feb 24, 2012 11:52 am Naslov sporočila: |
|
|
Da določiš optimization level le za eno funkcijo lahko s #pragma narediš takole:
#pragma push
#pragma Ox //vrednost x = 0, 1, 2, 3 za različen optimisation level
/* funkcija */
void f (void) {
...
}
#pragma pop
Moj pomislek:
Če imaš težave zaradi spremenjenega optimisation levela, to lahko pomeni, da je koda slabo napisana (ni pa to nujno v vseh primerih res, so pa to redki primeri). Vsi moji programi so v končnih variantah buildani na optimisation levelu 3 in vse mora takrat tudi delovat.
|
|
Nazaj na vrh |
|
 |
aly Član



Pridružen-a: Tor 28 Sep 2004 14:51 Prispevkov: 9407 Aktiv.: 39.62 Kraj: Kranj - struževo
|
Objavljeno: Pet Feb 24, 2012 12:05 pm Naslov sporočila: |
|
|
Kako je koda napisana se itak ne morem primerjati s teboj
Problem se pojavi samo na opisanem mestu. Verjetno zato, ker imam definirano kot const:
const u32 serijska_stevilka_Flash[] ...
Sem poskusil z volatile, pa potem nabašem težave pri linkerju.
Bom poskusil tole branje iz flasha v ram prestavit v ločeno funkcijo in ji izklopit optimizacijo.
EDIT: Ta trik deluje
--> Umnik
Če pa ima kdo idejo, kako compiler prpričati, da naj vedno prebere vrednost iz Flash v RAM, ne da RAM nafila s konstantami, pa je še vedno dobrodošel.
_________________ I'm going to stand outside, so if anyone asks, I'm outstanding  |
|
Nazaj na vrh |
|
 |
|
|
Ne, ne moreš dodajati novih tem v tem forumu Ne, ne moreš odgovarjati na teme v tem forumu Ne, ne moreš urejati svojih prispevkov v tem forumu Ne, ne moreš brisati svojih prispevkov v tem forumu Ne ne moreš glasovati v anketi v tem forumu Ne, ne moreš pripeti datotek v tem forumu Ne, ne moreš povleči datotek v tem forumu
|
Uptime: 6 dni
Powered by phpBB © 2001, 2005 phpBB Group
|