Sida 1 av 2

minnas global variabel efter reset? (C-programmering)

Postat: 31 mars 2010, 16:11:10
av jesse
Jag har en global variabel i ett C-program som ständigt förändras och jag vill att den behåller sitt värde även om man startar om processorn (AVR). Jag vill inte spara den i EEPROM, då det skulle bli allt för många uppdateringar på sikt.

Normalt så nollställs ju alla globala variabler vid start, men jag undrar om det finns något sätt att hoppa över detta. (bara med denna variabeln, alla andra ska nollas).

jag testade med att skriva static framför, men då verkade själva variabeln upphöra att fungera alls. Den är noll, men kan inte ändras ??? Funkar kanske inte på en global variabel?

Nu råkar det handla om en struct, och egentligen är det bara ett värde som behöver "minnas" och det är soc.millicoulomb, men det spelar ingen roll om de andra delvariablerna i "soc" inte nollställs.

main.h:

Kod: Markera allt

	struct socdata {
		int32_t ampere; // hundradelar 0.01
		int64_t millicoulomb;
		int16_t deciamphours;
		int16_t maxdeciah;
		int16_t mindeciah;
		} soc;

Re: minnas global variabel efter reset? (C-programmering)

Postat: 31 mars 2010, 16:15:11
av Micke_s

Re: minnas global variabel efter reset? (C-programmering)

Postat: 31 mars 2010, 16:20:44
av sodjan
Vad menar du med "startas om" ?
Soft reset ?
Hard reset ?
Power off/on ?

Re: minnas global variabel efter reset? (C-programmering)

Postat: 31 mars 2010, 16:26:58
av TomasL
Det enda du kan göra är att spara den i EPROM, alternativt externt RAM eller FRAM.

Re: minnas global variabel efter reset? (C-programmering)

Postat: 31 mars 2010, 16:53:26
av jesse
Sodjan: jag menar framför allt hard-reset, men även vid soft-reset.
Vid "power down" är det ju inte aktuellt för då tappar SRAM-minnet ändå sitt innehåll.

Tomas: Är du säker på det? I assembler är det i alla fall inga problem alls, eftersom man själv aktivt måste "nollställa" eller initiera sina data vid start. Annars behåller det ju automatiskt alla data i SRAM.

MickeS: verkar som om du är något på spåret här:
The .noinit Section
This sections is a part of the .bss section. What makes the .noinit section special is that variables which are defined as such:

int foo __attribute__ ((section (".noinit")));

will not be initialized to zero during startup as would normal .bss data.
ska testa detta!

Fanns ju faktiskt med i avr-libc! Men den kan vara lite svår att hitta i om man inte vet vad man letar efter. Jag letade faktiskt inte där alls, då jag trodde det jag sökte ingick i själva språket C, och inte som en del i avr-biblioteken.

Re: minnas global variabel efter reset? (C-programmering)

Postat: 31 mars 2010, 16:58:25
av Swech
Oavsett så är det inte att lita på värden i RAM efter en reset, t.ex. en brownout reset innebär ju att processorn
noterat att spänningen är såpass låg att funktion inte kan garanteras.
Att anta att ens ramvärde överlever till 100% verkar lite modigt.

Swech

Re: minnas global variabel efter reset? (C-programmering)

Postat: 31 mars 2010, 17:15:55
av Icecap
Man måste självklart skapa en checksum som beskriver värdet man vill spara fast på ett annat sätt, vid uppstart jämför man dom och bör då kunde avgöra om värdet är legalt eller inte.

Men bäst ville det vara att göra ett solitt program som inte resetter...

Re: minnas global variabel efter reset? (C-programmering)

Postat: 31 mars 2010, 18:40:48
av AndLi
för IAR kompilatorer kan man ange NO_INIT så nollas de inte vid uppstart.

Självklart går de ej att lita på vid brownout/power on/off. Men en vanlig reset av µC ska inte påverka raminnehållet.

I ett projekt jag jobbar med för tillfället ligger allt i ram, finns inte ens något flash att tillgå. Funkar utmärkt så länge man har batterier anslutna, gäller ju att designen är strömsnål dock :)

En crc är bra att ha för att säkerställa datan, men har man en fungerande brownout som man faktiskt kollar så borde den inte behövas...

Re: minnas global variabel efter reset? (C-programmering)

Postat: 31 mars 2010, 19:22:34
av jesse
För min del är det inte ens jätteviktigt att datan behålls 100% av fallen. Det räcker att den minns värdena vid reset oftare än vad den gör nu (dvs aldrig).

Kod: Markera allt

struct socdata {
	int32_t ampere; // hundradelar 0.01
	int64_t millicoulomb;
	int16_t deciamphours;
	int16_t maxdeciah;
	int16_t mindeciah;
	} soc __attribute__ ((section (".noinit")));
