Programmering: Kod till buffer samt söka igenom buffern

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
foal
Inlägg: 31
Blev medlem: 27 november 2012, 08:23:39

Programmering: Kod till buffer samt söka igenom buffern

Inlägg av foal »

Hej!

Håller på med ett projekt där jag ska skicka paket över USB CDC till en PIC18F25K50. Överföringen från PC till PIC kommer att ske i paket som är 15 byte långa med {{{ som start och }}} som slut.
Alltså, {{{xxxxxxxxx}}} där x är data jag vill åt.

Jag har funderat på att implementera en cirkulär buffer där jag kan lägga inkommande data men fastnar på hur jag ska hitta paketen och hur jag ska hantera skräpdata som inte tillhör paketen. Tycker dock att det här borde vara en mycket vanlig uppgift och tänkte höra vad ni har för erfarenheter kring liknande implementeringar?

Till projektet utgår jag från microchips CDC - Basic Demo. Demon ekar bara tillbaka det den tagit emot och koden för den funktionen ser ut enligt nedan.

Kod: Markera allt

		
numBytesRead = getsUSBUSART(USB_Out_Buffer,64);
if(numBytesRead != 0)
{
	BYTE i;
       
	for(i=0;i<numBytesRead;i++)
	{
	USB_In_Buffer[i] = USB_Out_Buffer[i];
	}
}
putUSBUSART(USB_In_Buffer,numBytesRead);
Lite info om getsUSBUSART funktionen:
getsUSBUSART copies a string of BYTEs received through USB CDC Bulk OUT endpoint to a user's specified location. Returns a byte indicating the total number of bytes that were actually received and copied into the specified buffer.
sodjan
EF Sponsor
Inlägg: 43241
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Programmering: Kod till buffer samt söka igenom buffern

Inlägg av sodjan »

> Jag har funderat på att implementera en cirkulär buffer där jag kan lägga inkommande
> data men fastnar på hur jag ska hitta paketen...

Alltså förrutom att leta efter "{{{" och "}}}" ?
Det verkar ju annars vara det logiska svaret.

> ...och hur jag ska hantera skräpdata som inte tillhör paketen.

Är det "skräpdata" mellan "{{{" och "}}}" eller mellan "}}}" och "{{{" ?

Varför just "{{{" och "}}}" som avgränsare av paketen?
Det är sannolikt enklare att leta efter entaka unika tecken.
Kan paketen innehålla vilka "byte" som helst?
ie
EF Sponsor
Inlägg: 1371
Blev medlem: 23 oktober 2006, 13:12:57
Ort: Tyresö

Re: Programmering: Kod till buffer samt söka igenom buffern

Inlägg av ie »

1. Läs tecken till du hittar ett '{'
2. Läs nästa tecken, om '{' gå till 3 annars till 1
3. Läs nästa tecken, om '{' gå till 4 annars till 1
4. Läs tecken, om '}' gå till 5, annars lägg i "buffer" och gå till 4
5. Läs nästa tecken, om '}' gå till 6 annars till 1
6. Läs nästa tecken, om '}' gå till 7 annars till 1
7. Ok paket finns i "buffer" (om ev checksumma är ok)
Användarvisningsbild
Icecap
Inlägg: 26621
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Programmering: Kod till buffer samt söka igenom buffern

Inlägg av Icecap »

Jag "packar in" de datapaket jag skickar mellan enheter men jag använder ett STX och ett ETX som start hhv. stopp.
STX nollställer inputpekaren och rensar per definition inputbuffern.
ETX aktiverar en "behandla inkomna data"-funktion.

Allt som kommer mellan ETX och STX är helt bortkastat och stör inget.

Att använda fler tecken som start och stopp ser jag som en stor nackdel, det kan dock finnas grund till detta men då kan det lösas på ett annat sätt som gör det enklare att känna igen dessa saker.
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Programmering: Kod till buffer samt söka igenom buffern

Inlägg av jesse »

Att STX nollställer inputpekaren ser jag som potentiellt riskfyllt. Det innebär att om meddelande nr2 kommer in innan du hunnit läsa färdigt meddelande nr1 så skrivs nr1 över av nr2. Därför brukar jag använda roterande buffert, dvs meddelande nr2 kommer direkt efter nr1 i bufferten. Det medger flera meddelanden i rad (om bufferten är tillräckligt stor) om någonting skulle ta lång tid.
foal
Inlägg: 31
Blev medlem: 27 november 2012, 08:23:39

