Dynamisk minneshantering i AVR?
Dynamisk minneshantering i AVR?
En polare till mej frågade hur han ska gå tillväga för att läsa in ett godtyckligt antal värden via USART till en Atmega16. Han skall läsa in x, y, z och lägga i en vektor.
Jag kom på att jag inte har nån aning om ifall man kan använda dynamisk minneshantering i AVRstudio/gcc som jag tror han använder. Kan man det? Hur löser man det annars?
Han vill alltså läsa in:
x, y, z
x, y, z
x, y, z
...
...
..
ett ospeciferat antal gånger.
Jag kom på att jag inte har nån aning om ifall man kan använda dynamisk minneshantering i AVRstudio/gcc som jag tror han använder. Kan man det? Hur löser man det annars?
Han vill alltså läsa in:
x, y, z
x, y, z
x, y, z
...
...
..
ett ospeciferat antal gånger.
Antalet värden kanske det är "ospecificerat", men det måste
rimligtsvis finnas ett *max* antal värden. Börja med att välja
en processor med tillräckligt med minne för detta antal.
Sen vet jag inte vad som är problemet !?
Bara att definiera en buffert som klarar *max* antal värden, och börja läsa in...
rimligtsvis finnas ett *max* antal värden. Börja med att välja
en processor med tillräckligt med minne för detta antal.
Sen vet jag inte vad som är problemet !?
Bara att definiera en buffert som klarar *max* antal värden, och börja läsa in...
Rent generellt så är dynamisk minneshantering inte så lyckad i en mikrokontroller. Du har oftast begränsat med minne och ingen swap att nyttja så du måste ändå begränsa dig beroende på mängden minne.
I vissa fall skulle det kunna vara bra att ha ändå. Om man har en viss mängd minne men vill kunna använda det till x antal av objekt A eller y antal av objekt B etc. Men fortfarande måste man på något sätt hålla koll på hur mycket utrymme det tar.
Om GCC stöder det rent programmatiskt i mikrokontrollers, vet jag inte.
I vissa fall skulle det kunna vara bra att ha ändå. Om man har en viss mängd minne men vill kunna använda det till x antal av objekt A eller y antal av objekt B etc. Men fortfarande måste man på något sätt hålla koll på hur mycket utrymme det tar.
Om GCC stöder det rent programmatiskt i mikrokontrollers, vet jag inte.
Är det inte ganska inneffektivt att försöka köra med helt dynamisk
allokering vid runtime på en mikrokontroller. Man har i alla fall så
pass "dåligt" med minne att man nog får försöka tänka till lite själv
istället...
> Om man har definierat ett maxvärde.
Det är inget *om*, det *måste* man i princip göra...
allokering vid runtime på en mikrokontroller. Man har i alla fall så
pass "dåligt" med minne att man nog får försöka tänka till lite själv
istället...
> Om man har definierat ett maxvärde.
Det är inget *om*, det *måste* man i princip göra...
> dock blev jag inte speciellt mkt klokare.
Jasså ? Vad var det som var oklart ?
Jag förstår inte riktigt problemet, ingen "dynamisk minneshantering" i världen
kan få in dubbelt så många värden som det finns minne till.
Sen är det naturligtsvis så att man inte bara kan sätta ett maxvärde
lite hur som helst, dels måste det passa applikationen, dels måste det
finnas (väljas) en processor som matchar kraven. Ibland kan man låta
applikationen styra valet av processor, ibland är det tvärt om. Det är en
del av designprocessen. Man får alltså sitta med "Line Card" över
tillgängliga processorer samtidigt som man funderar på hur applikationen
ska se ut. Försöker man designa en applikation utan att ta hänsyn till
processorerna blir det ofta pannkaka...
Jasså ? Vad var det som var oklart ?
Jag förstår inte riktigt problemet, ingen "dynamisk minneshantering" i världen
kan få in dubbelt så många värden som det finns minne till.
Sen är det naturligtsvis så att man inte bara kan sätta ett maxvärde
lite hur som helst, dels måste det passa applikationen, dels måste det
finnas (väljas) en processor som matchar kraven. Ibland kan man låta
applikationen styra valet av processor, ibland är det tvärt om. Det är en
del av designprocessen. Man får alltså sitta med "Line Card" över
tillgängliga processorer samtidigt som man funderar på hur applikationen
ska se ut. Försöker man designa en applikation utan att ta hänsyn till
processorerna blir det ofta pannkaka...

