RTV forum PL | NewsGroups PL

Jak zachować wartość komórek RAM przy starcie programu w CodeVision AVR?

CVAVR - jak nie inicjalizować wartości zm iennej

NOWY TEMAT

elektroda NewsGroups Forum Index - Elektronika Polska - Jak zachować wartość komórek RAM przy starcie programu w CodeVision AVR?

Goto page 1, 2  Next

EM
Guest

Tue Jan 27, 2009 12:17 pm   



Witam
Nie jestem biegły w programowaniu i mam taki problem odnośnie AVRka
programowanego za pomocą CodeVision AVR.

Otóż potrzebuję na początku programu sprawdzić wartość 2 komórek pamięci
RAM. Zakładam, że komórki te mają wartość taka jak poprzednio, jeśli
napięcie zasilania nie spadło poniżej pewnego poziomu. Podobnie robię w
PICach i to się dobrze sprawdza.


Umiem zmusić program do umieszczenia danych w konkretnym obszarze, robi
się dodając adres po nazwie zmiennej, np.
char data @0x60;
jednak z tego co widzę, to nawet pomimo wyłączonej opcji: clear global
variables at program startup w konfiguracji projektu - wygląda na to, że
te zmienne są zerowane.


To co mi przychodzi na myśl, to użyć jakiejś wstawki assemblerowej,
gdzie będę kopiował wartość z komórki RAM o konkretnym adresie do
jakiejś zmiennej w C.
Potrzebuję tak przekopiować dwie komórki, które mają nie być zerowane
przy inicjalizacji.

Proszę o pomoc
--
Pozdrawiam
EM

EM
Guest

Tue Jan 27, 2009 12:35 pm   



;GLOBAL VARIABLES INITIALIZATION
LDI R30,LOW(__GLOBAL_INI_TBL*2)
LDI R31,HIGH(__GLOBAL_INI_TBL*2)
__GLOBAL_INI_NEXT:
LPM R24,Z+
LPM R25,Z+
SBIW R24,0
BREQ __GLOBAL_INI_END
LPM R26,Z+
LPM R27,Z+
LPM R0,Z+
LPM R1,Z+
MOVW R22,R30
MOVW R30,R0
__GLOBAL_INI_LOOP:
LPM R0,Z+
ST X+,R0
SBIW R24,1
BRNE __GLOBAL_INI_LOOP
MOVW R30,R22
RJMP __GLOBAL_INI_NEXT
__GLOBAL_INI_END:

EM
Guest

Tue Jan 27, 2009 12:38 pm   



PawelM pisze:
Quote:
...zainstaluj AVR Studio4, CV generuje plik COF dzieki temu przejrzysz
dokłądnie asemblera krok po kroku...

Ogólnie z podejrzeniem ASM nie ma problemu


Występuje taka sekcja:

;GLOBAL VARIABLES INITIALIZATION
LDI R30,LOW(__GLOBAL_INI_TBL*2)
LDI R31,HIGH(__GLOBAL_INI_TBL*2)
__GLOBAL_INI_NEXT:
LPM R24,Z+
LPM R25,Z+
SBIW R24,0
BREQ __GLOBAL_INI_END
LPM R26,Z+
LPM R27,Z+
LPM R0,Z+
LPM R1,Z+
MOVW R22,R30
MOVW R30,R0
__GLOBAL_INI_LOOP:
LPM R0,Z+
ST X+,R0
SBIW R24,1
BRNE __GLOBAL_INI_LOOP
MOVW R30,R22
RJMP __GLOBAL_INI_NEXT
__GLOBAL_INI_END:

ale przecież ja nie chcę tego ręcznie usuwać.

Chcę by wszystko było w pliku C, bez kombinacji.
--
Pozdr
EM

PawelM
Guest

Tue Jan 27, 2009 12:45 pm   



....zainstaluj AVR Studio4, CV generuje plik COF dzieki temu przejrzysz
dokłądnie asemblera krok po kroku...
Pzdr.

Piotrne
Guest

Tue Jan 27, 2009 2:54 pm   



EM pisze:

Quote:
To co mi przychodzi na myśl, to użyć jakiejś wstawki assemblerowej,

A takie coś:

char data;
data = *(char*)0x60;

nie działa?

P.

T.M.F.
Guest

Tue Jan 27, 2009 3:59 pm   



