Stora variabler/listor (PIC18fxxxx)
Stora variabler/listor (PIC18fxxxx)
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?
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?
Javisst, här kommer...
Output:
VALUE: 0
VALUE: 0
VALUE: 0
VALUE: 0
VALUE: 0
VALUE: 0
VALUE: 0
VALUE: 0
VALUE: 0
...
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]);
}
}
VALUE: 0
VALUE: 0
VALUE: 0
VALUE: 0
VALUE: 0
VALUE: 0
VALUE: 0
VALUE: 0
VALUE: 0
...
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...
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...
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.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:
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?
> 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"...
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"...

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.
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.
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 ?
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 ?
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.
Slänger med programsnutten som fungerar:
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.
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.

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]); }
}
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.
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.
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...
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...