Stora variabler/listor (PIC18fxxxx)

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
rävekorre
Inlägg: 37
Blev medlem: 4 augusti 2005, 14:40:11
Ort: Östergötland

Stora variabler/listor (PIC18fxxxx)

Inlägg av rävekorre »

Jag vill lagra en stor bitmat (1024bytes) i programminnet på en pic (18f), men det vill sig inte.

Först får jag felmeddelandet:


MPLINK 4.00, Linker Copyright (c) 2005 Microchip Technology Inc. Error - section '.idata_minfel.o' can not fit the section. Section '.idata_minfil.o' length=0x00000400 Errors : 1

Nedan skall åtgärda felet, men så länge jag har kvar protected kvarstår problemet. Tar jag bort det kompileras filen, men alla element i bitmapen läses som 0. Inge kul.

FAQ-10 How do I create a large object in data memory (> 256 bytes)?
By default, MPLAB C18 assumes that an object will not cross a bank boundary. The
following steps are required to safely use an object that is larger than 256 bytes:
1. The object must be allocated into its own section using the #pragma idata or
#pragma udata directive:
#pragma udata buffer_scn
static char buffer[0x180];
#pragma udata
2. Accesses to the object must be done via a pointer:
char * buf_ptr = &buffer[0];
...
// examples of use
buf_ptr[5] = 10;
if (buf_ptr[275] > 127)
...
3. A region that spans multiple banks must be created in the linker script:
- Linker script before modification:
DATABANK NAME=gpr2 START=0x200 END=0x2FF
DATABANK NAME=gpr3 START=0x300 END=0x3FF
- Linker script after modification:
DATABANK NAME=big START=0x200 END=0x37F PROTECTED
DATABANK NAME=gpr3 START=0x380 END=0x3FF
4. The objects section (created in Step 1) must be assigned into the new region
(created in Step 3) by adding a SECTION directive to the linker script:
SECTION NAME=buffer_scn RAM=big

Någon som har ett förslag?
sodjan
EF Sponsor
Inlägg: 43250
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Vilken PIC ?
Hur ser din kod och LNK fil ut efter att du har gjort det som står i FAQ-10 ?
Användarvisningsbild
rävekorre
Inlägg: 37
Blev medlem: 4 augusti 2005, 14:40:11
Ort: Östergötland

Inlägg av rävekorre »

Det är en PIC18f4431.

Jag antar att du menar LKR-filen? ;)

LKR-filen:
...
DATABANK NAME=gpr2 START=0x200 END=0x3FF
DATABANK NAME=big START=0x400 END=0x8FF PROTECTED
ACCESSBANK NAME=accesssfr START=0xF60 END=0xFFF PROTECTED

SECTION NAME=CONFIG ROM=config
SECTION NAME=buffer_scn RAM=big
sodjan
EF Sponsor
Inlägg: 43250
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Och (rellevant) kod ?
Användarvisningsbild
rävekorre
Inlägg: 37
Blev medlem: 4 augusti 2005, 14:40:11
Ort: Östergötland

Inlägg av rävekorre »

Javisst, här kommer...

Kod: Markera allt

#include <p18f4431.h>
#include <stdio.h>

#pragma udata big
static char buffer[1024] = { 1,2,3,4,5...1024};
#pragma udata
	
char * buf_ptr = &buffer[0];

void main() 
{ 
	int i; 
	for(i = 0; i < 10; i ++) 
	{ 
	  printf("VALUE: %d\n", buffer[i]);
	  printf("VALUE: %d\n", buf_ptr[i]);
	} 
}
Output:
VALUE: 0
VALUE: 0
VALUE: 0
VALUE: 0
VALUE: 0
VALUE: 0
VALUE: 0
VALUE: 0
VALUE: 0
...
Användarvisningsbild
Xyzzy
Inlägg: 1260
Blev medlem: 30 januari 2004, 22:31:07
Ort: Uppsala, Sweden

Inlägg av Xyzzy »

du kan inte ha så stora tal (större än 255) i en char (8 bitar)...
Kanske inte det som åstakommer ditt problem, men ett fel iaf. :)
sodjan
EF Sponsor
Inlägg: 43250
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

RAM minne har *aldrig* något fördefinierat värde.
Du måste ange värden i runtime.
Eller lägga din "tabell" i ROM...
Kolla dokumentationen till den kompiliator du använder...



EDIT: Jag kollade lite mer av vad du har skrivit tidigare...

Först : "Jag vill lagra en stor bitmat (1024bytes) i programminnet"

Alltså i Flash, inte RAM !!

Sedan är det ju RAM (GPR) du fixar med i LKR filen, jag får inte ihop det...
Användarvisningsbild
rävekorre
Inlägg: 37
Blev medlem: 4 augusti 2005, 14:40:11
Ort: Östergötland

Inlägg av rävekorre »

du kan inte ha så stora tal (större än 255) i en char (8 bitar)...
Kanske inte det som åstakommer ditt problem, men ett fel iaf.
Oj, när jag pulade ihop den relevanta koden missade jag detta. Vad jag menade var att det finns 1024 element i "listan". Givetvis bara chars.