Quote:
Otóż potrzebuję na początku programu sprawdzić wartość 2 komórek pamięci
RAM. Zakładam, że komórki te mają wartość taka jak poprzednio, jeśli
napięcie zasilania nie spadło poniżej pewnego poziomu. Podobnie robię w
PICach i to się dobrze sprawdza.

Do tego sluza bity stanu procesora, ktore wskazuja na przyczyne resetu.
Zobacz rejestr MCU, bity WDRF, BORF, EXTRF i PORF.
Metoda o ktorej piszesz nic nie da, bo zawartosc pamieci RAM dosyc dlugo
pozostaje nieuszkodzona. Co wiecej, jesli w pamieci stale jest ta sama
wartosc to jest spora szansa, ze po wlaczeniu zasilania ta wartosc
ciagle tam bedzie. Ot taki ciekawy efekt pamieciowy.

EM
Guest

Tue Jan 27, 2009 4:35 pm   



T.M.F. pisze:
Quote:
Otóż potrzebuję na początku programu sprawdzić wartość 2 komórek
pamięci RAM. Zakładam, że komórki te mają wartość taka jak poprzednio,
jeśli napięcie zasilania nie spadło poniżej pewnego poziomu. Podobnie
robię w PICach i to się dobrze sprawdza.

Do tego sluza bity stanu procesora, ktore wskazuja na przyczyne resetu.
Zobacz rejestr MCU, bity WDRF, BORF, EXTRF i PORF.
Metoda o ktorej piszesz nic nie da, bo zawartosc pamieci RAM dosyc dlugo
pozostaje nieuszkodzona. Co wiecej, jesli w pamieci stale jest ta sama
wartosc to jest spora szansa, ze po wlaczeniu zasilania ta wartosc
ciagle tam bedzie. Ot taki ciekawy efekt pamieciowy.

Tak na prawdę to potrzebuję rozróżnić, czy przerwa w zasilaniu była

dłuższa niż np. 1-2 sekundy, czy nie.
Zakładam, że jeśli zapiszę w jednej komórce jakąś wartość i w innej jej
negację, to odczyt tych dwóch komórek pozwoli stwierdzić, że jeżeli
wpisy są komplementarne, to prawdopodobnie przerwa w zasilaniu była
krótka - czytaj zasilanie nie spadło do jakiegoś granicznego progu.

Jeśli uda mi się w końcu czytać te komórki bez inicjalizacji to sprawdzę
jak się zachowują AVRki pod tym względem.
Popróbuję z tym wskaźnikiem.

Jak wspominałem podobny mechanizm mam na PICu i działa bez problemów.

Co do hardware nie mam niczego, co mógłbym wykorzystać - to jest w
istniejącym układzie. Istnieje tam kondensator podtrzymujący zasilanie -
może to być 10u, nie sprawdzałem dokładnie i to jest wszystko.
--
Pozdr
EM

EM
Guest

Tue Jan 27, 2009 8:57 pm   



Piotrne pisze:
Quote:
EM pisze:

To co mi przychodzi na myśl, to użyć jakiejś wstawki assemblerowej,

A takie coś:

char data;
data = *(char*)0x60;

nie działa?

Witam

Dzięki

Rozumiem, że ten kawałek odczytuje z komórki o adresie 0x60

A jak zapisać do takiej komórki, nie inicjalizując jej jakoś?
--
Pozdrawiam
EM

Piotrne
Guest

Tue Jan 27, 2009 10:02 pm   



EM pisze:

Quote:
A jak zapisać do takiej komórki, nie inicjalizując jej jakoś?

Jeśli tamto działa, to tak:
char data;
data = 123;
*(char*)0x60 = data;

Pozdrawiam
P.

T.M.F.
Guest

Tue Jan 27, 2009 11:00 pm   



Quote:
To co mi przychodzi na myśl, to użyć jakiejś wstawki assemblerowej,

A takie coś:

char data;
data = *(char*)0x60;

nie działa?

ALe to tylko odczyta komorke o adresie 0x60, ale nie spowoduje, ze
zostanie ona zarezerwowana. W efekcie kompilator umiesci tam pierwsza
lepsza zmienna i nic z tego nie wyniknie.
W AVR-gcc wystarczy stworzyc globalna zmienna niestatyczna, kompilator
nie inicjalizuje takich zmiennych.

Adam Dybkowski
Guest

Tue Jan 27, 2009 11:19 pm   



T.M.F. pisze:

Quote:
W AVR-gcc wystarczy stworzyc globalna zmienna niestatyczna, kompilator
nie inicjalizuje takich zmiennych.

