Vad är det som äter RAM?

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Vad är det som äter RAM?

Inlägg av sodjan »

Vad säger MAP filen? Eller du kanske aldrig får en MAP fil p.g.a felen...
Ta bort något så att det kompilerar och länkar OK, och kolla sedan
i MAP filen vad det är som tar plats...
Användarvisningsbild
Icecap
Inlägg: 26139
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Vad är det som äter RAM?

Inlägg av Icecap »

Magnus_K: Om du kan skriva ut dessa strängar ligger de definitivt i RAM!
Nästan alla C-program på µC har en startgrej som kopierar sådana saker från ROM till RAM om det behövs - vilket betyder att de tuggar RAM.
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Vad är det som äter RAM?

Inlägg av Magnus_K »

Hmm, ok.. en erfaren skulle antagligen kunna klämma in det här lätt på RAM:et men jag fixar inte det. Ska förenkla så mycket som möjligt och se vad som händer.

@sodjan:
Lite osäker på vad en MAP-fil är och det verkar inte som att MikroC kan generera en sån när jag söker lite på det.
Jag kommenterade bort "det tyngsta" så den kompilerade utan fel och statistiken för RAM:et syns nedan.

EDIT: Det är verkligen all text och mina två stora arrayer som slukar allt RAM. Rensat bort allt onödigt pladder men arrayerna tillåts inte vara större 45 byte var.
Functions Sorted By Size Chart.jpg
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
johano
Inlägg: 1943
Blev medlem: 22 januari 2008, 10:07:45
Ort: Stockholm

Re: Vad är det som äter RAM?

Inlägg av johano »

Varför behöver buffertarna ha den storleken?
Kanske går att lösa på annat sätt?

/j
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Vad är det som äter RAM?

Inlägg av sodjan »

> Lite osäker på vad en MAP-fil är och det verkar inte som att MikroC kan generera en sån när jag söker lite på det.

Normalt är det en av ut-filerna från länkaren. Där ser man hur de olika variablerna
och annat är allokerat över minnet. Men det ser ut som att MikroC inkluderar
det i sin "List File" istället. OK, men då finns ju informationen där istället.
Bara att kolla.

> Det är verkligen all text [...] som slukar allt RAM.

Har du kollat på "const char code" (sidan 136 i manualen)?
Användarvisningsbild
Icecap
Inlägg: 26139
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Vad är det som äter RAM?

Inlägg av Icecap »

Problemet ligger ju i att den "färdiga" rutinen som används till att skicka till UART inte klarar ROM-baserat text/data. Alltså borde det rätta vara att göra en rutin som klarar att göra detta, sedan är den del klar.

Nästa del är maximal storlek på bufferna och det är svårt att ändra utan att ändra modell på µC. En PIC18Fxxxx hade varit en bättre modell att jobba med.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Vad är det som äter RAM?

Inlägg av sodjan »

Eller en PIC16F1xxx som nog finns i samma storlek och är
mer lik 16F690 fast med mer interna resurser.
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Vad är det som äter RAM?

Inlägg av Magnus_K »

@johano:
Valde den buffer-storleken för att ha samma storlek på MCU:n som i CC1101:an. Dess register är 64 byte stort och FIFO-registret är också 64 bytes så tyckte det verkade klokt för att läsa ut/skriva till allt på en gång.
Någon som kan programmera skulle säkert köra en byte i taget men inte ens det får jag till.

@sodjan:
Det som jag tror spelar roll i "List file" är detta:

Kod: Markera allt