Re: Programmering: Kod till buffer samt söka igenom buffern

Inlägg av foal »

Datat kan innehålla precis vad som helst, där ibland { och }. Därför använder jag flera bytes som start och stop. Helt enkelt minska sannolikheten att datat ska gestalta ett start eller stoptecken.

Jag har varit inne på något liknande som ie beskriver då det verkar vara det enklaste sättet. Dock insåg jag att det kan bli problem om inte hela sändningen har avslutats, dvs inte hela paketet ligger i buffern när funktionen körs. I så fall kommer bara {{{ och lite data hittas men inte }}}. Paketet får då inte slängas utan pekarna måste stå kvar på samma position även nästa gång funktionen körs.

Icecaps metod låter mycket intressant. Hur signalerar du STX och ETX? Med unika bytes?
Användarvisningsbild
Icecap
Inlägg: 26621
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Programmering: Kod till buffer samt söka igenom buffern

Inlägg av Icecap »

Om data kan innehålla precis alla tecken får man gå till den binäre överföring.

Men i mitt fall är det uteslutande ren text som överförs, alltså duger ASCII STX (0x02) och ETX (0x03) utmärkt.

Men behöver man en binär synkronisering väljer man ett byte-värde som "escape"-tecken. För diskutionens skull väljer jag 0x10 men det kan vara precis vad som helst.

Om 0x10 avkänns i byte-strömmen kollas nästa byte också! Om nästa byte är:
0x10 är det verkliga datavärdet en 0x10 byte. 0x10 0x10 blir alltså en 0x10 byte.
0x01 tolkas som STX. 0x10 0x01 blir alltså STX.
0x02 tolkas som ETX. 0x10 0x02 blir ETX.

Jesse: helt korrekt. Därför brukar jag ha en timeout på dessa data.Om det kommer en ETX ställs denna timeout-variabel till ett värde. Variabeln räknas ner av en systemtimer om den är icke-noll men i main-loop finns det en funktion som kollar om den är icke-noll också. Är den det finns det ett meddelande som ska bearbetas, detta sker då i main-loop och timeouten nollas.

Nya data tas inte emot så länge timeouten är icke-noll, alltså kan ett meddelande inte raderas innan det är behandlat eller för gammalt och main-loop får en lagom frist att tugga igenom det.

Detta sätt är skalbart och jag kör ibland 4-6 UART samtidig som kör på detta vis, då kan jag överföra från interruptstyrd mottagning till asynkron behandling av data, det säkrar snabba ISR och stabila kommunikationer.
hummel
Inlägg: 2525
Blev medlem: 28 november 2009, 10:40:52
Ort: Stockholm

Re: Programmering: Kod till buffer samt söka igenom buffern

Inlägg av hummel »

Lägg med en checksumma av data i varje meddelande för att säkerställa att informationen överförs korrekt.
sodjan
EF Sponsor
Inlägg: 43241
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Programmering: Kod till buffer samt söka igenom buffern

Inlägg av sodjan »

> Datat kan innehålla precis vad som helst, där ibland { och }.

Och alltså även "{{{" eller "}}}" ?

> Därför använder jag flera bytes som start och stop. Helt enkelt minska
> sannolikheten att datat ska gestalta ett start eller stoptecken.

Är det inte bättre med en metod och ett format som helt *utesluter* det ?
Om du har kontroll över (d.v.s din egen kod) i båda ändar så är det ju inget problem.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46878
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Programmering: Kod till buffer samt söka igenom buffern

Inlägg av TomasL »

Kör med 9-bitars kod, då behöver du inte använda några start eller stopp-tecken.
Sätt bit 9 i första byten i datagrammet, resterande byte sätter du den till 0.
Då behöver du bara kontrollera den nionde biten vilket är enkelt, är den satt så vet du att det är den första byten, sedan är det bara att räkna hur många byte du får.
Är det för få eller för många när du får nästa byte med den nionde biten satt, så vet du att något är fel.
Sedan kan ju du få rätt antal byte, men att det fortfarande är skräp, det får du kontrollera med en checksumma.
foal
Inlägg: 31
Blev medlem: 27 november 2012, 08:23:39