Kanske, men det är inte poängen !
Utan att veta vilket *MAX* antal värden man kommer att
hantera kan man inte välja processor (d.v.s m.a.p minnesstorlek)...
Jag kan inte riktigt se behovet av malloc() i en PIC/AVR kompilator.
Så varför testa ??
Och i så fall, varfär testa genom att skriva kod ??
RTFM till kompilatorn lär räcka ganska långt...
Utan att veta vilket *MAX* antal värden man kommer att
hantera kan man inte välja processor (d.v.s m.a.p minnesstorlek)...
Jag kan inte riktigt se behovet av malloc() i en PIC/AVR kompilator.
Så varför testa ??
Och i så fall, varfär testa genom att skriva kod ??
RTFM till kompilatorn lär räcka ganska långt...
Dynamisk minneshantering är bra till mycket men precis som sodjan påpekar kan man inte, hur dynamisk minneshantering man än har, peta in 10KB på 2KB minne!
Är det så att man löser olika uppgifter och behöver minnet till antingen det ena eller det andra är det bra med att kunna allokera om minnet.
Så fakta kvarstår: Det går fint att ladda in ett antal värden.... till en viss gräns, sedan är det stopp. Om man ändå vill ladda in får man ta till en ring-buffer vilket i sin tur betyder att de sista talen kommer att bli överskrivna. På det vis kan man ladda in oändliga mängder data men man har bara det senaste X antal i minnet.
Är det så att man löser olika uppgifter och behöver minnet till antingen det ena eller det andra är det bra med att kunna allokera om minnet.
Så fakta kvarstår: Det går fint att ladda in ett antal värden.... till en viss gräns, sedan är det stopp. Om man ändå vill ladda in får man ta till en ring-buffer vilket i sin tur betyder att de sista talen kommer att bli överskrivna. På det vis kan man ladda in oändliga mängder data men man har bara det senaste X antal i minnet.
Dumt av mej att fråga "hur gör man annars?" när jag egentligen visste det... 
Men det där med ringbuffer skulle kunna funka i hans fall då han ska läsa in massa data som sen skall styra en CNC. Då gör det ju inget om man skriver över de första koordinaterna när man har använt dom.
Jag tror iof att han har så pass lite data att allt får plats i minnet, men jag vet inte något om hans projekt egentligen.

Men det där med ringbuffer skulle kunna funka i hans fall då han ska läsa in massa data som sen skall styra en CNC. Då gör det ju inget om man skriver över de första koordinaterna när man har använt dom.
Jag tror iof att han har så pass lite data att allt får plats i minnet, men jag vet inte något om hans projekt egentligen.
Aha !
Så det är det det ska användas till...
Ja då är det ju bara att bestämma en buffertstorlek i AVR'en samt
ett lämpligt protokoll mot det överordnade systemet så att dataströmmen
kan styras från AVR'en, vilket i sig naturligtsvis är beroende på hur snabbt
CNC maskinen utför de olika kommandona...
En ring buffert med två pekare, en som pekar på nästa kommando för CNC
maskinen, och en som pekar där nästa kommando från det överordnade
systemet ska lagras. Sedan en räknare som håller reda på hur många
kommandon bufferten innehåller. Varje gång ett kommando utförs av CNC
maskinen räknas räknaren ner med ett (och pekaren flyttas), och varje
gång ett kommando kommer från det överordnade systemet räknas
räknaren upp (och *den* pakeren flyttas).
När ett kommando läggs in kollas om den övre gränsen för bufferten är
uppnåd, då skickas "stopp" till det överordnade systemet.
När ett kommando skickas till CNC maskinen kollas om den undre
gränsen är uppnåd, då skickas "start" till det överordnade systemet.
Var de två gränserna ska sättas är antingen uppenbart för den som
känner till miljön, eller får provas fram.
Alternativet är att CNC maskinen och det överordnade systemet har en
annan kommunikationskanal där start/stop kan skickas...
*Eller* att man räknar med att kunna lagra *hela* det aktuella CNC
"progrmmat" lokalt i AVR'en...
Så det är det det ska användas till...
Ja då är det ju bara att bestämma en buffertstorlek i AVR'en samt
ett lämpligt protokoll mot det överordnade systemet så att dataströmmen
kan styras från AVR'en, vilket i sig naturligtsvis är beroende på hur snabbt
CNC maskinen utför de olika kommandona...
En ring buffert med två pekare, en som pekar på nästa kommando för CNC
maskinen, och en som pekar där nästa kommando från det överordnade
systemet ska lagras. Sedan en räknare som håller reda på hur många
kommandon bufferten innehåller. Varje gång ett kommando utförs av CNC
maskinen räknas räknaren ner med ett (och pekaren flyttas), och varje
gång ett kommando kommer från det överordnade systemet räknas
räknaren upp (och *den* pakeren flyttas).
När ett kommando läggs in kollas om den övre gränsen för bufferten är
uppnåd, då skickas "stopp" till det överordnade systemet.
När ett kommando skickas till CNC maskinen kollas om den undre
gränsen är uppnåd, då skickas "start" till det överordnade systemet.
Var de två gränserna ska sättas är antingen uppenbart för den som
känner till miljön, eller får provas fram.
Alternativet är att CNC maskinen och det överordnade systemet har en
annan kommunikationskanal där start/stop kan skickas...
*Eller* att man räknar med att kunna lagra *hela* det aktuella CNC
"progrmmat" lokalt i AVR'en...