Symbol List:
//** Routines locations **
//ADDRESS    SIZE    PROCEDURE
//----------------------------------------------
0x0003      [16]    _UART1_Init
0x0013      [10]    _UART1_Write
0x001D      [11]    _UART1_Read
0x0028      [43]    _SPI1_Init_Advanced
0x0053       [7]    _UART1_Data_Ready
0x005A       [7]    _____DoICP
0x0061      [13]    _SPI1_Write
0x006E      [22]    _UART1_Write_Text
0x0084      [67]    _UART1_Read_Text
0x00C7      [42]    _BASIC_init
0x00F1      [12]    ___CC2DW
0x00FD      [38]    _main
Det är väl i stort sett samma som bilden jag bifogade innan?
Skulle absolut kunna byta hårdvara men tyckte upplägget blev perfekt med min PicKit2:a. Får dock tänka över det en gång till.
Om jag förstår det rätt så är det väl just "const char code" som dom beskriver väldigt bra i den länken som johano bifogade? Man skapar typ RAM-adresser på ROM:et, eller något sånt?

@Icecap:
Mmm, håller nog med dig. Hade varit hemskt smidigt om funktionen kunde läsa från ROM.

Vi får se var det här slutar. Då jag inte ens får till att skicka/ta emot en enda byte, hur enkelt jag än försöker göra det så går det trögt just nu.
Kommer jag inte igång med kommunikationen under helgen så planerar jag att byta till en annan radiomodul där det finns betydligt mer bibliotek till.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45270
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Vad är det som äter RAM?

Inlägg av TomasL »

Kan du inte använda samma buffer för både RX och TX.
Vad är det du försöker läsa och skriva till?
Användarvisningsbild
Icecap
Inlägg: 26139
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Vad är det som äter RAM?

Inlägg av Icecap »

Magnus_K: funktionen finns ju redan!
pgm_read_byte(s)
Det bör finnas en en "Send denna byte med UART" och då borde det klaras med:

Kod: Markera allt