Re: Programmering: Kod till buffer samt söka igenom buffern

Inlägg av foal »

Jag gillar ändå idén med någon form av start och stop då det underlättar när buffern ska sökas igenom.

Jag har istället funderat på att försöka få till några unika tecken. Då det bara är kommandon som ska skickas och dessa inte skickas särskilt ofta finns inga större prestandakrav på överföringen. En tanke är därför att bara använda 4 bitar av varje byte till datat. I så fall kan jag använda dom 4 övre bitarna för att skapa unika tecken för start och stop. Optimerar jag det ordentligt så kommer jag ner till 15 byte vilket är precis det jag hade från början. Så jag tror att det blir vägen att gå. Synpunkter på detta?
sodjan
EF Sponsor
Inlägg: 43241
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Programmering: Kod till buffer samt söka igenom buffern

Inlägg av sodjan »

> Kör med 9-bitars kod...

Det skulle jag inte generellt rekomendera.
Det kan bli problem när man t.ex vill testköra eller
felsöka med en terminalemulator i ena änden. Och
just med tanke på det så vill jag gärna ha med CRLF
som, i alla fall en del av, slutet på packetet, det ger snygga
utskrifter på terminalen av trafiken. Helt ovärderligt vid felsökning...

> finns inga större prestandakrav på överföringen.

OK. Då kan du ju se till att datat är rent och snyggt, allt kodat som vanliga
ASCII 0-9 och A-Z o.s.v. Börja paketet med en LF och avsluta med en CR.
På en terminal blir det snygga och helt läsbara rader för varje paket.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46878
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Programmering: Kod till buffer samt söka igenom buffern

Inlägg av TomasL »

Att debugga kan bli lite konstigt, förvisso (utan rätt verktyg), dock är det så stora fördelar med det, så det uppväger den lilla nackdelen.
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Programmering: Kod till buffer samt söka igenom buffern

Inlägg av jesse »

Du verkar vilja skriva/läsa både binäer och ascii samtidigt. Det kan bli lite förvirrande när du ska kommunicera. Antingen kör du binärt helt och hållet (alltså tecken som skickas anges i hexadecimal form, t.ex. 0x00, 0x01, 0xff... Eller så kör du enbart ASCII, och då ska du inte sända några andra data än godkända tecken!

Sodjan föreslår t.ex. att en rad alltid ska avslutas med CRLF, alltså tecknen för "return" och "ny rad" i ASCII-tabellen. Det fungerar givetvis bara om du i övrigt bara sänder ASCII. En rad kan då börja med ett specialtecken, t.ex. '$' , följt av data i form av bokstäver, siffror, kommatecken eller vad du vill, samt avslutas med CR/LF. Ska du skicka en massa binär data så är hexadecimal kod i ASCII-form ett utmärkt sätt, och blir även lätt att felsöka.

En rad kan då se ut så här, om du ska skicka 16 bytes binära data som hexadecimalt ASCII:
$10000102030405060708090A0B0C0D0E0FE3 (avlutas med CRLF)

$ = starttecken
10 = antal bytes data
.... data
E3 = checksumma (beräknas samtidigt som man skickar / tar emot data)
sodjan
EF Sponsor
Inlägg: 43241
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Programmering: Kod till buffer samt söka igenom buffern

Inlägg av sodjan »

Ja, alltså, det hela är ju väldigt beroende på *VAD* som ska skickas,
det har vi inte en susning om just nu. :-)

Angående 9-bit tecken...

> Att debugga kan bli lite konstigt, förvisso (utan rätt verktyg), dock är det så stora
> fördelar med det, så det uppväger den lilla nackdelen.

Och jag hävdar att det är ENORMA fördelar med en enkel felsökning/debugging! :-)

Man kan både enkelt lyssna på vad sändaran skickar och visa det i t.ex en vanlig
Putty session, eller använda samma Putty och skicka testdata till mottagaren.
Man kan ha färdigt testdata i ett vanligt Notepad fönster och bara cut/paste
till Putty för att skicka testdata till mottagaren. Priceless... :-)
Skriv svar