denna syntax fungerade i alla fall inte hos mig.. det blev knasfel i kompilatorn:
avr-gcc -mmcu=atmega644 -Wl,-Map=bms6802.map main.o spi.o bms.o flashmem.o uart.o dogm16.o ampere.o -o bms6802.elf
spi.o: In function `SPI_MasterInit':
C:\AVR_projekt\AVR_GCC_projekt\BMS6802A\default/../spi.c:28: multiple definition of `soc'
main.o:c:/program/atmel/winavr-20090313/lib/gcc/../../avr/include/avr/eeprom.h:196: first defined here
bms.o: In function `ntcTemp':
C:\AVR_projekt\AVR_GCC_projekt\BMS6802A\default/../bms.c:19: multiple definition of `soc'
main.o:c:/program/atmel/winavr-20090313/lib/gcc/../../avr/include/avr/eeprom.h:196: first defined here
flashmem.o: In function `SPI_flashadress':
C:\AVR_projekt\AVR_GCC_projekt\BMS6802A\default/../flashmem.c:31: multiple definition of `soc'
main.o:c:/program/atmel/winavr-20090313/lib/gcc/../../avr/include/avr/eeprom.h:196: first defined here
uart.o: In function `uart0_init':
C:\AVR_projekt\AVR_GCC_projekt\BMS6802A\default/../uart.c:27: multiple definition of `soc'
main.o:c:/program/atmel/winavr-20090313/lib/gcc/../../avr/include/avr/eeprom.h:196: first defined here
dogm16.o: In function `d16_keyCheckB':
C:\AVR_projekt\AVR_GCC_projekt\BMS6802A\default/../dogm16.c:80: multiple definition of `soc'
main.o:c:/program/atmel/winavr-20090313/lib/gcc/../../avr/include/avr/eeprom.h:196: first defined here
ampere.o: In function `eeprom_read_byte':
c:/program/atmel/winavr-20090313/lib/gcc/../../avr/include/avr/eeprom.h:196: multiple definition of `soc'
main.o:c:/program/atmel/winavr-20090313/lib/gcc/../../avr/include/avr/eeprom.h:196: first defined here
make: *** [bms6802.elf] Error 1
Build failed with 1 errors and 0 warnings...
jag vet inte varför den klagar på " multiple definition of `soc' " , jag har inte skrivit soc mer än en gång.

Re: minnas global variabel efter reset? (C-programmering)

Postat: 31 mars 2010, 19:38:30
av ahlsten
Det är med största sannolikhet ett länkningsfel som beror på att din struct initialiseras i header-filen.
Definiera bara "huvudet" för structen i header-filen och initialisera "kroppen" i någon c-fil.

Re: minnas global variabel efter reset? (C-programmering)

Postat: 31 mars 2010, 19:40:33
av bearing
Blir det samma fel om du skriver såhär?

Kod: Markera allt

typedef struct socdata {
   int32_t ampere; // hundradelar 0.01
   int64_t millicoulomb;
   int16_t deciamphours;
   int16_t maxdeciah;
   int16_t mindeciah;
   };

socdata soc __attribute__ ((section (".noinit")));

Re: minnas global variabel efter reset? (C-programmering)

Postat: 31 mars 2010, 20:13:56
av jesse
jag kan inte ens skriva såhär utan att få konstiga varningar:

Kod: Markera allt

typedef struct socdata {
   int32_t ampere; // hundradelar 0.01
   int64_t millicoulomb;
   int16_t deciamphours;
   int16_t maxdeciah;
   int16_t mindeciah;
   };

struct socdata soc;
../main.h:148: warning: useless storage class specifier in empty declaration
vilket jag inte heller begriper ???
Och om jag lägger till __atribute__ ... osv... efter soc så blir det samma error som innan.

Re: minnas global variabel efter reset? (C-programmering)

Postat: 31 mars 2010, 20:21:34
av TomasL
Förmodligen måste du göra så här:

Kod: Markera allt

typedef struct SOC_DATA {
   int32_t ampere; // hundradelar 0.01
   int64_t millicoulomb;
   int16_t deciamphours;
   int16_t maxdeciah;
   int16_t mindeciah;
   }socdata;

socdata soc;
Har råkat ut för detta ett antal gånger, enligt ANSI så borde din version fungera, men en del kompilatorer gillar det inte

Re: minnas global variabel efter reset? (C-programmering)

Postat: 31 mars 2010, 20:25:00
av jesse
ok, nu har jag faktiskt lyckats lägga till attibutet med en annan ordning.

Kod: Markera allt

struct __attribute__ ((section (".noinit"))) socdata soc ;
Men jag fattar fortfarande inte den varning som kommer då jag separerade definitionen av "socdata" med definitionen av varibeln "soc":
../main.h:148: warning: useless storage class specifier in empty declaration
Varningen pekar på slutparentesen på själva typedef-delen.

Likväl nollställs variablerna i soc vid reset , så det verkade inte ha nån effekt med det tillägget.
Jag har inte märkt att det fungerar sämre / annorlunda trors varningen. Men jag gillar inte varningar , så jag lägger nog tillbaks soc till slutet på typdefinitionen.

Re: minnas global variabel efter reset? (C-programmering)

Postat: 31 mars 2010, 20:30:01
av TomasL
Har du pröva min version?