void Send_String(const char* String)
  {
  while(*String)
    {
    UART_Send_Byte(pgm_read_byte(String));
    String++;
    }
I annat fall man kan göra den själv utan att använda dessa färdiga rutiner.
Man ska kolla flaggan för om UART Tx-register är ledigt. Är det inte väntar man till det är.
Sedan petar man i data som ska sändas.
Klart.
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Vad är det som äter RAM?

Inlägg av Magnus_K »

Men det där pgm_read_byte är bara för AVR:er va? Hittar inget i hjälpfilen om det och det verkar peka mot AVR när jag googlar på funktionen.

Jag ska hitta på något annat, det här klarar jag inte av.
Tack ändå för all hjälp!

@TomasL:
Tror inte jag kan göra det när både UART och SPI ska dela buffer mellan varandra?
Det är (fortfarande) min radiomodul jag försöker snacka med.

Ska göra ett sista försök med en hallonpaj startar ingen ny tråd om det. Kan inte ha 4 ( :wall: ) trådar om samma sak...
Användarvisningsbild
Icecap
Inlägg: 26139
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Vad är det som äter RAM?

Inlägg av Icecap »

OK, det kan vara en AVR, det känns vettigt.

Men det är möjligt och ganska enkelt om man vill.
Användarvisningsbild
swesysmgr
Inlägg: 14172
Blev medlem: 28 mars 2009, 06:56:43
Ort: Göteborg

Re: Vad är det som äter RAM?

Inlägg av swesysmgr »

Magnus_K skrev:Men det där pgm_read_byte är bara för AVR:er va? Hittar inget i hjälpfilen om det och det verkar peka mot AVR när jag googlar på funktionen.

Jag ska hitta på något annat, det här klarar jag inte av.
Tack ändå för all hjälp!

@TomasL:
Tror inte jag kan göra det när både UART och SPI ska dela buffer mellan varandra?
Det är (fortfarande) min radiomodul jag försöker snacka med.

Ska göra ett sista försök med en hallonpaj startar ingen ny tråd om det. Kan inte ha 4 ( :wall: ) trådar om samma sak...
Eller byt till en bättre kompilator?

Går inte hjälpfunktionen "codetxt_to_ramtxt" från foruminlägget som det tidigare länkats till att använda? Ser ut att vara samma problem. Borde finnas ett makro till kompilatorn som löser detta men jag använder inte MikroC.

Kod: Markera allt

const code unsigned char Const_Text1[] = "This is text 1";
const code unsigned char Const_Text2[] = "This is text 2";
const code unsigned char Const_Text3[] = "This is text 3";

char* codetxt_to_ramtxt(const char* ctxt){
  static char txt[20];
  char i;
  for(i =0; txt[i] = ctxt[i]; i++);

  return txt;
}

//......other declarations and functions

void main(){
  //.... your code
  UART1_Init(9600);
  UART1_Write_Text(codetxt_to_ramtxt(Const_Text1));
  UART1_Write_Text(codetxt_to_ramtxt(Const_Text2));
  UART1_Write_Text(codetxt_to_ramtxt(Const_Text3));
}
Användarvisningsbild
adent
Inlägg: 4100
Blev medlem: 27 november 2008, 22:56:23
Ort: Utanför Jönköping
Kontakt:

Re: Vad är det som äter RAM?

Inlägg av adent »

Det här visar tydligt på skillnaden mellan en Harvard-arkitektur och en Von-neumann-arkitektur.

Med Von-Neumann-ariktektur har man EN enda adressbuss. Man har sin adressrymd från t.ex. 0x0000 till 0xFFFF

Därunder hittar man allt: flash, ram och register. (T.ex register från 0x0000 till 0x02FF, RAM från 0x0300 till 0x10FF och flash från 0x1100 till 0x90FF och resten används inte).
Så en helt vanlig pekare i koden kan peka på ram, flash eller ett register.

Har man då en funktion som tar en "char *" in så kan man kasta in en adress som pekar till RAM eller Flash eller t.om. register, det funkar fint.

Skriver man:

char *mystring ="Hej alla glada!";

så kommer C-kompilatorn se till att texten "Hej alla glada!" hamnar i flash, sedan kommer c_init eller liknande som körs före din main() att
kopiera in strängen från flash till ram och därefter se till att mystring pekar till rätt ställe i RAM. Lite dubbellagring så att säga.

Skriver man istället:

const char *mystring = "Hej alla glada!";

Så betyder det att det pekaren pekar på inte kan/ska/får ändra på sig (texten). Alltså kan kompilatorn välja att stoppa texten i flash enbart, ingen kopiering till RAM behövs och
dessutom kan pekaren mystring peka direkt till texten i flash och allt är frid och fröjd. I en von-neumann-arkitektur då.

(MSP430, PIC24 är Von-neumann) (8-bitars AVR:er (och pic:ar?) är Harvard-arkitektur).

Eftersom din Pic är en hardvard-aktiktetur så hjälper det inte att skriva: const char *mystring ="Min fina sträng"; eftersom
den inte KAN peka rätt in i flash, flash har en helt egen adress-rymd t.ex.

Flash: 0x0000 till 0x7FFF
RAM: 0x0000 till 0x07FF

Processorn hanterar dem på olika sätt och det är inte transparent om det är flash eller RAM, man måste veta.
Och det är precis detta problem som vi försöker komma runt som ni märkt. Ska man själva skriva en funktion
kan man förstås se till att man läser en byte i taget från flash på det specialsätt som erbjuds. Det blir helt
klart värre när man har en färdig funktion som kräver en sträng (char *) in.

I tråden har vi sett ett exempel som har EN enda ram-buffert och där man läser in en sträng från flash till RAM
innan man kastar in den till funktionen som kräver en char *, sedan återanvänder man samma ram-buffert nästa gång, men för att
läsa in en annan sträng från flash.

Ärligt talat vet jag inte om jag tillförde något i tråden, möjligen att förklara just skillnaden mellan de bägge arkitekturerna och att
det är den som spökar...

MVH: Mikael
Användarvisningsbild
Icecap
Inlägg: 26139
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Vad är det som äter RAM?

Inlägg av Icecap »

Det går utmärkt att ha konstanter i ROM och läsa ut dom "on the fly". Instruktionen RETLW är lösningen, att skapa en funktion som hämtar data från ROM lär inte vara ett problem.

Men jag menar faktisk att det finns, kanske även i MikroC. Det är bara en fråga om att hitta rätt namn på rutinen - eller skapa den själv.
Skriv svar