Sodjan:
Variabeln lagras väl i programminnet för att sedan överföras till RAM när MCUn initieras? Är jag ute och cyklar (ja uppenbart)? Hur annars skulle jag kunna ändra innehållet i listan?
sodjan
EF Sponsor
Inlägg: 43250
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Variabeln lagras väl i programminnet för att sedan överföras till RAM när MCUn initieras?

Har du kollat om det skapas kod för det ??

Jag såg just att du kör C18, eller hur ?
Kolla "2.4.3 ram/rom" om det kan vara något...

EDIT : Ville bara tillägga, att om det några tveksamheter kring vad kompilatorn skapar för kod, så är det bara att kolla assembler listningen. Där fins "facit"... :-)
Användarvisningsbild
rävekorre
Inlägg: 37
Blev medlem: 4 augusti 2005, 14:40:11
Ort: Östergötland

Inlägg av rävekorre »

Näru, det ser inte ut som det skapats en droppe kod.

Jag kikade på 2.4.3.

Jag får inte ihop det med FAQ-10.

Data memory gaugen säger att jag förbrukat nästan 200% av det tillgängliga.

Jag vill poängtera att jag för första gången började använda C18 för lite drygt 36h sedan. Har sedan tidigare ingen erfarenhet av maskinnära C.

Bockar och bugar för hjälpen.
sodjan
EF Sponsor
Inlägg: 43250
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Precis, vill man ha en förpopulerad (heter det så?) tabell/array så får man lägga den i Flash ("rom"). Sedan kan man läsa den direkt från rom, eller om man måste ha högsta prestanda när man "slår" i tabellen, kopiera över datat till RAM i sin uppstartsrutin.
En tabell (array) som man själv fyller med data ligger naturligtsvis bäst i RAM från början.

2.4.3 visar enbart på skillndaden att skapa ett objekt i RAM vs. ROM.
FAQ-10 talade väll specifikt om att skapa en tabell > 256 bytes i RAM ?
Jag ser ingen direkt konflikt mellan de två valen.

EDIT : En annan sak, en så stor array är lite ovanligt skulle jag tro.
Har du möjlighet att beskriva vilken funktion den har ?
Användarvisningsbild
rävekorre
Inlägg: 37
Blev medlem: 4 augusti 2005, 14:40:11
Ort: Östergötland

Inlägg av rävekorre »

Nu kontrollerade jag och visst stämmer det, minnet ska inte räcka till. Opps. Dumdidumdidum

Till rom då.
Jag skriver rom variabel och vips så hamnar den lite snyggt där, ramen frias upp och bitmappen fungerar. Igår hade jag kunnat offra min högra hand på att det inte fungerade (då lite drygt 20h utan sömn). Data fick jag, men inte rätt. Nu spelar det ingen roll vad jag gör, det blir rätt. ;)

Det är en bitmap som jag tänkte slänga ut på en display. I praktiken kommer jag ha mindre objekt men de kommer kanske sträcka sig uppåt 256. Det självklara valet då är rom.

Hade jag inte frågat skulle jag inte ha sprungit på ram/rom biten utan levt i min egen illusion. Nu har jag mängder med god information att frossa i, vilket jag ska göra först.

Problemet tycks vara löst och lite till. Som sagt kan jag alltid kopiera det som ryms till ram. Först då kommer FAQ-10 biten in i bilden.

Stort tack!!

Efter denna exemplariska hjälp kommer jag kanske att ställa fler dumma frågor. :wink:

Slänger med programsnutten som fungerar:

Kod: Markera allt

	rom unsigned char * buf_ptr = &buffer[0]; 
	void main(void) 
	{ 
		char blah[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 
			int i; 
				for(i = 0; i < 1023; i ++) 
					{ printf("Element: %d Värde: %d\n", i, buf_ptr[i]); } 
	}
Varför totalvägrar den om jag skriver "for(int i = 0; i < 1023; i ++)"? Att skriva "int i;" ovan känns för mig helt fel.
Seven11
Inlägg: 547
Blev medlem: 13 maj 2004, 23:43:33

Inlägg av Seven11 »

Bara undrar... vilken kompilator använder du?
sodjan
EF Sponsor
Inlägg: 43250
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Seven11: "Bara undrar... vilken kompilator använder du?"

Från rävekorre's första injägg :

> "By default, MPLAB C18 assumes that an object....."

Ska vi gissa på C18 ?? :-)

"Hade jag inte frågat skulle jag inte ha sprungit på ram/rom biten utan levt i min egen illusion.

Här hänger jag inte med, det är ju ganska tydligt i dokumentationen.
Tog ett par minuter att hitta, fast jag aldrig har använt C18 eller programmerat (på PIC) i C...

Om det gäller bitmappar för en LCD, så verkar det väll som om du inte behöver den extra performance du får genom att kopiera den till RAM.
Uppslagningen mot ROM sker med TBLREAD vilket antagligen är snabbt nog.
Användarvisningsbild
Icecap
Inlägg: 26641
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Det är inte alla kompilatorer som accepterar att man deklarerar en variabel "on the fly", därför måste man då deklarera den först (innan nägon programdel i den rutin) för att det ska fungera, det är faktisk ANSI C på det vis.....

Jag är just i slutskedet för version 1.0 med ett ANSI C projekt och just det att man inte kan deklarera en variabel eftersom man behöver den så att säga kan vara lita störande....

Men men....life's a bitch and then you marry one...
Skriv svar