Jeżeli zmienna wpadnie do sekcji .bss - to zostanie automatycznie
wyzerowana. Jeżeli potrzeba zmiennej, która nie będzie inicjowana,
trzeba skorzystać z dobrodziejstwa sekcji ".noinit".

--
Adam Dybkowski
http://dybkowski.net/

Uwaga: przed wysłaniem do mnie maila usuń cyfry z adresu.

T.M.F.
Guest

Wed Jan 28, 2009 12:26 am   



Adam Dybkowski pisze:
Quote:
T.M.F. pisze:

W AVR-gcc wystarczy stworzyc globalna zmienna niestatyczna, kompilator
nie inicjalizuje takich zmiennych.

Jeżeli zmienna wpadnie do sekcji .bss - to zostanie automatycznie
wyzerowana. Jeżeli potrzeba zmiennej, która nie będzie inicjowana,
trzeba skorzystać z dobrodziejstwa sekcji ".noinit".

W takim przykladzie:
void main()
{
int a;

if(a==costam) DoSomething();
}

Zmienna a nie bedzie inicjalizowana. Poniewaz za kazdym razem trafia w
to samo miejsce programu jej wartosc bedzie zachowana pomiedzy
uruchomieniami. Oczywiscie kompilator wyrzuci ostrzezenie, ze uzywamy
niezainicjalizowanej zmiennej, ale w koncu o to nam chodzi.

EM
Guest

Wed Jan 28, 2009 10:45 am   



T.M.F. pisze:
Quote:
To co mi przychodzi na myśl, to użyć jakiejś wstawki assemblerowej,

A takie coś:

char data;
data = *(char*)0x60;

nie działa?

ALe to tylko odczyta komorke o adresie 0x60, ale nie spowoduje, ze
zostanie ona zarezerwowana. W efekcie kompilator umiesci tam pierwsza
lepsza zmienna i nic z tego nie wyniknie.
W AVR-gcc wystarczy stworzyc globalna zmienna niestatyczna, kompilator
nie inicjalizuje takich zmiennych.

Ale to mi powinno wystarczyć, sprawdzę w listingu, czy nie nastąpi jakiś
konflikt z wykorzystywaną komórką. Program jest prosty i akurat zasobów
RAM prawie nie wykorzystuje.
--
Pozdr
EM

EM
Guest

Wed Jan 28, 2009 10:52 am   



T.M.F. pisze:
Quote:
Adam Dybkowski pisze:
T.M.F. pisze:

W AVR-gcc wystarczy stworzyc globalna zmienna niestatyczna,
kompilator nie inicjalizuje takich zmiennych.

Jeżeli zmienna wpadnie do sekcji .bss - to zostanie automatycznie
wyzerowana. Jeżeli potrzeba zmiennej, która nie będzie inicjowana,
trzeba skorzystać z dobrodziejstwa sekcji ".noinit".

W takim przykladzie:
void main()
{
int a;

if(a==costam) DoSomething();
}

Zmienna a nie bedzie inicjalizowana. Poniewaz za kazdym razem trafia w
to samo miejsce programu jej wartosc bedzie zachowana pomiedzy
uruchomieniami. Oczywiscie kompilator wyrzuci ostrzezenie, ze uzywamy
niezainicjalizowanej zmiennej, ale w koncu o to nam chodzi.

Bardzo ciekawa propozycja jak dla mnie.
Rozumiem, że program przy każdym uruchomieniu natrafi na ten sam obszar
w RAM, a nie powinien on być inicjowany - zerowany.
Nie stanowi natomiast problemu, że tak na prawdę nie wiem jaki to będzie
adres.
Wcześniej próbowałem
void main()
{
char data @0x60;;
.....
}

ale taki podanie adresu działa tylko dla zmiennych globalnych.


Sprawdzam...
--
Pozdrawiam
EM

Konop
Guest

Wed Jan 28, 2009 5:09 pm   



Quote:
ale taki podanie adresu działa tylko dla zmiennych globalnych.

Dla lokalnych statycznych też chyba powinno Wink.... ale nie o to chodzi Very Happy

Goto page 1, 2  Next

elektroda NewsGroups Forum Index - Elektronika Polska - Jak zachować wartość komórek RAM przy starcie programu w CodeVision AVR?

NOWY TEMAT

Regulamin - Zasady uzytkowania Polityka prywatnosci Kontakt RTV map News map